summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTheodore Tso <tytso@mit.edu>1995-11-14 00:47:37 +0000
committerTheodore Tso <tytso@mit.edu>1995-11-14 00:47:37 +0000
commit37d97c4658b06f2ca7a0c2f7ef765ce8031d2765 (patch)
treea45aae1003d4020386c61ffe4ac9994d832a8aa1 /src
parent394becd543eca283dcd79d4cd26c7afa6ef720d8 (diff)
downloadkrb5-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/ChangeLog17
-rw-r--r--src/kdc/do_as_req.c90
-rw-r--r--src/kdc/kdc_preauth.c209
-rw-r--r--src/kdc/kdc_util.h8
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 **));