From 154551ad22e90d2e5f60103059fbaaadac017420 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Mon, 3 Jun 2019 17:32:20 -0400 Subject: [PATCH] Use new pa-data helpers where appropriate --- src/kdc/fast_util.c | 5 +- src/kdc/kdc_preauth.c | 112 +++++++++++++--------------------- src/kdc/kdc_util.c | 91 ++++----------------------- src/kdc/kdc_util.h | 6 -- src/lib/krb5/krb/get_in_tkt.c | 57 +++++------------ 5 files changed, 72 insertions(+), 199 deletions(-) diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c index c9ba83e5e3..a55fc1ba94 100644 --- a/src/kdc/fast_util.c +++ b/src/kdc/fast_util.c @@ -456,7 +456,7 @@ static krb5_error_code make_padata(krb5_preauthtype pa_type, const void *contents, size_t len, krb5_pa_data **out) { - if (alloc_pa_data(pa_type, len, out) != 0) + if (k5_alloc_pa_data(pa_type, len, out) != 0) return ENOMEM; memcpy((*out)->contents, contents, len); return 0; @@ -696,7 +696,8 @@ kdc_fast_make_cookie(krb5_context context, struct kdc_request_state *state, goto cleanup; /* Construct the cookie pa-data entry. */ - ret = alloc_pa_data(KRB5_PADATA_FX_COOKIE, 8 + enc.ciphertext.length, &pa); + ret = k5_alloc_pa_data(KRB5_PADATA_FX_COOKIE, 8 + enc.ciphertext.length, + &pa); memcpy(pa->contents, "MIT1", 4); store_32_be(kvno, pa->contents + 4); memcpy(pa->contents + 8, enc.ciphertext.data, enc.ciphertext.length); diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 508a5cf897..8f89c06f2f 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -108,9 +108,9 @@ static preauth_system *preauth_systems; static size_t n_preauth_systems; static krb5_error_code -make_etype_info(krb5_context context, krb5_preauthtype pa_type, +make_etype_info(krb5_context context, krb5_boolean etype_info2, krb5_principal client, krb5_key_data *client_key, - krb5_enctype enctype, krb5_pa_data **pa_out); + krb5_enctype enctype, krb5_data **der_out); /* Get all available kdcpreauth vtables and a count of preauth types they * support. Return an empty list on failure. */ @@ -753,32 +753,32 @@ add_etype_info(krb5_context context, krb5_kdcpreauth_rock rock, krb5_pa_data ***pa_list) { krb5_error_code ret; - krb5_pa_data *pa; + krb5_data *der; if (rock->client_key == NULL) return 0; if (!requires_info2(rock->request)) { /* Include PA-ETYPE-INFO only for old clients. */ - ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO, - rock->client->princ, rock->client_key, - rock->client_keyblock->enctype, &pa); + ret = make_etype_info(context, FALSE, rock->client->princ, + rock->client_key, rock->client_keyblock->enctype, + &der); if (ret) return ret; - /* add_pa_data_element() claims pa on success or failure. */ - ret = add_pa_data_element(pa_list, pa); + ret = k5_add_pa_data_from_data(pa_list, KRB5_PADATA_ETYPE_INFO, der); + krb5_free_data(context, der); if (ret) return ret; } /* Always include PA-ETYPE-INFO2. */ - ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO2, - rock->client->princ, rock->client_key, - rock->client_keyblock->enctype, &pa); + ret = make_etype_info(context, TRUE, rock->client->princ, rock->client_key, + rock->client_keyblock->enctype, &der); if (ret) return ret; - /* add_pa_data_element() claims pa on success or failure. */ - return add_pa_data_element(pa_list, pa); + ret = k5_add_pa_data_from_data(pa_list, KRB5_PADATA_ETYPE_INFO2, der); + krb5_free_data(context, der); + return ret; } /* Add PW-SALT entries to pa_list as appropriate for the request and client @@ -788,7 +788,6 @@ add_pw_salt(krb5_context context, krb5_kdcpreauth_rock rock, krb5_pa_data ***pa_list) { krb5_error_code ret; - krb5_pa_data *pa; krb5_data *salt = NULL; krb5_int16 salttype; @@ -801,18 +800,7 @@ add_pw_salt(krb5_context context, krb5_kdcpreauth_rock rock, if (ret) return 0; - /* Steal memory from salt to make the pa-data entry. */ - ret = alloc_pa_data(KRB5_PADATA_PW_SALT, 0, &pa); - if (ret) - goto cleanup; - pa->length = salt->length; - pa->contents = (uint8_t *)salt->data; - salt->data = NULL; - - /* add_pa_data_element() claims pa on success or failure. */ - ret = add_pa_data_element(pa_list, pa); - -cleanup: + ret = k5_add_pa_data_from_data(pa_list, KRB5_PADATA_PW_SALT, salt); krb5_free_data(context, salt); return ret; } @@ -827,7 +815,7 @@ add_freshness_token(krb5_context context, krb5_kdcpreauth_rock rock, krb5_keyblock kb; krb5_checksum cksum; krb5_data d; - krb5_pa_data *pa; + krb5_pa_data *pa = NULL; char ckbuf[4]; memset(&cksum, 0, sizeof(cksum)); @@ -857,19 +845,19 @@ add_freshness_token(krb5_context context, krb5_kdcpreauth_rock rock, &d, &cksum); /* Compose a freshness token from the time, krbtgt kvno, and checksum. */ - ret = alloc_pa_data(KRB5_PADATA_AS_FRESHNESS, 8 + cksum.length, &pa); + ret = k5_alloc_pa_data(KRB5_PADATA_AS_FRESHNESS, 8 + cksum.length, &pa); if (ret) goto cleanup; store_32_be(now, pa->contents); store_32_be(kd->key_data_kvno, pa->contents + 4); memcpy(pa->contents + 8, cksum.contents, cksum.length); - /* add_pa_data_element() claims pa on success or failure. */ - ret = add_pa_data_element(pa_list, pa); + ret = k5_add_pa_data_element(pa_list, &pa); cleanup: krb5_free_keyblock_contents(context, &kb); krb5_free_checksum_contents(context, &cksum); + k5_free_pa_data_element(pa); return ret; } @@ -927,12 +915,12 @@ finish_get_edata(void *arg, krb5_error_code code, krb5_pa_data *pa) if (code == 0) { if (pa == NULL) { - ret = alloc_pa_data(state->pa_type, 0, &pa); + ret = k5_alloc_pa_data(state->pa_type, 0, &pa); if (ret) goto error; } - /* add_pa_data_element() claims pa on success or failure. */ - ret = add_pa_data_element(&state->pa_data, pa); + ret = k5_add_pa_data_element(&state->pa_data, &pa); + k5_free_pa_data_element(pa); if (ret) goto error; } @@ -981,7 +969,6 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock, { kdc_realm_t *kdc_active_realm = rock->rstate->realm_data; struct hint_state *state; - krb5_pa_data *pa; *e_data_out = NULL; @@ -1001,10 +988,7 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock, state->ap = preauth_systems; /* Add an empty PA-FX-FAST element to advertise FAST support. */ - if (alloc_pa_data(KRB5_PADATA_FX_FAST, 0, &pa) != 0) - goto error; - /* add_pa_data_element() claims pa on success or failure. */ - if (add_pa_data_element(&state->pa_data, pa) != 0) + if (k5_add_empty_pa_data(&state->pa_data, KRB5_PADATA_FX_FAST) != 0) goto error; if (add_etype_info(kdc_context, rock, &state->pa_data) != 0) @@ -1151,7 +1135,7 @@ maybe_add_etype_info2(struct padata_state *state, krb5_error_code code) krb5_error_code ret; krb5_context context = state->context; krb5_kdcpreauth_rock rock = state->rock; - krb5_pa_data *pa; + krb5_data *der; /* Only add key information when requesting another preauth round trip. */ if (code != KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED) @@ -1167,14 +1151,14 @@ maybe_add_etype_info2(struct padata_state *state, krb5_error_code code) KRB5_PADATA_FX_COOKIE) != NULL) return 0; - ret = make_etype_info(context, KRB5_PADATA_ETYPE_INFO2, - rock->client->princ, rock->client_key, - rock->client_keyblock->enctype, &pa); + ret = make_etype_info(context, TRUE, rock->client->princ, rock->client_key, + rock->client_keyblock->enctype, &der); if (ret) return ret; - - /* add_pa_data_element() claims pa on success or failure. */ - return add_pa_data_element(&state->pa_e_data, pa); + ret = k5_add_pa_data_from_data(&state->pa_e_data, KRB5_PADATA_ETYPE_INFO2, + der); + krb5_free_data(context, der); + return ret; } /* Release state and respond to the AS-REQ processing code with the result of @@ -1468,8 +1452,8 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock, goto cleanup; if (send_pa != NULL) { - /* add_pa_data_element() claims send_pa on success or failure. */ - retval = add_pa_data_element(&send_pa_list, send_pa); + retval = k5_add_pa_data_element(&send_pa_list, &send_pa); + k5_free_pa_data_element(send_pa); if (retval) goto cleanup; } @@ -1552,19 +1536,17 @@ cleanup: return retval; } -/* Create etype-info or etype-info2 padata for client_key with the given +/* Encode an etype-info or etype-info2 message for client_key with the given * enctype, using client to compute the salt if necessary. */ static krb5_error_code -make_etype_info(krb5_context context, krb5_preauthtype pa_type, +make_etype_info(krb5_context context, krb5_boolean etype_info2, krb5_principal client, krb5_key_data *client_key, - krb5_enctype enctype, krb5_pa_data **pa_out) + krb5_enctype enctype, krb5_data **der_out) { krb5_error_code retval; krb5_etype_info_entry **entry = NULL; - krb5_data *der_etype_info = NULL; - int etype_info2 = (pa_type == KRB5_PADATA_ETYPE_INFO2); - *pa_out = NULL; + *der_out = NULL; entry = k5calloc(2, sizeof(*entry), &retval); if (entry == NULL) @@ -1575,23 +1557,12 @@ make_etype_info(krb5_context context, krb5_preauthtype pa_type, goto cleanup; if (etype_info2) - retval = encode_krb5_etype_info2(entry, &der_etype_info); + retval = encode_krb5_etype_info2(entry, der_out); else - retval = encode_krb5_etype_info(entry, &der_etype_info); - if (retval) - goto cleanup; - - /* Steal the data from der_etype_info to create a pa-data element. */ - retval = alloc_pa_data(pa_type, 0, pa_out); - if (retval) - goto cleanup; - (*pa_out)->contents = (uint8_t *)der_etype_info->data; - (*pa_out)->length = der_etype_info->length; - der_etype_info->data = NULL; + retval = encode_krb5_etype_info(entry, der_out); cleanup: krb5_free_etype_info(context, entry); - krb5_free_data(context, der_etype_info); return retval; } @@ -1643,13 +1614,14 @@ return_referral_enc_padata( krb5_context context, if (code || tl_data.tl_data_length == 0) return 0; - code = alloc_pa_data(KRB5_PADATA_SVR_REFERRAL_INFO, tl_data.tl_data_length, - &pa); + code = k5_alloc_pa_data(KRB5_PADATA_SVR_REFERRAL_INFO, + tl_data.tl_data_length, &pa); if (code) return code; memcpy(pa->contents, tl_data.tl_data_contents, tl_data.tl_data_length); - /* add_pa_data_element() claims pa on success or failure. */ - return add_pa_data_element(&reply->enc_padata, pa); + code = k5_add_pa_data_element(&reply->enc_padata, &pa); + k5_free_pa_data_element(pa); + return code; } krb5_error_code diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 02d934297c..2b949cf1be 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -1375,7 +1375,7 @@ kdc_make_s4u2self_rep(krb5_context context, krb5_error_code code; krb5_data *der_user_id = NULL, *der_s4u_x509_user = NULL; krb5_pa_s4u_x509_user rep_s4u_user; - krb5_pa_data *pa; + krb5_pa_data *pa = NULL; krb5_enctype enctype; krb5_keyusage usage; @@ -1405,15 +1405,8 @@ kdc_make_s4u2self_rep(krb5_context context, if (code != 0) goto cleanup; - /* Add a padata element, stealing memory from der_s4u_x509_user. */ - code = alloc_pa_data(KRB5_PADATA_S4U_X509_USER, 0, &pa); - if (code != 0) - goto cleanup; - pa->length = der_s4u_x509_user->length; - pa->contents = (uint8_t *)der_s4u_x509_user->data; - der_s4u_x509_user->data = NULL; - /* add_pa_data_element() claims pa on success or failure. */ - code = add_pa_data_element(&reply->padata, pa); + code = k5_add_pa_data_from_data(&reply->padata, KRB5_PADATA_S4U_X509_USER, + der_s4u_x509_user); if (code != 0) goto cleanup; @@ -1429,9 +1422,9 @@ kdc_make_s4u2self_rep(krb5_context context, */ if ((req_s4u_user->user_id.options & KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE) && enctype_requires_etype_info_2(enctype) == FALSE) { - code = alloc_pa_data(KRB5_PADATA_S4U_X509_USER, - req_s4u_user->cksum.length + - rep_s4u_user.cksum.length, &pa); + code = k5_alloc_pa_data(KRB5_PADATA_S4U_X509_USER, + req_s4u_user->cksum.length + + rep_s4u_user.cksum.length, &pa); if (code != 0) goto cleanup; memcpy(pa->contents, @@ -1439,8 +1432,7 @@ kdc_make_s4u2self_rep(krb5_context context, memcpy(&pa->contents[req_s4u_user->cksum.length], rep_s4u_user.cksum.contents, rep_s4u_user.cksum.length); - /* add_pa_data_element() claims pa on success or failure. */ - code = add_pa_data_element(&reply_encpart->enc_padata, pa); + code = k5_add_pa_data_element(&reply_encpart->enc_padata, &pa); if (code != 0) goto cleanup; } @@ -1450,7 +1442,7 @@ cleanup: krb5_free_checksum_contents(context, &rep_s4u_user.cksum); krb5_free_data(context, der_user_id); krb5_free_data(context, der_s4u_x509_user); - + k5_free_pa_data_element(pa); return code; } @@ -1778,53 +1770,6 @@ enctype_requires_etype_info_2(krb5_enctype enctype) } } -/* Allocate a pa-data entry with an uninitialized buffer of size len. */ -krb5_error_code -alloc_pa_data(krb5_preauthtype pa_type, size_t len, krb5_pa_data **out) -{ - krb5_pa_data *pa; - uint8_t *buf = NULL; - - *out = NULL; - if (len > 0) { - buf = malloc(len); - if (buf == NULL) - return ENOMEM; - } - pa = malloc(sizeof(*pa)); - if (pa == NULL) { - free(buf); - return ENOMEM; - } - pa->magic = KV5M_PA_DATA; - pa->pa_type = pa_type; - pa->length = len; - pa->contents = buf; - *out = pa; - return 0; -} - -/* Add pa to list, claiming its memory. Free pa on failure. */ -krb5_error_code -add_pa_data_element(krb5_pa_data ***list, krb5_pa_data *pa) -{ - size_t count; - krb5_pa_data **newlist; - - for (count = 0; *list != NULL && (*list)[count] != NULL; count++); - - newlist = realloc(*list, (count + 2) * sizeof(*newlist)); - if (newlist == NULL) { - free(pa->contents); - free(pa); - return ENOMEM; - } - newlist[count] = pa; - newlist[count + 1] = NULL; - *list = newlist; - return 0; -} - void kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, krb5_timestamp starttime, @@ -1926,7 +1871,7 @@ kdc_handle_protected_negotiation(krb5_context context, krb5_error_code retval = 0; krb5_checksum checksum; krb5_data *der_cksum = NULL; - krb5_pa_data *pa, *pa_in; + krb5_pa_data *pa_in; memset(&checksum, 0, sizeof(checksum)); @@ -1944,24 +1889,14 @@ kdc_handle_protected_negotiation(krb5_context context, if (retval != 0) goto cleanup; - /* Add a pa-data element to the list, stealing memory from der_cksum. */ - retval = alloc_pa_data(KRB5_ENCPADATA_REQ_ENC_PA_REP, 0, &pa); - if (retval) - goto cleanup; - pa->length = der_cksum->length; - pa->contents = (uint8_t *)der_cksum->data; - der_cksum->data = NULL; - /* add_pa_data_element() claims pa on success or failure. */ - retval = add_pa_data_element(out_enc_padata, pa); + retval = k5_add_pa_data_from_data(out_enc_padata, + KRB5_ENCPADATA_REQ_ENC_PA_REP, + der_cksum); if (retval) goto cleanup; /* Add a zero-length PA-FX-FAST element to the list. */ - retval = alloc_pa_data(KRB5_PADATA_FX_FAST, 0, &pa); - if (retval) - goto cleanup; - /* add_pa_data_element() claims pa on success or failure. */ - retval = add_pa_data_element(out_enc_padata, pa); + retval = k5_add_empty_pa_data(out_enc_padata, KRB5_PADATA_FX_FAST); cleanup: krb5_free_checksum_contents(context, &checksum); diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 1314bdd587..fea35d70a9 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -198,12 +198,6 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock, void free_padata_context(krb5_context context, void *padata_context); -krb5_error_code -alloc_pa_data(krb5_preauthtype pa_type, size_t len, krb5_pa_data **out); - -krb5_error_code -add_pa_data_element(krb5_pa_data ***list, krb5_pa_data *pa); - /* kdc_preauth_ec.c */ krb5_error_code kdcpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver, diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index 1e53d7ac08..dcf6663cfa 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -402,40 +402,6 @@ make_preauth_list(krb5_context context, #define MAX_IN_TKT_LOOPS 16 -/* Add a pa-data item with the specified type and contents to *padptr. */ -static krb5_error_code -add_padata(krb5_pa_data ***padptr, krb5_preauthtype pa_type, - const void *contents, unsigned int length) -{ - size_t size = 0; - krb5_pa_data **pad = *padptr; - krb5_pa_data *pa= NULL; - if (pad) - for (size=0; pad[size]; size++); - pad = realloc(pad, sizeof(*pad)*(size+2)); - if (pad == NULL) - return ENOMEM; - *padptr = pad; - pad[size] = pad[size + 1] = NULL; - - pa = malloc(sizeof(krb5_pa_data)); - if (pa == NULL) - return ENOMEM; - pa->contents = NULL; - pa->length = length; - if (contents != NULL) { - pa->contents = malloc(length); - if (pa->contents == NULL) { - free(pa); - return ENOMEM; - } - memcpy(pa->contents, contents, length); - } - pa->pa_type = pa_type; - pad[size] = pa; - return 0; -} - /* Sort a pa_data sequence so that types named in the "preferred_preauth_types" * libdefaults entry are listed before any others. */ static krb5_error_code @@ -1300,8 +1266,8 @@ maybe_add_pac_request(krb5_context context, krb5_init_creds_context ctx) code = encode_krb5_pa_pac_req(&pac_req, &encoded); if (code) return code; - code = add_padata(&ctx->request->padata, KRB5_PADATA_PAC_REQUEST, - encoded->data, encoded->length); + code = k5_add_pa_data_from_data(&ctx->request->padata, + KRB5_PADATA_PAC_REQUEST, encoded); krb5_free_data(context, encoded); return code; } @@ -1313,6 +1279,7 @@ init_creds_step_request(krb5_context context, { krb5_error_code code; krb5_preauthtype pa_type; + krb5_data copy; struct errinfo save = EMPTY_ERRINFO; uint32_t rcode = (ctx->err_reply == NULL) ? 0 : ctx->err_reply->error; @@ -1414,21 +1381,25 @@ init_creds_step_request(krb5_context context, ctx->encoded_previous_request = NULL; } if (ctx->info_pa_permitted) { - code = add_padata(&ctx->request->padata, KRB5_PADATA_AS_FRESHNESS, - NULL, 0); + code = k5_add_empty_pa_data(&ctx->request->padata, + KRB5_PADATA_AS_FRESHNESS); if (code) goto cleanup; - code = add_padata(&ctx->request->padata, KRB5_ENCPADATA_REQ_ENC_PA_REP, - NULL, 0); + code = k5_add_empty_pa_data(&ctx->request->padata, + KRB5_ENCPADATA_REQ_ENC_PA_REP); } if (code) goto cleanup; if (ctx->subject_cert != NULL) { - code = add_padata(&ctx->request->padata, KRB5_PADATA_S4U_X509_USER, - ctx->subject_cert->data, ctx->subject_cert->length); + code = krb5int_copy_data_contents(context, ctx->subject_cert, ©); if (code) - return code; + goto cleanup; + code = k5_add_pa_data_from_data(&ctx->request->padata, + KRB5_PADATA_S4U_X509_USER, ©); + krb5_free_data_contents(context, ©); + if (code) + goto cleanup; } code = maybe_add_pac_request(context, ctx); -- 2.47.2