예제 #1
0
static krb5_error_code
return_pkinit_kx(krb5_context context, krb5_kdc_req *request,
                 krb5_kdc_rep *reply, krb5_keyblock *encrypting_key,
                 krb5_pa_data **out_padata)
{
    krb5_error_code ret = 0;
    krb5_keyblock *session = reply->ticket->enc_part2->session;
    krb5_keyblock *new_session = NULL;
    krb5_pa_data *pa = NULL;
    krb5_enc_data enc;
    krb5_data *scratch = NULL;

    *out_padata = NULL;
    enc.ciphertext.data = NULL;
    if (!krb5_principal_compare(context, request->client,
                                krb5_anonymous_principal()))
        return 0;
    /*
     * The KDC contribution key needs to be a fresh key of an enctype supported
     * by the client and server. The existing session key meets these
     * requirements so we use it.
     */
    ret = krb5_c_fx_cf2_simple(context, session, "PKINIT",
                               encrypting_key, "KEYEXCHANGE",
                               &new_session);
    if (ret)
        goto cleanup;
    ret = encode_krb5_encryption_key( session, &scratch);
    if (ret)
        goto cleanup;
    ret = krb5_encrypt_helper(context, encrypting_key,
                              KRB5_KEYUSAGE_PA_PKINIT_KX, scratch, &enc);
    if (ret)
        goto cleanup;
    memset(scratch->data, 0, scratch->length);
    krb5_free_data(context, scratch);
    scratch = NULL;
    ret = encode_krb5_enc_data(&enc, &scratch);
    if (ret)
        goto cleanup;
    pa = malloc(sizeof(krb5_pa_data));
    if (pa == NULL) {
        ret = ENOMEM;
        goto cleanup;
    }
    pa->pa_type = KRB5_PADATA_PKINIT_KX;
    pa->length = scratch->length;
    pa->contents = (krb5_octet *) scratch->data;
    *out_padata = pa;
    scratch->data = NULL;
    memset(session->contents, 0, session->length);
    krb5_free_keyblock_contents(context, session);
    *session = *new_session;
    new_session->contents = NULL;
cleanup:
    krb5_free_data_contents(context, &enc.ciphertext);
    krb5_free_keyblock(context, new_session);
    krb5_free_data(context, scratch);
    return ret;
}
예제 #2
0
static krb5_error_code
prepare_error_as (struct kdc_request_state *rstate, krb5_kdc_req *request,
                  int error, krb5_pa_data **e_data, krb5_boolean typed_e_data,
                  krb5_principal canon_client, krb5_data **response,
                  const char *status)
{
    krb5_error errpkt;
    krb5_error_code retval;
    krb5_data *scratch = NULL, *e_data_asn1 = NULL, *fast_edata = NULL;
    kdc_realm_t *kdc_active_realm = rstate->realm_data;

    errpkt.ctime = request->nonce;
    errpkt.cusec = 0;

    retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec);
    if (retval)
        return retval;
    errpkt.error = error;
    errpkt.server = request->server;
    errpkt.client = (error == KRB5KDC_ERR_WRONG_REALM) ? canon_client :
        request->client;
    errpkt.text = string2data((char *)status);

    if (e_data != NULL) {
        if (typed_e_data)
            retval = encode_krb5_typed_data(e_data, &e_data_asn1);
        else
            retval = encode_krb5_padata_sequence(e_data, &e_data_asn1);
        if (retval)
            goto cleanup;
        errpkt.e_data = *e_data_asn1;
    } else
        errpkt.e_data = empty_data();

    retval = kdc_fast_handle_error(kdc_context, rstate, request, e_data,
                                   &errpkt, &fast_edata);
    if (retval)
        goto cleanup;
    if (fast_edata != NULL)
        errpkt.e_data = *fast_edata;

    scratch = k5alloc(sizeof(*scratch), &retval);
    if (scratch == NULL)
        goto cleanup;
    if (kdc_fast_hide_client(rstate) && errpkt.client != NULL)
        errpkt.client = (krb5_principal)krb5_anonymous_principal();
    retval = krb5_mk_error(kdc_context, &errpkt, scratch);
    if (retval)
        goto cleanup;

    *response = scratch;
    scratch = NULL;

