Lots of random changes.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1107 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1996-12-15 21:30:34 +00:00
parent dfdad286ad
commit fad81ed299
38 changed files with 3453 additions and 372 deletions

View File

@@ -8,7 +8,9 @@ lib_LIBRARIES = krb5
krb5_SOURCES = cache.c config_file.y constants.c context.c data.c \
get_addrs.c get_cred.c get_in_tkt.c get_in_tkt_pw.c get_port.c \
krbhst.c misc.c principal.c principal_p.c send_to_kdc.c str2key.c
krbhst.c misc.c principal.c principal_p.c send_to_kdc.c str2key.c \
mit-crc.c build_ap_req.c build_auth.c mk_req.c get_host_realm.c \
auth_context.c rd_rep.c keytab.c
config_file.c: config_file.y
$(YACC) -p __k5cf_ $<

27
lib/krb5/auth_context.c Normal file
View File

@@ -0,0 +1,27 @@
#include "krb5_locl.h"
krb5_error_code
krb5_auth_con_init(krb5_context context,
krb5_auth_context **auth_context)
{
krb5_auth_context *p;
p = ALLOC(1, krb5_auth_context);;
if(!p)
return ENOMEM;
memset(p, 0, sizeof(p));
p->authenticator = ALLOC(1, krb5_authenticator);
if (!p->authenticator)
return ENOMEM;
*auth_context = p;
return 0;
}
krb5_error_code
krb5_auth_con_free(krb5_context context,
krb5_auth_context *auth_context,
krb5_flags flags)
{
free (auth_context->authenticator);
free (auth_context);
return 0;
}

60
lib/krb5/build_ap_req.c Normal file
View File

@@ -0,0 +1,60 @@
#include <krb5_locl.h>
#include <krb5_error.h>
krb5_error_code
krb5_build_ap_req (krb5_context context,
krb5_creds *cred,
krb5_flags ap_options,
krb5_data authenticator,
krb5_data *ret)
{
AP_REQ ap;
Ticket t;
des_cblock key;
des_key_schedule schedule;
u_int32_t crc;
unsigned char *p;
unsigned char buf[1024];
ap.pvno = 5;
ap.msg_type = krb_ap_req;
memset(&ap.ap_options, 0, sizeof(ap.ap_options));
if (ap_options & AP_OPTS_USE_SESSION_KEY)
ap.ap_options.use_session_key = 1;
if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
ap.ap_options.mutual_required = 1;
ap.ticket.tkt_vno = 5;
ap.ticket.realm = malloc(cred->server->realm.length + 1);
strncpy(ap.ticket.realm, cred->server->realm.data,
cred->server->realm.length);
ap.ticket.realm[cred->server->realm.length] = '\0';
krb5_principal2principalname(&ap.ticket.sname, cred->server);
decode_Ticket(cred->ticket.data, cred->ticket.length, &t);
ap.ticket.enc_part.etype = t.enc_part.etype;
ap.ticket.enc_part.kvno = NULL;
ap.ticket.enc_part.cipher = t.enc_part.cipher;
memcpy(&key, cred->session.contents.data, sizeof(key));
des_set_key (&key, schedule);
/* authenticator */
des_cbc_encrypt (authenticator.data,
authenticator.data,
authenticator.length,
schedule, &key, DES_ENCRYPT);
ap.authenticator.etype = ap.ticket.enc_part.etype;
ap.authenticator.kvno = NULL;
ap.authenticator.cipher = authenticator;
ret->length = encode_AP_REQ(buf + sizeof(buf) - 1, sizeof(buf), &ap);
ret->data = malloc(ret->length);
memcpy (ret->data, buf + sizeof(buf) - ret->length, ret->length);
return 0;
}

52
lib/krb5/build_auth.c Normal file
View File

@@ -0,0 +1,52 @@
#include <krb5_locl.h>
#include <krb5_error.h>
#include <md4.h>
krb5_error_code
krb5_build_authenticator (krb5_context context,
krb5_principal client,
Checksum *cksum,
Authenticator **auth_result,
krb5_data *result)
{
struct timeval tv;
Authenticator *auth = malloc(sizeof(*auth));
char buf[1024];
unsigned char *p;
int len;
struct md4 m;
u_int32_t crc;
if (auth_result)
*auth_result = auth;
auth->authenticator_vno = 5;
auth->crealm = malloc(client->realm.length + 1);
strncpy(auth->crealm, client->realm.data, client->realm.length);
auth->crealm[client->realm.length] = '\0';
krb5_principal2principalname(&auth->cname, client);
gettimeofday(&tv, NULL);
auth->cusec = tv.tv_usec;
auth->ctime = tv.tv_sec;
auth->subkey = NULL;
auth->seq_number = NULL;
auth->authorization_data = NULL;
auth->cksum = cksum;
memset (buf, 0, sizeof(buf));
len = encode_Authenticator(buf + sizeof(buf) - 9,
sizeof(buf) - 8 - 12,
auth);
p = buf + sizeof(buf) - 8 - len;
p -= 12;
len += 12;
len = (len + 7) & ~7;
crc_init_table ();
crc = crc_update(p, len, 0);
memcpy(p + 8, &crc, 4);
result->length = len;
result->data = malloc(len);
memcpy(result->data, p, len);
return 0;
}

View File

