typedef struct _krb5_fast_req {
krb5_magic magic;
- krb5_int32 fast_options;
+ krb5_flags fast_options;
/* padata from req_body is used*/
krb5_kdc_req *req_body;
} krb5_fast_req;
typedef struct _krb5_fast_response {
krb5_magic magic;
krb5_pa_data **padata;
- krb5_keyblock *rep_key;
+ krb5_keyblock *strengthen_key;
krb5_fast_finished *finished;
krb5_int32 nonce;
} krb5_fast_response;
krb5_keylist_node *tmp_mkey_list;
struct kdc_request_state *state = NULL;
krb5_data encoded_req_body;
+ krb5_keyblock *as_encrypting_key = NULL;
#if APPLE_PKINIT
goto errout;
}
ticket_reply.enc_part.kvno = server_key->key_data_kvno;
- errcode = kdc_fast_response_handle_padata(state, request, &reply);
+ errcode = kdc_fast_response_handle_padata(state, request, &reply, client_keyblock.enctype);
if (errcode) {
status = "fast response handling";
goto errout;
reply.enc_part.enctype = client_keyblock.enctype;
- errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart,
- 0, &client_keyblock, &reply, response);
+ errcode = kdc_fast_handle_reply_key(state, &client_keyblock, &as_encrypting_key);
+ if (errcode) {
+ status = "generating reply key";
+ goto errout;
+ }
+ errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart,
+ 0, as_encrypting_key, &reply, response);
reply.enc_part.kvno = client_key->key_data_kvno;
if (errcode) {
status = "ENCODE_KDC_REP";
egress:
if (pa_context)
free_padata_context(kdc_context, &pa_context);
-
+ if (as_encrypting_key)
+ krb5_free_keyblock(kdc_context, as_encrypting_key);
if (errcode)
emsg = krb5_get_error_message(kdc_context, errcode);
if (pa == NULL)
retval = ENOMEM;
else for (size = 0; td[size]; size++) {
- krb5_pa_data *pad = malloc(sizeof(krb5_pa_data *));
+ krb5_pa_data *pad = malloc(sizeof(krb5_pa_data ));
if (pad == NULL) {
retval = ENOMEM;
break;
reply.enc_part.enctype = subkey ? subkey->enctype :
header_ticket->enc_part2->session->enctype;
- errcode = kdc_fast_response_handle_padata(state, request, &reply);
+ errcode = kdc_fast_response_handle_padata(state, request, &reply,
+ subkey?subkey->enctype:header_ticket->enc_part2->session->enctype);
if (errcode !=0 ) {
status = "Preparing FAST padata";
goto cleanup;
krb5_data **response, const char *status)
{
krb5_error errpkt;
- krb5_error_code retval;
+ krb5_error_code retval = 0;
krb5_data *scratch;
errpkt.ctime = request->nonce;
}
errpkt.e_data.length = 0;
errpkt.e_data.data = NULL;
- retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt);
+ if (state)
+ retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt);
if (retval) {
free(scratch);
free(errpkt.text.data);
krb5_ticket *ticket = NULL;
krb5_keyblock *subkey = NULL;
- assert(armor->armor_type = KRB5_FAST_ARMOR_AP_REQUEST);
+ assert(armor->armor_type == KRB5_FAST_ARMOR_AP_REQUEST);
krb5_clear_error_message(kdc_context);
retval = krb5_auth_con_init(kdc_context, &authcontext);
if (retval == 0)
return;
if (s->armor_key)
krb5_free_keyblock(kdc_context, s->armor_key);
- if (s->reply_key)
- krb5_free_keyblock(kdc_context, s->reply_key);
+ if (s->strengthen_key)
+ krb5_free_keyblock(kdc_context, s->strengthen_key);
if (s->cookie) {
free(s->cookie->contents);
free(s->cookie);
krb5_error_code kdc_fast_response_handle_padata
(struct kdc_request_state *state,
krb5_kdc_req *request,
- krb5_kdc_rep *rep)
+ 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;
+ 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;
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.rep_key = state->reply_key;
+ fast_response.strengthen_key = state->strengthen_key;
fast_response.nonce = request->nonce;
fast_response.finished = &finish;
finish.client = rep->client;
pa_array[0] = &pa[0];
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;
krb5_fast_response resp;
krb5_error fx_error;
krb5_data *encoded_fx_error = NULL, *encrypted_reply = NULL;
- krb5_pa_data pa[2];
- krb5_pa_data *outer_pa[3];
+ krb5_pa_data pa[1];
+ krb5_pa_data *outer_pa[3], *cookie = NULL;
krb5_pa_data **inner_pa = NULL;
size_t size = 0;
krb5_data *encoded_e_data = NULL;
pa[0].length = encoded_fx_error->length;
pa[0].contents = (unsigned char *) encoded_fx_error->data;
inner_pa[size++] = &pa[0];
- resp.padata = inner_pa;
+ if (find_pa_data(inner_pa, KRB5_PADATA_FX_COOKIE) == NULL)
+ retval = kdc_preauth_get_cookie(state, &cookie);
+ }
+ if (cookie != NULL)
+ inner_pa[size++] = cookie;
+ if (retval == 0) {
+ resp.padata = inner_pa;
resp.nonce = request->nonce;
- resp.rep_key = NULL;
+ resp.strengthen_key = NULL;
resp.finished = NULL;
}
if (retval == 0)
retval = encrypt_fast_reply(state, &resp, &encrypted_reply);
if (inner_pa)
free(inner_pa); /*contained storage from caller and our stack*/
+ if (cookie) {
+ free(cookie->contents);
+ free(cookie);
+ cookie = NULL;
+ }
if (retval == 0) {
pa[0].pa_type = KRB5_PADATA_FX_FAST;
pa[0].length = encrypted_reply->length;
krb5_free_data(kdc_context, encoded_fx_error);
return retval;
}
+
+krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state,
+ krb5_keyblock *existing_key,
+ krb5_keyblock **out_key)
+{
+ krb5_error_code retval = 0;
+ if (state->armor_key)
+ retval = krb5_c_fx_cf2_simple(kdc_context,
+ state->strengthen_key, "strengthenkey",
+ existing_key,
+ "replykey", out_key);
+ else retval = krb5_copy_keyblock(kdc_context, existing_key, out_key);
+ return retval;
+}
+
+
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+ krb5_pa_data **cookie)
+{
+ char *contents;
+ krb5_pa_data *pa = NULL;
+ /* In our current implementation, the only purpose served by
+ * returning a cookie is to indicate that a conversation should
+ * continue on error. Thus, the cookie can have a constant
+ * string. If cookies are used for real, versioning so that KDCs
+ * can be upgraded, keying, expiration and many other issues need
+ * to be considered.
+ */
+ contents = strdup("MIT");
+ if (contents == NULL)
+ return ENOMEM;
+ pa = calloc(1, sizeof(krb5_pa_data));
+ if (pa == NULL) {
+ free(contents);
+ return ENOMEM;
+ }
+ pa->pa_type = KRB5_PADATA_FX_COOKIE;
+ pa->length = strlen(contents);
+ pa->contents = (unsigned char *) contents;
+ *cookie = pa;
+ return 0;
+}
verify_enc_timestamp,
0
},
+ {
+ "FAST",
+ KRB5_PADATA_FX_FAST,
+ PA_HARDWARE,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0
+ },
{
"etype-info",
KRB5_PADATA_ETYPE_INFO,
e_data->data = 0;
hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
- pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+1));
+ /* Allocate 1 entry for the terminator and one for the cookie*/
+ pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+21));
if (pa_data == 0)
return;
memset(pa_data, 0, sizeof(krb5_pa_data *) * (n_preauth_systems+1));
"%spreauth required but hint list is empty",
hw_only ? "hw" : "");
}
+/* If we fail to get the cookie it is probably still reasonable to continue with the response*/
+ kdc_preauth_get_cookie(request->kdc_state, pa);
retval = encode_krb5_padata_sequence(pa_data, &edat);
if (retval)
goto errout;
authenticator->authorization_data,
KRB5_AUTHDATA_FX_ARMOR, &authdata);
if (retval != 0)
- goto cleanup_auth_context;
+ goto cleanup_authenticator;
if (authdata&& authdata[0]) {
krb5_set_error_message(kdc_context, KRB5KDC_ERR_POLICY,
"ticket valid only as FAST armor");
retval = KRB5KDC_ERR_POLICY;
krb5_free_authdata(kdc_context, authdata);
- goto cleanup_auth_context;
+ goto cleanup_authenticator;
}
krb5_free_authdata(kdc_context, authdata);
struct kdc_request_state {
krb5_keyblock *armor_key;
- krb5_keyblock *reply_key; /*When replaced by FAST*/
+ krb5_keyblock *strengthen_key;
krb5_pa_data *cookie;
krb5_int32 fast_options;
krb5_int32 fast_internal_flags;
};
+
krb5_error_code kdc_make_rstate(struct kdc_request_state **out);
void kdc_free_rstate
(struct kdc_request_state *s);
krb5_error_code kdc_fast_response_handle_padata
(struct kdc_request_state *state,
krb5_kdc_req *request,
- krb5_kdc_rep *rep);
+ krb5_kdc_rep *rep,
+ krb5_enctype enctype);
krb5_error_code kdc_fast_handle_error
(krb5_context context, struct kdc_request_state *state,
krb5_kdc_req *request,
krb5_pa_data **in_padata, krb5_error *err);
+krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state,
+ krb5_keyblock *existing_key,
+ krb5_keyblock **out_key);
+
+
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+ krb5_pa_data **cookie);
+
*/
#include "k5-int.h"
#include "arcfour-int.h"
+#include "../hash_provider/hash_provider.h"
+
const char *const krb5int_arcfour_l40 = "fortybits";
void
return (ret);
}
+ krb5_error_code krb5int_arcfour_prf(
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ const krb5_data *in, krb5_data *out)
+ {
+ assert(out->length == 20);
+ return krb5_hmac(&krb5int_hash_sha1, key, 1, in, out);
+ }
extern const struct krb5_enc_provider krb5int_enc_arcfour;
extern const struct krb5_aead_provider krb5int_aead_arcfour;
+ krb5_error_code krb5int_arcfour_prf(
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ const krb5_data *in, krb5_data *out);
#endif /* ARCFOUR_H */
"ArcFour with HMAC/md5",
&krb5int_enc_arcfour,
&krb5int_hash_md5,
- 0,
+ 20,
krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
- NULL, /*PRF*/
+ krb5int_arcfour_prf, /*PRF*/
CKSUMTYPE_HMAC_MD5_ARCFOUR,
&krb5int_aead_arcfour,
0 /*flags*/ },
"Exportable ArcFour with HMAC/md5",
&krb5int_enc_arcfour,
&krb5int_hash_md5,
- 0,
+ 20,
krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
- NULL, /*PRF*/
+ krb5int_arcfour_prf, /*PRF*/
CKSUMTYPE_HMAC_MD5_ARCFOUR,
&krb5int_aead_arcfour,
ETYPE_WEAK
DEFPTRTYPE(ptr_fast_req_padata, fast_req_padata);
static const struct field_info fast_req_fields[] = {
- FIELDOF_NORM(krb5_fast_req, int32, fast_options, 0),
+ FIELDOF_NORM(krb5_fast_req, krb5_flags, fast_options, 0),
FIELDOF_NORM( krb5_fast_req, ptr_fast_req_padata, req_body, 1),
FIELDOF_NORM( krb5_fast_req, ptr_kdc_req_body, req_body, 2),
};
static const struct field_info fast_response_fields[] = {
FIELDOF_NORM(krb5_fast_response, ptr_seqof_pa_data, padata, 0),
- FIELDOF_OPT( krb5_fast_response, ptr_encryption_key, rep_key, 1, 1),
+ FIELDOF_OPT( krb5_fast_response, ptr_encryption_key, strengthen_key, 1, 1),
FIELDOF_OPT( krb5_fast_response, ptr_fast_finished, finished, 2, 2),
FIELDOF_NORM(krb5_fast_response, int32, nonce, 3),
};
{
unsigned int optional = 0;
const krb5_fast_response *val = p;
- if (val->rep_key)
+ if (val->strengthen_key)
optional |= (1u <<1);
if (val->finished)
optional |= (1u<<2);
alloc_field(rep->req_body);
clear_field(rep, req_body->padata);
{begin_structure();
- get_field(rep->fast_options, 0, asn1_decode_int32);
+ get_field(rep->fast_options, 0, asn1_decode_krb5_flags);
opt_field(rep->req_body->padata, 1, asn1_decode_sequence_of_pa_data);
get_field(*(rep->req_body), 2, asn1_decode_kdc_req_body);
end_structure(); }
alloc_field(rep);
clear_field(rep, finished);
clear_field(rep, padata);
- clear_field(rep,rep_key);
+ clear_field(rep,strengthen_key);
{begin_structure();
get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data);
- opt_field(rep->rep_key, 1, asn1_decode_encryption_key_ptr);
+ opt_field(rep->strengthen_key, 1, asn1_decode_encryption_key_ptr);
opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr);
get_field(rep->nonce, 3, asn1_decode_int32);
end_structure(); }
$(srcdir)/srv_dec_tkt.c \
$(srcdir)/srv_rcache.c \
$(srcdir)/str_conv.c \
+ $(srcdir)/t_ad_fx_armor.c \
$(srcdir)/tgtname.c \
$(srcdir)/unparse.c \
$(srcdir)/valid_times.c \
t_walk_rtree: $(T_WALK_RTREE_OBJS) $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o t_walk_rtree $(T_WALK_RTREE_OBJS) $(KRB5_BASE_LIBS)
+t_ad_fx_armor: t_ad_fx_armor.o
+ $(CC_LINK) -o $@ $< $(KRB5_BASE_LIBS)
+
t_authdata: t_authdata.o copy_auth.o
$(CC_LINK) -o $@ $< copy_auth.o $(KRB5_BASE_LIBS)
free(scratch.data);
if (encrypted_response)
krb5_free_enc_data(context, encrypted_response);
+ if (local_resp)
+ krb5_free_fast_response(context, local_resp);
return retval;
}
fast_response->padata = NULL;
/*
* If there is more than the fx_error padata, then we want
- * to retry the error
+ * to retry the error if a cookie is present
*/
*retry = (*out_padata)[1] != NULL;
+ if (krb5int_find_pa_data(context, *out_padata, KRB5_PADATA_FX_COOKIE) == NULL)
+ *retry = 0;
}
if (fx_error)
krb5_free_error(context, fx_error);
krb5_error_code krb5int_fast_process_response
(krb5_context context, struct krb5int_fast_request_state *state,
krb5_kdc_rep *resp,
- krb5_keyblock **as_key)
+ 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);
- *as_key = NULL;
+ *strengthen_key = NULL;
if (state->armor_key == 0)
return 0;
retval = decrypt_fast_reply(context, state, resp->padata,
krb5_free_principal(context, resp->client);
resp->client = fast_response->finished->client;
fast_response->finished->client = NULL;
- *as_key = fast_response->rep_key;
- fast_response->rep_key = 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;
krb5_free_data(context, encoded_ticket);
return retval;
}
+
+krb5_error_code krb5int_fast_reply_key(krb5_context context,
+ krb5_keyblock *strengthen_key,
+ krb5_keyblock *existing_key,
+ krb5_keyblock *out_key)
+{
+ krb5_keyblock *key = NULL;
+ krb5_error_code retval = 0;
+ krb5_free_keyblock_contents(context, out_key);
+ if (strengthen_key) {
+ retval = krb5_c_fx_cf2_simple(context, strengthen_key,
+ "strengthenkey", existing_key, "replykey", &key);
+ if (retval == 0) {
+ *out_key = *key;
+ free(key);
+ }
+ } else {
+ retval = krb5_copy_keyblock_contents(context, existing_key, out_key);
+ }
+ return retval;
+}
+
+
krb5_error_code
krb5int_fast_make_state( krb5_context context, struct krb5int_fast_request_state **state)
{
/*We are responsible for none of the store in the fast_outer_req*/
krb5_free_keyblock(context, state->armor_key);
krb5_free_fast_armor(context, state->armor);
- if (state->cookie) {
- free(state->cookie->contents);
- free(state->cookie);
- state->cookie = NULL;
- }
free(state);
}
krb5_fast_armor *armor;
krb5_ui_4 fast_state_flags;
krb5_ui_4 fast_options;
- krb5_pa_data *cookie;
krb5_int32 nonce;
};
krb5_error_code krb5int_fast_process_response
(krb5_context context, struct krb5int_fast_request_state *state,
krb5_kdc_rep *resp,
- krb5_keyblock **as_key);
+ krb5_keyblock **strengthen_key);
krb5_error_code
krb5int_fast_make_state( krb5_context context, struct krb5int_fast_request_state **state);
krb5_gic_opt_ext *opte,
krb5_kdc_req *request);
+krb5_error_code krb5int_fast_reply_key(krb5_context context,
+ krb5_keyblock *strengthen_key,
+ krb5_keyblock *existing_key,
+ krb5_keyblock *output_key);
+
+
#endif
int loopcount;
krb5_data salt;
krb5_data s2kparams;
- krb5_keyblock as_key;
- krb5_keyblock *fast_as_key = NULL;
+ krb5_keyblock as_key, encrypting_key;
+ krb5_keyblock *strengthen_key = NULL;
krb5_error *err_reply;
krb5_kdc_rep *local_as_reply;
krb5_timestamp time_now;
preauth_to_use = NULL;
kdc_padata = NULL;
as_key.length = 0;
+ encrypting_key.length = 0;
+ encrypting_key.contents = NULL;
salt.length = 0;
salt.data = NULL;
out_padata = NULL;
krb5_free_error(context, err_reply);
err_reply = NULL;
- if (ret)
- goto cleanup;
ret = sort_krb5_padata_sequence(context,
&request.server->realm,
preauth_to_use);
/* process any preauth data in the as_reply */
krb5_clear_preauth_context_use_counts(context);
ret = krb5int_fast_process_response(context, fast_state,
- local_as_reply, &fast_as_key);
+ local_as_reply, &strengthen_key);
if (ret)
goto cleanup;
if ((ret = sort_krb5_padata_sequence(context, &request.server->realm,
it. If decrypting the as_rep fails, or if there isn't an
as_key at all yet, then use the gak_fct to get one, and try
again. */
- if (fast_as_key) {
- if (as_key.length)
- krb5_free_keyblock_contents(context, &as_key);
- as_key = *fast_as_key;
- free(fast_as_key);
- fast_as_key = NULL;
- }
- if (as_key.length)
- ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
- NULL, &as_key, krb5_kdc_rep_decrypt_proc,
+ if (as_key.length) {
+ ret = krb5int_fast_reply_key(context, strengthen_key, &as_key,
+ &encrypting_key);
+ if (ret)
+ goto cleanup;
+ ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
+ NULL, &encrypting_key, krb5_kdc_rep_decrypt_proc,
NULL);
- else
+ } else
ret = -1;
if (ret) {
&as_key, gak_data))))
goto cleanup;
+ ret = krb5int_fast_reply_key(context, strengthen_key, &as_key,
+ &encrypting_key);
+ if (ret)
+ goto cleanup;
if ((ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
NULL, &as_key, krb5_kdc_rep_decrypt_proc,
NULL)))
}
}
krb5_preauth_request_context_fini(context);
- krb5_free_keyblock(context, fast_as_key);
- if (fast_state)
+ krb5_free_keyblock(context, strengthen_key);
+ if (encrypting_key.contents)
+ krb5_free_keyblock_contents(context, &encrypting_key);
+ if (fast_state)
krb5int_fast_free_state(context, fast_state);
if (out_padata)
krb5_free_pa_data(context, out_padata);
return;
krb5_free_pa_data(context, val->padata);
krb5_free_fast_finished(context, val->finished);
+ krb5_free_keyblock(context, val->strengthen_key);
free(val);
}
return(0);
}
+static
+krb5_error_code pa_fx_cookie(krb5_context context,
+ krb5_kdc_req *request,
+ krb5_pa_data *in_padata,
+ krb5_pa_data **out_padata,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_enctype *etype,
+ krb5_keyblock *as_key,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ krb5_gic_get_as_key_fct gak_fct,
+ void *gak_data)
+{
+ krb5_pa_data *pa = calloc(1, sizeof(krb5_pa_data));
+ krb5_octet *contents;
+ if (pa == NULL)
+ return ENOMEM;
+ contents = malloc(in_padata->length);
+ if (contents == NULL) {
+ free(pa);
+ return ENOMEM;
+ }
+ *pa = *in_padata;
+ pa->contents = contents;
+ memcpy(contents, in_padata->contents, pa->length);
+ *out_padata = pa;
+ return 0;
+}
+
static
krb5_error_code pa_enc_timestamp(krb5_context context,
krb5_kdc_req *request,
pa_sam,
PA_REAL,
},
+ {
+ KRB5_PADATA_FX_COOKIE,
+ pa_fx_cookie,
+ PA_INFO,
+ },
{
-1,
NULL,
--- /dev/null
+#include <memory.h>
+#include <stdio.h>
+#include <krb5/krb5.h>
+
+#define test(x) do {retval = (x); \
+ if(retval != 0) { \
+ const char *errmsg = krb5_get_error_message(context, retval); \
+ fprintf(stderr, "Error message: %s\n", errmsg); \
+ abort(); } \
+ } while(0);
+
+krb5_authdata ad_fx_armor = {0, KRB5_AUTHDATA_FX_ARMOR, 1, ""};
+krb5_authdata *array[] = {&ad_fx_armor, NULL};
+
+
+int main( int argc, char **argv)
+{
+ krb5_context context;
+ krb5_ccache ccache = NULL;
+ krb5_creds creds, *out_creds = NULL;
+ krb5_error_code retval = 0;
+ test(krb5_init_context(&context));
+ memset(&creds, 0, sizeof(creds));
+ creds.authdata = array;
+ test(krb5_cc_default(context, &ccache));
+ test(krb5_cc_get_principal(context, ccache, &creds.client));
+ test(krb5_parse_name(context, argv[1], &creds.server));
+ test(krb5_get_credentials(context, 0, ccache, &creds, &out_creds));
+ test(krb5_cc_destroy(context, ccache));
+ test(krb5_cc_default(context, &ccache));
+ test(krb5_cc_initialize(context, ccache, out_creds->client));
+ test(krb5_cc_store_cred(context, ccache, out_creds));
+ test(krb5_cc_close(context,ccache));
+ return 0;
+
+}
krb5_pa_data **pa_array = NULL;
krb5_data *encoded_ts = NULL;
krb5_pa_enc_ts ts;
+ enc.ciphertext.data = NULL;
if (retval == 0)
retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec);
if (retval == 0)
}
if (armor_key)
krb5_free_keyblock(context, armor_key);
- if (challenge_key)
- krb5_free_keyblock(context, challenge_key);
if (plain.data)
free(plain.data);
if (enc)