cleanup:
    krb5_free_data(kdc_context, fast_edata);
    krb5_free_data(kdc_context, e_data_asn1);
    free(scratch);
    return retval;
}
예제 #3
0
static krb5_error_code
kdc_return_preauth(krb5_context context, krb5_pa_data *padata,
                   struct _krb5_db_entry_new *client, krb5_data *req_pkt,
                   krb5_kdc_req *request, krb5_kdc_rep *reply,
                   struct _krb5_key_data *client_keys,
                   krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
                   preauth_get_entry_data_proc get_entry_proc,
                   void *pa_module_context, void **pa_request_context)
{
    krb5_error_code retval = 0;
    krb5_keyblock *challenge_key = *pa_request_context;
    krb5_pa_enc_ts ts;
    krb5_data *plain = NULL;
    krb5_enc_data enc;
    krb5_data *encoded = NULL;
    krb5_pa_data *pa = NULL;
    krb5int_access kaccess;

    if (krb5int_accessor(&kaccess, KRB5INT_ACCESS_VERSION) != 0)
        return 0;
    if (challenge_key == NULL)
        return 0;
    * pa_request_context = NULL; /*this function will free the
                                  * challenge key*/
    enc.ciphertext.data = NULL; /* In case of error pass through */

    retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec);
    if (retval == 0)
        retval = kaccess.encode_enc_ts(&ts, &plain);
    if (retval == 0)
        retval = kaccess.encrypt_helper(context, challenge_key,
                                        KRB5_KEYUSAGE_ENC_CHALLENGE_KDC,
                                        plain, &enc);
    if (retval == 0)
        retval = kaccess.encode_enc_data(&enc, &encoded);
    if (retval == 0) {
        pa = calloc(1, sizeof(krb5_pa_data));
        if (pa == NULL)
            retval = ENOMEM;
    }
    if (retval == 0) {
        pa->pa_type = KRB5_PADATA_ENCRYPTED_CHALLENGE;
        pa->contents = (unsigned char *) encoded->data;
        pa->length = encoded->length;
        encoded->data = NULL;
        *send_pa = pa;
        pa = NULL;
    }
    if (challenge_key)
        krb5_free_keyblock(context, challenge_key);
    if (encoded)
        krb5_free_data(context, encoded);
    if (plain)
        krb5_free_data(context, plain);
    if (enc.ciphertext.data)
        krb5_free_data_contents(context, &enc.ciphertext);
    return retval;
}
예제 #4
0
/* Obtain and return any preauthentication data (which is destined for the
 * client) which matches type data->pa_type. */
static krb5_error_code
server_get_edata(krb5_context kcontext,
		 krb5_kdc_req *request,
		 struct _krb5_db_entry_new *client,
		 struct _krb5_db_entry_new *server,
		 preauth_get_entry_data_proc server_get_entry_data,
		 void *pa_module_context,
		 krb5_pa_data *data)
{
    krb5_data *key_data;
    krb5_keyblock *keys, *key;
    krb5_int32 *enctypes, enctype;
    int i;

    /* Retrieve the client's keys. */
    key_data = NULL;
    if ((*server_get_entry_data)(kcontext, request, client,
				 krb5plugin_preauth_keys, &key_data) != 0) {
#ifdef DEBUG
	fprintf(stderr, "Error retrieving client keys.\n");
#endif
	return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
    }

    /* Count which types of keys we've got, freeing the contents, which we
     * don't need at this point. */
    keys = (krb5_keyblock *) key_data->data;
    key = NULL;
    for (i = 0; keys[i].enctype != 0; i++)
	krb5_free_keyblock_contents(kcontext, &keys[i]);

    /* Return the list of encryption types. */
    enctypes = malloc((unsigned)i * 4);
    if (enctypes == NULL) {
	krb5_free_data(kcontext, key_data);
	return ENOMEM;
    }
#ifdef DEBUG
    fprintf(stderr, "Supported enctypes = {");
#endif
    for (i = 0; keys[i].enctype != 0; i++) {
#ifdef DEBUG
	fprintf(stderr, "%s%d", (i > 0) ? ", " : "", keys[i].enctype);
#endif
	enctype = htonl(keys[i].enctype);
	memcpy(&enctypes[i], &enctype, 4);
    }
#ifdef DEBUG
    fprintf(stderr, "}.\n");
#endif
    data->pa_type = KRB5_PADATA_CKSUM_BODY_REQ;
    data->length = (i * 4);
    data->contents = (unsigned char *) enctypes;
    krb5_free_data(kcontext, key_data);
    return 0;
}
예제 #5
0
/*
 * This routine is the "obtain" function for the ENC_TIMESTAMP
 * preauthentication type.  It take the current time and encrypts it
 * in the user's key.
 */