@@ -246,7 +246,7 @@ store_keyblock(int fd, krb5_keyblock p)
static krb5_error_code
ret_keyblock(int fd, krb5_keyblock *p)
{
ret_int32(fd, (int32_t*)&p->keytype);
ret_int32(fd, (int32_t*)&p->keytype); /* keytype + etype */
ret_data(fd, &p->contents);
return 0;
}
@@ -274,7 +274,7 @@ ret_times(int fd, krb5_times *times)
static krb5_error_code
store_address(int fd, krb5_address p)
{
store_int32(fd, p.type);
store_int16(fd, p.type);
store_data(fd, p.address);
return 0;
}
@@ -282,7 +282,7 @@ store_address(int fd, krb5_address p)
static krb5_error_code
ret_address(int fd, krb5_address *adr)
{
ret_int32(fd, (int32_t*)&adr->type);
ret_int16(fd, (int16_t*)&adr->type);
ret_data(fd, &adr->address);
return 0;
}
@@ -308,20 +308,6 @@ ret_addrs(int fd, krb5_addresses *adr)
return 0;
}
static krb5_error_code
store_ticket(int fd, krb5_ticket p)
{
store_data(fd, p.enc_part);
return 0;
}
static krb5_error_code
ret_ticket(int fd, krb5_ticket *tkt)
{
ret_data(fd, &tkt->enc_part);
return 0;
}
static krb5_error_code
store_authdata(int fd, krb5_data p)
{
@@ -430,8 +416,8 @@ krb5_cc_store_cred(krb5_context context,
store_int32(fd, 0); /* flags */
store_addrs(fd, creds->addresses);
store_authdata(fd, creds->authdata);
store_ticket(fd, creds->ticket);
store_ticket(fd, creds->second_ticket);
store_data(fd, creds->ticket);
store_data(fd, creds->second_ticket);
close(fd);
return 0; /* XXX */
}
@@ -440,19 +426,30 @@ static krb5_error_code
krb5_cc_read_cred (int fd,
krb5_creds *creds)
{
int ret;
int8_t dummy8;
int32_t dummy32;
return ret_principal (fd, &creds->client) ||
ret_principal (fd, &creds->server) ||
ret_keyblock (fd, &creds->session) ||
ret_times (fd, &creds->times) ||
ret_int8 (fd, &dummy8) ||
ret_int32 (fd, &dummy32) ||
ret_addrs (fd, &creds->addresses) ||
ret_authdata (fd, &creds->authdata) ||
ret_ticket (fd, &creds->ticket) ||
ret_ticket (fd, &creds->second_ticket);
ret = ret_principal (fd, &creds->client);
if(ret) return ret;
ret = ret_principal (fd, &creds->server);
if(ret) return ret;
ret = ret_keyblock (fd, &creds->session);
if(ret) return ret;
ret = ret_times (fd, &creds->times);
if(ret) return ret;
ret = ret_int8 (fd, &dummy8);
if(ret) return ret;
ret = ret_int32 (fd, &dummy32);
if(ret) return ret;
ret = ret_addrs (fd, &creds->addresses);
if(ret) return ret;
ret = ret_authdata (fd, &creds->authdata);
if(ret) return ret;
ret = ret_data (fd, &creds->ticket);
if(ret) return ret;
ret = ret_data (fd, &creds->second_ticket);
return ret;
}
krb5_error_code
@@ -462,7 +459,17 @@ krb5_cc_retrieve_cred(krb5_context context,
krb5_creds *mcreds,
krb5_creds *creds)
{
return 0; /* XXX */
krb5_error_code ret;
krb5_cc_cursor cursor;
krb5_cc_get_first(context, id, &cursor);
while((ret = krb5_cc_get_next(context, id, creds, &cursor)) == 0){
if(krb5_principal_compare(context, mcreds->server, creds->server)){
ret = 0;
break;
}
}
krb5_cc_end_get(context, id, &cursor);
return ret;
}
krb5_error_code
@@ -527,7 +534,15 @@ krb5_cc_get_first(krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
{
return 0; /* XXX */
int fd;
int16_t tag;
krb5_principal principal;
fd = open(krb5_cc_get_name (context, id), O_RDONLY);
cursor->fd = fd;
ret_int16(fd, &tag);
ret_principal(fd, &principal);
return 0;
}
krb5_error_code
@@ -536,7 +551,7 @@ krb5_cc_get_next(krb5_context context,
krb5_creds *creds,
krb5_cc_cursor *cursor)
{
return 0; /* XXX */
return krb5_cc_read_cred(cursor->fd, creds);
}
krb5_error_code
@@ -544,7 +559,8 @@ krb5_cc_end_get(krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
{
return 0; /* XXX */
close(cursor->fd);
return 0;
}
krb5_error_code

33
lib/krb5/crc.c Normal file
View File

@@ -0,0 +1,33 @@
#include <stdio.h>
#include "crc.h"
static u_long table[256];
void
crc_init_table( )
{
unsigned long crc, poly;
int i, j;
poly = 0xEDB88320L;
for (i = 0; i < 256; i++) {
crc = i;
for (j = 8; j > 0; j--) {
if (crc & 1) {
crc = (crc >> 1) ^ poly;
} else {
crc >>= 1;
}
}
table[i] = crc;
}
}
u_long
crc_update (char *p, size_t len, u_long res)
{
res ^= 0xFFFFFFFF;
while (len--)
res = table[(res ^ *p++) & 0xFF] ^ (res >> 8);
return res & 0xFFFFFFFF;
}

6
lib/krb5/crc.h Normal file
View File

@@ -0,0 +1,6 @@
#include <sys/types.h>
#define CRC_GEN 0xEDB88320L
void crc_init_table ();
u_long crc_update (char *p, size_t len, u_long res);

View File

@@ -1,82 +1,316 @@
#include <krb5_locl.h>
#include <krb5_error.h>
#include <md4.h>
/*
*
*/
static krb5_error_code
key_proc (krb5_context context,
krb5_keytype type,
krb5_data *salt,
krb5_const_pointer keyseed,
krb5_keyblock **key)
{
*key = malloc (sizeof (**key));
if (*key == NULL)
return ENOMEM;
(*key)->keytype = type;
(*key)->contents.length = 8;
(*key)->contents.data = malloc(8);
memcpy((*key)->contents.data, keyseed, 8);
return 0;
}
int
extract_ticket(krb5_context context,
krb5_kdc_rep *rep,
krb5_creds **creds,
krb5_key_proc key_proc,
krb5_const_pointer keyseed,
krb5_decrypt_proc decrypt_proc,
krb5_const_pointer decryptarg);
krb5_error_code
krb5_get_credentials (krb5_context context,
krb5_flags options,
krb5_ccache ccache,
krb5_creds *in_creds,
krb5_creds *out_creds)
krb5_creds **out_creds)
{
return 17;
}
krb5_error_code err;
TGS_REQ a;
Authenticator auth;
krb5_data authenticator;
Checksum c;
AP_REQ ap;
krb5_kdc_rep rep;
KRB_ERROR error;
krb5_data req, resp;
char buf[BUFSIZ];
int i;
unsigned char data[1024], buf2[1024];
int len;
PA_DATA foo;
des_key_schedule schedule;
des_cblock key;
/*
* XXX - Check if cred found in ccache
*/
/*
* Prepare Tgs_Req.
*/
err = krb5_get_default_in_tkt_etypes (context,
(krb5_enctype**)&a.req_body.etype.val);
if (err)
return err;
a.req_body.etype.len = 1;
a.req_body.addresses = malloc(sizeof(*a.req_body.addresses));
err = krb5_get_all_client_addrs ((krb5_addresses*)a.req_body.addresses);
if (err)
return err;
a.pvno = 5;
a.msg_type = krb_tgs_req;
memset (&a.req_body.kdc_options, 0, sizeof(a.req_body.kdc_options));
/* a.kdc_options */
a.req_body.realm = malloc(in_creds->server->realm.length + 1);
strncpy (a.req_body.realm, in_creds->server->realm.data,
in_creds->server->realm.length);
a.req_body.realm[in_creds->server->realm.length] = '\0';
a.req_body.sname = malloc(sizeof(*a.req_body.sname));
krb5_principal2principalname(a.req_body.sname, in_creds->server);
a.req_body.from = NULL;
a.req_body.till = in_creds->times.endtime;
a.req_body.rtime = NULL;
a.req_body.nonce = getpid();
a.req_body.additional_tickets = NULL;
a.req_body.enc_authorization_data = NULL;
{
char buf[1024];
int len;
struct md4 m;
Checksum c;
len = encode_KDC_REQ_BODY(buf + sizeof(buf) - 1, sizeof(buf),
&a.req_body);
md4_init(&m);
md4_update(&m, buf + sizeof(buf) - len, len);
c.cksumtype = rsa_md4;
c.checksum.length = 16;
c.checksum.data = malloc(16);
md4_finito(&m, c.checksum.data);
krb5_build_authenticator (context, in_creds->client,
&c, NULL, &authenticator);
}
#if 0
{
struct timeval tv;
auth.authenticator_vno = 5;
krb5_cc_get_principal(context, ccache, &out_creds->client);
krb5_error_code err;
Tgs_Req a;
krb5_kdc_rep rep;
krb5_data req, resp;
char buf[BUFSIZ];
int i;
Buffer buffer;
/*
* XXX - Check if cred found in ccache
*/
/*
* Prepare Tgs_Req.
*/
err = krb5_get_default_in_tkt_etypes (context, &a.etypes);
if (err)
return err;
a.num_etypes = 1;
err = krb5_get_all_client_addrs (&a.addrs);
if (err)
return err;
a.pvno = 5;
a.msg_type = KRB_TGS_REQ;
memset (&a.kdc_options, 0, sizeof(a.kdc_options));
/* a.kdc_options */
a.realm.length = 0;
krb5_data_copy (&a.realm, in_creds->server->realm.data,
in_creds->server->realm.length);
krb5_copy_principal (context, in_creds->server, &a.sname);
a.till = in_creds->times.endtime;
a.nonce = 17;
a.cname = NULL;
/*
* Encode
*/
req.length = der_put_as_req (buf + sizeof (buf) - 1, &a);
req.data = buf + sizeof(buf) - req.length;
for (i = 0; i < a.addrs.number; ++i)
krb5_data_free (&a.addrs.addrs[i].address);
free (a.addrs.addrs);
/*
* Send and receive
*/
err = krb5_sendto_kdc (context, &req, &a.realm, &resp);
if (err) {
return err;
}
buf_init (&buffer, resp.data, resp.length);
if (der_get_tgs_rep (&buffer, &rep) == -1) {
return ASN1_PARSE_ERROR;
}
}
auth.crealm = malloc(out_creds->client->realm.length + 1);
strncpy (auth.crealm, out_creds->client->realm.data,
out_creds->client->realm.length);
auth.crealm[out_creds->client->realm.length] = 0;
krb5_principal2principalname(&auth.cname, out_creds->client);
gettimeofday(&tv, NULL);
{
char buf[1024];
int len;
struct md4 m;
len = encode_KDC_REQ_BODY(buf + sizeof(buf) - 1, sizeof(buf),
&a.req_body);
md4_init(&m);
md4_update(&m, buf + sizeof(buf) - len, len);
c.cksumtype = rsa_md4;
c.checksum.length = 16;
c.checksum.data = malloc(16);
md4_finito(&m, c.checksum.data);
auth.cksum = &c;
}
auth.cusec = tv.tv_usec;
auth.ctime = tv.tv_sec;
auth.subkey = NULL;
auth.seq_number = NULL;
auth.authorization_data = NULL;
}
#endif
#if 0
/*
AP-REQ ::= [APPLICATION 14] SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER,
ap-options[2] APOptions,
ticket[3] Ticket,
authenticator[4] EncryptedData
}
*/
{
krb5_creds cred, mcred;
ap.pvno = 5;
ap.msg_type = krb_ap_req;
memset(&ap.ap_options, 0, sizeof(ap.ap_options));
/* ap.ap_options.use_session_key = 1;*/
krb5_build_principal(context, &mcred.server,
out_creds->client.realm.length,
out_creds->client.realm.data,
"krbtgt", a.req_body.realm, NULL);
krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
/*
tkt-vno[0] INTEGER,
realm[1] Realm,
sname[2] PrincipalName,
enc-part[3] EncryptedData
*/
ap.ticket.tkt_vno = 5;
ap.ticket.realm = (char*)malloc(cred.server->realm.length + 1);
strncpy(ap.ticket.realm, cred.server->realm.data,
cred.server->realm.length);
ap.ticket.realm[cred.server->realm.length] = 0;
krb5_principal2principalname(&ap.ticket.sname, cred.server);
{
Ticket t;
decode_Ticket(cred.ticket.data,
cred.ticket.length,
&t);
ap.ticket.enc_part.etype = t.enc_part.etype;
ap.ticket.enc_part.kvno = NULL;
ap.ticket.enc_part.cipher = t.enc_part.cipher;
}
memcpy(&key, cred.session.contents.data, sizeof(key));
des_set_key(cred.session.contents.data, schedule);
}
#endif
#if 0
{
u_int32_t crc;
unsigned char *p;
memset(data, 0, sizeof(data));
len = encode_Authenticator(data + sizeof(data) - 9,
sizeof(data) - 8 - 12, &auth);
p = data + sizeof(data) - 8 - len;
p -= 12;
len += 12;
len = (len + 7) & ~7;
crc_init_table();
crc = crc_update(p, len, 0);
/* crc = htonl(crc); */
memcpy(p + 8, &crc, 4);
#if 0
des_cbc_encrypt((void*)p, (void*)p, len, schedule, &key, DES_ENCRYPT);
#endif
#if 0
ap.authenticator.etype = ap.ticket.enc_part.etype;
ap.authenticator.kvno = NULL;
ap.authenticator.cipher.data = p; /* p */
ap.authenticator.cipher.length = len; /* len */
#endif
authenticator.data = p;
authenticator.length = len;
}
#endif
{
krb5_creds cred, mcred;
krb5_build_principal(context, &mcred.server,
in_creds->client->realm.length,
in_creds->client->realm.data,
"krbtgt", a.req_body.realm, NULL);
krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
memcpy(&key, cred.session.contents.data, sizeof(key));
foo.padata_type = pa_tgs_req;
err = krb5_build_ap_req(context, &cred,
0,
authenticator,
&foo.padata_value);
if(err)
return err;
}
a.padata = malloc(sizeof(*a.padata));
a.padata->len = 1;
a.padata->val = &foo;
#if 0
foo.padata_value.length = encode_AP_REQ(buf2 + sizeof(buf2) - 1,
sizeof(buf2), &ap);
foo.padata_value.data = buf2 + sizeof(buf2) - foo.padata_value.length;
a.padata = malloc(sizeof(*a.padata));
a.padata->len = 1;
a.padata->val = &foo;
#endif
/*
* Encode
*/
req.length = encode_TGS_REQ (buf + sizeof (buf) - 1, sizeof(buf), &a);
req.data = buf + sizeof(buf) - req.length;
for (i = 0; i < a.req_body.addresses->len; ++i)
krb5_data_free (&a.req_body.addresses->val[i].address);
free (a.req_body.addresses->val);
/*
* Send and receive
*/
{
TGS_REQ xx;
decode_TGS_REQ (req.data, req.length, &xx);
req.length = req.length;
}
err = krb5_sendto_kdc (context, &req, &in_creds->server->realm, &resp);
if (err) {
return err;
}
switch(((unsigned char*)resp.data)[0] & 0x1f){
case krb_error:
len = decode_TGS_REP(resp.data, resp.length, &error);
if(len < 0)
return ASN1_PARSE_ERROR;
break;
case krb_tgs_rep:
len = decode_TGS_REP(resp.data, resp.length, &rep.part1);
if(len < 0)
return ASN1_PARSE_ERROR;
out_creds = malloc(sizeof(*out_creds));
*out_creds = NULL;
err = extract_ticket(context, &rep, *out_creds, key_proc, key, NULL, NULL);
if(err)
return err;
return krb5_cc_store_cred (context, ccache, out_creds);
break;
}
}

