diff options
Diffstat (limited to 'crypto/heimdal/kdc/kaserver.c')
-rw-r--r-- | crypto/heimdal/kdc/kaserver.c | 496 |
1 files changed, 304 insertions, 192 deletions
diff --git a/crypto/heimdal/kdc/kaserver.c b/crypto/heimdal/kdc/kaserver.c index 8694471..27f497e 100644 --- a/crypto/heimdal/kdc/kaserver.c +++ b/crypto/heimdal/kdc/kaserver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,9 +33,9 @@ #include "kdc_locl.h" -RCSID("$Id: kaserver.c,v 1.21.2.1 2003/10/06 21:02:35 lha Exp $"); - +RCSID("$Id: kaserver.c 21654 2007-07-21 17:30:18Z lha $"); +#include <krb5-v4compat.h> #include <rx.h> #define KA_AUTHENTICATION_SERVICE 731 @@ -107,38 +107,69 @@ RCSID("$Id: kaserver.c,v 1.21.2.1 2003/10/06 21:02:35 lha Exp $"); #define KATOOSOON (180521L) #define KALOCKED (180522L) -static void + +static krb5_error_code decode_rx_header (krb5_storage *sp, struct rx_header *h) { - krb5_ret_int32(sp, &h->epoch); - krb5_ret_int32(sp, &h->connid); - krb5_ret_int32(sp, &h->callid); - krb5_ret_int32(sp, &h->seqno); - krb5_ret_int32(sp, &h->serialno); - krb5_ret_int8(sp, &h->type); - krb5_ret_int8(sp, &h->flags); - krb5_ret_int8(sp, &h->status); - krb5_ret_int8(sp, &h->secindex); - krb5_ret_int16(sp, &h->reserved); - krb5_ret_int16(sp, &h->serviceid); + krb5_error_code ret; + + ret = krb5_ret_uint32(sp, &h->epoch); + if (ret) return ret; + ret = krb5_ret_uint32(sp, &h->connid); + if (ret) return ret; + ret = krb5_ret_uint32(sp, &h->callid); + if (ret) return ret; + ret = krb5_ret_uint32(sp, &h->seqno); + if (ret) return ret; + ret = krb5_ret_uint32(sp, &h->serialno); + if (ret) return ret; + ret = krb5_ret_uint8(sp, &h->type); + if (ret) return ret; + ret = krb5_ret_uint8(sp, &h->flags); + if (ret) return ret; + ret = krb5_ret_uint8(sp, &h->status); + if (ret) return ret; + ret = krb5_ret_uint8(sp, &h->secindex); + if (ret) return ret; + ret = krb5_ret_uint16(sp, &h->reserved); + if (ret) return ret; + ret = krb5_ret_uint16(sp, &h->serviceid); + if (ret) return ret; + + return 0; } -static void +static krb5_error_code encode_rx_header (struct rx_header *h, krb5_storage *sp) { - krb5_store_int32(sp, h->epoch); - krb5_store_int32(sp, h->connid); - krb5_store_int32(sp, h->callid); - krb5_store_int32(sp, h->seqno); - krb5_store_int32(sp, h->serialno); - krb5_store_int8(sp, h->type); - krb5_store_int8(sp, h->flags); - krb5_store_int8(sp, h->status); - krb5_store_int8(sp, h->secindex); - krb5_store_int16(sp, h->reserved); - krb5_store_int16(sp, h->serviceid); + krb5_error_code ret; + + ret = krb5_store_uint32(sp, h->epoch); + if (ret) return ret; + ret = krb5_store_uint32(sp, h->connid); + if (ret) return ret; + ret = krb5_store_uint32(sp, h->callid); + if (ret) return ret; + ret = krb5_store_uint32(sp, h->seqno); + if (ret) return ret; + ret = krb5_store_uint32(sp, h->serialno); + if (ret) return ret; + ret = krb5_store_uint8(sp, h->type); + if (ret) return ret; + ret = krb5_store_uint8(sp, h->flags); + if (ret) return ret; + ret = krb5_store_uint8(sp, h->status); + if (ret) return ret; + ret = krb5_store_uint8(sp, h->secindex); + if (ret) return ret; + ret = krb5_store_uint16(sp, h->reserved); + if (ret) return ret; + ret = krb5_store_uint16(sp, h->serviceid); + if (ret) return ret; + + return 0; } static void @@ -160,19 +191,28 @@ init_reply_header (struct rx_header *hdr, reply_hdr->serviceid = hdr->serviceid; } +/* + * Create an error `reply´ using for the packet `hdr' with the error + * `error´ code. + */ static void make_error_reply (struct rx_header *hdr, - u_int32_t ret, + uint32_t error, krb5_data *reply) { - krb5_storage *sp; struct rx_header reply_hdr; + krb5_error_code ret; + krb5_storage *sp; init_reply_header (hdr, &reply_hdr, HT_ABORT, HF_LAST); sp = krb5_storage_emem(); - encode_rx_header (&reply_hdr, sp); - krb5_store_int32(sp, ret); + if (sp == NULL) + return; + ret = encode_rx_header (&reply_hdr, sp); + if (ret) + return; + krb5_store_int32(sp, error); krb5_storage_to_data (sp, reply); krb5_storage_free (sp); } @@ -240,7 +280,8 @@ krb5_store_xdr_data(krb5_storage *sp, static krb5_error_code -create_reply_ticket (struct rx_header *hdr, +create_reply_ticket (krb5_context context, + struct rx_header *hdr, Key *skey, char *name, char *instance, char *realm, struct sockaddr_in *addr, @@ -248,29 +289,38 @@ create_reply_ticket (struct rx_header *hdr, int kvno, int32_t max_seq_len, const char *sname, const char *sinstance, - u_int32_t challenge, + uint32_t challenge, const char *label, - des_cblock *key, + krb5_keyblock *key, krb5_data *reply) { - KTEXT_ST ticket; - des_cblock session; + krb5_error_code ret; + krb5_data ticket; + krb5_keyblock session; krb5_storage *sp; krb5_data enc_data; - des_key_schedule schedule; struct rx_header reply_hdr; - des_cblock zero; + char zero[8]; size_t pad; unsigned fyrtiosjuelva; /* create the ticket */ - des_new_random_key(&session); - - krb_create_ticket (&ticket, 0, name, instance, realm, - addr->sin_addr.s_addr, - &session, life, kdc_time, - sname, sinstance, skey->key.keyvalue.data); + krb5_generate_random_keyblock(context, ETYPE_DES_PCBC_NONE, &session); + + _krb5_krb_create_ticket(context, + 0, + name, + instance, + realm, + addr->sin_addr.s_addr, + &session, + life, + kdc_time, + sname, + sinstance, + &skey->key, + &ticket); /* create the encrypted part of the reply */ sp = krb5_storage_emem (); @@ -278,10 +328,10 @@ create_reply_ticket (struct rx_header *hdr, fyrtiosjuelva &= 0xffffffff; krb5_store_int32 (sp, fyrtiosjuelva); krb5_store_int32 (sp, challenge); - krb5_storage_write (sp, session, 8); - memset (&session, 0, sizeof(session)); + krb5_storage_write (sp, session.keyvalue.data, 8); + krb5_free_keyblock_contents(context, &session); krb5_store_int32 (sp, kdc_time); - krb5_store_int32 (sp, kdc_time + krb_life_to_time (0, life)); + krb5_store_int32 (sp, kdc_time + _krb5_krb_life_to_time (0, life)); krb5_store_int32 (sp, kvno); krb5_store_int32 (sp, ticket.length); krb5_store_stringz (sp, name); @@ -293,7 +343,7 @@ create_reply_ticket (struct rx_header *hdr, #endif krb5_store_stringz (sp, sname); krb5_store_stringz (sp, sinstance); - krb5_storage_write (sp, ticket.dat, ticket.length); + krb5_storage_write (sp, ticket.data, ticket.length); krb5_storage_write (sp, label, strlen(label)); /* pad to DES block */ @@ -311,19 +361,26 @@ create_reply_ticket (struct rx_header *hdr, } /* encrypt it */ - des_set_key (key, schedule); - des_pcbc_encrypt (enc_data.data, - enc_data.data, - enc_data.length, - schedule, - key, - DES_ENCRYPT); - memset (&schedule, 0, sizeof(schedule)); + { + DES_key_schedule schedule; + DES_cblock deskey; + + memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); + DES_set_key (&deskey, &schedule); + DES_pcbc_encrypt (enc_data.data, + enc_data.data, + enc_data.length, + &schedule, + &deskey, + DES_ENCRYPT); + memset (&schedule, 0, sizeof(schedule)); + memset (&deskey, 0, sizeof(deskey)); + } /* create the reply packet */ init_reply_header (hdr, &reply_hdr, HT_DATA, HF_LAST); sp = krb5_storage_emem (); - encode_rx_header (&reply_hdr, sp); + ret = encode_rx_header (&reply_hdr, sp); krb5_store_int32 (sp, max_seq_len); krb5_store_xdr_data (sp, enc_data); krb5_data_free (&enc_data); @@ -373,9 +430,12 @@ unparse_auth_args (krb5_storage *sp, } static void -do_authenticate (struct rx_header *hdr, +do_authenticate (krb5_context context, + krb5_kdc_configuration *config, + struct rx_header *hdr, krb5_storage *sp, struct sockaddr_in *addr, + const char *from, krb5_data *reply) { krb5_error_code ret; @@ -385,87 +445,99 @@ do_authenticate (struct rx_header *hdr, time_t end_time; krb5_data request; int32_t max_seq_len; - hdb_entry *client_entry = NULL; - hdb_entry *server_entry = NULL; + hdb_entry_ex *client_entry = NULL; + hdb_entry_ex *server_entry = NULL; Key *ckey = NULL; Key *skey = NULL; - des_cblock key; - des_key_schedule schedule; krb5_storage *reply_sp; time_t max_life; - u_int8_t life; + uint8_t life; int32_t chal; char client_name[256]; char server_name[256]; krb5_data_zero (&request); - unparse_auth_args (sp, &name, &instance, &start_time, &end_time, - &request, &max_seq_len); - if (request.length < 8) { + ret = unparse_auth_args (sp, &name, &instance, &start_time, &end_time, + &request, &max_seq_len); + if (ret != 0 || request.length < 8) { make_error_reply (hdr, KABADREQUEST, reply); goto out; } snprintf (client_name, sizeof(client_name), "%s.%s@%s", - name, instance, v4_realm); + name, instance, config->v4_realm); + snprintf (server_name, sizeof(server_name), "%s.%s@%s", + "krbtgt", config->v4_realm, config->v4_realm); - ret = db_fetch4 (name, instance, v4_realm, &client_entry); + kdc_log(context, config, 0, "AS-REQ (kaserver) %s from %s for %s", + client_name, from, server_name); + + ret = _kdc_db_fetch4 (context, config, name, instance, + config->v4_realm, HDB_F_GET_CLIENT, + &client_entry); if (ret) { - kdc_log(0, "Client not found in database: %s: %s", + kdc_log(context, config, 0, "Client not found in database: %s: %s", client_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } - snprintf (server_name, sizeof(server_name), "%s.%s@%s", - "krbtgt", v4_realm, v4_realm); - - ret = db_fetch4 ("krbtgt", v4_realm, v4_realm, &server_entry); + ret = _kdc_db_fetch4 (context, config, "krbtgt", + config->v4_realm, config->v4_realm, + HDB_F_GET_KRBTGT, &server_entry); if (ret) { - kdc_log(0, "Server not found in database: %s: %s", + kdc_log(context, config, 0, "Server not found in database: %s: %s", server_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } - ret = check_flags (client_entry, client_name, - server_entry, server_name, - TRUE); + ret = _kdc_check_flags (context, config, + client_entry, client_name, + server_entry, server_name, + TRUE); if (ret) { make_error_reply (hdr, KAPWEXPIRED, reply); goto out; } /* find a DES key */ - ret = get_des_key(client_entry, FALSE, TRUE, &ckey); + ret = _kdc_get_des_key(context, client_entry, FALSE, TRUE, &ckey); if(ret){ - kdc_log(0, "no suitable DES key for client"); + kdc_log(context, config, 0, "no suitable DES key for client"); make_error_reply (hdr, KANOKEYS, reply); goto out; } /* find a DES key */ - ret = get_des_key(server_entry, TRUE, TRUE, &skey); + ret = _kdc_get_des_key(context, server_entry, TRUE, TRUE, &skey); if(ret){ - kdc_log(0, "no suitable DES key for server"); + kdc_log(context, config, 0, "no suitable DES key for server"); make_error_reply (hdr, KANOKEYS, reply); goto out; } - /* try to decode the `request' */ - memcpy (&key, ckey->key.keyvalue.data, sizeof(key)); - des_set_key (&key, schedule); - des_pcbc_encrypt (request.data, - request.data, - request.length, - schedule, - &key, - DES_DECRYPT); - memset (&schedule, 0, sizeof(schedule)); + { + DES_cblock key; + DES_key_schedule schedule; + + /* try to decode the `request' */ + memcpy (&key, ckey->key.keyvalue.data, sizeof(key)); + DES_set_key (&key, &schedule); + DES_pcbc_encrypt (request.data, + request.data, + request.length, + &schedule, + &key, + DES_DECRYPT); + memset (&schedule, 0, sizeof(schedule)); + memset (&key, 0, sizeof(key)); + } /* check for the magic label */ if (memcmp ((char *)request.data + 4, "gTGS", 4) != 0) { + kdc_log(context, config, 0, "preauth failed for %s", client_name); make_error_reply (hdr, KABADREQUEST, reply); goto out; } @@ -485,23 +557,23 @@ do_authenticate (struct rx_header *hdr, time skew between client and server. Let's make sure it is postive */ if(max_life < 1) max_life = 1; - if (client_entry->max_life) - max_life = min(max_life, *client_entry->max_life); - if (server_entry->max_life) - max_life = min(max_life, *server_entry->max_life); + if (client_entry->entry.max_life) + max_life = min(max_life, *client_entry->entry.max_life); + if (server_entry->entry.max_life) + max_life = min(max_life, *server_entry->entry.max_life); life = krb_time_to_life(kdc_time, kdc_time + max_life); - create_reply_ticket (hdr, skey, - name, instance, v4_realm, - addr, life, server_entry->kvno, + create_reply_ticket (context, + hdr, skey, + name, instance, config->v4_realm, + addr, life, server_entry->entry.kvno, max_seq_len, - "krbtgt", v4_realm, + "krbtgt", config->v4_realm, chal + 1, "tgsT", - &key, reply); - memset (&key, 0, sizeof(key)); + &ckey->key, reply); -out: + out: if (request.length) { memset (request.data, 0, request.length); krb5_data_free (&request); @@ -511,9 +583,9 @@ out: if (instance) free (instance); if (client_entry) - free_ent (client_entry); + _kdc_free_ent (context, client_entry); if (server_entry) - free_ent (server_entry); + _kdc_free_ent (context, server_entry); } static krb5_error_code @@ -571,9 +643,12 @@ unparse_getticket_args (krb5_storage *sp, } static void -do_getticket (struct rx_header *hdr, +do_getticket (krb5_context context, + krb5_kdc_configuration *config, + struct rx_header *hdr, krb5_storage *sp, struct sockaddr_in *addr, + const char *from, krb5_data *reply) { krb5_error_code ret; @@ -584,24 +659,26 @@ do_getticket (struct rx_header *hdr, char *instance = NULL; krb5_data times; int32_t max_seq_len; - hdb_entry *server_entry = NULL; - hdb_entry *krbtgt_entry = NULL; + hdb_entry_ex *server_entry = NULL; + hdb_entry_ex *client_entry = NULL; + hdb_entry_ex *krbtgt_entry = NULL; Key *kkey = NULL; Key *skey = NULL; - des_cblock key; - des_key_schedule schedule; - des_cblock session; + DES_cblock key; + DES_key_schedule schedule; + DES_cblock session; time_t max_life; int8_t life; time_t start_time, end_time; - char pname[ANAME_SZ]; - char pinst[INST_SZ]; - char prealm[REALM_SZ]; char server_name[256]; + char client_name[256]; + struct _krb5_krb_auth_data ad; krb5_data_zero (&aticket); krb5_data_zero (×); + memset(&ad, 0, sizeof(ad)); + unparse_getticket_args (sp, &kvno, &auth_domain, &aticket, &name, &instance, ×, &max_seq_len); if (times.length < 8) { @@ -611,44 +688,40 @@ do_getticket (struct rx_header *hdr, } snprintf (server_name, sizeof(server_name), - "%s.%s@%s", name, instance, v4_realm); + "%s.%s@%s", name, instance, config->v4_realm); - ret = db_fetch4 (name, instance, v4_realm, &server_entry); + ret = _kdc_db_fetch4 (context, config, name, instance, + config->v4_realm, HDB_F_GET_SERVER, &server_entry); if (ret) { - kdc_log(0, "Server not found in database: %s: %s", + kdc_log(context, config, 0, "Server not found in database: %s: %s", server_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } - ret = check_flags (NULL, NULL, - server_entry, server_name, - FALSE); + ret = _kdc_db_fetch4 (context, config, "krbtgt", + config->v4_realm, config->v4_realm, HDB_F_GET_KRBTGT, &krbtgt_entry); if (ret) { - make_error_reply (hdr, KAPWEXPIRED, reply); - goto out; - } - - ret = db_fetch4 ("krbtgt", v4_realm, v4_realm, &krbtgt_entry); - if (ret) { - kdc_log(0, "Server not found in database: %s.%s@%s: %s", - "krbtgt", v4_realm, v4_realm, krb5_get_err_text(context, ret)); + kdc_log(context, config, 0, + "Server not found in database: %s.%s@%s: %s", + "krbtgt", config->v4_realm, config->v4_realm, + krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } /* find a DES key */ - ret = get_des_key(krbtgt_entry, TRUE, TRUE, &kkey); + ret = _kdc_get_des_key(context, krbtgt_entry, TRUE, TRUE, &kkey); if(ret){ - kdc_log(0, "no suitable DES key for krbtgt"); + kdc_log(context, config, 0, "no suitable DES key for krbtgt"); make_error_reply (hdr, KANOKEYS, reply); goto out; } /* find a DES key */ - ret = get_des_key(server_entry, TRUE, TRUE, &skey); + ret = _kdc_get_des_key(context, server_entry, TRUE, TRUE, &skey); if(ret){ - kdc_log(0, "no suitable DES key for server"); + kdc_log(context, config, 0, "no suitable DES key for server"); make_error_reply (hdr, KANOKEYS, reply); goto out; } @@ -658,67 +731,95 @@ do_getticket (struct rx_header *hdr, /* unpack the ticket */ { - KTEXT_ST ticket; - u_char flags; - int life; - u_int32_t time_sec; - char sname[ANAME_SZ]; - char sinstance[SNAME_SZ]; - u_int32_t paddress; - - if (aticket.length > sizeof(ticket.dat)) { - kdc_log(0, "ticket too long (%u > %u)", - (unsigned)aticket.length, - (unsigned)sizeof(ticket.dat)); + char *sname = NULL; + char *sinstance = NULL; + + ret = _krb5_krb_decomp_ticket(context, &aticket, &kkey->key, + config->v4_realm, &sname, + &sinstance, &ad); + if (ret) { + kdc_log(context, config, 0, + "kaserver: decomp failed for %s.%s with %d", + sname, sinstance, ret); make_error_reply (hdr, KABADTICKET, reply); goto out; } - ticket.length = aticket.length; - memcpy (ticket.dat, aticket.data, ticket.length); - - des_set_key (&key, schedule); - decomp_ticket (&ticket, &flags, pname, pinst, prealm, - &paddress, session, &life, &time_sec, - sname, sinstance, - &key, schedule); - if (strcmp (sname, "krbtgt") != 0 - || strcmp (sinstance, v4_realm) != 0) { - kdc_log(0, "no TGT: %s.%s for %s.%s@%s", + || strcmp (sinstance, config->v4_realm) != 0) { + kdc_log(context, config, 0, "no TGT: %s.%s for %s.%s@%s", sname, sinstance, - pname, pinst, prealm); + ad.pname, ad.pinst, ad.prealm); make_error_reply (hdr, KABADTICKET, reply); + free(sname); + free(sinstance); goto out; } + free(sname); + free(sinstance); - if (kdc_time > krb_life_to_time(time_sec, life)) { - kdc_log(0, "TGT expired: %s.%s@%s", - pname, pinst, prealm); + if (kdc_time > _krb5_krb_life_to_time(ad.time_sec, ad.life)) { + kdc_log(context, config, 0, "TGT expired: %s.%s@%s", + ad.pname, ad.pinst, ad.prealm); make_error_reply (hdr, KABADTICKET, reply); goto out; } } + snprintf (client_name, sizeof(client_name), + "%s.%s@%s", ad.pname, ad.pinst, ad.prealm); + + kdc_log(context, config, 0, "TGS-REQ (kaserver) %s from %s for %s", + client_name, from, server_name); + + ret = _kdc_db_fetch4 (context, config, + ad.pname, ad.pinst, ad.prealm, HDB_F_GET_CLIENT, + &client_entry); + if(ret && ret != HDB_ERR_NOENTRY) { + kdc_log(context, config, 0, + "Client not found in database: (krb4) %s: %s", + client_name, krb5_get_err_text(context, ret)); + make_error_reply (hdr, KANOENT, reply); + goto out; + } + if (client_entry == NULL && strcmp(ad.prealm, config->v4_realm) == 0) { + kdc_log(context, config, 0, + "Local client not found in database: (krb4) " + "%s", client_name); + make_error_reply (hdr, KANOENT, reply); + goto out; + } + + ret = _kdc_check_flags (context, config, + client_entry, client_name, + server_entry, server_name, + FALSE); + if (ret) { + make_error_reply (hdr, KAPWEXPIRED, reply); + goto out; + } + /* decrypt the times */ - des_set_key (&session, schedule); - des_ecb_encrypt (times.data, + memcpy(&session, ad.session.keyvalue.data, sizeof(session)); + DES_set_key (&session, &schedule); + DES_ecb_encrypt (times.data, times.data, - schedule, + &schedule, DES_DECRYPT); memset (&schedule, 0, sizeof(schedule)); + memset (&session, 0, sizeof(session)); /* and extract them */ { - krb5_storage *sp; + krb5_storage *tsp; int32_t tmp; - sp = krb5_storage_from_mem (times.data, times.length); - krb5_ret_int32 (sp, &tmp); + tsp = krb5_storage_from_mem (times.data, times.length); + krb5_ret_int32 (tsp, &tmp); start_time = tmp; - krb5_ret_int32 (sp, &tmp); + krb5_ret_int32 (tsp, &tmp); end_time = tmp; - krb5_storage_free (sp); + krb5_storage_free (tsp); } /* life */ @@ -727,23 +828,28 @@ do_getticket (struct rx_header *hdr, time skew between client and server. Let's make sure it is postive */ if(max_life < 1) max_life = 1; - if (krbtgt_entry->max_life) - max_life = min(max_life, *krbtgt_entry->max_life); - if (server_entry->max_life) - max_life = min(max_life, *server_entry->max_life); - - life = krb_time_to_life(kdc_time, kdc_time + max_life); - - create_reply_ticket (hdr, skey, - pname, pinst, prealm, - addr, life, server_entry->kvno, + if (krbtgt_entry->entry.max_life) + max_life = min(max_life, *krbtgt_entry->entry.max_life); + if (server_entry->entry.max_life) + max_life = min(max_life, *server_entry->entry.max_life); + /* if this is a cross realm request, the client_entry will likely + be NULL */ + if (client_entry && client_entry->entry.max_life) + max_life = min(max_life, *client_entry->entry.max_life); + + life = _krb5_krb_time_to_life(kdc_time, kdc_time + max_life); + + create_reply_ticket (context, + hdr, skey, + ad.pname, ad.pinst, ad.prealm, + addr, life, server_entry->entry.kvno, max_seq_len, name, instance, 0, "gtkt", - &session, reply); - memset (&session, 0, sizeof(session)); + &ad.session, reply); -out: + out: + _krb5_krb_free_auth_data(context, &ad); if (aticket.length) { memset (aticket.data, 0, aticket.length); krb5_data_free (&aticket); @@ -759,28 +865,32 @@ out: if (instance) free (instance); if (krbtgt_entry) - free_ent (krbtgt_entry); + _kdc_free_ent (context, krbtgt_entry); if (server_entry) - free_ent (server_entry); + _kdc_free_ent (context, server_entry); } krb5_error_code -do_kaserver(unsigned char *buf, - size_t len, - krb5_data *reply, - const char *from, - struct sockaddr_in *addr) +_kdc_do_kaserver(krb5_context context, + krb5_kdc_configuration *config, + unsigned char *buf, + size_t len, + krb5_data *reply, + const char *from, + struct sockaddr_in *addr) { krb5_error_code ret = 0; struct rx_header hdr; - u_int32_t op; + uint32_t op; krb5_storage *sp; if (len < RX_HEADER_SIZE) return -1; sp = krb5_storage_from_mem (buf, len); - decode_rx_header (sp, &hdr); + ret = decode_rx_header (sp, &hdr); + if (ret) + goto out; buf += RX_HEADER_SIZE; len -= RX_HEADER_SIZE; @@ -806,13 +916,16 @@ do_kaserver(unsigned char *buf, goto out; } - krb5_ret_int32(sp, &op); + ret = krb5_ret_uint32(sp, &op); + if (ret) + goto out; switch (op) { case AUTHENTICATE : - do_authenticate (&hdr, sp, addr, reply); + case AUTHENTICATE_V2 : + do_authenticate (context, config, &hdr, sp, addr, from, reply); break; case GETTICKET : - do_getticket (&hdr, sp, addr, reply); + do_getticket (context, config, &hdr, sp, addr, from, reply); break; case AUTHENTICATE_OLD : case CHANGEPASSWORD : @@ -827,7 +940,6 @@ do_kaserver(unsigned char *buf, case DEBUG : case GETPASSWORD : case GETRANDOMKEY : - case AUTHENTICATE_V2 : default : make_error_reply (&hdr, RXGEN_OPCODE, reply); break; |