krb5_error_code krb5int_fast_process_response(krb5_context context, struct krb5int_fast_request_state *state, krb5_kdc_rep *resp, krb5_keyblock **strengthen_key) { krb5_error_code retval = 0; krb5_fast_response *fast_response = NULL; krb5_data *encoded_ticket = NULL; krb5_boolean cksum_valid; krb5_clear_error_message(context); *strengthen_key = NULL; if (state->armor_key == 0) return 0; retval = decrypt_fast_reply(context, state, resp->padata, &fast_response); if (retval == 0) { if (fast_response->finished == 0) { retval = KRB5_KDCREP_MODIFIED; krb5_set_error_message(context, retval, _("FAST response missing finish message " "in KDC reply")); } } if (retval == 0) retval = encode_krb5_ticket(resp->ticket, &encoded_ticket); if (retval == 0) retval = krb5_c_verify_checksum(context, state->armor_key, KRB5_KEYUSAGE_FAST_FINISHED, encoded_ticket, &fast_response->finished->ticket_checksum, &cksum_valid); if (retval == 0 && cksum_valid == 0) { retval = KRB5_KDCREP_MODIFIED; krb5_set_error_message(context, retval, _("Ticket modified in KDC reply")); } if (retval == 0) { krb5_free_principal(context, resp->client); resp->client = fast_response->finished->client; fast_response->finished->client = NULL; *strengthen_key = fast_response->strengthen_key; fast_response->strengthen_key = NULL; krb5_free_pa_data(context, resp->padata); resp->padata = fast_response->padata; fast_response->padata = NULL; } if (fast_response) krb5_free_fast_response(context, fast_response); if (encoded_ticket) krb5_free_data(context, encoded_ticket); return retval; }
static OM_uint32 create_constrained_deleg_creds(OM_uint32 *minor_status, krb5_gss_cred_id_t verifier_cred_handle, krb5_ticket *ticket, krb5_gss_cred_id_t *out_cred, krb5_context context) { OM_uint32 major_status; krb5_creds krb_creds; krb5_data *data; krb5_error_code code; assert(out_cred != NULL); assert(verifier_cred_handle->usage == GSS_C_BOTH); memset(&krb_creds, 0, sizeof(krb_creds)); krb_creds.client = ticket->enc_part2->client; krb_creds.server = ticket->server; krb_creds.keyblock = *(ticket->enc_part2->session); krb_creds.ticket_flags = ticket->enc_part2->flags; krb_creds.times = ticket->enc_part2->times; krb_creds.magic = KV5M_CREDS; krb_creds.authdata = NULL; code = encode_krb5_ticket(ticket, &data); if (code) { *minor_status = code; return GSS_S_FAILURE; } krb_creds.ticket = *data; major_status = kg_compose_deleg_cred(minor_status, verifier_cred_handle, &krb_creds, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, out_cred, NULL, NULL, context); krb5_free_data(context, data); return major_status; }
krb5_error_code kdc_fast_response_handle_padata(struct kdc_request_state *state, krb5_kdc_req *request, krb5_kdc_rep *rep, krb5_enctype enctype) { krb5_error_code retval = 0; krb5_fast_finished finish; krb5_fast_response fast_response; krb5_data *encoded_ticket = NULL; krb5_data *encrypted_reply = NULL; krb5_pa_data *pa = NULL, **pa_array = NULL; krb5_cksumtype cksumtype = CKSUMTYPE_RSA_MD5; krb5_pa_data *empty_padata[] = {NULL}; krb5_keyblock *strengthen_key = NULL; kdc_realm_t *kdc_active_realm = state->realm_data; if (!state->armor_key) return 0; memset(&finish, 0, sizeof(finish)); retval = krb5_init_keyblock(kdc_context, enctype, 0, &strengthen_key); if (retval == 0) retval = krb5_c_make_random_key(kdc_context, enctype, strengthen_key); if (retval == 0) { state->strengthen_key = strengthen_key; strengthen_key = NULL; } fast_response.padata = rep->padata; if (fast_response.padata == NULL) fast_response.padata = &empty_padata[0]; fast_response.strengthen_key = state->strengthen_key; fast_response.nonce = request->nonce; fast_response.finished = &finish; finish.client = rep->client; pa_array = calloc(3, sizeof(*pa_array)); if (pa_array == NULL) retval = ENOMEM; pa = calloc(1, sizeof(krb5_pa_data)); if (retval == 0 && pa == NULL) retval = ENOMEM; if (retval == 0) retval = krb5_us_timeofday(kdc_context, &finish.timestamp, &finish.usec); if (retval == 0) retval = encode_krb5_ticket(rep->ticket, &encoded_ticket); if (retval == 0) retval = krb5int_c_mandatory_cksumtype(kdc_context, state->armor_key->enctype, &cksumtype); if (retval == 0) retval = krb5_c_make_checksum(kdc_context, cksumtype, state->armor_key, KRB5_KEYUSAGE_FAST_FINISHED, encoded_ticket, &finish.ticket_checksum); if (retval == 0) retval = encrypt_fast_reply(state, &fast_response, &encrypted_reply); if (retval == 0) { pa[0].pa_type = KRB5_PADATA_FX_FAST; pa[0].length = encrypted_reply->length; pa[0].contents = (unsigned char *) encrypted_reply->data; pa_array[0] = &pa[0]; krb5_free_pa_data(kdc_context, rep->padata); rep->padata = pa_array; pa_array = NULL; free(encrypted_reply); encrypted_reply = NULL; pa = NULL; } if (pa) free(pa); if (pa_array) free(pa_array); if (encrypted_reply) krb5_free_data(kdc_context, encrypted_reply); if (encoded_ticket) krb5_free_data(kdc_context, encoded_ticket); if (strengthen_key != NULL) krb5_free_keyblock(kdc_context, strengthen_key); if (finish.ticket_checksum.contents) krb5_free_checksum_contents(kdc_context, &finish.ticket_checksum); return retval; }
static krb5_error_code kdcrep2creds(krb5_context context, krb5_kdc_rep *pkdcrep, krb5_address *const *address, krb5_data *psectkt, krb5_creds **ppcreds) { krb5_error_code retval; krb5_data *pdata; if ((*ppcreds = (krb5_creds *)calloc(1,sizeof(krb5_creds))) == NULL) { return ENOMEM; } if ((retval = krb5_copy_principal(context, pkdcrep->client, &(*ppcreds)->client))) goto cleanup; if ((retval = krb5_copy_principal(context, pkdcrep->enc_part2->server, &(*ppcreds)->server))) goto cleanup; if ((retval = krb5_copy_keyblock_contents(context, pkdcrep->enc_part2->session, &(*ppcreds)->keyblock))) goto cleanup; TRACE_TGS_REPLY(context, (*ppcreds)->client, (*ppcreds)->server, &(*ppcreds)->keyblock); if ((retval = krb5_copy_data(context, psectkt, &pdata))) goto cleanup_keyblock; (*ppcreds)->second_ticket = *pdata; free(pdata); (*ppcreds)->ticket_flags = pkdcrep->enc_part2->flags; (*ppcreds)->times = pkdcrep->enc_part2->times; (*ppcreds)->magic = KV5M_CREDS; (*ppcreds)->authdata = NULL; /* not used */ (*ppcreds)->is_skey = psectkt->length != 0; if (pkdcrep->enc_part2->caddrs) { if ((retval = krb5_copy_addresses(context, pkdcrep->enc_part2->caddrs, &(*ppcreds)->addresses))) goto cleanup_keyblock; } else { /* no addresses in the list means we got what we had */ if ((retval = krb5_copy_addresses(context, address, &(*ppcreds)->addresses))) goto cleanup_keyblock; } if ((retval = encode_krb5_ticket(pkdcrep->ticket, &pdata))) goto cleanup_keyblock; (*ppcreds)->ticket = *pdata; free(pdata); return 0; cleanup_keyblock: krb5_free_keyblock_contents(context, &(*ppcreds)->keyblock); cleanup: free (*ppcreds); *ppcreds = NULL; return retval; }
/* * Populate the credentials structure corresponding to the ticket we are * printing. */ static int populate_creds(krb5_context context, krb5_principal service_principal, krb5_principal client_principal, krb5_keyblock *session_key, void *tr_in, void *er_in, krb5_creds *creds) { krb5_error_code code; #if USING_HEIMDAL Ticket *ticket_reply; EncTicketPart *enc_tkt_reply; size_t dummy; #else krb5_ticket *ticket_reply; krb5_enc_tkt_part *enc_tkt_reply; krb5_data *temp = NULL; #endif /* Requisite aliasing for Heimdal/MIT support. */ ticket_reply = tr_in; enc_tkt_reply = er_in; code = krb5_copy_principal(context, service_principal, &creds->server); if (code != 0) goto cleanup; code = krb5_copy_principal(context, client_principal, &creds->client); if (code != 0) goto cleanup; code = krb5_copy_keyblock_contents(context, session_key, &deref_session_key(creds)); if (code != 0) goto cleanup; #if USING_HEIMDAL creds->times.authtime = enc_tkt_reply->authtime; creds->times.starttime = *(enc_tkt_reply->starttime); creds->times.endtime = enc_tkt_reply->endtime; creds->times.renew_till = 0; /* *(enc_tkt_reply->renew_till) */ creds->flags.b = enc_tkt_reply->flags; #else creds->times = enc_tkt_reply->times; creds->ticket_flags = enc_tkt_reply->flags; #endif #if USING_HEIMDAL ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length, ticket_reply, &dummy, code); if (code != 0 || dummy != creds->ticket.length) goto cleanup; #else code = encode_krb5_ticket(ticket_reply, &temp); if (code != 0) goto cleanup; creds->ticket = *temp; #endif cleanup: #if USING_HEIMDAL /* nothing */ #else free(temp); #endif return code; }
static krb5_error_code krb5_rd_cred_basic(krb5_context context, krb5_data *pcreddata, krb5_key pkey, krb5_replay_data *replaydata, krb5_creds ***pppcreds) { krb5_error_code retval = 0; krb5_cred * pcred = NULL; krb5_int32 ncreds = 0; krb5_int32 i = 0; krb5_cred_enc_part encpart; /* decode cred message */ if ((retval = decode_krb5_cred(pcreddata, &pcred))) return retval; memset(&encpart, 0, sizeof(encpart)); if ((retval = decrypt_credencdata(context, pcred, pkey, &encpart))) goto cleanup_cred; replaydata->timestamp = encpart.timestamp; replaydata->usec = encpart.usec; replaydata->seq = encpart.nonce; /* * Allocate the list of creds. The memory is allocated so that * krb5_free_tgt_creds can be used to free the list. */ for (ncreds = 0; pcred->tickets[ncreds]; ncreds++); if ((*pppcreds = (krb5_creds **)malloc((size_t)(sizeof(krb5_creds *) * (ncreds + 1)))) == NULL) { retval = ENOMEM; goto cleanup_cred; } (*pppcreds)[0] = NULL; /* * For each credential, create a strcture in the list of * credentials and copy the information. */ while (i < ncreds) { krb5_cred_info * pinfo; krb5_creds * pcur; krb5_data * pdata; if ((pcur = (krb5_creds *)calloc(1, sizeof(krb5_creds))) == NULL) { retval = ENOMEM; goto cleanup; } (*pppcreds)[i] = pcur; (*pppcreds)[i+1] = 0; pinfo = encpart.ticket_info[i++]; if ((retval = krb5_copy_principal(context, pinfo->client, &pcur->client))) goto cleanup; if ((retval = krb5_copy_principal(context, pinfo->server, &pcur->server))) goto cleanup; if ((retval = krb5_copy_keyblock_contents(context, pinfo->session, &pcur->keyblock))) goto cleanup; if ((retval = krb5_copy_addresses(context, pinfo->caddrs, &pcur->addresses))) goto cleanup; if ((retval = encode_krb5_ticket(pcred->tickets[i - 1], &pdata))) goto cleanup; pcur->ticket = *pdata; free(pdata); pcur->is_skey = FALSE; pcur->magic = KV5M_CREDS; pcur->times = pinfo->times; pcur->ticket_flags = pinfo->flags; pcur->authdata = NULL; /* not used */ memset(&pcur->second_ticket, 0, sizeof(pcur->second_ticket)); } /* * NULL terminate the list */ (*pppcreds)[i] = NULL; cleanup: if (retval) { krb5_free_tgt_creds(context, *pppcreds); *pppcreds = NULL; } cleanup_cred: krb5_free_cred(context, pcred); krb5_free_cred_enc_part(context, &encpart); return retval; }
/* Produce a list of credentials from a KRB-CRED message and its enc_part. */ static krb5_error_code make_cred_list(krb5_context context, krb5_cred *krbcred, krb5_cred_enc_part *encpart, krb5_creds ***creds_out) { krb5_error_code ret = 0; krb5_creds **list = NULL; krb5_cred_info *info; krb5_data *ticket_data; size_t i, count; *creds_out = NULL; /* Allocate the list of creds. */ for (count = 0; krbcred->tickets[count] != NULL; count++); list = k5calloc(count + 1, sizeof(*list), &ret); if (list == NULL) goto cleanup; /* For each credential, create a strcture in the list of credentials and * copy the information. */ for (i = 0; i < count; i++) { list[i] = k5alloc(sizeof(*list[i]), &ret); if (list[i] == NULL) goto cleanup; info = encpart->ticket_info[i]; ret = krb5_copy_principal(context, info->client, &list[i]->client); if (ret) goto cleanup; ret = krb5_copy_principal(context, info->server, &list[i]->server); if (ret) goto cleanup; ret = krb5_copy_keyblock_contents(context, info->session, &list[i]->keyblock); if (ret) goto cleanup; ret = krb5_copy_addresses(context, info->caddrs, &list[i]->addresses); if (ret) goto cleanup; ret = encode_krb5_ticket(krbcred->tickets[i], &ticket_data); if (ret) goto cleanup; list[i]->ticket = *ticket_data; free(ticket_data); list[i]->is_skey = FALSE; list[i]->magic = KV5M_CREDS; list[i]->times = info->times; list[i]->ticket_flags = info->flags; list[i]->authdata = NULL; list[i]->second_ticket = empty_data(); } *creds_out = list; list = NULL; cleanup: krb5_free_tgt_creds(context, list); return ret; }