diff --git a/e.c b/e.c index faedaea68..6dd83279a 100644 --- a/e.c +++ b/e.c @@ -69,11 +69,13 @@ der_get_encrypteddata (Buffer *b, EncryptedData *e) } int -der_get_ticket (Buffer *b, Ticket *t) +der_get_ticket (Buffer *b, krb5_ticket *t) { Identifier i0, i1, i; + EncryptedData e; Buffer tmp; int len; + int tkt_vno; if (matchid3 (b, &i0, APPL, CONS, APPL_TICKET) == NULL) return -1; @@ -81,14 +83,19 @@ der_get_ticket (Buffer *b, Ticket *t) return -1; if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) return -1; - getdata (b, &i, &t->tkt_vno); + getdata (b, &i, &tkt_vno); + if (tkt_vno != 5) + return -1; + t->sprinc = malloc (sizeof (*t->sprinc)); + if (t->sprinc == NULL) + return -1; if (matchcontextid3 (b, &i, UNIV, PRIM, UT_GeneralString, 1) == NULL) return -1; - getdata (b, &i, &t->realm); + getdata (b, &i, &t->sprinc->realm); if (matchid3 (b, &i, CONTEXT, CONS, 2) == NULL) return -1; buf_derive(b, &tmp, i.len); - len = der_get_principalname (&tmp, &t->sname); + len = der_get_principalname (&tmp, &t->sprinc); if (len == -1) return -1; buf_advance (b, len); @@ -96,13 +103,16 @@ der_get_ticket (Buffer *b, Ticket *t) if (matchid3 (b, &i, CONTEXT, CONS, 3) == NULL) return -1; buf_derive (b, &tmp, i.len); - len = der_get_encrypteddata (&tmp, &t->enc_part); + len = der_get_encrypteddata (&tmp, &e); if (len == -1) return -1; buf_advance (b, len); getzeros (b, i.len); getzeros (b, i1.len); getzeros (b, i0.len); + t->kvno = *e.kvno; + t->etype = e.etype; + t->enc_part = e.cipher; return buf_length (b); } @@ -183,7 +193,7 @@ der_get_tgs_rep (Buffer *b, Tgs_Rep *a) } int -der_get_encryptionkey (Buffer *b, EncryptionKey *k) +der_get_encryptionkey (Buffer *b, krb5_keyblock *k) { Identifier i; @@ -194,7 +204,7 @@ der_get_encryptionkey (Buffer *b, EncryptionKey *k) getdata (b, &i, &k->keytype); if (matchcontextid3 (b, &i, UNIV, PRIM, UT_OctetString, 1) == NULL) return -1; - getdata (b, &i, &k->keyvalue); + getdata (b, &i, &k->contents); return buf_length (b); } diff --git a/get_in_tkt.c b/get_in_tkt.c index 716012e2e..e78843b8c 100644 --- a/get_in_tkt.c +++ b/get_in_tkt.c @@ -80,24 +80,17 @@ krb5_get_in_tkt(krb5_context context, krb5_error_code err; As_Req a; krb5_kdc_rep rep; - krb5_principal_data server; krb5_data req, resp; char buf[BUFSIZ]; Buffer buffer; krb5_data salt; krb5_keyblock *key; - server.type = KRB5_NT_SRV_INST; - server.ncomp = 2; - server.comp = malloc (sizeof(*server.comp) * server.ncomp); - server.comp[0] = string_make ("krbtgt"); - server.comp[1] = creds->client->realm; - a.pvno = 5; a.msg_type = KRB_AS_REQ; /* a.kdc_options */ a.cname = creds->client; - a.sname = &server; + a.sname = creds->server; a.realm = creds->client->realm; a.till = creds->times.endtime; a.nonce = 17; @@ -118,7 +111,6 @@ krb5_get_in_tkt(krb5_context context, req.length = der_put_as_req (buf + sizeof(buf) - 1, &a); req.data = buf + sizeof(buf) - req.length; - free (server.comp); if (addrs == NULL) { int i; @@ -135,6 +127,22 @@ krb5_get_in_tkt(krb5_context context, if (der_get_as_rep (&buffer, &rep) == -1) { return ASN1_PARSE_ERROR; } + krb5_data_free (&rep.realm); + krb5_principal_free (rep.cname); + creds->ticket.kvno = rep.ticket.kvno; + creds->ticket.etype = rep.ticket.etype; + creds->ticket.enc_part.length = 0; + creds->ticket.enc_part.data = NULL; + krb5_data_copy (&creds->ticket.enc_part, + rep.ticket.enc_part.data, + rep.ticket.enc_part.length); + krb5_data_free (&rep.ticket.enc_part); + + krb5_copy_principal (context, + rep.ticket.sprinc, + &creds->ticket.sprinc); + krb5_free_principal (rep.ticket.sprinc); + salt.length = 0; salt.data = NULL; err = krb5_get_salt (creds->client, creds->client->realm, &salt); @@ -152,7 +160,40 @@ krb5_get_in_tkt(krb5_context context, memset (key->contents.data, 0, key->contents.length); krb5_data_free (&key->contents); free (key); + if (rep.enc_part2.key_expiration) + free (rep.enc_part2.key_expiration); + if (rep.enc_part2.starttime) + free (rep.enc_part2.starttime); + if (rep.enc_part2.renew_till) + free (rep.enc_part2.renew_till); + if (rep.enc_part2.req.values) + free (rep.enc_part2.req.values); + if (rep.enc_part2.caddr.addrs) { + int i; + + for (i = 0; i < rep.enc_part2.caddr.number; ++i) { + krb5_data_free (&rep.enc_part2.caddr.addrs[i].address); + } + free (rep.enc_part2.caddr.addrs); + } + krb5_principal_free (rep.enc_part2.sname); + krb5_data_free (&rep.enc_part2.srealm); + if (err) return err; + + creds->session.contents.length = 0; + creds->session.contents.data = NULL; + creds->session.keytype = rep.enc_part2.key.keytype; + err = krb5_data_copy (&creds->session.contents, + rep.enc_part2.key.contents.data, + rep.enc_part2.key.contents.length); + memset (rep.enc_part2.key.contents.data, 0, + rep.enc_part2.key.contents.length); + krb5_data_free (&rep.enc_part2.key.contents); + + if (err) + return err; + return 0; } diff --git a/k5_der.h b/k5_der.h index ab8991abb..432cff307 100644 --- a/k5_der.h +++ b/k5_der.h @@ -50,8 +50,6 @@ struct KdcOptions { typedef struct KdcOptions KdcOptions; -typedef int EncryptionType; - struct Kdc_Req { int pvno; int msg_type; @@ -78,22 +76,6 @@ struct EncryptedData { typedef struct EncryptedData EncryptedData; -struct Ticket { - int tkt_vno; - krb5_realm realm; - krb5_principal sname; - EncryptedData enc_part; -}; - -typedef struct Ticket Ticket; - -struct EncryptionKey { - int keytype; - krb5_data keyvalue; -}; - -typedef struct EncryptionKey EncryptionKey; - struct LastReq { int number; struct { @@ -121,7 +103,7 @@ struct TicketFlags { typedef struct TicketFlags TicketFlags; struct EncKdcRepPart { - EncryptionKey key; + krb5_keyblock key; LastReq req; int nonce; krb5_time *key_expiration; @@ -145,7 +127,7 @@ struct krb5_kdc_rep { int msg_type; krb5_realm realm; krb5_principal cname; - Ticket ticket; + krb5_ticket ticket; EncryptedData enc_part; EncASRepPart enc_part2; }; diff --git a/kinit.c b/kinit.c index c0bbb5374..3eeac3a7f 100644 --- a/kinit.c +++ b/kinit.c @@ -8,6 +8,7 @@ main (int argc, char **argv) krb5_context context; krb5_ccache ccache; krb5_principal principal; + krb5_principal server; krb5_creds cred; err = krb5_init_context (&context); @@ -29,6 +30,17 @@ main (int argc, char **argv) cred.client = principal; cred.times.endtime = time (NULL) + 4711; + err = krb5_build_principal (context, + &cred.server, + principal->realm.length, + principal->realm.data, + "krbtgt", + principal->realm.data, + NULL); + if (err) + abort (); + cred.server->type = KRB5_NT_SRV_INST; + err = krb5_get_in_tkt_with_password (context, 0, NULL, diff --git a/krb5.h b/krb5.h index 4fdf082aa..652c0895c 100644 --- a/krb5.h +++ b/krb5.h @@ -137,8 +137,6 @@ typedef struct krb5_ticket{ krb5_enctype etype; }krb5_ticket; - - #define KRB5_PARSE_MALFORMED 17 #define KRB5_PROG_ETYPE_NOSUPP 4711 diff --git a/kuser/kinit.c b/kuser/kinit.c index c0bbb5374..3eeac3a7f 100644 --- a/kuser/kinit.c +++ b/kuser/kinit.c @@ -8,6 +8,7 @@ main (int argc, char **argv) krb5_context context; krb5_ccache ccache; krb5_principal principal; + krb5_principal server; krb5_creds cred; err = krb5_init_context (&context); @@ -29,6 +30,17 @@ main (int argc, char **argv) cred.client = principal; cred.times.endtime = time (NULL) + 4711; + err = krb5_build_principal (context, + &cred.server, + principal->realm.length, + principal->realm.data, + "krbtgt", + principal->realm.data, + NULL); + if (err) + abort (); + cred.server->type = KRB5_NT_SRV_INST; + err = krb5_get_in_tkt_with_password (context, 0, NULL, diff --git a/lib/krb5/get_in_tkt.c b/lib/krb5/get_in_tkt.c index 716012e2e..e78843b8c 100644 --- a/lib/krb5/get_in_tkt.c +++ b/lib/krb5/get_in_tkt.c @@ -80,24 +80,17 @@ krb5_get_in_tkt(krb5_context context, krb5_error_code err; As_Req a; krb5_kdc_rep rep; - krb5_principal_data server; krb5_data req, resp; char buf[BUFSIZ]; Buffer buffer; krb5_data salt; krb5_keyblock *key; - server.type = KRB5_NT_SRV_INST; - server.ncomp = 2; - server.comp = malloc (sizeof(*server.comp) * server.ncomp); - server.comp[0] = string_make ("krbtgt"); - server.comp[1] = creds->client->realm; - a.pvno = 5; a.msg_type = KRB_AS_REQ; /* a.kdc_options */ a.cname = creds->client; - a.sname = &server; + a.sname = creds->server; a.realm = creds->client->realm; a.till = creds->times.endtime; a.nonce = 17; @@ -118,7 +111,6 @@ krb5_get_in_tkt(krb5_context context, req.length = der_put_as_req (buf + sizeof(buf) - 1, &a); req.data = buf + sizeof(buf) - req.length; - free (server.comp); if (addrs == NULL) { int i; @@ -135,6 +127,22 @@ krb5_get_in_tkt(krb5_context context, if (der_get_as_rep (&buffer, &rep) == -1) { return ASN1_PARSE_ERROR; } + krb5_data_free (&rep.realm); + krb5_principal_free (rep.cname); + creds->ticket.kvno = rep.ticket.kvno; + creds->ticket.etype = rep.ticket.etype; + creds->ticket.enc_part.length = 0; + creds->ticket.enc_part.data = NULL; + krb5_data_copy (&creds->ticket.enc_part, + rep.ticket.enc_part.data, + rep.ticket.enc_part.length); + krb5_data_free (&rep.ticket.enc_part); + + krb5_copy_principal (context, + rep.ticket.sprinc, + &creds->ticket.sprinc); + krb5_free_principal (rep.ticket.sprinc); + salt.length = 0; salt.data = NULL; err = krb5_get_salt (creds->client, creds->client->realm, &salt); @@ -152,7 +160,40 @@ krb5_get_in_tkt(krb5_context context, memset (key->contents.data, 0, key->contents.length); krb5_data_free (&key->contents); free (key); + if (rep.enc_part2.key_expiration) + free (rep.enc_part2.key_expiration); + if (rep.enc_part2.starttime) + free (rep.enc_part2.starttime); + if (rep.enc_part2.renew_till) + free (rep.enc_part2.renew_till); + if (rep.enc_part2.req.values) + free (rep.enc_part2.req.values); + if (rep.enc_part2.caddr.addrs) { + int i; + + for (i = 0; i < rep.enc_part2.caddr.number; ++i) { + krb5_data_free (&rep.enc_part2.caddr.addrs[i].address); + } + free (rep.enc_part2.caddr.addrs); + } + krb5_principal_free (rep.enc_part2.sname); + krb5_data_free (&rep.enc_part2.srealm); + if (err) return err; + + creds->session.contents.length = 0; + creds->session.contents.data = NULL; + creds->session.keytype = rep.enc_part2.key.keytype; + err = krb5_data_copy (&creds->session.contents, + rep.enc_part2.key.contents.data, + rep.enc_part2.key.contents.length); + memset (rep.enc_part2.key.contents.data, 0, + rep.enc_part2.key.contents.length); + krb5_data_free (&rep.enc_part2.key.contents); + + if (err) + return err; + return 0; } diff --git a/lib/krb5/krb5.h b/lib/krb5/krb5.h index 4fdf082aa..652c0895c 100644 --- a/lib/krb5/krb5.h +++ b/lib/krb5/krb5.h @@ -137,8 +137,6 @@ typedef struct krb5_ticket{ krb5_enctype etype; }krb5_ticket; - - #define KRB5_PARSE_MALFORMED 17 #define KRB5_PROG_ETYPE_NOSUPP 4711 diff --git a/lib/krb5/principal.c b/lib/krb5/principal.c index 92aa62076..a68b139bf 100644 --- a/lib/krb5/principal.c +++ b/lib/krb5/principal.c @@ -287,6 +287,7 @@ krb5_copy_principal(krb5_context context, } for(i=0; incomp; i++){ + p->comp[i].length = 0; if(krb5_data_copy(&p->comp[i], inprinc->comp[i].data, inprinc->comp[i].length)){ krb5_free_principal(p); diff --git a/principal.c b/principal.c index 92aa62076..a68b139bf 100644 --- a/principal.c +++ b/principal.c @@ -287,6 +287,7 @@ krb5_copy_principal(krb5_context context, } for(i=0; incomp; i++){ + p->comp[i].length = 0; if(krb5_data_copy(&p->comp[i], inprinc->comp[i].data, inprinc->comp[i].length)){ krb5_free_principal(p);