12
lib/krb5/get_host_realm.c Normal file
View File

@@ -0,0 +1,12 @@
#include "krb5_locl.h"
krb5_error_code
krb5_get_host_realm(krb5_context context,
const char *host,
char ***realms)
{
*realms = malloc(2 * sizeof(char*));
(*realms)[0] = strdup("FOO.SE");
(*realms)[1] = NULL;
return 0;
}

View File

@@ -6,25 +6,25 @@ krb5_get_salt (krb5_principal princ,
krb5_data realm,
krb5_data *salt)
{
size_t len;
int i;
krb5_error_code err;
char *p;
size_t len;
int i;
krb5_error_code err;
char *p;
len = realm.length;
for (i = 0; i < princ->ncomp; ++i)
len += princ->comp[i].length;
err = krb5_data_alloc (salt, len);
if (err)
return err;
p = salt->data;
strncpy (p, realm.data, realm.length);
p += realm.length;
for (i = 0; i < princ->ncomp; ++i) {
strncpy (p, princ->comp[i].data, princ->comp[i].length);
p += princ->comp[i].length;
}
return 0;
len = realm.length;
for (i = 0; i < princ->ncomp; ++i)
len += princ->comp[i].length;
err = krb5_data_alloc (salt, len);
if (err)
return err;
p = salt->data;
strncpy (p, realm.data, realm.length);
p += realm.length;
for (i = 0; i < princ->ncomp; ++i) {
strncpy (p, princ->comp[i].data, princ->comp[i].length);
p += princ->comp[i].length;
}
return 0;
}
static krb5_error_code
@@ -33,28 +33,28 @@ decrypt_tkt (krb5_context context,
krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep)
{
des_key_schedule sched;
char *buf;
int i;
int len = dec_rep->part1.enc_part.cipher.length;
des_key_schedule sched;
char *buf;
int i;
int len = dec_rep->part1.enc_part.cipher.length;
des_set_key (key->contents.data, sched);
buf = malloc (len);
if (buf == NULL)
return ENOMEM;
des_cbc_encrypt ((des_cblock *)dec_rep->part1.enc_part.cipher.data,
(des_cblock *)buf,
len,
sched,
key->contents.data,
DES_DECRYPT);
/* XXX: Check CRC */
des_set_key (key->contents.data, sched);
buf = malloc (len);
if (buf == NULL)
return ENOMEM;
des_cbc_encrypt ((des_cblock *)dec_rep->part1.enc_part.cipher.data,
(des_cblock *)buf,
len,
sched,
key->contents.data,
DES_DECRYPT);
/* XXX: Check CRC */
i = decode_EncTGSRepPart((unsigned char*)buf + 12, len - 12, &dec_rep->part2);
free (buf);
if (i < 0)
return ASN1_PARSE_ERROR;
return 0;
i = decode_EncTGSRepPart((unsigned char*)buf + 12, len - 12, &dec_rep->part2);
free (buf);
if (i < 0)
return ASN1_PARSE_ERROR;
return 0;
}
/*
@@ -65,38 +65,149 @@ krb5_error_code
krb5_principal2principalname (PrincipalName *p,
krb5_principal from)
{
int i;
int i;
p->name_type = from->type;
p->name_string.len = from->ncomp;
p->name_string.val = malloc(from->ncomp * sizeof(*p->name_string.val));
for (i = 0; i < from->ncomp; ++i) {
int len = from->comp[i].length;
p->name_string.val[i] = malloc(len + 1);
strncpy (p->name_string.val[i], from->comp[i].data, len);
p->name_string.val[i][len] = '\0';
}
return 0;
p->name_type = from->type;
p->name_string.len = from->ncomp;
p->name_string.val = malloc(from->ncomp * sizeof(*p->name_string.val));
for (i = 0; i < from->ncomp; ++i) {
int len = from->comp[i].length;
p->name_string.val[i] = malloc(len + 1);
strncpy (p->name_string.val[i], from->comp[i].data, len);
p->name_string.val[i][len] = '\0';
}
return 0;
}
krb5_error_code
principalname2krb5_principal (krb5_principal p,
principalname2krb5_principal (krb5_principal *principal,
PrincipalName from,
krb5_data realm)
char *realm)
{
int i;
int i;
krb5_principal p;
p = malloc (sizeof(*p));
p->type = from.name_type;
p->ncomp = from.name_string.len;
p->comp = malloc (p->ncomp * sizeof(*p->comp));
for (i = 0; i < p->ncomp; ++i) {
int len = strlen(from.name_string.val[i]);
p->comp[i].length = len;
p->comp[i].data = strdup(from.name_string.val[i]);
}
p->realm.data = strdup(realm);
p->realm.length = strlen(realm);
*principal = p;
return 0;
}
p = malloc (sizeof(*p));
p->type = from.name_type;
p->ncomp = from.name_string.len;
p->comp = malloc (p->ncomp * sizeof(*p->comp));
for (i = 0; i < p->ncomp; ++i) {
int len = strlen(from.name_string.val[i]) + 1;
p->comp[i].length = len;
p->comp[i].data = strdup(from.name_string.val[i]);
}
p->realm = realm;
return 0;
int
extract_ticket(krb5_context context,
krb5_kdc_rep *rep,
krb5_creds *creds,
krb5_key_proc key_proc,
krb5_const_pointer keyseed,
krb5_decrypt_proc decrypt_proc,
krb5_const_pointer decryptarg)
{
krb5_keyblock *key;
krb5_error_code err;
krb5_data salt;
principalname2krb5_principal(&creds->client,
rep->part1.cname,
rep->part1.crealm);
free (rep->part1.crealm);
/* krb5_principal_free (rep.part1.cname);*/
{
char buf[1024];
int len;
len = encode_Ticket(buf + sizeof(buf) - 1, sizeof(buf),
&rep->part1.ticket);
creds->ticket.data = malloc(len);
memcpy(creds->ticket.data, buf + sizeof(buf) - len, len);
creds->ticket.length = len;
creds->second_ticket.length = 0;
}
/* krb5_free_principal (rep->part1.ticket.sprinc);*/
salt.length = 0;
salt.data = NULL;
err = krb5_get_salt (creds->client, creds->client->realm, &salt);
if (err)
return err;
err = (*key_proc)(context, rep->part1.enc_part.etype, &salt,
keyseed, &key);
krb5_data_free (&salt);
if (err)
return err;
if (decrypt_proc == NULL)
decrypt_proc = decrypt_tkt;
err = (*decrypt_proc)(context, key, decryptarg, rep);
if (err)
return err;
memset (key->contents.data, 0, key->contents.length);
krb5_data_free (&key->contents);
free (key);
principalname2krb5_principal(&creds->server,
rep->part1.ticket.sname,
rep->part1.ticket.realm);
if (rep->part2.key_expiration)
free (rep->part2.key_expiration);
if (rep->part2.starttime) {
creds->times.starttime = *rep->part2.starttime;
free (rep->part2.starttime);
} else
creds->times.starttime = rep->part2.authtime;
if (rep->part2.renew_till) {
creds->times.renew_till = *rep->part2.renew_till;
free (rep->part2.renew_till);
} else
creds->times.renew_till = 0;
creds->times.authtime = rep->part2.authtime;
creds->times.endtime = rep->part2.endtime;
creds->addresses.number = 0;
creds->addresses.addrs = NULL;
#if 0 /* What? */
if (rep->part2.req.values)
free (rep->part2.req.values);
#endif
#if 0
if (rep->part2.caddr.addrs) {
int i;
for (i = 0; i < rep->part2.caddr.number; ++i) {
krb5_data_free (&rep->part2.caddr.addrs[i].address);
}
free (rep->part2.caddr.addrs);
}
krb5_principal_free (rep->part2.sname);
krb5_data_free (&rep->part2.srealm);
#endif
if (err)
return err;
creds->session.contents.length = 0;
creds->session.contents.data = NULL;
creds->session.keytype = rep->part2.key.keytype;
err = krb5_data_copy (&creds->session.contents,
rep->part2.key.keyvalue.data,
rep->part2.key.keyvalue.length);
memset (rep->part2.key.keyvalue.data, 0,
rep->part2.key.keyvalue.length);
krb5_data_free (&rep->part2.key.keyvalue);
creds->authdata.length = 0;
creds->authdata.data = NULL;
return err;
}
/*
@@ -117,155 +228,72 @@ krb5_get_in_tkt(krb5_context context,
krb5_ccache ccache,
krb5_kdc_rep **ret_as_reply)
{
krb5_error_code err;
AS_REQ a;
krb5_kdc_rep rep;
krb5_data req, resp;
char buf[BUFSIZ];
krb5_data salt;
krb5_keyblock *key;
krb5_error_code err;
AS_REQ a;
krb5_kdc_rep rep;
krb5_data req, resp;
char buf[BUFSIZ];
a.pvno = 5;
a.msg_type = krb_as_req;
memset (&a.req_body.kdc_options, 0, sizeof(a.req_body.kdc_options));
/* a.kdc_options */
a.req_body.cname = malloc(sizeof(*a.req_body.cname));
a.req_body.sname = malloc(sizeof(*a.req_body.sname));
krb5_principal2principalname (a.req_body.cname, creds->client);
krb5_principal2principalname (a.req_body.sname, creds->server);
a.req_body.realm = malloc(creds->client->realm.length + 1);
strncpy (a.req_body.realm, creds->client->realm.data,
creds->client->realm.length);
a.req_body.realm[creds->client->realm.length] = '\0';
a.pvno = 5;
a.msg_type = krb_as_req;
memset (&a.req_body.kdc_options, 0, sizeof(a.req_body.kdc_options));
/* a.kdc_options */
a.req_body.cname = malloc(sizeof(*a.req_body.cname));
a.req_body.sname = malloc(sizeof(*a.req_body.sname));
krb5_principal2principalname (a.req_body.cname, creds->client);
krb5_principal2principalname (a.req_body.sname, creds->server);
a.req_body.realm = malloc(creds->client->realm.length + 1);
strncpy (a.req_body.realm, creds->client->realm.data,
creds->client->realm.length);
a.req_body.realm[creds->client->realm.length] = '\0';
a.req_body.till = creds->times.endtime;
a.req_body.nonce = 17;
if (etypes)
abort ();
else {
err = krb5_get_default_in_tkt_etypes (context,
(krb5_enctype**)&a.req_body.etype.val);
if (err)
return err;
a.req_body.etype.len = 1;
}
if (addrs){
} else {
a.req_body.addresses = malloc(sizeof(*a.req_body.addresses));
a.req_body.till = creds->times.endtime;
a.req_body.nonce = 17;
if (etypes)
abort ();
else {
err = krb5_get_default_in_tkt_etypes (context,
(krb5_enctype**)&a.req_body.etype.val);
if (err)
return err;
a.req_body.etype.len = 1;
}
if (addrs){
} else {
a.req_body.addresses = malloc(sizeof(*a.req_body.addresses));
err = krb5_get_all_client_addrs ((krb5_addresses*)a.req_body.addresses);
if (err)
return err;
}
a.req_body.enc_authorization_data = NULL;
a.req_body.additional_tickets = NULL;
a.padata = NULL;
err = krb5_get_all_client_addrs ((krb5_addresses*)a.req_body.addresses);
if (err)
return err;
}
a.req_body.enc_authorization_data = NULL;
a.req_body.additional_tickets = NULL;
a.padata = NULL;
req.length = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
sizeof(buf),
&a);
if (req.length < 0)
return ASN1_PARSE_ERROR;
req.data = buf + sizeof(buf) - req.length;
if (addrs == NULL) {
int i;
req.length = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
sizeof(buf),
&a);
if (req.length < 0)
return ASN1_PARSE_ERROR;
req.data = buf + sizeof(buf) - req.length;
if (addrs == NULL) {
int i;
for (i = 0; i < a.req_body.addresses->len; ++i)
krb5_data_free (&a.req_body.addresses->val[i].address);
free (a.req_body.addresses->val);
}
for (i = 0; i < a.req_body.addresses->len; ++i)
krb5_data_free (&a.req_body.addresses->val[i].address);
free (a.req_body.addresses->val);
}
err = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
if (err) {
return err;
}
if(decode_AS_REP(resp.data, resp.length, &rep.part1) < 0)
return ASN1_PARSE_ERROR;
err = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
if (err) {
return err;
}
if(decode_AS_REP(resp.data, resp.length, &rep.part1) < 0)
return ASN1_PARSE_ERROR;
free (rep.part1.crealm);
/* krb5_principal_free (rep.part1.cname);*/
creds->ticket.kvno = rep.part1.ticket.tkt_vno;
creds->ticket.etype = rep.part1.enc_part.etype;
creds->ticket.enc_part.length = 0;
creds->ticket.enc_part.data = NULL;
krb5_data_copy (&creds->ticket.enc_part,
rep.part1.ticket.enc_part.cipher.data,
rep.part1.ticket.enc_part.cipher.length);
krb5_data_free (&rep.part1.ticket.enc_part.cipher);
principalname2krb5_principal (creds->ticket.sprinc,
rep.part1.ticket.sname,
creds->client->realm);
/* krb5_free_principal (rep.part1.ticket.sprinc);*/
salt.length = 0;
salt.data = NULL;
err = krb5_get_salt (creds->client, creds->client->realm, &salt);
if (err)
return err;
err = (*key_proc)(context, rep.part1.enc_part.etype, &salt,
keyseed, &key);
krb5_data_free (&salt);
if (err)
return err;
if (decrypt_proc == NULL)
decrypt_proc = decrypt_tkt;
err = (*decrypt_proc)(context, key, decryptarg, &rep);
if (err)
return err;
memset (key->contents.data, 0, key->contents.length);
krb5_data_free (&key->contents);
free (key);
if (rep.part2.key_expiration)
free (rep.part2.key_expiration);
if (rep.part2.starttime) {
creds->times.starttime = *rep.part2.starttime;
free (rep.part2.starttime);
} else
creds->times.starttime = rep.part2.authtime;
if (rep.part2.renew_till) {
creds->times.renew_till = *rep.part2.renew_till;
free (rep.part2.renew_till);
} else
creds->times.renew_till = rep.part2.endtime;
creds->times.authtime = rep.part2.authtime;
creds->times.endtime = rep.part2.endtime;
#if 0 /* What? */
if (rep.part2.req.values)
free (rep.part2.req.values);
#endif
#if 0
if (rep.part2.caddr.addrs) {
int i;
for (i = 0; i < rep.part2.caddr.number; ++i) {
krb5_data_free (&rep.part2.caddr.addrs[i].address);
}
free (rep.part2.caddr.addrs);
}
krb5_principal_free (rep.part2.sname);
krb5_data_free (&rep.part2.srealm);
#endif
if (err)
return err;
creds->session.contents.length = 0;
creds->session.contents.data = NULL;
creds->session.keytype = rep.part2.key.keytype;
err = krb5_data_copy (&creds->session.contents,
rep.part2.key.keyvalue.data,
rep.part2.key.keyvalue.length);
memset (rep.part2.key.keyvalue.data, 0,
rep.part2.key.keyvalue.length);
krb5_data_free (&rep.part2.key.keyvalue);
creds->authdata.length = 0;
creds->authdata.data = NULL;
if (err)
return err;
return krb5_cc_store_cred (context, ccache, creds);
err = extract_ticket(context, &rep, creds, key_proc, keyseed,
decrypt_proc, decryptarg);
if(err)
return err;
return krb5_cc_store_cred (context, ccache, creds);
}

