diff options
author | Luke Howard <lukeh@padl.com> | 2009-11-15 15:28:27 +0000 |
---|---|---|
committer | Luke Howard <lukeh@padl.com> | 2009-11-15 15:28:27 +0000 |
commit | bd60d0606a42e0db3d53e6acc1509ecdf46c6270 (patch) | |
tree | 472e7a65b551a9947cb2fb8e0904568161542d32 | |
parent | 6c6ad2d802ce43ab484d306800e81846ad8fc17d (diff) | |
download | krb5-bd60d0606a42e0db3d53e6acc1509ecdf46c6270.zip krb5-bd60d0606a42e0db3d53e6acc1509ecdf46c6270.tar.gz krb5-bd60d0606a42e0db3d53e6acc1509ecdf46c6270.tar.bz2 |
checkpoint
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/iakerb@23196 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r-- | src/lib/gssapi/krb5/iakerb.c | 178 |
1 files changed, 145 insertions, 33 deletions
diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c index f0022aa..a716e49 100644 --- a/src/lib/gssapi/krb5/iakerb.c +++ b/src/lib/gssapi/krb5/iakerb.c @@ -129,6 +129,66 @@ iakerb_save_token(iakerb_ctx_id_t ctx, const gss_buffer_t token) } static krb5_error_code +iakerb_parse_token(iakerb_ctx_id_t ctx, + int initialContextToken, + const gss_buffer_t token, + krb5_data *realm, + krb5_data **cookie, + krb5_data *request) +{ + krb5_error_code code; + krb5_iakerb_header *iah = NULL; + unsigned int bodysize; + unsigned char *ptr; + int flags = 0; + krb5_data data; + + if (token == GSS_C_NO_BUFFER || token->length == 0) { + code = G_BAD_TOK_HEADER; + goto cleanup; + } + + if (initialContextToken) + flags |= G_VFY_TOKEN_HDR_WRAPPER_REQUIRED; + + code = g_verify_token_header(gss_mech_iakerb, + &bodysize, &ptr, + IAKERB_TOK_PROXY, + token->length, flags); + if (code != 0) + goto cleanup; + + data.data = (char *)ptr; + data.length = der_read_length(&ptr, &bodysize); + if (data.length < 0) { + code = G_BAD_TOK_HEADER; + goto cleanup; + } + + code = decode_krb5_iakerb_header(&data, &iah); + if (code != 0) + goto cleanup; + + if (realm != NULL) { + *realm = iah->target_realm; + iah->target_realm.data = NULL; + } + + if (cookie != NULL) { + *cookie = iah->cookie; + iah->cookie = NULL; + } + + request->data = ptr; + request->length = bodysize; + +cleanup: + krb5_free_iakerb_header(ctx->k5c, iah); + + return code; +} + +static krb5_error_code iakerb_make_token(iakerb_ctx_id_t ctx, krb5_data *realm, krb5_data *cookie, @@ -197,54 +257,86 @@ cleanup: } static krb5_error_code +iakerb_acceptor_step(iakerb_ctx_id_t ctx, + int initialContextToken, + const gss_buffer_t input_token, + gss_buffer_t output_token) +{ + krb5_error_code code; + krb5_data request, reply, realm; + unsigned int bodysize; + unsigned char *ptr; + krb5_iakerb_header *iah = NULL; + OM_uint32 tmp; + int responseTooBig = 0; + + output_token->length = 0; + output_token->value = NULL; + + request.data = NULL; + request.length = 0; + reply.data = NULL; + reply.length = 0; + realm.data = NULL; + realm.length = 0; + + code = iakerb_parse_token(ctx, + initialContextToken, + input_token, + &realm, + NULL, + &request); + if (code != 0) + goto cleanup; + + +cleanup: + if (code != 0) + gss_release_buffer(&tmp, output_token); + /* request is a pointer into input_token, no need to free */ + krb5_free_data_contents(ctx->k5c, &realm); + krb5_free_data_contents(ctx->k5c, &reply); + + return code; +} + +static krb5_error_code iakerb_initiator_step(iakerb_ctx_id_t ctx, krb5_gss_cred_id_t cred, const gss_buffer_t input_token, gss_buffer_t output_token) { krb5_error_code code; - krb5_data in, out, realm; + krb5_data in, out, realm, *cookie = NULL; unsigned int bodysize; unsigned char *ptr; - krb5_iakerb_header *iah = NULL; OM_uint32 tmp; + int initialContextToken = (input_token == GSS_C_NO_BUFFER); output_token->length = 0; output_token->value = NULL; - if (input_token != GSS_C_NO_BUFFER) { - code = g_verify_token_header(gss_mech_iakerb, - &bodysize, &ptr, IAKERB_TOK_PROXY, - input_token->length, 0); - if (code != 0) - goto cleanup; - - /* Now, ptr points into the IAKERB-HEADER. Decode that. */ - in.data = (char *)ptr; - in.length = der_read_length(&ptr, &bodysize); - if (in.length < 0) { - code = G_BAD_TOK_HEADER; - goto cleanup; - } - - code = decode_krb5_iakerb_header(&in, &iah); - if (code != 0) - goto cleanup; + in.data = NULL; + in.length = 0; + out.data = NULL; + out.length = 0; + realm.data = NULL; + realm.length = 0; - /* Now, ptr points into the Kerberos message. */ - in.data = (char *)ptr; - in.length = bodysize; - } else { + if (initialContextToken) { in.data = NULL; in.length = 0; + } else { + code = iakerb_parse_token(ctx, + 0, + input_token, + NULL, + &cookie, + &in); + if (code != 0) + goto cleanup; } - out.length = 0; - out.data = NULL; - - realm.length = 0; - realm.data = NULL; - code = krb5_init_creds_step(ctx->k5c, ctx->icc, &in, @@ -273,7 +365,7 @@ iakerb_initiator_step(iakerb_ctx_id_t ctx, } krb5_free_cred_contents(ctx->k5c, &creds); } else { - code = iakerb_make_token(ctx, &realm, iah ? iah->cookie : NULL, &out, + code = iakerb_make_token(ctx, &realm, cookie, &out, (input_token == GSS_C_NO_BUFFER), output_token); if (code != 0) @@ -288,7 +380,7 @@ iakerb_initiator_step(iakerb_ctx_id_t ctx, cleanup: if (code != 0) gss_release_buffer(&tmp, output_token); - krb5_free_iakerb_header(ctx->k5c, iah); + krb5_free_data(ctx->k5c, cookie); krb5_free_data_contents(ctx->k5c, &out); krb5_free_data_contents(ctx->k5c, &realm); @@ -387,7 +479,7 @@ iakerb_delete_sec_context(OM_uint32 *minor_status, OM_uint32 iakerb_accept_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handler, + gss_ctx_id_t *context_handle, gss_cred_id_t verifier_cred_handle, gss_buffer_t input_token, gss_channel_bindings_t input_chan_bindings, @@ -398,6 +490,24 @@ iakerb_accept_sec_context(OM_uint32 *minor_status, OM_uint32 *time_rec, gss_cred_id_t *delegated_cred_handle) { + OM_uint32 major_status = GSS_S_FAILURE; + OM_uint32 code; + iakerb_ctx_id_t ctx; + int initialContextToken = (*context_handle == GSS_C_NO_CONTEXT); + + if (initialContextToken) { + code = iakerb_alloc_context(&ctx); + if (code != 0) + goto cleanup; + } else + ctx = (iakerb_ctx_id_t)*context_handle; + +cleanup: + if (initialContextToken && ctx != NULL) + iakerb_release_context(ctx); + + *minor_status = code; + return major_status; } OM_uint32 @@ -460,6 +570,8 @@ iakerb_init_sec_context(OM_uint32 *minor_status, kcred, input_token, output_token); + if (code == G_BAD_TOK_HEADER) + major_status = GSS_S_DEFECTIVE_TOKEN; if (code != 0) goto cleanup; } |