static krb5_error_code
obtain_enc_ts_padata(krb5_context context, krb5_pa_data *in_padata, krb5_etype_info etype_info, krb5_keyblock *def_enc_key, git_key_proc key_proc, krb5_const_pointer key_seed, krb5_creds *creds, krb5_kdc_req *request, krb5_pa_data **out_padata)
{
    krb5_pa_enc_ts		pa_enc;
    krb5_error_code		retval;
    krb5_data *			scratch;
    krb5_enc_data 		enc_data;
    krb5_pa_data *		pa;

    retval = krb5_us_timeofday(context, &pa_enc.patimestamp, &pa_enc.pausec);
    if (retval)
	return retval;

    if ((retval = encode_krb5_pa_enc_ts(&pa_enc, &scratch)) != 0)
	return retval;

    enc_data.ciphertext.data = 0;

    if ((retval = krb5_encrypt_helper(context, def_enc_key,
				      KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS,
				      scratch, &enc_data)))
	goto cleanup;

    krb5_free_data(context, scratch);
    scratch = 0;
    
    if ((retval = encode_krb5_enc_data(&enc_data, &scratch)) != 0)
	goto cleanup;

    if ((pa = malloc(sizeof(krb5_pa_data))) == NULL) {
	retval = ENOMEM;
	goto cleanup;
    }

    pa->magic = KV5M_PA_DATA;
    pa->pa_type = KRB5_PADATA_ENC_TIMESTAMP;
    pa->length = scratch->length;
    pa->contents = (krb5_octet *) scratch->data;

    *out_padata = pa;

    free(scratch);
    scratch = 0;

    retval = 0;
    
cleanup:
    if (scratch)
	krb5_free_data(context, scratch);
    if (enc_data.ciphertext.data)
	free(enc_data.ciphertext.data);
    return retval;
}
예제 #6
0
static krb5_error_code
ec_return(krb5_context context, krb5_pa_data *padata, krb5_data *req_pkt,
          krb5_kdc_req *request, krb5_kdc_rep *reply,
          krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
          krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
          krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq)
{
    krb5_error_code retval = 0;
    krb5_keyblock *challenge_key = (krb5_keyblock *)modreq;
    krb5_pa_enc_ts ts;
    krb5_data *plain = NULL;
    krb5_enc_data enc;
    krb5_data *encoded = NULL;
    krb5_pa_data *pa = NULL;

    if (challenge_key == NULL)
        return 0;
    enc.ciphertext.data = NULL; /* In case of error pass through */

    retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec);
    if (retval == 0)
        retval = encode_krb5_pa_enc_ts(&ts, &plain);
    if (retval == 0)
        retval = krb5_encrypt_helper(context, challenge_key,
                                     KRB5_KEYUSAGE_ENC_CHALLENGE_KDC,
                                     plain, &enc);
    if (retval == 0)
        retval = encode_krb5_enc_data(&enc, &encoded);
    if (retval == 0) {
        pa = calloc(1, sizeof(krb5_pa_data));
        if (pa == NULL)
            retval = ENOMEM;
    }
    if (retval == 0) {
        pa->pa_type = KRB5_PADATA_ENCRYPTED_CHALLENGE;
        pa->contents = (unsigned char *) encoded->data;
        pa->length = encoded->length;
        encoded->data = NULL;
        *send_pa = pa;
        pa = NULL;
    }
    if (challenge_key)
        krb5_free_keyblock(context, challenge_key);
    if (encoded)
        krb5_free_data(context, encoded);
    if (plain)
        krb5_free_data(context, plain);
    if (enc.ciphertext.data)
        krb5_free_data_contents(context, &enc.ciphertext);
    return retval;
}
예제 #7
0
static krb5_error_code
make_ad_signedpath_checksum(krb5_context context,
                            krb5_const_principal for_user_princ,
                            const krb5_db_entry *krbtgt,
                            krb5_keyblock *krbtgt_key,
                            krb5_enc_tkt_part *enc_tkt_part,
                            krb5_principal *deleg_path,
                            krb5_pa_data **method_data,
                            krb5_checksum *cksum)
{
    krb5_error_code                 code;
    krb5_data                      *data;
    krb5_cksumtype                  cksumtype;
    krb5_const_principal            client;

    if (for_user_princ != NULL)
        client = for_user_princ;
    else
        client = enc_tkt_part->client;

    code = make_ad_signedpath_data(context,
                                   client,
                                   enc_tkt_part->times.authtime,
                                   deleg_path,
                                   method_data,
                                   enc_tkt_part->authorization_data,
                                   &data);
    if (code != 0)
        return code;

    code = krb5int_c_mandatory_cksumtype(context,
                                         krbtgt_key->enctype,
                                         &cksumtype);
    if (code != 0) {
        krb5_free_data(context, data);
        return code;
    }

    if (!krb5_c_is_keyed_cksum(cksumtype)) {
        krb5_free_data(context, data);
        return KRB5KRB_AP_ERR_INAPP_CKSUM;
    }

    code = krb5_c_make_checksum(context, cksumtype, krbtgt_key,
                                KRB5_KEYUSAGE_AD_SIGNEDPATH, data,
                                cksum);

    krb5_free_data(context, data);

    return code;
}
예제 #8
0
krb5_boolean
kdc_check_lookaside(krb5_data *inpkt, krb5_data **outpkt)
{
    krb5_int32 timenow;
    register krb5_kdc_replay_ent *eptr, *last, *hold;
    time_t db_age;

    if (krb5_timeofday(kdc_context, &timenow) || 
	krb5_db_get_age(kdc_context, 0, &db_age))
	return FALSE;

    calls++;

    /* search for a replay entry in the queue, possibly removing
       stale entries while we're here */

    if (root_ptr.next) {
	for (last = &root_ptr, eptr = root_ptr.next;
	     eptr;
	     eptr = eptr->next) {
	    if (MATCH(eptr)) {
		eptr->num_hits++;
		hits++;

		if (krb5_copy_data(kdc_context, eptr->reply_packet, outpkt))
		    return FALSE;
		else
		    return TRUE;
		/* return here, don't bother flushing even if it is stale.
		   if we just matched, we may get another retransmit... */
	    }
	    if (STALE(eptr)) {
		/* flush it and collect stats */
		max_hits_per_entry = max(max_hits_per_entry, eptr->num_hits);
		krb5_free_data(kdc_context, eptr->req_packet);
		krb5_free_data(kdc_context, eptr->reply_packet);
		hold = eptr;
		last->next = eptr->next;
		eptr = last;
		free(hold);
	    } else {
		/* this isn't it, just move along */
		last = eptr;
	    }
	}
    }
    return FALSE;
}
예제 #9
0
static void
free_paid(krb5_context context, struct pa_info_data *ppaid)
{
    krb5_free_salt(context, ppaid->salt);
    if (ppaid->s2kparams)
	krb5_free_data(context, ppaid->s2kparams);
}
예제 #10
0
/* frees memory associated with the lookaside queue for memory profiling */
void
kdc_free_lookaside(krb5_context kcontext)
{
    register krb5_kdc_replay_ent *eptr, *last, *hold;
    if (root_ptr.next) {
        for (last = &root_ptr, eptr = root_ptr.next;
	     eptr; eptr = eptr->next) {
		krb5_free_data(kcontext, eptr->req_packet);
		krb5_free_data(kcontext, eptr->reply_packet);
		hold = eptr;
		last->next = eptr->next;
		eptr = last;
		free(hold);
	}
    }
}
예제 #11
0
파일: mk_cred.c 프로젝트: Akasurde/krb5
/*
 * encrypt the enc_part of krb5_cred
 */