124
lib/krb5/keytab.c Normal file
View File

@@ -0,0 +1,124 @@
#include "krb5_locl.h"
krb5_error_code
krb5_kt_resolve(krb5_context context,
const char *name,
krb5_keytab *id)
{
krb5_keytab k;
if (strncmp (name, "FILE:", 5) != 0)
return -1;
k = ALLOC(1, krb5_keytab);
if (k == NULL)
return ENOMEM;
k->filename = strdup(name + 5);
if (k->filename == NULL)
return ENOMEM;
*id = k;
return 0;
}
#define KEYTAB_DEFAULT "FILE:/etc/v5srvtab"
krb5_error_code
krb5_kt_default_name(krb5_context context,
char *name,
int namesize)
{
strncpy (name, KEYTAB_DEFAULT, namesize);
return 0;
}
krb5_error_code
krb5_kt_default(krb5_context context,
krb5_keytab *id)
{
return krb5_kt_resolve (context, KEYTAB_DEFAULT, id);
}
krb5_error_code
krb5_kt_read_service_key(krb5_context context,
krb5_pointer keyprocarg,
krb5_principal principal,
krb5_kvno vno,
krb5_keytype keytype,
krb5_keyblock **key)
{
krb5_keytab keytab;
krb5_keytab_entry entry;
krb5_error_code r;
if (keyprocarg)
r = krb5_kt_resolve (context, keyprocarg, &keytab);
else
r = krb5_kt_default (context, &keytab);
r = krb5_kt_get_entry (context, keytab, principal, vno, keytype, &entry);
krb5_kt_close (context, keytab);
return r;
}
krb5_error_code
krb5_kt_add_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
{
abort ();
}
krb5_error_code
krb5_kt_remove_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
{
abort ();
}
krb5_error_code
krb5_kt_get_name(krb5_context context,
krb5_keytab keytab,
char *name,
int namesize)
{
strncpy (name, keytab->filename, namesize);
return 0;
}
krb5_error_code
krb5_kt_close(krb5_context context,
krb5_keytab id)
{
}
krb5_error_code
krb5_kt_get_entry(krb5_context,
krb5_keytab,
krb5_principal,
krb5_kvno,
krb5_keytype,
krb5_keytab_entry *);
krb5_error_code
krb5_kt_free_entry(krb5_context,
krb5_keytab_entry *);
krb5_error_code
krb5_kt_start_seq_get(krb5_context,
krb5_keytab id,
krb5_kt_cursor *);
krb5_error_code
krb5_kt_next_entry(krb5_context,
krb5_keytab,
krb5_keytab_entry *,
krb5_kt_cursor *);
krb5_error_code
krb5_kt_end_seq_get(krb5_context,
krb5_keytab,
krb5_kt_cursor *);

