diff options
| author | Theodore Tso <tytso@mit.edu> | 1995-11-14 00:47:37 +0000 |
|---|---|---|
| committer | Theodore Tso <tytso@mit.edu> | 1995-11-14 00:47:37 +0000 |
| commit | 37d97c4658b06f2ca7a0c2f7ef765ce8031d2765 (patch) | |
| tree | a45aae1003d4020386c61ffe4ac9994d832a8aa1 /src | |
| parent | 394becd543eca283dcd79d4cd26c7afa6ef720d8 (diff) | |
| download | krb5-37d97c4658b06f2ca7a0c2f7ef765ce8031d2765.tar.gz krb5-37d97c4658b06f2ca7a0c2f7ef765ce8031d2765.tar.xz krb5-37d97c4658b06f2ca7a0c2f7ef765ce8031d2765.zip | |
* kdc_util.h: Added new prototypes for return_padata() and check_padata()
* kdc_preauth.c (return_padata): New function which calls out to each preauth
type to see if it is necessary to return preauth data or not.
(return_pw_salt): New function responsible for returning the
KRB5_PW_SALT preauth information.
* do_as_req.c (process_as_req): Move creation of the PW_SALT
preauthentication step into kdc_preauth.c. Call return_pdata()
which is responsible for all padata info which is returned by
the KDC in the KRB_AS_REP message.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7103 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
| -rw-r--r-- | src/kdc/ChangeLog | 17 | ||||
| -rw-r--r-- | src/kdc/do_as_req.c | 90 | ||||
| -rw-r--r-- | src/kdc/kdc_preauth.c | 209 | ||||
| -rw-r--r-- | src/kdc/kdc_util.h | 8 |
4 files changed, 214 insertions, 110 deletions
diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index bea2674c1..acc9b73ba 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,20 @@ +Mon Nov 13 19:40:50 1995 Theodore Y. Ts'o <tytso@dcl> + + * kdc_util.h: Added new prototypes for return_padata() and + check_padata(). + + * kdc_preauth.c (return_padata): New function which calls out to + each preauth type to see if it is necessary to return + preauth data or not. + (return_pw_salt): New function responsible for returning the + KRB5_PW_SALT preauth information. + + * do_as_req.c (process_as_req): Move creation of the PW_SALT + preauthentication step into kdc_preauth.c. Call + return_pdata() which is responsible for all padata info + which is returned by the KDC in the KRB_AS_REP message. + + Thu Nov 9 00:05:55 1995 Theodore Y. Ts'o <tytso@dcl> * kdc_preauth.c (get_etype_info): Added function to return the diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 3e7ebc99a..9542c05d8 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -63,13 +63,10 @@ krb5_data **response; /* filled in with a response packet */ krb5_enc_tkt_part enc_tkt_reply; krb5_error_code errcode; int c_nprincs = 0, s_nprincs = 0; - int pa_id, pa_flags; krb5_boolean more; krb5_timestamp kdc_time, authtime; krb5_keyblock *session_key = 0; krb5_keyblock encrypting_key; - krb5_pa_data *padat_tmp[2], padat_local; - krb5_data salt_data; const char *status; krb5_encrypt_block eblock; krb5_key_data *server_key, *client_key; @@ -83,8 +80,8 @@ krb5_data **response; /* filled in with a response packet */ char *cname = 0, *sname = 0, *fromstring = 0; ticket_reply.enc_part.ciphertext.data = 0; - salt_data.data = 0; e_data.data = 0; + encrypting_key.contents = 0; #ifdef KRB5_USE_INET if (from->address->addrtype == ADDRTYPE_INET) @@ -326,6 +323,7 @@ krb5_data **response; /* filled in with a response packet */ errcode = krb5_encrypt_tkt_part(kdc_context, &encrypting_key, &ticket_reply); memset((char *)encrypting_key.contents, 0, encrypting_key.length); krb5_xfree(encrypting_key.contents); + encrypting_key.contents = 0; if (errcode) { status = "ENCRYPTING_TICKET"; goto errout; @@ -353,66 +351,25 @@ krb5_data **response; /* filled in with a response packet */ goto errout; } + /* convert client.key_data into a real key */ + if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context, &master_encblock, + client_key, &encrypting_key, + NULL))) { + status = "DECRYPT_CLIENT_KEY"; + goto errout; + } + encrypting_key.enctype = useenctype; + /* Start assembling the response */ reply.msg_type = KRB5_AS_REP; - reply.padata = 0; - - if (client_key->key_data_ver > 1) { - padat_tmp[0] = &padat_local; - padat_tmp[1] = 0; - - padat_tmp[0]->pa_type = KRB5_PADATA_PW_SALT; - - /* WARNING: sharing substructure here, but it's not a real problem, - since nothing below will "pull out the rug" */ - - switch (client_key->key_data_type[1]) { - krb5_data *data_foo; - case KRB5_KDB_SALTTYPE_NORMAL: - reply.padata = (krb5_pa_data **) NULL; - break; - case KRB5_KDB_SALTTYPE_V4: - /* send an empty (V4) salt */ - padat_tmp[0]->contents = 0; - padat_tmp[0]->length = 0; - reply.padata = padat_tmp; - break; - case KRB5_KDB_SALTTYPE_NOREALM: - if ((errcode = krb5_principal2salt_norealm(kdc_context, - request->client, - &salt_data))) { - status = "SALT_NOREALM"; - goto errout; - } - padat_tmp[0]->contents = (krb5_octet *)salt_data.data; - padat_tmp[0]->length = salt_data.length; - reply.padata = padat_tmp; - break; - case KRB5_KDB_SALTTYPE_ONLYREALM: - data_foo = krb5_princ_realm(kdc_context, request->client); - padat_tmp[0]->contents = (krb5_octet *)data_foo->data; - padat_tmp[0]->length = data_foo->length; - reply.padata = padat_tmp; - break; - case KRB5_KDB_SALTTYPE_SPECIAL: - padat_tmp[0]->contents = client_key->key_data_contents[1]; - padat_tmp[0]->length = client_key->key_data_length[1]; - reply.padata = padat_tmp; - break; - } - } - reply.client = request->client; - reply.ticket = &ticket_reply; - reply_encpart.session = session_key; if ((errcode = fetch_last_req_info(&client, &reply_encpart.last_req))) { status = "FETCH_LAST_REQ"; goto errout; } - reply_encpart.nonce = request->nonce; reply_encpart.key_exp = client.expiration; reply_encpart.flags = enc_tkt_reply.flags; @@ -424,20 +381,19 @@ krb5_data **response; /* filled in with a response packet */ reply_encpart.times.authtime = authtime = kdc_time; reply_encpart.caddrs = enc_tkt_reply.caddrs; - - /* now encode/encrypt the response */ - - reply.enc_part.enctype = useenctype; reply.enc_part.kvno = client_key->key_data_kvno; - /* convert client.key_data into a real key */ - if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context, &master_encblock, - client_key, &encrypting_key, - NULL))) { - status = "DECRYPT_CLIENT_KEY"; + /* Fetch the padata info to be returned */ + errcode = return_padata(kdc_context, &client, request, &reply, client_key, + &encrypting_key); + if (errcode) { + status = "KDC_RETURN_PADATA"; goto errout; } - encrypting_key.enctype = useenctype; + + /* now encode/encrypt the response */ + + reply.enc_part.enctype = encrypting_key.enctype; errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart, &eblock, &encrypting_key, &reply, response); @@ -481,6 +437,10 @@ errout: errcode = prepare_error_as(request, errcode, &e_data, response); } + if (encrypting_key.contents) { + memset((char *)encrypting_key.contents, 0, encrypting_key.length); + krb5_xfree(encrypting_key.contents); + } if (cname) free(cname); if (sname) @@ -510,8 +470,6 @@ errout: ticket_reply.enc_part.ciphertext.length); free(ticket_reply.enc_part.ciphertext.data); } - if (salt_data.data) - krb5_xfree(salt_data.data); if (e_data.data) krb5_xfree(e_data.data); diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 056cd0681..10cd2c52d 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -38,15 +38,25 @@ typedef krb5_error_code (edata_proc) krb5_db_entry *client, krb5_db_entry *server, krb5_pa_data *data)); +typedef krb5_error_code (return_proc) + KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, + krb5_db_entry *client, + krb5_kdc_req *request, krb5_kdc_rep *reply, + krb5_key_data *client_key, + krb5_keyblock *encrypting_key, + krb5_pa_data **send_pa)); + typedef struct _krb5_preauth_systems { int type; int flags; edata_proc *get_edata; - verify_proc *verify; + verify_proc *verify_padata; + return_proc *return_padata; } krb5_preauth_systems; static verify_proc verify_enc_timestamp; static edata_proc get_etype_info; +static return_proc return_pw_salt; /* * Preauth property flags @@ -61,13 +71,22 @@ static krb5_preauth_systems preauth_systems[] = { 0, 0, verify_enc_timestamp, + 0 }, { KRB5_PADATA_ETYPE_INFO, 0, get_etype_info, + 0, 0 }, + { + KRB5_PADATA_PW_SALT, + 0, + 0, + 0, + return_pw_salt + }, { -1,} }; @@ -88,45 +107,6 @@ find_pa_system(type, preauth) return 0; } -krb5_error_code -krb5_decrypt_data(context, key, ivec, enc_data, data) - krb5_context context; - krb5_keyblock * key; - krb5_pointer ivec; - krb5_enc_data * enc_data; - krb5_data * data; -{ - krb5_error_code retval; - krb5_encrypt_block eblock; - - krb5_use_enctype(context, &eblock, key->enctype); - data->length = enc_data->ciphertext.length; - if (!(data->data = malloc(data->length))) - return ENOMEM; - - if ((retval = krb5_process_key(context, &eblock, key)) != 0) - goto cleanup; - - if ((retval = krb5_decrypt(context, - (krb5_pointer) enc_data->ciphertext.data, - (krb5_pointer) data->data, - enc_data->ciphertext.length, &eblock, ivec))) { - krb5_finish_key(context, &eblock); - goto cleanup; - } - (void) krb5_finish_key(context, &eblock); - - return 0; - -cleanup: - if (data->data) { - free(data->data); - data->data = 0; - } - return retval; -} - - const char *missing_required_preauth(client, server, enc_tkt_reply) krb5_db_entry *client, *server; krb5_enc_tkt_part *enc_tkt_reply; @@ -227,10 +207,10 @@ check_padata (context, client, request, enc_tkt_reply) for (padata = request->padata; *padata; padata++) { if (find_pa_system((*padata)->pa_type, &pa_sys)) continue; - if (pa_sys->verify == 0) + if (pa_sys->verify_padata == 0) continue; - retval = pa_sys->verify(context, client, request, - enc_tkt_reply, *padata); + retval = pa_sys->verify_padata(context, client, request, + enc_tkt_reply, *padata); if (retval) { if (pa_sys->flags & PA_REQUIRED) break; @@ -244,6 +224,73 @@ check_padata (context, client, request, enc_tkt_reply) return retval; } +/* + * return_padata creates any necessary preauthentication + * structures which should be returned by the KDC to the client + */ +krb5_error_code +return_padata(context, client, request, reply, + client_key, encrypting_key) + krb5_context context; + krb5_db_entry * client; + krb5_kdc_req * request; + krb5_kdc_rep * reply; + krb5_key_data * client_key; + krb5_keyblock * encrypting_key; +{ + krb5_error_code retval; + krb5_pa_data ** padata; + krb5_pa_data ** send_pa_list; + krb5_pa_data ** send_pa; + krb5_pa_data * pa = 0; + krb5_preauth_systems * ap; + int size; + + for (ap = preauth_systems; ap->type != -1; ap++) { + if (ap->return_padata) + size++; + } + + if ((send_pa_list = malloc((size+1) * sizeof(krb5_pa_data *))) == NULL) + return ENOMEM; + + send_pa = send_pa_list; + *send_pa = 0; + + for (ap = preauth_systems; ap->type != -1; ap++) { + if (ap->return_padata == 0) + continue; + pa = 0; + if (request->padata) { + for (padata = request->padata; *padata; padata++) { + if ((*padata)->pa_type == ap->type) { + pa = *padata; + break; + } + } + } + if ((retval = ap->return_padata(context, pa, client, request, reply, + client_key, encrypting_key, send_pa))) + goto cleanup; + + if (*send_pa) + send_pa++; + *send_pa = 0; + } + + retval = 0; + + if (send_pa_list[0]) { + reply->padata = send_pa_list; + send_pa_list = 0; + } + +cleanup: + if (send_pa_list) + krb5_free_pa_data(context, send_pa_list); + return (retval); +} + static krb5_error_code verify_enc_timestamp(context, client, request, enc_tkt_reply, pa) krb5_context context; @@ -281,7 +328,7 @@ verify_enc_timestamp(context, client, request, enc_tkt_reply, pa) goto cleanup; key.enctype = enc_data->enctype; - retval = krb5_decrypt_data(context, key, 0, enc_data, &enc_ts_data); + retval = krb5_decrypt_data(context, &key, 0, enc_data, &enc_ts_data); memset((char *)key.contents, 0, key.length); krb5_xfree(key.contents); @@ -404,3 +451,77 @@ cleanup: return retval; } +static krb5_error_code +return_pw_salt(context, in_padata, client, request, reply, client_key, + encrypting_key, send_pa) + krb5_context context; + krb5_pa_data * in_padata; + krb5_db_entry * client; + krb5_kdc_req * request; + krb5_kdc_rep * reply; + krb5_key_data * client_key; + krb5_keyblock * encrypting_key; + krb5_pa_data ** send_pa; +{ + krb5_error_code retval; + krb5_pa_data * padata; + krb5_data * scratch; + krb5_data salt_data; + + if (client_key->key_data_ver == 1 || + client_key->key_data_type[1] == KRB5_KDB_SALTTYPE_NORMAL) + return 0; + + if ((padata = malloc(sizeof(krb5_pa_data))) == NULL) + return ENOMEM; + padata->magic = KV5M_PA_DATA; + padata->pa_type = KRB5_PADATA_PW_SALT; + + switch (client_key->key_data_type[1]) { + case KRB5_KDB_SALTTYPE_V4: + /* send an empty (V4) salt */ + padata->contents = 0; + padata->length = 0; + break; + case KRB5_KDB_SALTTYPE_NOREALM: + if ((retval = krb5_principal2salt_norealm(kdc_context, + request->client, + &salt_data))) + goto cleanup; + padata->contents = (krb5_octet *)salt_data.data; + padata->length = salt_data.length; + break; + case KRB5_KDB_SALTTYPE_ONLYREALM: + scratch = krb5_princ_realm(kdc_context, request->client); + if ((padata->contents = malloc(scratch->length)) == NULL) { + retval = ENOMEM; + goto cleanup; + } + memcpy(padata->contents, scratch->data, scratch->length); + padata->length = scratch->length; + break; + case KRB5_KDB_SALTTYPE_SPECIAL: + if ((padata->contents = malloc(client_key->key_data_length[1])) + == NULL) { + retval = ENOMEM; + goto cleanup; + } + memcpy(padata->contents, client_key->key_data_contents[1], + client_key->key_data_length[1]); + padata->length = client_key->key_data_length[1]; + break; + default: + free(padata); + return 0; + } + + *send_pa = padata; + return 0; + +cleanup: + free(padata); + return retval; +} + + + diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 7491ca905..b869f6f8a 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -135,6 +135,14 @@ void get_preauth_hint_list PROTOTYPE((krb5_kdc_req * request, krb5_db_entry *client, krb5_db_entry *server, krb5_data *e_data)); +krb5_error_code check_padata + PROTOTYPE((krb5_context context, krb5_db_entry *client, + krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply)); + +krb5_error_code return_padata + PROTOTYPE((krb5_context context, krb5_db_entry *client, + krb5_kdc_req *request, krb5_kdc_rep *reply, + krb5_key_data *client_key, krb5_keyblock *encrypting_key)); /* replay.c */ krb5_boolean kdc_check_lookaside PROTOTYPE((krb5_data *, krb5_data **)); |