static krb5_error_code
encrypt_credencpart(krb5_context context, krb5_cred_enc_part *pcredpart,
                    krb5_key pkey, krb5_enc_data *pencdata)
{
    krb5_error_code       retval;
    krb5_data           * scratch;

    /* start by encoding to-be-encrypted part of the message */
    if ((retval = encode_krb5_enc_cred_part(pcredpart, &scratch)))
        return retval;

    /*
     * If the keyblock is NULL, just copy the data from the encoded
     * data to the ciphertext area.
     */
    if (pkey == NULL) {
        pencdata->ciphertext.data = scratch->data;
        pencdata->ciphertext.length = scratch->length;
        free(scratch);
        return 0;
    }

    /* call the encryption routine */
    retval = k5_encrypt_keyhelper(context, pkey,
                                  KRB5_KEYUSAGE_KRB_CRED_ENCPART, scratch,
                                  pencdata);

    memset(scratch->data, 0, scratch->length);
    krb5_free_data(context, scratch);

    return retval;
}
예제 #12
0
파일: greet_auth.c 프로젝트: PADL/krb5
static krb5_error_code
greet_authdata(krb5_context context,
               krb5_kdcauthdata_moddata moddata,
               unsigned int flags,
               krb5_db_entry *client,
               krb5_db_entry *server,
               krb5_db_entry *tgs,
               krb5_keyblock *client_key,
               krb5_keyblock *server_key,
               krb5_keyblock *krbtgt_key,
               krb5_data *req_pkt,
               krb5_kdc_req *request,
               krb5_const_principal for_user_princ,
               krb5_enc_tkt_part *enc_tkt_request,
               krb5_enc_tkt_part *enc_tkt_reply)
{
    krb5_error_code code;
    krb5_data *greeting = NULL;

    if (request->msg_type != KRB5_TGS_REQ)
        return 0;

    code = greet_hello(context, &greeting);
    if (code != 0)
        return code;

    code = greet_kdc_sign(context, enc_tkt_reply, tgs->princ, greeting);

    krb5_free_data(context, greeting);

    return code;
}
예제 #13
0
파일: main.c 프로젝트: DirectXMan12/krb5
static krb5_error_code
nonce_verify(krb5_context ctx, krb5_keyblock *armor_key,
             const krb5_data *nonce)
{
    krb5_error_code retval;
    krb5_timestamp ts;
    krb5_data *er = NULL;

    if (armor_key == NULL || nonce->data == NULL) {
        retval = EINVAL;
        goto out;
    }

    /* Decode the PA-OTP-ENC-REQUEST structure. */
    retval = decode_krb5_pa_otp_enc_req(nonce, &er);
    if (retval != 0)
        goto out;

    /* Make sure the nonce is exactly the same size as the one generated. */
    if (er->length != armor_key->length + sizeof(krb5_timestamp))
        goto out;

    /* Check to make sure the timestamp at the beginning is still valid. */
    ts = load_32_be(er->data);
    retval = krb5_check_clockskew(ctx, ts);

out:
    krb5_free_data(ctx, er);
    return retval;
}
예제 #14
0
파일: t_replay.c 프로젝트: PADL/krb5
static void
test_kdc_check_lookaside_hit_multiple(void **state)
{
    struct entry *e1, *e2;
    krb5_boolean result;
    krb5_data *result_data;
    krb5_context context = *state;
    krb5_data req1 = string2data("I'm a test request");
    krb5_data rep1 = string2data("I'm a test response");
    krb5_data req2 = string2data("I'm a different test request");

    e1 = insert_entry(context, &req1, &rep1, 0);
    e2 = insert_entry(context, &req2, NULL, 0);

    result = kdc_check_lookaside(context, &req1, &result_data);

    assert_true(result);
    assert_true(data_eq(rep1, *result_data));
    assert_int_equal(hits, 1);
    assert_int_equal(e1->num_hits, 1);
    assert_int_equal(e2->num_hits, 0);

    krb5_free_data(context, result_data);

    /* Set result_data so we can verify that it is reset to NULL. */
    result_data = &req1;
    result = kdc_check_lookaside(context, &req2, &result_data);

    assert_true(result);
    assert_null(result_data);
    assert_int_equal(hits, 2);
    assert_int_equal(e1->num_hits, 1);
    assert_int_equal(e2->num_hits, 1);
}
예제 #15
0
파일: main.c 프로젝트: DirectXMan12/krb5
static void
otp_edata(krb5_context context, krb5_kdc_req *request,
          krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
          krb5_kdcpreauth_moddata moddata, krb5_preauthtype pa_type,
          krb5_kdcpreauth_edata_respond_fn respond, void *arg)
{
    krb5_otp_tokeninfo ti, *tis[2] = { &ti, NULL };
    krb5_keyblock *armor_key = NULL;
    krb5_pa_otp_challenge chl;
    krb5_pa_data *pa = NULL;
    krb5_error_code retval;
    krb5_data *encoding;
    char *config;

    /* Determine if otp is enabled for the user. */
    retval = cb->get_string(context, rock, "otp", &config);
    if (retval == 0 && config == NULL)
        retval = ENOENT;
    if (retval != 0)
        goto out;
    cb->free_string(context, rock, config);

    /* Get the armor key.  This indicates the length of random data to use in
     * the nonce. */
    armor_key = cb->fast_armor(context, rock);
    if (armor_key == NULL) {
        retval = ENOENT;
        goto out;
    }

    /* Build the (mostly empty) challenge. */
    memset(&ti, 0, sizeof(ti));
    memset(&chl, 0, sizeof(chl));
    chl.tokeninfo = tis;
    ti.format = -1;
    ti.length = -1;
    ti.iteration_count = -1;

    /* Generate the nonce. */
    retval = nonce_generate(context, armor_key->length, &chl.nonce);
    if (retval != 0)
        goto out;

    /* Build the output pa-data. */
    retval = encode_krb5_pa_otp_challenge(&chl, &encoding);
    if (retval != 0)
        goto out;
    pa = k5alloc(sizeof(krb5_pa_data), &retval);
    if (pa == NULL) {
        krb5_free_data(context, encoding);
        goto out;
    }
    pa->pa_type = KRB5_PADATA_OTP_CHALLENGE;
    pa->contents = (krb5_octet *)encoding->data;
    pa->length = encoding->length;
    free(encoding);

out:
    (*respond)(arg, retval, pa);
}
예제 #16
0
파일: fast.c 프로젝트: DirectXMan12/krb5
krb5_error_code
krb5int_fast_prep_req_body(krb5_context context,
                           struct krb5int_fast_request_state *state,
                           krb5_kdc_req *request,
                           krb5_data **encoded_request_body)
{
    krb5_error_code retval = 0;
    krb5_data *local_encoded_request_body = NULL;

    assert(state != NULL);
    *encoded_request_body = NULL;
    if (state->armor_key == NULL)
        return encode_krb5_kdc_req_body(request, encoded_request_body);
    state->fast_outer_request = *request;
    state->fast_outer_request.padata = NULL;
    if (retval == 0)
        retval = encode_krb5_kdc_req_body(&state->fast_outer_request,
                                          &local_encoded_request_body);
    if (retval == 0) {
        *encoded_request_body = local_encoded_request_body;
        local_encoded_request_body = NULL;
    }
    if (local_encoded_request_body != NULL)
        krb5_free_data(context, local_encoded_request_body);
    return retval;
}
예제 #17
0
krb5_error_code KRB5_CALLCONV
krb5_encode_authdata_container(krb5_context context,
			       krb5_authdatatype type,
			       krb5_authdata *const*authdata,
			       krb5_authdata ***container)
{
    krb5_error_code code;
    krb5_data *data;
    krb5_authdata ad_datum;
    krb5_authdata *ad_data[2];

    *container = NULL;

    code = encode_krb5_authdata((krb5_authdata * const *)authdata, &data);
    if (code)
	return code;

    ad_datum.ad_type = type & AD_TYPE_FIELD_TYPE_MASK;
    ad_datum.length = data->length;
    ad_datum.contents = (unsigned char *)data->data;

    ad_data[0] = &ad_datum;
    ad_data[1] = NULL;

    code = krb5_copy_authdata(context, ad_data, container);

    krb5_free_data(context, data);

    return code;
}
예제 #18
0
파일: fast_util.c 프로젝트: hautreux/krb5
static krb5_error_code
encrypt_fast_reply(struct kdc_request_state *state,
                   const krb5_fast_response *response,
                   krb5_data **fx_fast_reply)
{
    krb5_error_code retval = 0;
    krb5_enc_data encrypted_reply;
    krb5_data *encoded_response = NULL;
    kdc_realm_t *kdc_active_realm = state->realm_data;

    assert(state->armor_key);
    retval = encode_krb5_fast_response(response, &encoded_response);
    if (retval== 0)
        retval = krb5_encrypt_helper(kdc_context, state->armor_key,
                                     KRB5_KEYUSAGE_FAST_REP,
                                     encoded_response, &encrypted_reply);
    if (encoded_response)
        krb5_free_data(kdc_context, encoded_response);
    encoded_response = NULL;
    if (retval == 0) {
        retval = encode_krb5_pa_fx_fast_reply(&encrypted_reply,
                                              fx_fast_reply);
        krb5_free_data_contents(kdc_context, &encrypted_reply.ciphertext);
    }
    return retval;
}
예제 #19
0
파일: kfree.c 프로젝트: kennymacdonald/krb5
void
k5_free_data_ptr_list(krb5_data **list)
{
    int i;

    for (i = 0; list != NULL && list[i] != NULL; i++)
        krb5_free_data(NULL, list[i]);
    free(list);
}
예제 #20
0
krb5_error_code
securid_make_sam_challenge_2_and_cksum(krb5_context context,
                                       krb5_sam_challenge_2 *sc2,
                                       krb5_sam_challenge_2_body *sc2b,
                                       krb5_keyblock *cksum_key)
{
    krb5_error_code retval;
    krb5_checksum **cksum_array = NULL;
    krb5_checksum *cksum = NULL;
    krb5_cksumtype cksumtype;
    krb5_data *encoded_challenge_body = NULL;

    if (!cksum_key)
        return KRB5_PREAUTH_NO_KEY;
    if (!sc2 || !sc2b)
        return KRB5KDC_ERR_PREAUTH_FAILED;

    retval = encode_krb5_sam_challenge_2_body(sc2b, &encoded_challenge_body);
    if (retval || !encoded_challenge_body) {
        encoded_challenge_body = NULL;
        goto cksum_cleanup;
    }

    cksum_array = calloc(2, sizeof(krb5_checksum *));
    if (!cksum_array) {
        retval = ENOMEM;
        goto cksum_cleanup;
    }

    cksum = (krb5_checksum *)k5alloc(sizeof(krb5_checksum), &retval);
    if (retval)
        goto cksum_cleanup;
    cksum_array[0] = cksum;
    cksum_array[1] = NULL;

    retval = krb5int_c_mandatory_cksumtype(context, cksum_key->enctype,
                                           &cksumtype);
    if (retval)
        goto cksum_cleanup;

    retval = krb5_c_make_checksum(context, cksumtype, cksum_key,
                                  KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM,
                                  encoded_challenge_body, cksum);
    if (retval)
        goto cksum_cleanup;

    sc2->sam_cksum = cksum_array;
    sc2->sam_challenge_2_body = *encoded_challenge_body;
    return 0;

cksum_cleanup:
    krb5_free_data(context, encoded_challenge_body);
    free(cksum_array);
    free(cksum);
    return retval;
}
예제 #21
0
파일: kfree.c 프로젝트: kennymacdonald/krb5
void KRB5_CALLCONV
krb5_free_iakerb_header(krb5_context context, krb5_iakerb_header *val)
{
    if (val == NULL)
        return ;

    krb5_free_data_contents(context, &val->target_realm);
    krb5_free_data(context, val->cookie);
    free(val);
}
예제 #22
0
파일: fast.c 프로젝트: WeiY/krb5
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;
}
예제 #23
0
파일: sendto_kdc.c 프로젝트: Akasurde/krb5
static krb5_error_code
make_proxy_request(struct conn_state *state, const krb5_data *realm,
                   const krb5_data *message, char **req_out, size_t *len_out)
{
    krb5_kkdcp_message pm;
    krb5_data *encoded_pm = NULL;
    struct k5buf buf;
    const char *uri_path;
    krb5_error_code ret;

    *req_out = NULL;
    *len_out = 0;

    /*
     * Stuff the message length in at the front of the kerb_message field
     * before encoding.  The proxied messages are actually the payload we'd
     * be sending and receiving if we were using plain TCP.
     */
    memset(&pm, 0, sizeof(pm));
    ret = alloc_data(&pm.kerb_message, message->length + 4);
    if (ret != 0)
        goto cleanup;
    store_32_be(message->length, pm.kerb_message.data);
    memcpy(pm.kerb_message.data + 4, message->data, message->length);
    pm.target_domain = *realm;
    ret = encode_krb5_kkdcp_message(&pm, &encoded_pm);
    if (ret != 0)
        goto cleanup;

    /* Build the request to transmit: the headers + the proxy message. */
    k5_buf_init_dynamic(&buf);
    uri_path = (state->http.uri_path != NULL) ? state->http.uri_path : "";
    k5_buf_add_fmt(&buf, "POST /%s HTTP/1.0\r\n", uri_path);
    k5_buf_add(&buf, "Cache-Control: no-cache\r\n");
    k5_buf_add(&buf, "Pragma: no-cache\r\n");
    k5_buf_add(&buf, "User-Agent: kerberos/1.0\r\n");
    k5_buf_add(&buf, "Content-type: application/kerberos\r\n");
    k5_buf_add_fmt(&buf, "Content-Length: %d\r\n\r\n", encoded_pm->length);
    k5_buf_add_len(&buf, encoded_pm->data, encoded_pm->length);
    if (k5_buf_status(&buf) != 0) {
        ret = ENOMEM;
        goto cleanup;
    }

    *req_out = buf.data;
    *len_out = buf.len;

cleanup:
    krb5_free_data_contents(NULL, &pm.kerb_message);
    krb5_free_data(NULL, encoded_pm);
    return ret;
}
예제 #24
0
파일: schpw.c 프로젝트: Akasurde/krb5
/* Dispatch routine for set/change password */
void
dispatch(void *handle, struct sockaddr *local_saddr,
         const krb5_fulladdr *remote_faddr, krb5_data *request, int is_tcp,
         verto_ctx *vctx, loop_respond_fn respond, void *arg)
{
    krb5_error_code ret;
    krb5_keytab kt = NULL;
    kadm5_server_handle_t server_handle = (kadm5_server_handle_t)handle;
    krb5_fulladdr local_faddr;
    krb5_address **local_kaddrs = NULL, local_kaddr_buf;
    krb5_data *response = NULL;

    if (local_saddr == NULL) {
        ret = krb5_os_localaddr(server_handle->context, &local_kaddrs);
        if (ret != 0)
            goto egress;

        local_faddr.address = local_kaddrs[0];
        local_faddr.port = 0;
    } else {
        local_faddr.address = &local_kaddr_buf;
        init_addr(&local_faddr, local_saddr);
    }

    ret = krb5_kt_resolve(server_handle->context, "KDB:", &kt);
    if (ret != 0) {
        krb5_klog_syslog(LOG_ERR, _("chpw: Couldn't open admin keytab %s"),
                         krb5_get_error_message(server_handle->context, ret));
        goto egress;
    }

    response = k5alloc(sizeof(krb5_data), &ret);
    if (response == NULL)
        goto egress;

    ret = process_chpw_request(server_handle->context,
                               handle,
                               server_handle->params.realm,
                               kt,
                               &local_faddr,
                               remote_faddr,
                               request,
                               response);
egress:
    if (ret)
        krb5_free_data(server_handle->context, response);
    krb5_free_addresses(server_handle->context, local_kaddrs);
    krb5_kt_close(server_handle->context, kt);
    (*respond)(arg, ret, ret == 0 ? response : NULL);
}
예제 #25
0
파일: chpw.c 프로젝트: jmoldow/krb5
krb5_error_code
krb5int_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context,
                    krb5_data *packet, int *result_code_out,
                    krb5_data *result_data_out)
{
    krb5_error_code ret;
    krb5_data result_data, *clear = NULL;
    krb5_boolean is_error;
    char *ptr;
    int result_code;

    *result_code_out = 0;
    *result_data_out = empty_data();

    ret = get_clear_result(context, auth_context, packet, &clear, &is_error);
    if (ret)
        return ret;

    if (clear->length < 2) {
        ret = KRB5KRB_AP_ERR_MODIFIED;
        goto cleanup;
    }

    /* Decode and check the result code. */
    ptr = clear->data;
    result_code = (*ptr++ & 0xff);
    result_code = (result_code << 8) | (*ptr++ & 0xff);
    if (result_code < KRB5_KPASSWD_SUCCESS ||
        result_code > KRB5_KPASSWD_INITIAL_FLAG_NEEDED) {
        ret = KRB5KRB_AP_ERR_MODIFIED;
        goto cleanup;
    }

    /* Successful replies must not come from errors. */
    if (is_error && result_code == KRB5_KPASSWD_SUCCESS) {
        ret = KRB5KRB_AP_ERR_MODIFIED;
        goto cleanup;
    }

    result_data = make_data(ptr, clear->data + clear->length - ptr);
    ret = krb5int_copy_data_contents(context, &result_data, result_data_out);
    if (ret)
        goto cleanup;
    *result_code_out = result_code;

cleanup:
    krb5_free_data(context, clear);
    return ret;
}
예제 #26
0
파일: kerberos_v4.c 프로젝트: aosm/Kerberos
static
int krb4_sendto(int s, const char *msg, int len, int flags,
		const struct sockaddr *to, int to_len)
{
    if (  !(response = (krb5_data *) malloc( sizeof *response))) {
	return ENOMEM;
    }
    if ( !(response->data = (char *) malloc( len))) {
	krb5_free_data(kdc_context,  response);
	return ENOMEM;
    }
    response->length = len;
    memcpy( response->data, msg, len);
    return( 0);
}
예제 #27
0
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;
}
예제 #28
0
파일: authdata.c 프로젝트: ln5/krb5-anonsvn
krb5_error_code KRB5_CALLCONV
krb5_authdata_export_attributes(krb5_context kcontext,
                                krb5_authdata_context context,
                                krb5_flags flags,
                                krb5_data **attrsp)
{
    krb5_error_code code;
    size_t required = 0;
    krb5_octet *bp;
    size_t remain;
    krb5_data *attrs;

    code = k5_ad_size(kcontext, context, AD_USAGE_MASK, &required);
    if (code != 0)
        return code;

    attrs = malloc(sizeof(*attrs));
    if (attrs == NULL)
        return ENOMEM;

    attrs->magic = KV5M_DATA;
    attrs->length = 0;
    attrs->data = malloc(required);
    if (attrs->data == NULL) {
        free(attrs);
        return ENOMEM;
    }

    bp = (krb5_octet *)attrs->data;
    remain = required;

    code = k5_ad_externalize(kcontext, context, AD_USAGE_MASK, &bp, &remain);
    if (code != 0) {
        krb5_free_data(kcontext, attrs);
        return code;
    }

    attrs->length = (bp - (krb5_octet *)attrs->data);

    *attrsp = attrs;

    return 0;
}
예제 #29
0
/*
 * AIX krb5 has krb5_decrypt_tkt_part, but no krb5_c_decrypt. So, implement our
 * own krb5_c_decrypt. Note that this krb5_c_decrypt is only suitable for
 * decrypting an encrypted krb5_enc_tkt_part. But since that's all we ever use
 * it for, that should be fine.
 */