74
lib/krb5/keytab.h Normal file
View File

@@ -0,0 +1,74 @@
#ifndef __KEYTAB_H__
#define __KEYTAB_H__
#if 0
krb5_error_code
krb5_kt_register(krb5_context, krb5_kt_ops *);
#endif
krb5_error_code
krb5_kt_resolve(krb5_context, const char *, krb5_keytab *id);
krb5_error_code
krb5_kt_default_name(krb5_context, char *name, int namesize);
krb5_error_code
krb5_kt_default(krb5_context, krb5_keytab *id);
krb5_error_code
krb5_kt_read_service_key(krb5_context,
krb5_pointer keyprocarg,
krb5_principal principal,
krb5_kvno vno,
krb5_keytype keytype,
krb5_keyblock **key);
krb5_error_code
krb5_kt_add_entry(krb5_context,
krb5_keytab id,
krb5_keytab_entry *entry);
krb5_error_code
krb5_kt_remove_entry(krb5_context,
krb5_keytab id,
krb5_keytab_entry *entry);
krb5_error_code
krb5_kt_get_name(krb5_context,
krb5_keytab,
char *name,
int namesize);
krb5_error_code
krb5_kt_close(krb5_context,
krb5_keytab id);
krb5_error_code
krb5_kt_get_entry(krb5_context,
krb5_keytab,
krb5_principal,
krb5_kvno,
krb5_keytype,
krb5_keytab_entry *);
krb5_error_code
krb5_kt_free_entry(krb5_context,
krb5_keytab_entry *);
krb5_error_code
krb5_kt_start_seq_get(krb5_context,
krb5_keytab id,
krb5_kt_cursor *);
krb5_error_code
krb5_kt_next_entry(krb5_context,
krb5_keytab,
krb5_keytab_entry *,
krb5_kt_cursor *);
krb5_error_code
krb5_kt_end_seq_get(krb5_context,
krb5_keytab,
krb5_kt_cursor *);
#endif /* __KEYTAB_H__ */

