Esempio n. 1
0
/*
 * Set up the request given by ctx->tgs_in_creds, using ctx->cur_tgt.  KDC
 * options for the requests are determined by ctx->cur_tgt->ticket_flags and
 * extra_options.
 */
static krb5_error_code
make_request(krb5_context context, krb5_tkt_creds_context ctx,
             int extra_options)
{
    krb5_error_code code;
    krb5_data request = empty_data();

    ctx->kdcopt = extra_options | FLAGS2OPTS(ctx->cur_tgt->ticket_flags);

    /* XXX This check belongs in gc_via_tgt.c or nowhere. */
    if (!krb5_c_valid_enctype(ctx->cur_tgt->keyblock.enctype))
        return KRB5_PROG_ETYPE_NOSUPP;

    /* Create a new FAST state structure to store this request's armor key. */
    krb5int_fast_free_state(context, ctx->fast_state);
    ctx->fast_state = NULL;
    code = krb5int_fast_make_state(context, &ctx->fast_state);
    if (code)
        return code;

    krb5_free_keyblock(context, ctx->subkey);
    ctx->subkey = NULL;
    code = k5_make_tgs_req(context, ctx->fast_state, ctx->cur_tgt, ctx->kdcopt,
                           ctx->cur_tgt->addresses, NULL, ctx->tgs_in_creds,
                           NULL, NULL, &request, &ctx->timestamp, &ctx->nonce,
                           &ctx->subkey);
    if (code != 0)
        return code;

    krb5_free_data_contents(context, &ctx->previous_request);
    ctx->previous_request = request;
    return set_caller_request(context, ctx);
}
Esempio n. 2
0
krb5_error_code
krb5_get_cred_via_tkt_ext(krb5_context context, krb5_creds *tkt,
                          krb5_flags kdcoptions, krb5_address *const *address,
                          krb5_pa_data **in_padata, krb5_creds *in_cred,
                          k5_pacb_fn pacb_fn, void *pacb_data,
                          krb5_pa_data ***out_padata,
                          krb5_pa_data ***out_enc_padata,
                          krb5_creds **out_cred, krb5_keyblock **out_subkey)
{
    krb5_error_code retval;
    krb5_data request_data;
    krb5_data response_data;
    krb5_timestamp timestamp;
    krb5_int32 nonce;
    krb5_keyblock *subkey = NULL;
    int tcp_only = 0, use_master = 0;
    struct krb5int_fast_request_state *fast_state = NULL;

    request_data.data = NULL;
    request_data.length = 0;
    response_data.data = NULL;
    response_data.length = 0;

    retval = krb5int_fast_make_state(context, &fast_state);
    if (retval)
        goto cleanup;

    TRACE_GET_CRED_VIA_TKT_EXT(context, in_cred->server, tkt->server,
                               kdcoptions);

    retval = k5_make_tgs_req(context, fast_state, tkt, kdcoptions, address,
                             in_padata, in_cred, pacb_fn, pacb_data,
                             &request_data, &timestamp, &nonce, &subkey);
    if (retval != 0)
        goto cleanup;

send_again:
    use_master = 0;
    retval = krb5_sendto_kdc(context, &request_data, &in_cred->server->realm,
                             &response_data, &use_master, tcp_only);
    if (retval == 0) {
        if (krb5_is_krb_error(&response_data)) {
            if (!tcp_only) {
                krb5_error *err_reply;
                retval = decode_krb5_error(&response_data, &err_reply);
                if (retval != 0)
                    goto cleanup;
                retval = krb5int_fast_process_error(context, fast_state,
                                                    &err_reply, NULL, NULL);
                if (retval)
                    goto cleanup;
                if (err_reply->error == KRB_ERR_RESPONSE_TOO_BIG) {
                    tcp_only = 1;
                    krb5_free_error(context, err_reply);
                    krb5_free_data_contents(context, &response_data);
                    goto send_again;
                }
                krb5_free_error(context, err_reply);
            }
        }
    } else
        goto cleanup;

    retval = krb5int_process_tgs_reply(context, fast_state, &response_data,
                                       tkt, kdcoptions, address,
                                       in_padata, in_cred,
                                       timestamp, nonce, subkey,
                                       out_padata,
                                       out_enc_padata, out_cred);
    if (retval != 0)
        goto cleanup;

cleanup:
    krb5int_fast_free_state(context, fast_state);
    TRACE_GET_CRED_VIA_TKT_EXT_RETURN(context, retval);

    krb5_free_data_contents(context, &request_data);
    krb5_free_data_contents(context, &response_data);

    if (subkey != NULL) {
        if (retval == 0 && out_subkey != NULL)
            *out_subkey = subkey;
        else
            krb5_free_keyblock(context, subkey);
    }

    return retval;
}
Esempio n. 3
0
krb5_error_code
krb5_get_cred_via_tkt_ext(krb5_context context, krb5_creds *tkt,
                          krb5_flags kdcoptions, krb5_address *const *address,
                          krb5_pa_data **in_padata,
                          krb5_creds *in_cred,
                          krb5_error_code (*pacb_fct)(krb5_context,
                                                      krb5_keyblock *,
                                                      krb5_kdc_req *,
                                                      void *),
                          void *pacb_data,
                          krb5_pa_data ***out_padata,
                          krb5_pa_data ***out_enc_padata,
                          krb5_creds **out_cred,
                          krb5_keyblock **out_subkey)
{
    krb5_error_code retval;
    krb5_data request_data;
    krb5_data response_data;
    krb5_timestamp timestamp;
    krb5_int32 nonce;
    krb5_keyblock *subkey = NULL;
    int tcp_only = 0, use_master = 0;
    struct krb5int_fast_request_state *fast_state = NULL;

    request_data.data = NULL;
    request_data.length = 0;
    response_data.data = NULL;
    response_data.length = 0;

    retval = krb5int_fast_make_state(context, &fast_state);
    if (retval)
        goto cleanup;

#ifdef DEBUG_REFERRALS
    printf("krb5_get_cred_via_tkt starting; referral flag is %s\n", kdcoptions&KDC_OPT_CANONICALIZE?"on":"off");
    krb5int_dbgref_dump_principal("krb5_get_cred_via_tkt requested ticket", in_cred->server);
    krb5int_dbgref_dump_principal("krb5_get_cred_via_tkt TGT in use", tkt->server);
#endif

    retval = krb5int_make_tgs_request(context, fast_state, tkt, kdcoptions,
                                      address, in_padata, in_cred,
                                      pacb_fct, pacb_data,
                                      &request_data, &timestamp, &nonce,
                                      &subkey);
    if (retval != 0)
        goto cleanup;

send_again:
    use_master = 0;
    retval = krb5_sendto_kdc(context, &request_data,
                             krb5_princ_realm(context, in_cred->server),
                             &response_data, &use_master, tcp_only);
    if (retval == 0) {
        if (krb5_is_krb_error(&response_data)) {
            if (!tcp_only) {
                krb5_error *err_reply;
                retval = decode_krb5_error(&response_data, &err_reply);
                if (retval != 0)
                    goto cleanup;
                retval = krb5int_fast_process_error(context, fast_state,
                                                    &err_reply, NULL, NULL);
                if (retval)
                    goto cleanup;
                if (err_reply->error == KRB_ERR_RESPONSE_TOO_BIG) {
                    tcp_only = 1;
                    krb5_free_error(context, err_reply);
                    krb5_free_data_contents(context, &response_data);
                    goto send_again;
                }
                krb5_free_error(context, err_reply);
            }
        }
    } else
        goto cleanup;

    retval = krb5int_process_tgs_reply(context, fast_state, &response_data,
                                       tkt, kdcoptions, address,
                                       in_padata, in_cred,
                                       timestamp, nonce, subkey,
                                       out_padata,
                                       out_enc_padata, out_cred);
    if (retval != 0)
        goto cleanup;

cleanup:
    krb5int_fast_free_state(context, fast_state);
#ifdef DEBUG_REFERRALS
    printf("krb5_get_cred_via_tkt ending; %s\n", retval?error_message(retval):"no error");
#endif

    krb5_free_data_contents(context, &request_data);
    krb5_free_data_contents(context, &response_data);

    if (subkey != NULL) {
        if (retval == 0 && out_subkey != NULL)
            *out_subkey = subkey;
        else
            krb5_free_keyblock(context, subkey);
    }

    return retval;
}