static krb5_error_code
krb5_c_decrypt(krb5_context context, const krb5_keyblock *key,
               krb5_keyusage usage, const krb5_data *cipher_state,
               const krb5_enc_data *input, krb5_data *output)
{
    krb5_ticket tkt;
    krb5_error_code code;
    krb5_data *tout = NULL;

    /* We only handle a subset of possible arguments; if we somehow get passed
     * something else, bail out with EINVAL. */
    if (cipher_state != NULL)
	return EINVAL;
    if (usage != KRB5_KEYUSAGE_KDC_REP_TICKET)
	return EINVAL;

    memset(&tkt, 0, sizeof(tkt));

    tkt.enc_part = *input;

    code = krb5_decrypt_tkt_part(context, key, &tkt);
    if (code != 0)
	return code;

    code = encode_krb5_enc_tkt_part(tkt.enc_part2, &tout);
    if (code != 0)
	return code;

    if (tout->length > output->length) {
	/* This should never happen, but don't assert since we may be dealing
	 * with untrusted user data. */
	code = EINVAL;
	goto error;
    }

    memcpy(output->data, tout->data, tout->length);
    output->length = tout->length;

 error:
    if (tout)
	krb5_free_data(context, tout);
    return code;
}
예제 #30
0
파일: t_replay.c 프로젝트: PADL/krb5
static void
test_kdc_check_lookaside_hit(void **state)
{
    struct entry *e;
    krb5_boolean result;
    krb5_data *result_data;
    krb5_context context = *state;
    krb5_data req = string2data("I'm a test request");
    krb5_data rep = string2data("I'm a test response");

    e = insert_entry(context, &req, &rep, 0);

    result = kdc_check_lookaside(context, &req, &result_data);

    assert_true(result);
    assert_true(data_eq(rep, *result_data));
    assert_int_equal(hits, 1);
    assert_int_equal(e->num_hits, 1);

    krb5_free_data(context, result_data);
}