View File

@@ -28,7 +28,7 @@ typedef int krb5_boolean;
typedef int32_t krb5_error_code;
typedef int krb5_kvno;
typedef void *krb5_pointer;
typedef const void *krb5_const_pointer;
@@ -70,17 +70,22 @@ typedef enum krb5_preauthtype {
typedef enum krb5_address_type {
KRB5_ADDRESS_INET = 2
KRB5_ADDRESS_INET = 2
} krb5_address_type;
enum {
AP_OPTS_USE_SESSION_KEY = 1,
AP_OPTS_MUTUAL_REQUIRED = 2
};
typedef struct krb5_address{
krb5_address_type type;
krb5_data address;
int16_t type;
krb5_data address;
} krb5_address;
typedef struct krb5_addresses {
int number;
krb5_address *addrs;
int number;
krb5_address *addrs;
} krb5_addresses;
typedef enum krb5_keytype { KEYTYPE_DES } krb5_keytype;
@@ -130,28 +135,27 @@ typedef const krb5_principal_data *krb5_const_principal;
typedef krb5_data krb5_realm;
typedef struct krb5_ticket{
int kvno;
krb5_principal sprinc;
krb5_data enc_part;
krb5_data enc_part2;
krb5_enctype etype;
}krb5_ticket;
typedef struct krb5_ticket {
krb5_principal server;
krb5_data enc_part;
krb5_data enc_part2;
} krb5_ticket;
#define KRB5_PARSE_MALFORMED 17
#define KRB5_PROG_ETYPE_NOSUPP 4711
typedef struct krb5_creds {
krb5_principal client;
krb5_principal server;
krb5_keyblock session;
krb5_times times;
krb5_ticket ticket;
krb5_principal client;
krb5_principal server;
krb5_keyblock session;
krb5_times times;
krb5_data ticket;
krb5_ticket second_ticket; /* ? */
krb5_data authdata; /* ? */
krb5_addresses addresses;
krb5_data second_ticket; /* ? */
krb5_data authdata; /* ? */
krb5_addresses addresses;
} krb5_creds;
@@ -184,10 +188,19 @@ typedef struct krb5_cc_cursor{
int fd;
}krb5_cc_cursor;
typedef struct krb5_keytab{
int dummy;
}krb5_keytab;
struct krb5_keytab_data {
char *filename;
};
typedef struct krb5_keytab_data *krb5_keytab;
typedef struct krb5_keytab_entry {
int foo;
} krb5_keytab_entry;
typedef struct krb5_kt_cursor {
int foo;
} krb5_kt_cursor;
typedef struct krb5_auth_context{
int32_t flags;
@@ -223,6 +236,14 @@ typedef struct {
krb5_error_code
krb5_init_context(krb5_context *context);
krb5_error_code
krb5_auth_con_init(krb5_context context,
krb5_auth_context **auth_context);
krb5_error_code
krb5_auth_con_free(krb5_context context,
krb5_auth_context *auth_context,
krb5_flags flags);
krb5_error_code
krb5_get_cred_from_kdc(krb5_context,
@@ -237,7 +258,7 @@ krb5_get_credentials(krb5_context context,
krb5_flags options,
krb5_ccache ccache,
krb5_creds *in_creds,
krb5_creds *out_creds);
krb5_creds **out_creds);
typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
krb5_keytype type,
@@ -299,6 +320,17 @@ krb5_rd_req(krb5_context context,
krb5_flags *ap_req_options,
krb5_ticket **ticket);
typedef EncAPRepPart krb5_ap_rep_enc_part;
krb5_error_code
krb5_rd_rep(krb5_context context,
krb5_auth_context *auth_context,
const krb5_data *inbuf,
krb5_ap_rep_enc_part **repl);
void
krb5_free_ap_rep_enc_part (krb5_context context,
krb5_ap_rep_enc_part *val);
krb5_error_code
krb5_parse_name(krb5_context context,
@@ -408,6 +440,7 @@ krb5_string_to_key (char *str,
#include "cache.h"
#include "keytab.h"
#endif /* __KRB5_H__ */

View File

@@ -57,7 +57,19 @@ krb5_sendto_kdc (krb5_context context,
const krb5_data *realm,
krb5_data *receive);
krb5_error_code
krb5_build_ap_req (krb5_context context,
krb5_creds *cred,
krb5_flags ap_options,
krb5_data authenticator,
krb5_data *ret);
krb5_error_code
krb5_build_authenticator (krb5_context context,
krb5_principal client,
Checksum *cksum,
Authenticator **auth,
krb5_data *result);
#define ALLOC(N, X) ((X*)malloc((N) * sizeof(X)))
#define FREE(X) do{if(X)free(X);}while(0)

View File

@@ -8,8 +8,12 @@ krb5_get_krbhst (krb5_context context,
krb5_error_code err;
char buf[BUFSIZ];
char *val;
sprintf (buf, "realms %.*s kdc", (int)realm->length, (char*)realm->data);
memset(buf, 0, sizeof(buf));
strcpy(buf, "realms ");
strncat(buf, (char*)realm->data, realm->length);
strcat(buf, " kdc");
err = krb5_get_config_tag (context->cf, buf, &val);
if (err)
return err;

141
lib/krb5/mit-crc.c Normal file
View File

@@ -0,0 +1,141 @@
#include <krb5_locl.h>
/* This table and block of comments are taken from code labeled: */
/*
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* 1. The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
/* be they sixteen or thirty-two bits wide. You simply choose the */
/* appropriate table. Alternatively, because the table can be */
/* generated at runtime, you can start by generating the table for */
/* the polynomial in question and use exactly the same "updcrc", */
/* if your application needn't simultaneously handle two CRC */
/* polynomials. (Note, however, that XMODEM is strange.) */
/* */
/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
/* of course, 32-bit entries work OK if the high 16 bits are zero. */
/* */
/* 4. The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
static u_long const crc_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
void
crc_init_table()
{
}
u_long
crc_update(void *in, size_t in_length, u_long crc)
{
u_char *data;
u_int32_t c = 0;
int idx;
size_t i;
data = (u_char *)in;
for (i = 0; i < in_length; i++) {
idx = (int) (data[i] ^ c);
idx &= 0xff;
c >>= 8;
c ^= crc_table[idx];
}
return c & 0xffffffff;
}

63
lib/krb5/mk_req.c Normal file
View File

@@ -0,0 +1,63 @@
#include <krb5_locl.h>
#include <krb5_error.h>
krb5_error_code
krb5_mk_req(krb5_context context,
krb5_auth_context **auth_context,
const krb5_flags ap_req_options,
char *service,
char *hostname,
krb5_data *in_data,
krb5_ccache ccache,
krb5_data *outbuf)
{
krb5_error_code r;
krb5_creds this_cred, cred;
char **realms;
Authenticator *auth;
krb5_data realm_data, authenticator;
if (*auth_context == NULL) {
r = krb5_auth_con_init(context, auth_context);
if (r)
return r;
}
r = krb5_get_host_realm(context, hostname, &realms);
if (r)
return r;
realm_data.length = strlen(*realms);
realm_data.data = *realms;
r = krb5_build_principal (context, &this_cred.server,
strlen(*realms),
*realms,
service,
hostname,
NULL);
if (r)
return r;
this_cred.times.endtime = time (NULL) + 4711;
r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
if (r)
return r;
(*auth_context)->key.keytype = cred.session.keytype;
krb5_data_copy (&(*auth_context)->key.contents,
cred.session.contents.data,
cred.session.contents.length);
r = krb5_build_authenticator (context, cred.client,
NULL, &auth,
&authenticator);
if (r)
return r;
(*auth_context)->authenticator->cusec = auth->cusec;
(*auth_context)->authenticator->ctime = auth->ctime;
r = krb5_build_ap_req (context, &cred, ap_req_options,
authenticator, outbuf);
return r;
}

View File

@@ -228,16 +228,51 @@ krb5_principal_set_component(krb5_principal p, int n, void *data, size_t len)
}
krb5_error_code
krb5_build_principal_va(krb5_context context,
krb5_principal *principal,
int rlen,
const char *realm,
va_list ap)
static void
va_ext_princ(krb5_principal p, va_list ap)
{
int n = 0;
while(1){
char *s;
int len;
len = va_arg(ap, int);
if(len == 0)
break;
s = va_arg(ap, char*);
krb5_principal_set_component(p, n, s, len);
n++;
}
p->ncomp = n;
}
static void
va_princ(krb5_principal p, va_list ap)
{
int n = 0;
while(1){
char *s;
int len;
s = va_arg(ap, char*);
if(s == NULL)
break;
len = strlen(s);
krb5_principal_set_component(p, n, s, len);
n++;
}
p->ncomp = n;
}
static krb5_error_code
build_principal(krb5_context context,
krb5_principal *principal,
int rlen,
const char *realm,
void (*func)(krb5_principal, va_list),
va_list ap)
{
krb5_principal p;
int n;
char *s;
if(krb5_principal_alloc(&p))
return ENOMEM;
@@ -248,19 +283,32 @@ krb5_build_principal_va(krb5_context context,
return ENOMEM;
}
n = 0;
while(1){
s = va_arg(ap, char*);
if(s == NULL)
break;
krb5_principal_set_component(p, n, s, strlen(s));
n++;
}
p->ncomp = n;
(*func)(p, ap);
*principal = p;
return 0;
}
krb5_error_code
krb5_build_principal_va(krb5_context context,
krb5_principal *principal,
int rlen,
const char *realm,
va_list ap)
{
return build_principal(context, principal, rlen, realm, va_princ, ap);
}
/* Not part of MIT K5 API */
krb5_error_code
krb5_build_principal_va_ext(krb5_context context,
krb5_principal *principal,
int rlen,
const char *realm,
va_list ap)
{
return build_principal(context, principal, rlen, realm, va_ext_princ, ap);
}
krb5_error_code
krb5_build_principal_ext(krb5_context context,
@@ -269,8 +317,12 @@ krb5_build_principal_ext(krb5_context context,
const char *realm,
...)
{
fprintf(stderr, "krb5_build_principal_ext: not implemented\n");
abort();
krb5_error_code ret;
va_list ap;
va_start(ap, realm);
ret = krb5_build_principal_va_ext(context, principal, rlen, realm, ap);
va_end(ap);
return ret;
}

65
lib/krb5/rd_rep.c Normal file
View File

@@ -0,0 +1,65 @@
#include <krb5_locl.h>
#include <krb5_error.h>
krb5_error_code
krb5_rd_rep(krb5_context context,
krb5_auth_context *auth_context,
const krb5_data *inbuf,
krb5_ap_rep_enc_part **repl)
{
AP_REP ap_rep;
int len;
des_key_schedule schedule;
char *buf;
int i;
len = decode_AP_REP(inbuf->data, inbuf->length, &ap_rep);
if (len < 0)
return ASN1_PARSE_ERROR;
if (ap_rep.pvno != 5)
return KRB_AP_ERR_BADVERSION;
if (ap_rep.msg_type != krb_ap_rep)
return KRB_AP_ERR_MSG_TYPE;
des_set_key (auth_context->key.contents.data, &schedule);
len = ap_rep.enc_part.cipher.length;
buf = malloc (len);
if (buf == NULL)
return ENOMEM;
des_cbc_encrypt ((des_cblock *)ap_rep.enc_part.cipher.data,
(des_cblock *)buf,
len,
schedule,
auth_context->key.contents.data,
DES_DECRYPT);
/* XXX - Check CRC */
*repl = malloc(sizeof(**repl));
if (*repl == NULL)
return ENOMEM;
i = decode_EncAPRepPart((unsigned char *)buf + 12, len - 12, *repl);
if (i < 0)
return ASN1_PARSE_ERROR;
if ((*repl)->ctime != auth_context->authenticator->ctime ||
(*repl)->cusec != auth_context->authenticator->cusec) {
printf("KRB_AP_ERR_MUT_FAIL\n");
printf ("(%u, %u) != (%u, %u)\n",
(*repl)->ctime, (*repl)->cusec,
auth_context->authenticator->ctime,
auth_context->authenticator->cusec);
}
#if 0
return KRB_AP_ERR_MUT_FAIL;
#endif
return 0;
}
void
krb5_free_ap_rep_enc_part (krb5_context context,
krb5_ap_rep_enc_part *val)
{
free (val);
}