From f7242f643763ccb6e10801af4ce53d0873e2d3e1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Jan 2007 01:57:32 +0000 Subject: r20640: Commit part 2/2 Update Heimdal to match current lorikeet-heimdal. This includes integrated PAC hooks, so Samba doesn't have to handle this any more. This also brings in the PKINIT code, hence so many new files. Andrew Bartlett (This used to be commit 351f7040f7bb73b9a60b22b564686f7c2f98a729) --- source4/heimdal/lib/gssapi/gssapi/gssapi.h | 8 +- source4/heimdal/lib/gssapi/gssapi_mech.h | 1 + .../heimdal/lib/gssapi/krb5/accept_sec_context.c | 143 ++- source4/heimdal/lib/gssapi/krb5/acquire_cred.c | 112 +-- source4/heimdal/lib/gssapi/krb5/add_cred.c | 31 +- .../heimdal/lib/gssapi/krb5/address_to_krb5addr.c | 7 +- source4/heimdal/lib/gssapi/krb5/arcfour.c | 56 +- source4/heimdal/lib/gssapi/krb5/cfx.c | 133 ++- source4/heimdal/lib/gssapi/krb5/cfx.h | 17 +- source4/heimdal/lib/gssapi/krb5/compare_name.c | 7 +- source4/heimdal/lib/gssapi/krb5/compat.c | 23 +- source4/heimdal/lib/gssapi/krb5/context_time.c | 16 +- source4/heimdal/lib/gssapi/krb5/copy_ccache.c | 38 +- .../heimdal/lib/gssapi/krb5/delete_sec_context.c | 15 +- source4/heimdal/lib/gssapi/krb5/display_name.c | 9 +- source4/heimdal/lib/gssapi/krb5/display_status.c | 168 ++-- source4/heimdal/lib/gssapi/krb5/duplicate_name.c | 8 +- source4/heimdal/lib/gssapi/krb5/export_name.c | 9 +- .../heimdal/lib/gssapi/krb5/export_sec_context.c | 5 +- source4/heimdal/lib/gssapi/krb5/external.c | 4 +- source4/heimdal/lib/gssapi/krb5/get_mic.c | 50 +- source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h | 34 +- source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h | 8 +- source4/heimdal/lib/gssapi/krb5/import_name.c | 24 +- .../heimdal/lib/gssapi/krb5/import_sec_context.c | 36 +- source4/heimdal/lib/gssapi/krb5/init.c | 86 +- source4/heimdal/lib/gssapi/krb5/init_sec_context.c | 130 +-- source4/heimdal/lib/gssapi/krb5/inquire_context.c | 6 +- source4/heimdal/lib/gssapi/krb5/inquire_cred.c | 10 +- .../heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c | 8 +- .../lib/gssapi/krb5/inquire_sec_context_by_oid.c | 49 +- .../lib/gssapi/krb5/process_context_token.c | 6 +- source4/heimdal/lib/gssapi/krb5/release_cred.c | 15 +- source4/heimdal/lib/gssapi/krb5/release_name.c | 9 +- source4/heimdal/lib/gssapi/krb5/set_cred_option.c | 21 +- .../lib/gssapi/krb5/set_sec_context_option.c | 15 +- source4/heimdal/lib/gssapi/krb5/unwrap.c | 43 +- source4/heimdal/lib/gssapi/krb5/verify_mic.c | 47 +- source4/heimdal/lib/gssapi/krb5/wrap.c | 109 +-- .../lib/gssapi/mech/gss_accept_sec_context.c | 13 +- .../heimdal/lib/gssapi/mech/gss_init_sec_context.c | 30 +- source4/heimdal/lib/gssapi/mech/gss_mech_switch.c | 5 +- .../heimdal/lib/gssapi/mech/gss_set_cred_option.c | 4 +- source4/heimdal/lib/gssapi/mech/gss_utils.c | 13 +- source4/heimdal/lib/gssapi/mech/utils.h | 3 +- .../heimdal/lib/gssapi/spnego/accept_sec_context.c | 978 ++++++++++++--------- source4/heimdal/lib/gssapi/spnego/compat.c | 154 ++-- source4/heimdal/lib/gssapi/spnego/context_stubs.c | 88 +- .../heimdal/lib/gssapi/spnego/init_sec_context.c | 219 +++-- source4/heimdal/lib/gssapi/spnego/spnego-private.h | 25 +- source4/heimdal/lib/gssapi/spnego/spnego.asn1 | 17 +- source4/heimdal/lib/gssapi/spnego/spnego_locl.h | 27 +- 52 files changed, 1745 insertions(+), 1347 deletions(-) (limited to 'source4/heimdal/lib/gssapi') diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index f89e5dfbee..8077aeb223 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gssapi.h,v 1.6 2006/11/10 00:39:50 lha Exp $ */ +/* $Id: gssapi.h,v 1.7 2006/12/15 20:02:54 lha Exp $ */ #ifndef GSSAPI_GSSAPI_H_ #define GSSAPI_GSSAPI_H_ @@ -300,6 +300,12 @@ extern gss_OID GSS_C_NT_EXPORT_NAME; extern gss_OID GSS_SASL_DIGEST_MD5_MECHANISM; +/* + * NTLM mechanism + */ + +extern gss_OID GSS_NTLM_MECHANISM; + /* Major status codes */ #define GSS_S_COMPLETE 0 diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h index a05919b510..2bb5ecedf5 100644 --- a/source4/heimdal/lib/gssapi/gssapi_mech.h +++ b/source4/heimdal/lib/gssapi/gssapi_mech.h @@ -344,5 +344,6 @@ __gss_get_mechanism(gss_OID /* oid */); gssapi_mech_interface __gss_spnego_initialize(void); gssapi_mech_interface __gss_krb5_initialize(void); +gssapi_mech_interface __gss_ntlm_initialize(void); #endif /* GSSAPI_MECH_H */ diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index 6ac80461c3..434fbee352 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: accept_sec_context.c,v 1.65 2006/11/07 14:52:05 lha Exp $"); +RCSID("$Id: accept_sec_context.c,v 1.66 2006/11/13 18:00:54 lha Exp $"); HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; krb5_keytab _gsskrb5_keytab; @@ -41,20 +41,21 @@ krb5_keytab _gsskrb5_keytab; OM_uint32 _gsskrb5_register_acceptor_identity (const char *identity) { + krb5_context context; krb5_error_code ret; - ret = _gsskrb5_init(); + ret = _gsskrb5_init(&context); if(ret) return GSS_S_FAILURE; HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); if(_gsskrb5_keytab != NULL) { - krb5_kt_close(_gsskrb5_context, _gsskrb5_keytab); + krb5_kt_close(context, _gsskrb5_keytab); _gsskrb5_keytab = NULL; } if (identity == NULL) { - ret = krb5_kt_default(_gsskrb5_context, &_gsskrb5_keytab); + ret = krb5_kt_default(context, &_gsskrb5_keytab); } else { char *p; @@ -63,7 +64,7 @@ _gsskrb5_register_acceptor_identity (const char *identity) HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); return GSS_S_FAILURE; } - ret = krb5_kt_resolve(_gsskrb5_context, p, &_gsskrb5_keytab); + ret = krb5_kt_resolve(context, p, &_gsskrb5_keytab); free(p); } HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); @@ -120,6 +121,7 @@ static OM_uint32 gsskrb5_accept_delegated_token (OM_uint32 * minor_status, gsskrb5_ctx ctx, + krb5_context context, gss_cred_id_t * delegated_cred_handle ) { @@ -131,33 +133,31 @@ gsskrb5_accept_delegated_token /* XXX Create a new delegated_cred_handle? */ if (delegated_cred_handle == NULL) { - kret = krb5_cc_default (_gsskrb5_context, &ccache); + kret = krb5_cc_default (context, &ccache); } else { *delegated_cred_handle = NULL; - kret = krb5_cc_gen_new (_gsskrb5_context, &krb5_mcc_ops, &ccache); + kret = krb5_cc_gen_new (context, &krb5_mcc_ops, &ccache); } if (kret) { ctx->flags &= ~GSS_C_DELEG_FLAG; goto out; } - kret = krb5_cc_initialize(_gsskrb5_context, ccache, ctx->source); + kret = krb5_cc_initialize(context, ccache, ctx->source); if (kret) { ctx->flags &= ~GSS_C_DELEG_FLAG; goto out; } - krb5_auth_con_removeflags(_gsskrb5_context, + krb5_auth_con_removeflags(context, ctx->auth_context, KRB5_AUTH_CONTEXT_DO_TIME, &ac_flags); - kret = krb5_rd_cred2(_gsskrb5_context, + kret = krb5_rd_cred2(context, ctx->auth_context, ccache, &ctx->fwd_data); - if (kret) - _gsskrb5_set_error_string(); - krb5_auth_con_setflags(_gsskrb5_context, + krb5_auth_con_setflags(context, ctx->auth_context, ac_flags); if (kret) { @@ -181,16 +181,16 @@ gsskrb5_accept_delegated_token handle = (gsskrb5_cred) *delegated_cred_handle; handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; - krb5_cc_close(_gsskrb5_context, ccache); + krb5_cc_close(context, ccache); ccache = NULL; } out: if (ccache) { if (delegated_cred_handle == NULL) - krb5_cc_close(_gsskrb5_context, ccache); + krb5_cc_close(context, ccache); else - krb5_cc_destroy(_gsskrb5_context, ccache); + krb5_cc_destroy(context, ccache); } return ret; } @@ -198,13 +198,14 @@ out: static OM_uint32 gsskrb5_acceptor_ready(OM_uint32 * minor_status, gsskrb5_ctx ctx, + krb5_context context, gss_cred_id_t *delegated_cred_handle) { OM_uint32 ret; int32_t seq_number; int is_cfx = 0; - krb5_auth_getremoteseqnumber (_gsskrb5_context, + krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number); @@ -222,7 +223,7 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status, * isn't a mutual authentication context */ if (!(ctx->flags & GSS_C_MUTUAL_FLAG) && _gssapi_msg_order_f(ctx->flags)) { - krb5_auth_con_setlocalseqnumber(_gsskrb5_context, + krb5_auth_con_setlocalseqnumber(context, ctx->auth_context, seq_number); } @@ -233,6 +234,7 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status, if (ctx->fwd_data.length > 0 && (ctx->flags & GSS_C_DELEG_FLAG)) { ret = gsskrb5_accept_delegated_token(minor_status, ctx, + context, delegated_cred_handle); if (ret) return ret; @@ -250,6 +252,7 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status, static OM_uint32 gsskrb5_acceptor_start(OM_uint32 * minor_status, gsskrb5_ctx ctx, + krb5_context context, const gss_cred_id_t acceptor_cred_handle, const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, @@ -301,49 +304,46 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, krb5_rd_req_in_ctx in = NULL; krb5_rd_req_out_ctx out = NULL; - kret = krb5_rd_req_in_ctx_alloc(_gsskrb5_context, &in); + kret = krb5_rd_req_in_ctx_alloc(context, &in); if (kret == 0) - kret = krb5_rd_req_in_set_keytab(_gsskrb5_context, in, keytab); + kret = krb5_rd_req_in_set_keytab(context, in, keytab); if (kret) { if (in) - krb5_rd_req_in_ctx_free(_gsskrb5_context, in); + krb5_rd_req_in_ctx_free(context, in); ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } - kret = krb5_rd_req_ctx(_gsskrb5_context, + kret = krb5_rd_req_ctx(context, &ctx->auth_context, &indata, (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) ? NULL : acceptor_cred->principal, in, &out); - krb5_rd_req_in_ctx_free(_gsskrb5_context, in); + krb5_rd_req_in_ctx_free(context, in); if (kret) { ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } /* * We need to remember some data on the context_handle. */ - kret = krb5_rd_req_out_get_ap_req_options(_gsskrb5_context, out, + kret = krb5_rd_req_out_get_ap_req_options(context, out, &ap_options); if (kret == 0) - kret = krb5_rd_req_out_get_ticket(_gsskrb5_context, out, + kret = krb5_rd_req_out_get_ticket(context, out, &ctx->ticket); if (kret == 0) - kret = krb5_rd_req_out_get_keyblock(_gsskrb5_context, out, + kret = krb5_rd_req_out_get_keyblock(context, out, &ctx->service_keyblock); ctx->lifetime = ctx->ticket->ticket.endtime; - krb5_rd_req_out_ctx_free(_gsskrb5_context, out); + krb5_rd_req_out_ctx_free(context, out); if (kret) { ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } } @@ -353,22 +353,20 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, * We need to copy the principal names to the context and the * calling layer. */ - kret = krb5_copy_principal(_gsskrb5_context, + kret = krb5_copy_principal(context, ctx->ticket->client, &ctx->source); if (kret) { ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); } - kret = krb5_copy_principal(_gsskrb5_context, + kret = krb5_copy_principal(context, ctx->ticket->server, &ctx->target); if (kret) { ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } @@ -376,18 +374,17 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, * We need to setup some compat stuff, this assumes that * context_handle->target is already set. */ - ret = _gss_DES3_get_mic_compat(minor_status, ctx); + ret = _gss_DES3_get_mic_compat(minor_status, ctx, context); if (ret) return ret; if (src_name != NULL) { - kret = krb5_copy_principal (_gsskrb5_context, + kret = krb5_copy_principal (context, ctx->ticket->client, (gsskrb5_name*)src_name); if (kret) { ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } } @@ -398,13 +395,12 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, { krb5_authenticator authenticator; - kret = krb5_auth_con_getauthenticator(_gsskrb5_context, + kret = krb5_auth_con_getauthenticator(context, ctx->auth_context, &authenticator); if(kret) { ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } @@ -415,22 +411,21 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, &ctx->flags, &ctx->fwd_data); - krb5_free_authenticator(_gsskrb5_context, &authenticator); + krb5_free_authenticator(context, &authenticator); if (ret) { return ret; } } else { krb5_crypto crypto; - kret = krb5_crypto_init(_gsskrb5_context, + kret = krb5_crypto_init(context, ctx->auth_context->keyblock, 0, &crypto); if(kret) { - krb5_free_authenticator(_gsskrb5_context, &authenticator); + krb5_free_authenticator(context, &authenticator); ret = GSS_S_FAILURE; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } @@ -439,16 +434,15 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, * GSSAPI checksum here */ - kret = krb5_verify_checksum(_gsskrb5_context, + kret = krb5_verify_checksum(context, crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0, authenticator->cksum); - krb5_free_authenticator(_gsskrb5_context, &authenticator); - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_free_authenticator(context, &authenticator); + krb5_crypto_destroy(context, crypto); if(kret) { ret = GSS_S_BAD_SIG; *minor_status = kret; - _gsskrb5_set_error_string (); return ret; } @@ -467,23 +461,22 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, if (is_cfx != 0 || (ap_options & AP_OPTS_USE_SUBKEY)) { - kret = krb5_auth_con_addflags(_gsskrb5_context, + kret = krb5_auth_con_addflags(context, ctx->auth_context, KRB5_AUTH_CONTEXT_USE_SUBKEY, NULL); ctx->more_flags |= ACCEPTOR_SUBKEY; } - kret = krb5_mk_rep(_gsskrb5_context, + kret = krb5_mk_rep(context, ctx->auth_context, &outbuf); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } - if (ctx->flags & GSS_C_DCE_STYLE) { + if (IS_DCE_STYLE(ctx)) { output_token->length = outbuf.length; output_token->value = outbuf.data; } else { @@ -510,6 +503,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, if (time_rec) { ret = _gsskrb5_lifetime_left(minor_status, + context, ctx->lifetime, time_rec); if (ret) { @@ -521,7 +515,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, * When GSS_C_DCE_STYLE is in use, we need ask for a AP-REP from * the client. */ - if (ctx->flags & GSS_C_DCE_STYLE) { + if (IS_DCE_STYLE(ctx)) { /* * Return flags to caller, but we haven't processed * delgations yet @@ -533,7 +527,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, return GSS_S_CONTINUE_NEEDED; } - ret = gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle); + ret = gsskrb5_acceptor_ready(minor_status, ctx, context, + delegated_cred_handle); if (ret_flags) *ret_flags = ctx->flags; @@ -544,6 +539,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, static OM_uint32 acceptor_wait_for_dcestyle(OM_uint32 * minor_status, gsskrb5_ctx ctx, + krb5_context context, const gss_cred_id_t acceptor_cred_handle, const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, @@ -572,29 +568,26 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status, * the remote seq_number to the old value */ { - kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context, + kret = krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &l_seq_number); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - kret = krb5_auth_getremoteseqnumber(_gsskrb5_context, + kret = krb5_auth_getremoteseqnumber(context, ctx->auth_context, &r_seq_number); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context, + kret = krb5_auth_con_setremoteseqnumber(context, ctx->auth_context, l_seq_number); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -609,19 +602,18 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status, krb5_ap_rep_enc_part *repl; int32_t auth_flags; - krb5_auth_con_removeflags(_gsskrb5_context, + krb5_auth_con_removeflags(context, ctx->auth_context, KRB5_AUTH_CONTEXT_DO_TIME, &auth_flags); - kret = krb5_rd_rep(_gsskrb5_context, ctx->auth_context, &inbuf, &repl); + kret = krb5_rd_rep(context, ctx->auth_context, &inbuf, &repl); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - krb5_free_ap_rep_enc_part(_gsskrb5_context, repl); - krb5_auth_con_setflags(_gsskrb5_context, ctx->auth_context, auth_flags); + krb5_free_ap_rep_enc_part(context, repl); + krb5_auth_con_setflags(context, ctx->auth_context, auth_flags); } /* We need to check the liftime */ @@ -629,6 +621,7 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status, OM_uint32 lifetime_rec; ret = _gsskrb5_lifetime_left(minor_status, + context, ctx->lifetime, &lifetime_rec); if (ret) { @@ -645,12 +638,11 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status, if (ret_flags) *ret_flags = ctx->flags; if (src_name) { - kret = krb5_copy_principal(_gsskrb5_context, + kret = krb5_copy_principal(context, ctx->source, (gsskrb5_name*)src_name); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } } @@ -664,20 +656,19 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status, { int32_t tmp_r_seq_number, tmp_l_seq_number; - kret = krb5_auth_getremoteseqnumber(_gsskrb5_context, + kret = krb5_auth_getremoteseqnumber(context, ctx->auth_context, &tmp_r_seq_number); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - kret = krb5_auth_con_getlocalseqnumber(_gsskrb5_context, + kret = krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &tmp_l_seq_number); if (kret) { - _gsskrb5_set_error_string (); + *minor_status = kret; return GSS_S_FAILURE; } @@ -695,17 +686,17 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status, * the old one for the GSS_wrap() calls */ { - kret = krb5_auth_con_setremoteseqnumber(_gsskrb5_context, + kret = krb5_auth_con_setremoteseqnumber(context, ctx->auth_context, r_seq_number); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } } - return gsskrb5_acceptor_ready(minor_status, ctx, delegated_cred_handle); + return gsskrb5_acceptor_ready(minor_status, ctx, context, + delegated_cred_handle); } @@ -722,10 +713,11 @@ _gsskrb5_accept_sec_context(OM_uint32 * minor_status, OM_uint32 * time_rec, gss_cred_id_t * delegated_cred_handle) { + krb5_context context; OM_uint32 ret; gsskrb5_ctx ctx; - GSSAPI_KRB5_INIT(); + GSSAPI_KRB5_INIT(&context); output_token->length = 0; output_token->value = NULL; @@ -738,6 +730,7 @@ _gsskrb5_accept_sec_context(OM_uint32 * minor_status, if (*context_handle == GSS_C_NO_CONTEXT) { ret = _gsskrb5_create_ctx(minor_status, context_handle, + context, input_chan_bindings, ACCEPTOR_START); if (ret) @@ -758,6 +751,7 @@ _gsskrb5_accept_sec_context(OM_uint32 * minor_status, case ACCEPTOR_START: ret = gsskrb5_acceptor_start(minor_status, ctx, + context, acceptor_cred_handle, input_token_buffer, input_chan_bindings, @@ -771,6 +765,7 @@ _gsskrb5_accept_sec_context(OM_uint32 * minor_status, case ACCEPTOR_WAIT_FOR_DCESTYLE: ret = acceptor_wait_for_dcestyle(minor_status, ctx, + context, acceptor_cred_handle, input_token_buffer, input_chan_bindings, diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c index df6e137402..e811a99a8b 100644 --- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c @@ -33,13 +33,14 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: acquire_cred.c,v 1.31 2006/10/07 22:13:55 lha Exp $"); +RCSID("$Id: acquire_cred.c,v 1.33 2006/11/20 18:09:30 lha Exp $"); OM_uint32 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, - krb5_ccache id, - krb5_principal principal, - OM_uint32 *lifetime) + krb5_context context, + krb5_ccache id, + krb5_principal principal, + OM_uint32 *lifetime) { krb5_creds in_cred, *out_cred; krb5_const_realm realm; @@ -48,32 +49,30 @@ __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, memset(&in_cred, 0, sizeof(in_cred)); in_cred.client = principal; - realm = krb5_principal_get_realm(_gsskrb5_context, principal); + realm = krb5_principal_get_realm(context, principal); if (realm == NULL) { _gsskrb5_clear_status (); *minor_status = KRB5_PRINC_NOMATCH; /* XXX */ return GSS_S_FAILURE; } - kret = krb5_make_principal(_gsskrb5_context, &in_cred.server, + kret = krb5_make_principal(context, &in_cred.server, realm, KRB5_TGS_NAME, realm, NULL); if (kret) { - _gsskrb5_set_error_string(); *minor_status = kret; return GSS_S_FAILURE; } - kret = krb5_get_credentials(_gsskrb5_context, 0, + kret = krb5_get_credentials(context, 0, id, &in_cred, &out_cred); - krb5_free_principal(_gsskrb5_context, in_cred.server); + krb5_free_principal(context, in_cred.server); if (kret) { - _gsskrb5_set_error_string(); *minor_status = kret; return GSS_S_FAILURE; } *lifetime = out_cred->times.endtime; - krb5_free_creds(_gsskrb5_context, out_cred); + krb5_free_creds(context, out_cred); return GSS_S_COMPLETE; } @@ -82,7 +81,7 @@ __gsskrb5_ccache_lifetime(OM_uint32 *minor_status, static krb5_error_code -get_keytab(krb5_keytab *keytab) +get_keytab(krb5_context context, krb5_keytab *keytab) { char kt_name[256]; krb5_error_code kret; @@ -90,13 +89,13 @@ get_keytab(krb5_keytab *keytab) HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); if (_gsskrb5_keytab != NULL) { - kret = krb5_kt_get_name(_gsskrb5_context, + kret = krb5_kt_get_name(context, _gsskrb5_keytab, kt_name, sizeof(kt_name)); if (kret == 0) - kret = krb5_kt_resolve(_gsskrb5_context, kt_name, keytab); + kret = krb5_kt_resolve(context, kt_name, keytab); } else - kret = krb5_kt_default(_gsskrb5_context, keytab); + kret = krb5_kt_default(context, keytab); HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); @@ -105,6 +104,7 @@ get_keytab(krb5_keytab *keytab) static OM_uint32 acquire_initiator_cred (OM_uint32 * minor_status, + krb5_context context, const gss_name_t desired_name, OM_uint32 time_req, const gss_OID_set desired_mechs, @@ -132,33 +132,33 @@ static OM_uint32 acquire_initiator_cred * caches, otherwise, fall back to default cache. Ignore * errors. */ if (handle->principal) - kret = krb5_cc_cache_match (_gsskrb5_context, + kret = krb5_cc_cache_match (context, handle->principal, NULL, &ccache); if (ccache == NULL) { - kret = krb5_cc_default(_gsskrb5_context, &ccache); + kret = krb5_cc_default(context, &ccache); if (kret) goto end; } - kret = krb5_cc_get_principal(_gsskrb5_context, ccache, + kret = krb5_cc_get_principal(context, ccache, &def_princ); if (kret != 0) { /* we'll try to use a keytab below */ - krb5_cc_destroy(_gsskrb5_context, ccache); + krb5_cc_destroy(context, ccache); ccache = NULL; kret = 0; } else if (handle->principal == NULL) { - kret = krb5_copy_principal(_gsskrb5_context, def_princ, + kret = krb5_copy_principal(context, def_princ, &handle->principal); if (kret) goto end; } else if (handle->principal != NULL && - krb5_principal_compare(_gsskrb5_context, handle->principal, + krb5_principal_compare(context, handle->principal, def_princ) == FALSE) { /* Before failing, lets check the keytab */ - krb5_free_principal(_gsskrb5_context, def_princ); + krb5_free_principal(context, def_princ); def_princ = NULL; } if (def_princ == NULL) { @@ -166,30 +166,30 @@ static OM_uint32 acquire_initiator_cred * so attempt to get a TGT using a keytab. */ if (handle->principal == NULL) { - kret = krb5_get_default_principal(_gsskrb5_context, + kret = krb5_get_default_principal(context, &handle->principal); if (kret) goto end; } - kret = get_keytab(&keytab); + kret = get_keytab(context, &keytab); if (kret) goto end; - kret = krb5_get_init_creds_opt_alloc(_gsskrb5_context, &opt); + kret = krb5_get_init_creds_opt_alloc(context, &opt); if (kret) goto end; - kret = krb5_get_init_creds_keytab(_gsskrb5_context, &cred, + kret = krb5_get_init_creds_keytab(context, &cred, handle->principal, keytab, 0, NULL, opt); - krb5_get_init_creds_opt_free(opt); + krb5_get_init_creds_opt_free(context, opt); if (kret) goto end; - kret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops, + kret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache); if (kret) goto end; - kret = krb5_cc_initialize(_gsskrb5_context, ccache, cred.client); + kret = krb5_cc_initialize(context, ccache, cred.client); if (kret) goto end; - kret = krb5_cc_store_cred(_gsskrb5_context, ccache, &cred); + kret = krb5_cc_store_cred(context, ccache, &cred); if (kret) goto end; handle->lifetime = cred.times.endtime; @@ -197,9 +197,10 @@ static OM_uint32 acquire_initiator_cred } else { ret = __gsskrb5_ccache_lifetime(minor_status, - ccache, - handle->principal, - &handle->lifetime); + context, + ccache, + handle->principal, + &handle->lifetime); if (ret != GSS_S_COMPLETE) goto end; kret = 0; @@ -210,17 +211,16 @@ static OM_uint32 acquire_initiator_cred end: if (cred.client != NULL) - krb5_free_cred_contents(_gsskrb5_context, &cred); + krb5_free_cred_contents(context, &cred); if (def_princ != NULL) - krb5_free_principal(_gsskrb5_context, def_princ); + krb5_free_principal(context, def_princ); if (keytab != NULL) - krb5_kt_close(_gsskrb5_context, keytab); + krb5_kt_close(context, keytab); if (ret != GSS_S_COMPLETE) { if (ccache != NULL) - krb5_cc_close(_gsskrb5_context, ccache); + krb5_cc_close(context, ccache); if (kret != 0) { *minor_status = kret; - _gsskrb5_set_error_string (); } } return (ret); @@ -228,6 +228,7 @@ end: static OM_uint32 acquire_acceptor_cred (OM_uint32 * minor_status, + krb5_context context, const gss_name_t desired_name, OM_uint32 time_req, const gss_OID_set desired_mechs, @@ -242,7 +243,7 @@ static OM_uint32 acquire_acceptor_cred kret = 0; ret = GSS_S_FAILURE; - kret = get_keytab(&handle->keytab); + kret = get_keytab(context, &handle->keytab); if (kret) goto end; @@ -250,21 +251,20 @@ static OM_uint32 acquire_acceptor_cred if (handle->principal) { krb5_keytab_entry entry; - kret = krb5_kt_get_entry(_gsskrb5_context, handle->keytab, + kret = krb5_kt_get_entry(context, handle->keytab, handle->principal, 0, 0, &entry); if (kret) goto end; - krb5_kt_free_entry(_gsskrb5_context, &entry); + krb5_kt_free_entry(context, &entry); } ret = GSS_S_COMPLETE; end: if (ret != GSS_S_COMPLETE) { if (handle->keytab != NULL) - krb5_kt_close(_gsskrb5_context, handle->keytab); + krb5_kt_close(context, handle->keytab); if (kret != 0) { *minor_status = kret; - _gsskrb5_set_error_string (); } } return (ret); @@ -281,6 +281,7 @@ OM_uint32 _gsskrb5_acquire_cred OM_uint32 * time_rec ) { + krb5_context context; gsskrb5_cred handle; OM_uint32 ret; @@ -289,7 +290,7 @@ OM_uint32 _gsskrb5_acquire_cred return GSS_S_FAILURE; } - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT(&context); *output_cred_handle = NULL; if (time_rec) @@ -320,31 +321,33 @@ OM_uint32 _gsskrb5_acquire_cred if (desired_name != GSS_C_NO_NAME) { krb5_principal name = (krb5_principal)desired_name; - ret = krb5_copy_principal(_gsskrb5_context, name, &handle->principal); + ret = krb5_copy_principal(context, name, &handle->principal); if (ret) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); - _gsskrb5_set_error_string(); *minor_status = ret; free(handle); return GSS_S_FAILURE; } } if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) { - ret = acquire_initiator_cred(minor_status, desired_name, time_req, - desired_mechs, cred_usage, handle, actual_mechs, time_rec); + ret = acquire_initiator_cred(minor_status, context, + desired_name, time_req, + desired_mechs, cred_usage, handle, + actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); - krb5_free_principal(_gsskrb5_context, handle->principal); + krb5_free_principal(context, handle->principal); free(handle); return (ret); } } if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) { - ret = acquire_acceptor_cred(minor_status, desired_name, time_req, + ret = acquire_acceptor_cred(minor_status, context, + desired_name, time_req, desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); - krb5_free_principal(_gsskrb5_context, handle->principal); + krb5_free_principal(context, handle->principal); free(handle); return (ret); } @@ -360,15 +363,16 @@ OM_uint32 _gsskrb5_acquire_cred if (handle->mechanisms != NULL) _gsskrb5_release_oid_set(NULL, &handle->mechanisms); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); - krb5_free_principal(_gsskrb5_context, handle->principal); + krb5_free_principal(context, handle->principal); free(handle); return (ret); } *minor_status = 0; if (time_rec) { ret = _gsskrb5_lifetime_left(minor_status, - handle->lifetime, - time_rec); + context, + handle->lifetime, + time_rec); if (ret) return ret; diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c index 4892e84798..3b0272af80 100644 --- a/source4/heimdal/lib/gssapi/krb5/add_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: add_cred.c,v 1.9 2006/10/07 22:13:58 lha Exp $"); +RCSID("$Id: add_cred.c,v 1.10 2006/11/13 18:01:01 lha Exp $"); OM_uint32 _gsskrb5_add_cred ( OM_uint32 *minor_status, @@ -48,6 +48,7 @@ OM_uint32 _gsskrb5_add_cred ( OM_uint32 *initiator_time_rec, OM_uint32 *acceptor_time_rec) { + krb5_context context; OM_uint32 ret, lifetime; gsskrb5_cred cred, handle; krb5_const_principal dname; @@ -56,6 +57,8 @@ OM_uint32 _gsskrb5_add_cred ( cred = (gsskrb5_cred)input_cred_handle; dname = (krb5_const_principal)desired_name; + GSSAPI_KRB5_INIT (&context); + if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) { *minor_status = 0; return GSS_S_BAD_MECH; @@ -83,7 +86,7 @@ OM_uint32 _gsskrb5_add_cred ( /* check that we have the same name */ if (dname != NULL && - krb5_principal_compare(_gsskrb5_context, dname, + krb5_principal_compare(context, dname, cred->principal) != FALSE) { if (output_cred_handle) HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); @@ -112,7 +115,7 @@ OM_uint32 _gsskrb5_add_cred ( ret = GSS_S_FAILURE; - kret = krb5_copy_principal(_gsskrb5_context, cred->principal, + kret = krb5_copy_principal(context, cred->principal, &handle->principal); if (kret) { HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); @@ -127,7 +130,7 @@ OM_uint32 _gsskrb5_add_cred ( ret = GSS_S_FAILURE; - kret = krb5_kt_get_type(_gsskrb5_context, cred->keytab, + kret = krb5_kt_get_type(context, cred->keytab, name, KRB5_KT_PREFIX_MAX_LEN); if (kret) { *minor_status = kret; @@ -136,7 +139,7 @@ OM_uint32 _gsskrb5_add_cred ( len = strlen(name); name[len++] = ':'; - kret = krb5_kt_get_name(_gsskrb5_context, cred->keytab, + kret = krb5_kt_get_name(context, cred->keytab, name + len, sizeof(name) - len); if (kret) { @@ -144,7 +147,7 @@ OM_uint32 _gsskrb5_add_cred ( goto failure; } - kret = krb5_kt_resolve(_gsskrb5_context, name, + kret = krb5_kt_resolve(context, name, &handle->keytab); if (kret){ *minor_status = kret; @@ -158,21 +161,21 @@ OM_uint32 _gsskrb5_add_cred ( ret = GSS_S_FAILURE; - type = krb5_cc_get_type(_gsskrb5_context, cred->ccache); + type = krb5_cc_get_type(context, cred->ccache); if (type == NULL){ *minor_status = ENOMEM; goto failure; } if (strcmp(type, "MEMORY") == 0) { - ret = krb5_cc_gen_new(_gsskrb5_context, &krb5_mcc_ops, + ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &handle->ccache); if (ret) { *minor_status = ret; goto failure; } - ret = krb5_cc_copy_cache(_gsskrb5_context, cred->ccache, + ret = krb5_cc_copy_cache(context, cred->ccache, handle->ccache); if (ret) { *minor_status = ret; @@ -180,7 +183,7 @@ OM_uint32 _gsskrb5_add_cred ( } } else { - name = krb5_cc_get_name(_gsskrb5_context, cred->ccache); + name = krb5_cc_get_name(context, cred->ccache); if (name == NULL) { *minor_status = ENOMEM; goto failure; @@ -192,7 +195,7 @@ OM_uint32 _gsskrb5_add_cred ( goto failure; } - kret = krb5_cc_resolve(_gsskrb5_context, type_name, + kret = krb5_cc_resolve(context, type_name, &handle->ccache); free(type_name); if (kret) { @@ -234,11 +237,11 @@ OM_uint32 _gsskrb5_add_cred ( if (handle) { if (handle->principal) - krb5_free_principal(_gsskrb5_context, handle->principal); + krb5_free_principal(context, handle->principal); if (handle->keytab) - krb5_kt_close(_gsskrb5_context, handle->keytab); + krb5_kt_close(context, handle->keytab); if (handle->ccache) - krb5_cc_destroy(_gsskrb5_context, handle->ccache); + krb5_cc_destroy(context, handle->ccache); if (handle->mechanisms) _gsskrb5_release_oid_set(NULL, &handle->mechanisms); free(handle); diff --git a/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c b/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c index 9aec53faaa..18a90fe9a7 100644 --- a/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c +++ b/source4/heimdal/lib/gssapi/krb5/address_to_krb5addr.c @@ -36,7 +36,8 @@ #include krb5_error_code -_gsskrb5i_address_to_krb5addr(OM_uint32 gss_addr_type, +_gsskrb5i_address_to_krb5addr(krb5_context context, + OM_uint32 gss_addr_type, gss_buffer_desc *gss_addr, int16_t port, krb5_address *address) @@ -61,7 +62,7 @@ _gsskrb5i_address_to_krb5addr(OM_uint32 gss_addr_type, return GSS_S_FAILURE; } - problem = krb5_h_addr2sockaddr (_gsskrb5_context, + problem = krb5_h_addr2sockaddr (context, addr_type, gss_addr->value, &sa, @@ -70,7 +71,7 @@ _gsskrb5i_address_to_krb5addr(OM_uint32 gss_addr_type, if (problem) return GSS_S_FAILURE; - problem = krb5_sockaddr2address (_gsskrb5_context, &sa, address); + problem = krb5_sockaddr2address (context, &sa, address); return problem; } diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c index 2c43ed8b32..d1bdbb641f 100644 --- a/source4/heimdal/lib/gssapi/krb5/arcfour.c +++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: arcfour.c,v 1.30 2006/11/07 19:05:16 lha Exp $"); +RCSID("$Id: arcfour.c,v 1.31 2006/11/13 18:01:08 lha Exp $"); /* * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt @@ -114,7 +114,8 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key, static krb5_error_code -arcfour_mic_cksum(krb5_keyblock *key, unsigned usage, +arcfour_mic_cksum(krb5_context context, + krb5_keyblock *key, unsigned usage, u_char *sgn_cksum, size_t sgn_cksum_sz, const u_char *v1, size_t l1, const void *v2, size_t l2, @@ -138,13 +139,13 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage, memcpy(ptr + l1, v2, l2); memcpy(ptr + l1 + l2, v3, l3); - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) { free(ptr); return ret; } - ret = krb5_create_checksum(_gsskrb5_context, + ret = krb5_create_checksum(context, crypto, usage, 0, @@ -155,7 +156,7 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage, memcpy(sgn_cksum, CKSUM.checksum.data, sgn_cksum_sz); free_Checksum(&CKSUM); } - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return ret; } @@ -164,6 +165,7 @@ arcfour_mic_cksum(krb5_keyblock *key, unsigned usage, OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, + krb5_context context, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -200,7 +202,8 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status, p = NULL; - ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SIGN, + ret = arcfour_mic_cksum(context, + key, KRB5_KU_USAGE_SIGN, p0 + 16, 8, /* SGN_CKSUM */ p0, 8, /* TOK_ID, SGN_ALG, Filer */ message_buffer->value, message_buffer->length, @@ -211,7 +214,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status, return GSS_S_FAILURE; } - ret = arcfour_mic_key(_gsskrb5_context, key, + ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { @@ -221,13 +224,13 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status, } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &seq_number); p = p0 + 8; /* SND_SEQ */ _gsskrb5_encode_be_om_uint32(seq_number, p); - krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + krb5_auth_con_setlocalseqnumber (context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -248,6 +251,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status, OM_uint32 _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -279,7 +283,8 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, return GSS_S_BAD_MIC; p += 4; - ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SIGN, + ret = arcfour_mic_cksum(context, + key, KRB5_KU_USAGE_SIGN, cksum_data, sizeof(cksum_data), p - 8, 8, message_buffer->value, message_buffer->length, @@ -289,7 +294,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, return GSS_S_FAILURE; } - ret = arcfour_mic_key(_gsskrb5_context, key, + ret = arcfour_mic_key(context, key, cksum_data, sizeof(cksum_data), k6_data, sizeof(k6_data)); if (ret) { @@ -339,6 +344,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, OM_uint32 _gssapi_wrap_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, + krb5_context context, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -396,13 +402,13 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, p = NULL; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &seq_number); _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8); - krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + krb5_auth_con_setlocalseqnumber (context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -420,7 +426,8 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, if (!IS_DCE_STYLE(context_handle)) p[input_message_buffer->length] = 1; /* padding */ - ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL, + ret = arcfour_mic_cksum(context, + key, KRB5_KU_USAGE_SEAL, p0 + 16, 8, /* SGN_CKSUM */ p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */ p0 + 24, 8, /* Confounder */ @@ -442,7 +449,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } - ret = arcfour_mic_key(_gsskrb5_context, &Klocal, + ret = arcfour_mic_key(context, &Klocal, p0 + 8, 4, /* SND_SEQ */ k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); @@ -463,7 +470,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, } memset(k6_data, 0, sizeof(k6_data)); - ret = arcfour_mic_key(_gsskrb5_context, key, + ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { @@ -490,6 +497,7 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status, OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, @@ -562,7 +570,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, return GSS_S_BAD_MIC; p = NULL; - ret = arcfour_mic_key(_gsskrb5_context, key, + ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { @@ -601,7 +609,7 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } - ret = arcfour_mic_key(_gsskrb5_context, &Klocal, + ret = arcfour_mic_key(context, &Klocal, SND_SEQ, 4, k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); @@ -643,7 +651,8 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, output_message_buffer->length -= padlen; } - ret = arcfour_mic_cksum(key, KRB5_KU_USAGE_SEAL, + ret = arcfour_mic_cksum(context, + key, KRB5_KU_USAGE_SEAL, cksum_data, sizeof(cksum_data), p0, 8, Confounder, sizeof(Confounder), @@ -721,6 +730,7 @@ max_wrap_length_arcfour(const gsskrb5_ctx ctx, OM_uint32 _gssapi_wrap_size_arcfour(OM_uint32 *minor_status, const gsskrb5_ctx ctx, + krb5_context context, int conf_req_flag, gss_qop_t qop_req, OM_uint32 req_output_size, @@ -730,9 +740,8 @@ _gssapi_wrap_size_arcfour(OM_uint32 *minor_status, krb5_error_code ret; krb5_crypto crypto; - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } @@ -740,13 +749,12 @@ _gssapi_wrap_size_arcfour(OM_uint32 *minor_status, ret = max_wrap_length_arcfour(ctx, crypto, req_output_size, max_input_size); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c index cb3f9ee5d3..e75fe5da9d 100755 --- a/source4/heimdal/lib/gssapi/krb5/cfx.c +++ b/source4/heimdal/lib/gssapi/krb5/cfx.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: cfx.c,v 1.24 2006/10/24 21:13:22 lha Exp $"); +RCSID("$Id: cfx.c,v 1.25 2006/11/13 18:01:14 lha Exp $"); /* * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt @@ -43,7 +43,8 @@ RCSID("$Id: cfx.c,v 1.24 2006/10/24 21:13:22 lha Exp $"); #define CFXAcceptorSubkey (1 << 2) krb5_error_code -_gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, +_gsskrb5cfx_wrap_length_cfx(krb5_context context, + krb5_crypto crypto, int conf_req_flag, size_t input_length, size_t *output_length, @@ -57,11 +58,11 @@ _gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, *output_length = sizeof(gss_cfx_wrap_token_desc); *padlength = 0; - ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &type); + ret = krb5_crypto_get_checksum_type(context, crypto, &type); if (ret) return ret; - ret = krb5_checksumsize(_gsskrb5_context, type, cksumsize); + ret = krb5_checksumsize(context, type, cksumsize); if (ret) return ret; @@ -71,7 +72,7 @@ _gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, /* Header is concatenated with data before encryption */ input_length += sizeof(gss_cfx_wrap_token_desc); - ret = krb5_crypto_getpadsize(_gsskrb5_context, crypto, &padsize); + ret = krb5_crypto_getpadsize(context, crypto, &padsize); if (ret) { return ret; } @@ -83,7 +84,7 @@ _gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, input_length += *padlength; } - *output_length += krb5_get_wrapped_length(_gsskrb5_context, + *output_length += krb5_get_wrapped_length(context, crypto, input_length); } else { /* Checksum is concatenated with data */ @@ -96,7 +97,8 @@ _gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, } krb5_error_code -_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto, +_gsskrb5cfx_max_wrap_length_cfx(krb5_context context, + krb5_crypto crypto, int conf_req_flag, size_t input_length, OM_uint32 *output_length) @@ -116,7 +118,7 @@ _gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto, wrapped_size = input_length + 1; do { wrapped_size--; - sz = krb5_get_wrapped_length(_gsskrb5_context, + sz = krb5_get_wrapped_length(context, crypto, wrapped_size); } while (wrapped_size && sz > input_length); if (wrapped_size == 0) { @@ -136,11 +138,11 @@ _gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto, krb5_cksumtype type; size_t cksumsize; - ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, &type); + ret = krb5_crypto_get_checksum_type(context, crypto, &type); if (ret) return ret; - ret = krb5_checksumsize(_gsskrb5_context, type, &cksumsize); + ret = krb5_checksumsize(context, type, &cksumsize); if (ret) return ret; @@ -157,6 +159,7 @@ _gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto, OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, int conf_req_flag, gss_qop_t qop_req, OM_uint32 req_output_size, @@ -166,23 +169,21 @@ OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status, krb5_error_code ret; krb5_crypto crypto; - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } - ret = _gsskrb5cfx_max_wrap_length_cfx(crypto, conf_req_flag, + ret = _gsskrb5cfx_max_wrap_length_cfx(context, crypto, conf_req_flag, req_output_size, max_input_size); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_COMPLETE; } @@ -233,6 +234,7 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate) OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -250,20 +252,19 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, int32_t seq_number; u_char *p; - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } - ret = _gsskrb5cfx_wrap_length_cfx(crypto, conf_req_flag, + ret = _gsskrb5cfx_wrap_length_cfx(context, + crypto, conf_req_flag, input_message_buffer->length, &wrapped_len, &cksumsize, &padlength); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } @@ -274,7 +275,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, output_message_buffer->value = malloc(output_message_buffer->length); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } @@ -324,12 +325,12 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, token->RRC[1] = 0; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber(_gsskrb5_context, + krb5_auth_con_getlocalseqnumber(context, context_handle->auth_context, &seq_number); _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]); _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]); - krb5_auth_con_setlocalseqnumber(_gsskrb5_context, + krb5_auth_con_setlocalseqnumber(context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -364,15 +365,14 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, memcpy(p + input_message_buffer->length + padlength, token, sizeof(*token)); - ret = krb5_encrypt(_gsskrb5_context, crypto, + ret = krb5_encrypt(context, crypto, usage, p, input_message_buffer->length + padlength + sizeof(*token), &cipher); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } @@ -382,9 +382,8 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } @@ -397,22 +396,21 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, buf = malloc(input_message_buffer->length + sizeof(*token)); if (buf == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } memcpy(buf, input_message_buffer->value, input_message_buffer->length); memcpy(buf + input_message_buffer->length, token, sizeof(*token)); - ret = krb5_create_checksum(_gsskrb5_context, crypto, + ret = krb5_create_checksum(context, crypto, usage, 0, buf, input_message_buffer->length + sizeof(*token), &cksum); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); _gsskrb5_release_buffer(minor_status, output_message_buffer); free(buf); return GSS_S_FAILURE; @@ -434,9 +432,8 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, ret = rrc_rotate(p, input_message_buffer->length + cksum.checksum.length, rrc, FALSE); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); _gsskrb5_release_buffer(minor_status, output_message_buffer); free_Checksum(&cksum); return GSS_S_FAILURE; @@ -444,7 +441,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, free_Checksum(&cksum); } - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); if (conf_state != NULL) { *conf_state = conf_req_flag; @@ -456,6 +453,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status, OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, @@ -539,9 +537,8 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* * Decrypt and/or verify checksum */ - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } @@ -559,23 +556,22 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* Rotate by RRC; bogus to do this in-place XXX */ *minor_status = rrc_rotate(p, len, rrc, TRUE); if (*minor_status != 0) { - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } if (token_flags & CFXSealed) { - ret = krb5_decrypt(_gsskrb5_context, crypto, usage, + ret = krb5_decrypt(context, crypto, usage, p, len, &data); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_BAD_MIC; } /* Check that there is room for the pad and token header */ if (data.length < ec + sizeof(*token)) { - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); krb5_data_free(&data); return GSS_S_DEFECTIVE_TOKEN; } @@ -588,7 +584,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* Check the integrity of the header */ if (memcmp(p, token, sizeof(*token)) != 0) { - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); krb5_data_free(&data); return GSS_S_BAD_MIC; } @@ -599,12 +595,11 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, Checksum cksum; /* Determine checksum type */ - ret = krb5_crypto_get_checksum_type(_gsskrb5_context, + ret = krb5_crypto_get_checksum_type(context, crypto, &cksum.cksumtype); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } @@ -613,7 +608,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, /* Check we have at least as much data as the checksum */ if (len < cksum.checksum.length) { *minor_status = ERANGE; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_BAD_MIC; } @@ -625,7 +620,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, output_message_buffer->value = malloc(len + sizeof(*token)); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } @@ -642,21 +637,20 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, token->RRC[0] = 0; token->RRC[1] = 0; - ret = krb5_verify_checksum(_gsskrb5_context, crypto, + ret = krb5_verify_checksum(context, crypto, usage, output_message_buffer->value, len + sizeof(*token), &cksum); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_BAD_MIC; } } - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); if (qop_state != NULL) { *qop_state = GSS_C_QOP_DEFAULT; @@ -668,6 +662,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status, OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -682,9 +677,8 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, size_t len; int32_t seq_number; - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } @@ -693,7 +687,7 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, buf = malloc(len); if (buf == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } @@ -710,12 +704,12 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, memset(token->Filler, 0xFF, 5); HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber(_gsskrb5_context, + krb5_auth_con_getlocalseqnumber(context, context_handle->auth_context, &seq_number); _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]); _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]); - krb5_auth_con_setlocalseqnumber(_gsskrb5_context, + krb5_auth_con_setlocalseqnumber(context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); @@ -726,16 +720,15 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, usage = KRB5_KU_USAGE_ACCEPTOR_SIGN; } - ret = krb5_create_checksum(_gsskrb5_context, crypto, + ret = krb5_create_checksum(context, crypto, usage, 0, buf, len, &cksum); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); free(buf); return GSS_S_FAILURE; } - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); /* Determine MIC length */ message_token->length = sizeof(*token) + cksum.checksum.length; @@ -761,6 +754,7 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status, OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t *qop_state, @@ -830,19 +824,17 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, /* * Verify checksum */ - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_crypto_get_checksum_type(_gsskrb5_context, crypto, + ret = krb5_crypto_get_checksum_type(context, crypto, &cksum.cksumtype); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } @@ -858,20 +850,19 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status, buf = malloc(message_buffer->length + sizeof(*token)); if (buf == NULL) { *minor_status = ENOMEM; - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); return GSS_S_FAILURE; } memcpy(buf, message_buffer->value, message_buffer->length); memcpy(buf + message_buffer->length, token, sizeof(*token)); - ret = krb5_verify_checksum(_gsskrb5_context, crypto, + ret = krb5_verify_checksum(context, crypto, usage, buf, sizeof(*token) + message_buffer->length, &cksum); - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); if (ret != 0) { - _gsskrb5_set_error_string(); *minor_status = ret; free(buf); return GSS_S_BAD_MIC; diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.h b/source4/heimdal/lib/gssapi/krb5/cfx.h index 1120544fbe..ce021aa099 100755 --- a/source4/heimdal/lib/gssapi/krb5/cfx.h +++ b/source4/heimdal/lib/gssapi/krb5/cfx.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ -/* $Id: cfx.h,v 1.7 2006/07/19 14:16:33 lha Exp $ */ +/* $Id: cfx.h,v 1.8 2006/11/13 18:01:17 lha Exp $ */ #ifndef GSSAPI_CFX_H_ #define GSSAPI_CFX_H_ 1 @@ -62,19 +62,4 @@ typedef struct gss_cfx_delete_token_desc_struct { u_char SND_SEQ[8]; } gss_cfx_delete_token_desc, *gss_cfx_delete_token; -krb5_error_code -_gsskrb5cfx_wrap_length_cfx(krb5_crypto crypto, - int conf_req_flag, - size_t input_length, - size_t *output_length, - size_t *cksumsize, - uint16_t *padlength); - -krb5_error_code -_gsskrb5cfx_max_wrap_length_cfx(krb5_crypto crypto, - int conf_req_flag, - size_t input_length, - OM_uint32 *output_length); - - #endif /* GSSAPI_CFX_H_ */ diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c index 3e0f7edfee..6b537468df 100644 --- a/source4/heimdal/lib/gssapi/krb5/compare_name.c +++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: compare_name.c,v 1.7 2006/10/07 22:14:15 lha Exp $"); +RCSID("$Id: compare_name.c,v 1.8 2006/11/13 18:01:20 lha Exp $"); OM_uint32 _gsskrb5_compare_name (OM_uint32 * minor_status, @@ -44,10 +44,11 @@ OM_uint32 _gsskrb5_compare_name { krb5_const_principal princ1 = (krb5_const_principal)name1; krb5_const_principal princ2 = (krb5_const_principal)name2; + krb5_context context; - GSSAPI_KRB5_INIT(); + GSSAPI_KRB5_INIT(&context); - *name_equal = krb5_principal_compare (_gsskrb5_context, + *name_equal = krb5_principal_compare (context, princ1, princ2); *minor_status = 0; return GSS_S_COMPLETE; diff --git a/source4/heimdal/lib/gssapi/krb5/compat.c b/source4/heimdal/lib/gssapi/krb5/compat.c index 0ea2fce0e8..3e64df03db 100644 --- a/source4/heimdal/lib/gssapi/krb5/compat.c +++ b/source4/heimdal/lib/gssapi/krb5/compat.c @@ -33,11 +33,12 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: compat.c,v 1.13 2006/10/07 22:14:17 lha Exp $"); +RCSID("$Id: compat.c,v 1.14 2006/11/13 18:01:23 lha Exp $"); static krb5_error_code -check_compat(OM_uint32 *minor_status, krb5_const_principal name, +check_compat(OM_uint32 *minor_status, + krb5_context context, krb5_const_principal name, const char *option, krb5_boolean *compat, krb5_boolean match_val) { @@ -46,27 +47,27 @@ check_compat(OM_uint32 *minor_status, krb5_const_principal name, krb5_principal match; - p = krb5_config_get_strings(_gsskrb5_context, NULL, "gssapi", + p = krb5_config_get_strings(context, NULL, "gssapi", option, NULL); if(p == NULL) return 0; match = NULL; for(q = p; *q; q++) { - ret = krb5_parse_name(_gsskrb5_context, *q, &match); + ret = krb5_parse_name(context, *q, &match); if (ret) break; - if (krb5_principal_match(_gsskrb5_context, name, match)) { + if (krb5_principal_match(context, name, match)) { *compat = match_val; break; } - krb5_free_principal(_gsskrb5_context, match); + krb5_free_principal(context, match); match = NULL; } if (match) - krb5_free_principal(_gsskrb5_context, match); + krb5_free_principal(context, match); krb5_config_free_strings(p); if (ret) { @@ -83,17 +84,19 @@ check_compat(OM_uint32 *minor_status, krb5_const_principal name, */ OM_uint32 -_gss_DES3_get_mic_compat(OM_uint32 *minor_status, gsskrb5_ctx ctx) +_gss_DES3_get_mic_compat(OM_uint32 *minor_status, + gsskrb5_ctx ctx, + krb5_context context) { krb5_boolean use_compat = FALSE; OM_uint32 ret; if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) { - ret = check_compat(minor_status, ctx->target, + ret = check_compat(minor_status, context, ctx->target, "broken_des3_mic", &use_compat, TRUE); if (ret) return ret; - ret = check_compat(minor_status, ctx->target, + ret = check_compat(minor_status, context, ctx->target, "correct_des3_mic", &use_compat, FALSE); if (ret) return ret; diff --git a/source4/heimdal/lib/gssapi/krb5/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c index 4e9d9f5d1d..9012dd0b7f 100644 --- a/source4/heimdal/lib/gssapi/krb5/context_time.c +++ b/source4/heimdal/lib/gssapi/krb5/context_time.c @@ -33,12 +33,13 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: context_time.c,v 1.13 2006/10/07 22:14:19 lha Exp $"); +RCSID("$Id: context_time.c,v 1.14 2006/11/13 18:01:26 lha Exp $"); OM_uint32 _gsskrb5_lifetime_left(OM_uint32 *minor_status, - OM_uint32 lifetime, - OM_uint32 *lifetime_rec) + krb5_context context, + OM_uint32 lifetime, + OM_uint32 *lifetime_rec) { krb5_timestamp timeret; krb5_error_code kret; @@ -48,10 +49,9 @@ _gsskrb5_lifetime_left(OM_uint32 *minor_status, return GSS_S_COMPLETE; } - kret = krb5_timeofday(_gsskrb5_context, &timeret); + kret = krb5_timeofday(context, &timeret); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } @@ -70,17 +70,19 @@ OM_uint32 _gsskrb5_context_time OM_uint32 * time_rec ) { + krb5_context context; OM_uint32 lifetime; OM_uint32 major_status; const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); lifetime = ctx->lifetime; HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); - major_status = _gsskrb5_lifetime_left(minor_status, lifetime, time_rec); + major_status = _gsskrb5_lifetime_left(minor_status, context, + lifetime, time_rec); if (major_status != GSS_S_COMPLETE) return major_status; diff --git a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c index 91d21a1aec..4387a4e6ef 100644 --- a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c +++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c @@ -33,11 +33,12 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: copy_ccache.c,v 1.16 2006/11/08 02:42:50 lha Exp $"); +RCSID("$Id: copy_ccache.c,v 1.17 2006/11/13 18:01:29 lha Exp $"); #if 0 OM_uint32 gss_krb5_copy_ccache(OM_uint32 *minor_status, + krb5_context context, gss_cred_id_t cred, krb5_ccache out) { @@ -51,11 +52,10 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status, return GSS_S_FAILURE; } - kret = krb5_cc_copy_cache(_gsskrb5_context, cred->ccache, out); + kret = krb5_cc_copy_cache(context, cred->ccache, out); HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } *minor_status = 0; @@ -71,13 +71,14 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, krb5_keytab keytab, gss_cred_id_t *cred) { + krb5_context context; krb5_error_code kret; gsskrb5_cred handle; OM_uint32 ret; *cred = NULL; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); handle = calloc(1, sizeof(*handle)); if (handle == NULL) { @@ -94,11 +95,10 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, handle->usage |= GSS_C_INITIATE; - kret = krb5_cc_get_principal(_gsskrb5_context, id, + kret = krb5_cc_get_principal(context, id, &handle->principal); if (kret) { free(handle); - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -106,11 +106,11 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, if (keytab_principal) { krb5_boolean match; - match = krb5_principal_compare(_gsskrb5_context, + match = krb5_principal_compare(context, handle->principal, keytab_principal); if (match == FALSE) { - krb5_free_principal(_gsskrb5_context, handle->principal); + krb5_free_principal(context, handle->principal); free(handle); _gsskrb5_clear_status (); *minor_status = EINVAL; @@ -119,21 +119,22 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, } ret = __gsskrb5_ccache_lifetime(minor_status, - id, - handle->principal, - &handle->lifetime); + context, + id, + handle->principal, + &handle->lifetime); if (ret != GSS_S_COMPLETE) { - krb5_free_principal(_gsskrb5_context, handle->principal); + krb5_free_principal(context, handle->principal); free(handle); return ret; } - kret = krb5_cc_get_full_name(_gsskrb5_context, id, &str); + kret = krb5_cc_get_full_name(context, id, &str); if (kret) goto out; - kret = krb5_cc_resolve(_gsskrb5_context, str, &handle->ccache); + kret = krb5_cc_resolve(context, str, &handle->ccache); free(str); if (kret) goto out; @@ -146,18 +147,18 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, handle->usage |= GSS_C_ACCEPT; if (keytab_principal && handle->principal == NULL) { - kret = krb5_copy_principal(_gsskrb5_context, + kret = krb5_copy_principal(context, keytab_principal, &handle->principal); if (kret) goto out; } - kret = krb5_kt_get_full_name(_gsskrb5_context, keytab, &str); + kret = krb5_kt_get_full_name(context, keytab, &str); if (kret) goto out; - kret = krb5_kt_resolve(_gsskrb5_context, str, &handle->keytab); + kret = krb5_kt_resolve(context, str, &handle->keytab); free(str); if (kret) goto out; @@ -180,9 +181,8 @@ _gsskrb5_import_cred(OM_uint32 *minor_status, return GSS_S_COMPLETE; out: - _gsskrb5_set_error_string (); if (handle->principal) - krb5_free_principal(_gsskrb5_context, handle->principal); + krb5_free_principal(context, handle->principal); HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); *minor_status = kret; diff --git a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c index e890d7d2c2..c7f2ee262d 100644 --- a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c @@ -33,16 +33,17 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: delete_sec_context.c,v 1.19 2006/10/07 22:14:28 lha Exp $"); +RCSID("$Id: delete_sec_context.c,v 1.20 2006/11/13 18:01:32 lha Exp $"); OM_uint32 _gsskrb5_delete_sec_context(OM_uint32 * minor_status, gss_ctx_id_t * context_handle, gss_buffer_t output_token) { + krb5_context context; gsskrb5_ctx ctx; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); *minor_status = 0; @@ -59,17 +60,17 @@ _gsskrb5_delete_sec_context(OM_uint32 * minor_status, HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - krb5_auth_con_free (_gsskrb5_context, ctx->auth_context); + krb5_auth_con_free (context, ctx->auth_context); if(ctx->source) - krb5_free_principal (_gsskrb5_context, ctx->source); + krb5_free_principal (context, ctx->source); if(ctx->target) - krb5_free_principal (_gsskrb5_context, ctx->target); + krb5_free_principal (context, ctx->target); if (ctx->ticket) - krb5_free_ticket (_gsskrb5_context, ctx->ticket); + krb5_free_ticket (context, ctx->ticket); if(ctx->order) _gssapi_msg_order_destroy(&ctx->order); if (ctx->service_keyblock) - krb5_free_keyblock (_gsskrb5_context, ctx->service_keyblock); + krb5_free_keyblock (context, ctx->service_keyblock); krb5_data_free(&ctx->fwd_data); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); diff --git a/source4/heimdal/lib/gssapi/krb5/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c index 8fce7d8572..4956c2d77f 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_name.c +++ b/source4/heimdal/lib/gssapi/krb5/display_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: display_name.c,v 1.12 2006/10/07 22:14:31 lha Exp $"); +RCSID("$Id: display_name.c,v 1.13 2006/11/13 18:01:36 lha Exp $"); OM_uint32 _gsskrb5_display_name (OM_uint32 * minor_status, @@ -42,16 +42,17 @@ OM_uint32 _gsskrb5_display_name gss_OID * output_name_type ) { + krb5_context context; krb5_const_principal name = (krb5_const_principal)input_name; krb5_error_code kret; char *buf; size_t len; - GSSAPI_KRB5_INIT (); - kret = krb5_unparse_name (_gsskrb5_context, name, &buf); + GSSAPI_KRB5_INIT (&context); + + kret = krb5_unparse_name (context, name, &buf); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } len = strlen (buf); diff --git a/source4/heimdal/lib/gssapi/krb5/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c index 11926ca557..b0155a7fdf 100644 --- a/source4/heimdal/lib/gssapi/krb5/display_status.c +++ b/source4/heimdal/lib/gssapi/krb5/display_status.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1998 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: display_status.c,v 1.16 2006/10/07 22:14:33 lha Exp $"); +RCSID("$Id: display_status.c,v 1.17 2006/11/13 18:01:38 lha Exp $"); static const char * calling_error(OM_uint32 v) @@ -114,117 +114,87 @@ supplementary_error(OM_uint32 v) void _gsskrb5_clear_status (void) { - struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(1); - if (ctx == NULL) + krb5_context context; + + if (_gsskrb5_init (&context) != 0) return; - HEIMDAL_MUTEX_lock(&ctx->mutex); - if (ctx->error_string) - free(ctx->error_string); - ctx->error_string = NULL; - HEIMDAL_MUTEX_unlock(&ctx->mutex); + krb5_clear_error_string(context); } void _gsskrb5_set_status (const char *fmt, ...) { - struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(1); + krb5_context context; va_list args; + char *str; - if (ctx == NULL) + if (_gsskrb5_init (&context) != 0) return; - HEIMDAL_MUTEX_lock(&ctx->mutex); + va_start(args, fmt); - if (ctx->error_string) - free(ctx->error_string); - /* ignore failures, will use status code instead */ - vasprintf(&ctx->error_string, fmt, args); + vasprintf(&str, fmt, args); va_end(args); - HEIMDAL_MUTEX_unlock(&ctx->mutex); -} - -void -_gsskrb5_set_error_string (void) -{ - char *e; - - e = krb5_get_error_string(_gsskrb5_context); - if (e) { - _gsskrb5_set_status("%s", e); - krb5_free_error_string(_gsskrb5_context, e); - } else - _gsskrb5_clear_status(); -} - -char * -_gsskrb5_get_error_string (void) -{ - struct gssapi_thr_context *ctx = _gsskrb5_get_thread_context(0); - char *ret; - - if (ctx == NULL) - return NULL; - HEIMDAL_MUTEX_lock(&ctx->mutex); - ret = ctx->error_string; - ctx->error_string = NULL; - HEIMDAL_MUTEX_unlock(&ctx->mutex); - return ret; + if (str) { + krb5_set_error_string(context, str); + free(str); + } } OM_uint32 _gsskrb5_display_status - (OM_uint32 *minor_status, - OM_uint32 status_value, - int status_type, - const gss_OID mech_type, - OM_uint32 *message_context, - gss_buffer_t status_string) +(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, + const gss_OID mech_type, + OM_uint32 *message_context, + gss_buffer_t status_string) { - char *buf; - - GSSAPI_KRB5_INIT (); - - status_string->length = 0; - status_string->value = NULL; - - if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 && - gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) { - *minor_status = 0; - return GSS_C_GSS_CODE; - } - - if (status_type == GSS_C_GSS_CODE) { - if (GSS_SUPPLEMENTARY_INFO(status_value)) - asprintf(&buf, "%s", - supplementary_error(GSS_SUPPLEMENTARY_INFO(status_value))); - else - asprintf (&buf, "%s %s", - calling_error(GSS_CALLING_ERROR(status_value)), - routine_error(GSS_ROUTINE_ERROR(status_value))); - } else if (status_type == GSS_C_MECH_CODE) { - buf = _gsskrb5_get_error_string (); - if (buf == NULL) { - const char *tmp = krb5_get_err_text (_gsskrb5_context, - status_value); - if (tmp == NULL) - asprintf(&buf, "unknown mech error-code %u", - (unsigned)status_value); - else - buf = strdup(tmp); - } - } else { - *minor_status = EINVAL; - return GSS_S_BAD_STATUS; - } - - if (buf == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - *message_context = 0; - *minor_status = 0; - - status_string->length = strlen(buf); - status_string->value = buf; + krb5_context context; + char *buf; + + GSSAPI_KRB5_INIT (&context); + + status_string->length = 0; + status_string->value = NULL; + + if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 && + gss_oid_equal(mech_type, GSS_KRB5_MECHANISM) == 0) { + *minor_status = 0; + return GSS_C_GSS_CODE; + } + + if (status_type == GSS_C_GSS_CODE) { + if (GSS_SUPPLEMENTARY_INFO(status_value)) + asprintf(&buf, "%s", + supplementary_error(GSS_SUPPLEMENTARY_INFO(status_value))); + else + asprintf (&buf, "%s %s", + calling_error(GSS_CALLING_ERROR(status_value)), + routine_error(GSS_ROUTINE_ERROR(status_value))); + } else if (status_type == GSS_C_MECH_CODE) { + buf = krb5_get_error_string(context); + if (buf == NULL) { + const char *tmp = krb5_get_err_text (context, status_value); + if (tmp == NULL) + asprintf(&buf, "unknown mech error-code %u", + (unsigned)status_value); + else + buf = strdup(tmp); + } + } else { + *minor_status = EINVAL; + return GSS_S_BAD_STATUS; + } + + if (buf == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + *message_context = 0; + *minor_status = 0; + + status_string->length = strlen(buf); + status_string->value = buf; - return GSS_S_COMPLETE; + return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c index 475ae61efc..8375257180 100644 --- a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c +++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: duplicate_name.c,v 1.10 2006/10/07 22:14:35 lha Exp $"); +RCSID("$Id: duplicate_name.c,v 1.11 2006/11/13 18:01:42 lha Exp $"); OM_uint32 _gsskrb5_duplicate_name ( OM_uint32 * minor_status, @@ -41,16 +41,16 @@ OM_uint32 _gsskrb5_duplicate_name ( gss_name_t * dest_name ) { + krb5_context context; krb5_const_principal src = (krb5_const_principal)src_name; krb5_principal *dest = (krb5_principal *)dest_name; krb5_error_code kret; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); - kret = krb5_copy_principal (_gsskrb5_context, src, dest); + kret = krb5_copy_principal (context, src, dest); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } else { *minor_status = 0; diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c index d00c458898..646fdafb7c 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_name.c +++ b/source4/heimdal/lib/gssapi/krb5/export_name.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: export_name.c,v 1.8 2006/10/07 22:14:40 lha Exp $"); +RCSID("$Id: export_name.c,v 1.9 2006/11/13 18:01:50 lha Exp $"); OM_uint32 _gsskrb5_export_name (OM_uint32 * minor_status, @@ -41,16 +41,17 @@ OM_uint32 _gsskrb5_export_name gss_buffer_t exported_name ) { + krb5_context context; krb5_const_principal princ = (krb5_const_principal)input_name; krb5_error_code kret; char *buf, *name; size_t len; - GSSAPI_KRB5_INIT (); - kret = krb5_unparse_name (_gsskrb5_context, princ, &name); + GSSAPI_KRB5_INIT (&context); + + kret = krb5_unparse_name (context, princ, &name); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } len = strlen (name); diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c index aff03a0b67..ffa671a4a1 100644 --- a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: export_sec_context.c,v 1.11 2006/10/07 22:14:42 lha Exp $"); +RCSID("$Id: export_sec_context.c,v 1.12 2006/11/13 18:01:55 lha Exp $"); OM_uint32 _gsskrb5_export_sec_context ( @@ -42,6 +42,7 @@ _gsskrb5_export_sec_context ( gss_buffer_t interprocess_token ) { + krb5_context context; const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle; krb5_storage *sp; krb5_auth_context ac; @@ -52,7 +53,7 @@ _gsskrb5_export_sec_context ( OM_uint32 minor; krb5_error_code kret; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index 0681bd4038..bf7f64cf20 100644 --- a/source4/heimdal/lib/gssapi/krb5/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -34,7 +34,7 @@ #include "krb5/gsskrb5_locl.h" #include -RCSID("$Id: external.c,v 1.22 2006/11/08 23:00:20 lha Exp $"); +RCSID("$Id: external.c,v 1.23 2006/11/13 18:01:57 lha Exp $"); /* * The implementation must reserve static storage for a @@ -369,7 +369,7 @@ gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc; * Context for krb5 calls. */ -krb5_context _gsskrb5_context; +krb5_context context; /* * diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c index 5a078d634d..790c9b6166 100644 --- a/source4/heimdal/lib/gssapi/krb5/get_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c @@ -33,12 +33,13 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: get_mic.c,v 1.34 2006/10/18 15:59:23 lha Exp $"); +RCSID("$Id: get_mic.c,v 1.35 2006/11/13 18:02:00 lha Exp $"); static OM_uint32 mic_des (OM_uint32 * minor_status, const gsskrb5_ctx ctx, + krb5_context context, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -94,9 +95,9 @@ mic_des HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); /* sequence number */ - krb5_auth_con_getlocalseqnumber (_gsskrb5_context, - ctx->auth_context, - &seq_number); + krb5_auth_con_getlocalseqnumber (context, + ctx->auth_context, + &seq_number); p -= 16; /* SND_SEQ */ p[0] = (seq_number >> 0) & 0xFF; @@ -111,7 +112,7 @@ mic_des DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT); - krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + krb5_auth_con_setlocalseqnumber (context, ctx->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); @@ -127,6 +128,7 @@ static OM_uint32 mic_des3 (OM_uint32 * minor_status, const gsskrb5_ctx ctx, + krb5_context context, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, @@ -180,18 +182,17 @@ mic_des3 memcpy (tmp, p - 8, 8); memcpy (tmp + 8, message_buffer->value, message_buffer->length); - kret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + kret = krb5_crypto_init(context, key, 0, &crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; free (tmp); - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - kret = krb5_create_checksum (_gsskrb5_context, + kret = krb5_create_checksum (context, crypto, KRB5_KU_USAGE_SIGN, 0, @@ -199,12 +200,11 @@ mic_des3 message_buffer->length + 8, &cksum); free (tmp); - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -213,7 +213,7 @@ mic_des3 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); /* sequence number */ - krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + krb5_auth_con_getlocalseqnumber (context, ctx->auth_context, &seq_number); @@ -225,13 +225,12 @@ mic_des3 (ctx->more_flags & LOCAL) ? 0 : 0xFF, 4); - kret = krb5_crypto_init(_gsskrb5_context, key, + kret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE, &crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -241,16 +240,15 @@ mic_des3 else memcpy(ivec, p + 8, 8); - kret = krb5_encrypt_ivec (_gsskrb5_context, + kret = krb5_encrypt_ivec (context, crypto, KRB5_KU_USAGE_SEQ, seq, 8, &encdata, ivec); - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); if (kret) { free (message_token->value); message_token->value = NULL; message_token->length = 0; - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -260,7 +258,7 @@ mic_des3 memcpy (p, encdata.data, encdata.length); krb5_data_free (&encdata); - krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + krb5_auth_con_setlocalseqnumber (context, ctx->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); @@ -278,40 +276,42 @@ OM_uint32 _gsskrb5_get_mic gss_buffer_t message_token ) { + krb5_context context; const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; + GSSAPI_KRB5_INIT (&context); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - ret = _gsskrb5i_get_token_key(ctx, &key); + ret = _gsskrb5i_get_token_key(ctx, context, &key); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : - ret = mic_des (minor_status, ctx, qop_req, + ret = mic_des (minor_status, ctx, context, qop_req, message_buffer, message_token, key); break; case KEYTYPE_DES3 : - ret = mic_des3 (minor_status, ctx, qop_req, + ret = mic_des3 (minor_status, ctx, context, qop_req, message_buffer, message_token, key); break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_get_mic_arcfour (minor_status, ctx, qop_req, + ret = _gssapi_get_mic_arcfour (minor_status, ctx, context, qop_req, message_buffer, message_token, key); break; default : - ret = _gssapi_mic_cfx (minor_status, ctx, qop_req, + ret = _gssapi_mic_cfx (minor_status, ctx, context, qop_req, message_buffer, message_token, key); break; } - krb5_free_keyblock (_gsskrb5_context, key); + krb5_free_keyblock (context, key); return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h index 426c0ab200..15bd5c77da 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5-private.h @@ -10,6 +10,7 @@ __gss_krb5_initialize (void); OM_uint32 __gsskrb5_ccache_lifetime ( OM_uint32 */*minor_status*/, + krb5_context /*context*/, krb5_ccache /*id*/, krb5_principal /*principal*/, OM_uint32 */*lifetime*/); @@ -17,7 +18,8 @@ __gsskrb5_ccache_lifetime ( OM_uint32 _gss_DES3_get_mic_compat ( OM_uint32 */*minor_status*/, - gsskrb5_ctx /*ctx*/); + gsskrb5_ctx /*ctx*/, + krb5_context /*context*/); OM_uint32 _gssapi_decapsulate ( @@ -44,6 +46,7 @@ OM_uint32 _gssapi_get_mic_arcfour ( OM_uint32 * /*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, gss_qop_t /*qop_req*/, const gss_buffer_t /*message_buffer*/, gss_buffer_t /*message_token*/, @@ -59,6 +62,7 @@ OM_uint32 _gssapi_mic_cfx ( OM_uint32 */*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, gss_qop_t /*qop_req*/, const gss_buffer_t /*message_buffer*/, gss_buffer_t /*message_token*/, @@ -99,6 +103,7 @@ OM_uint32 _gssapi_unwrap_arcfour ( OM_uint32 */*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, const gss_buffer_t /*input_message_buffer*/, gss_buffer_t /*output_message_buffer*/, int */*conf_state*/, @@ -109,6 +114,7 @@ OM_uint32 _gssapi_unwrap_cfx ( OM_uint32 */*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, const gss_buffer_t /*input_message_buffer*/, gss_buffer_t /*output_message_buffer*/, int */*conf_state*/, @@ -125,6 +131,7 @@ OM_uint32 _gssapi_verify_mic_arcfour ( OM_uint32 * /*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, const gss_buffer_t /*message_buffer*/, const gss_buffer_t /*token_buffer*/, gss_qop_t * /*qop_state*/, @@ -135,6 +142,7 @@ OM_uint32 _gssapi_verify_mic_cfx ( OM_uint32 */*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, const gss_buffer_t /*message_buffer*/, const gss_buffer_t /*token_buffer*/, gss_qop_t */*qop_state*/, @@ -150,6 +158,7 @@ OM_uint32 _gssapi_wrap_arcfour ( OM_uint32 * /*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, int /*conf_req_flag*/, gss_qop_t /*qop_req*/, const gss_buffer_t /*input_message_buffer*/, @@ -161,6 +170,7 @@ OM_uint32 _gssapi_wrap_cfx ( OM_uint32 */*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, int /*conf_req_flag*/, gss_qop_t /*qop_req*/, const gss_buffer_t /*input_message_buffer*/, @@ -172,6 +182,7 @@ OM_uint32 _gssapi_wrap_size_arcfour ( OM_uint32 */*minor_status*/, const gsskrb5_ctx /*ctx*/, + krb5_context /*context*/, int /*conf_req_flag*/, gss_qop_t /*qop_req*/, OM_uint32 /*req_output_size*/, @@ -182,6 +193,7 @@ OM_uint32 _gssapi_wrap_size_cfx ( OM_uint32 */*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, int /*conf_req_flag*/, gss_qop_t /*qop_req*/, OM_uint32 /*req_output_size*/, @@ -268,6 +280,7 @@ OM_uint32 _gsskrb5_create_ctx ( OM_uint32 * /*minor_status*/, gss_ctx_id_t * /*context_handle*/, + krb5_context /*context*/, const gss_channel_bindings_t /*input_chan_bindings*/, enum gss_ctx_id_t_state /*state*/); @@ -359,9 +372,6 @@ _gsskrb5_export_sec_context ( gss_ctx_id_t * /*context_handle*/, gss_buffer_t interprocess_token ); -char * -_gsskrb5_get_error_string (void); - ssize_t _gsskrb5_get_mech ( const u_char */*ptr*/, @@ -376,9 +386,6 @@ _gsskrb5_get_mic ( const gss_buffer_t /*message_buffer*/, gss_buffer_t message_token ); -struct gssapi_thr_context * -_gsskrb5_get_thread_context (int /*createp*/); - OM_uint32 _gsskrb5_get_tkt_flags ( OM_uint32 */*minor_status*/, @@ -412,7 +419,7 @@ _gsskrb5_indicate_mechs ( gss_OID_set * mech_set ); krb5_error_code -_gsskrb5_init (void); +_gsskrb5_init (krb5_context */*context*/); OM_uint32 _gsskrb5_init_sec_context ( @@ -496,6 +503,7 @@ _gsskrb5_krb5_ccache_name ( OM_uint32 _gsskrb5_lifetime_left ( OM_uint32 */*minor_status*/, + krb5_context /*context*/, OM_uint32 /*lifetime*/, OM_uint32 */*lifetime_rec*/); @@ -552,9 +560,6 @@ _gsskrb5_set_cred_option ( const gss_OID /*desired_object*/, const gss_buffer_t /*value*/); -void -_gsskrb5_set_error_string (void); - OM_uint32 _gsskrb5_set_sec_context_option ( OM_uint32 */*minor_status*/, @@ -635,6 +640,7 @@ OM_uint32 _gsskrb5_verify_mic_internal ( OM_uint32 * /*minor_status*/, const gsskrb5_ctx /*context_handle*/, + krb5_context /*context*/, const gss_buffer_t /*message_buffer*/, const gss_buffer_t /*token_buffer*/, gss_qop_t * /*qop_state*/, @@ -661,6 +667,7 @@ _gsskrb5_wrap_size_limit ( krb5_error_code _gsskrb5cfx_max_wrap_length_cfx ( + krb5_context /*context*/, krb5_crypto /*crypto*/, int /*conf_req_flag*/, size_t /*input_length*/, @@ -668,6 +675,7 @@ _gsskrb5cfx_max_wrap_length_cfx ( krb5_error_code _gsskrb5cfx_wrap_length_cfx ( + krb5_context /*context*/, krb5_crypto /*crypto*/, int /*conf_req_flag*/, size_t /*input_length*/, @@ -677,6 +685,7 @@ _gsskrb5cfx_wrap_length_cfx ( krb5_error_code _gsskrb5i_address_to_krb5addr ( + krb5_context /*context*/, OM_uint32 /*gss_addr_type*/, gss_buffer_desc */*gss_addr*/, int16_t /*port*/, @@ -685,16 +694,19 @@ _gsskrb5i_address_to_krb5addr ( krb5_error_code _gsskrb5i_get_acceptor_subkey ( const gsskrb5_ctx /*ctx*/, + krb5_context /*context*/, krb5_keyblock **/*key*/); krb5_error_code _gsskrb5i_get_initiator_subkey ( const gsskrb5_ctx /*ctx*/, + krb5_context /*context*/, krb5_keyblock **/*key*/); OM_uint32 _gsskrb5i_get_token_key ( const gsskrb5_ctx /*ctx*/, + krb5_context /*context*/, krb5_keyblock **/*key*/); void diff --git a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h index 39c800bf31..1983a9b8e4 100644 --- a/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h +++ b/source4/heimdal/lib/gssapi/krb5/gsskrb5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: gsskrb5_locl.h,v 1.8 2006/11/10 00:36:40 lha Exp $ */ +/* $Id: gsskrb5_locl.h,v 1.9 2006/11/13 18:02:03 lha Exp $ */ #ifndef GSSKRB5_LOCL_H #define GSSKRB5_LOCL_H @@ -100,8 +100,6 @@ typedef struct Principal *gsskrb5_name; * */ -extern krb5_context _gsskrb5_context; - extern krb5_keytab _gsskrb5_keytab; extern HEIMDAL_MUTEX gssapi_keytab_mutex; @@ -116,9 +114,9 @@ struct gssapi_thr_context { #include -#define GSSAPI_KRB5_INIT() do { \ +#define GSSAPI_KRB5_INIT(ctx) do { \ krb5_error_code kret_gss_init; \ - if((kret_gss_init = _gsskrb5_init ()) != 0) { \ + if((kret_gss_init = _gsskrb5_init (ctx)) != 0) { \ *minor_status = kret_gss_init; \ return GSS_S_FAILURE; \ } \ diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c index dc24ed5cf2..15311b4614 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_name.c +++ b/source4/heimdal/lib/gssapi/krb5/import_name.c @@ -33,23 +33,23 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: import_name.c,v 1.17 2006/10/07 22:14:51 lha Exp $"); +RCSID("$Id: import_name.c,v 1.18 2006/11/13 18:02:06 lha Exp $"); static OM_uint32 parse_krb5_name (OM_uint32 *minor_status, + krb5_context context, const char *name, gss_name_t *output_name) { krb5_principal princ; krb5_error_code kerr; - kerr = krb5_parse_name (_gsskrb5_context, name, &princ); + kerr = krb5_parse_name (context, name, &princ); if (kerr == 0) { *output_name = (gss_name_t)princ; return GSS_S_COMPLETE; } - _gsskrb5_set_error_string (); *minor_status = kerr; if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) @@ -60,6 +60,7 @@ parse_krb5_name (OM_uint32 *minor_status, static OM_uint32 import_krb5_name (OM_uint32 *minor_status, + krb5_context context, const gss_buffer_t input_name_buffer, gss_name_t *output_name) { @@ -76,7 +77,7 @@ import_krb5_name (OM_uint32 *minor_status, input_name_buffer->length); tmp[input_name_buffer->length] = '\0'; - ret = parse_krb5_name(minor_status, tmp, output_name); + ret = parse_krb5_name(minor_status, context, tmp, output_name); free(tmp); return ret; @@ -84,6 +85,7 @@ import_krb5_name (OM_uint32 *minor_status, static OM_uint32 import_hostbased_name (OM_uint32 *minor_status, + krb5_context context, const gss_buffer_t input_name_buffer, gss_name_t *output_name) { @@ -117,7 +119,7 @@ import_hostbased_name (OM_uint32 *minor_status, host = local_hostname; } - kerr = krb5_sname_to_principal (_gsskrb5_context, + kerr = krb5_sname_to_principal (context, host, tmp, KRB5_NT_SRV_HST, @@ -128,8 +130,6 @@ import_hostbased_name (OM_uint32 *minor_status, *output_name = (gss_name_t)princ; return GSS_S_COMPLETE; } - _gsskrb5_set_error_string (); - *minor_status = kerr; if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED) return GSS_S_BAD_NAME; @@ -139,6 +139,7 @@ import_hostbased_name (OM_uint32 *minor_status, static OM_uint32 import_export_name (OM_uint32 *minor_status, + krb5_context context, const gss_buffer_t input_name_buffer, gss_name_t *output_name) { @@ -178,7 +179,7 @@ import_export_name (OM_uint32 *minor_status, memcpy(name, p, length); name[length] = '\0'; - ret = parse_krb5_name(minor_status, name, output_name); + ret = parse_krb5_name(minor_status, context, name, output_name); free(name); return ret; @@ -191,14 +192,17 @@ OM_uint32 _gsskrb5_import_name gss_name_t * output_name ) { - GSSAPI_KRB5_INIT (); + krb5_context context; *minor_status = 0; *output_name = GSS_C_NO_NAME; + GSSAPI_KRB5_INIT (&context); + if (gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) || gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE_X)) return import_hostbased_name (minor_status, + context, input_name_buffer, output_name); else if (gss_oid_equal(input_name_type, GSS_C_NO_OID) @@ -206,10 +210,12 @@ OM_uint32 _gsskrb5_import_name || gss_oid_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) /* default printable syntax */ return import_krb5_name (minor_status, + context, input_name_buffer, output_name); else if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) { return import_export_name(minor_status, + context, input_name_buffer, output_name); } else { diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c index 8131e2621d..bbdc1d36d0 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: import_sec_context.c,v 1.17 2006/10/07 22:14:53 lha Exp $"); +RCSID("$Id: import_sec_context.c,v 1.18 2006/11/13 18:02:09 lha Exp $"); OM_uint32 _gsskrb5_import_sec_context ( @@ -43,6 +43,7 @@ _gsskrb5_import_sec_context ( ) { OM_uint32 ret = GSS_S_FAILURE; + krb5_context context; krb5_error_code kret; krb5_storage *sp; krb5_auth_context ac; @@ -56,7 +57,7 @@ _gsskrb5_import_sec_context ( gsskrb5_ctx ctx; gss_name_t name; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); *context_handle = GSS_C_NO_CONTEXT; @@ -77,10 +78,9 @@ _gsskrb5_import_sec_context ( } HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); - kret = krb5_auth_con_init (_gsskrb5_context, + kret = krb5_auth_con_init (context, &ctx->auth_context); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; @@ -108,11 +108,11 @@ _gsskrb5_import_sec_context ( goto failure; } - krb5_auth_con_setaddrs (_gsskrb5_context, ac, localp, remotep); + krb5_auth_con_setaddrs (context, ac, localp, remotep); if (localp) - krb5_free_address (_gsskrb5_context, localp); + krb5_free_address (context, localp); if (remotep) - krb5_free_address (_gsskrb5_context, remotep); + krb5_free_address (context, remotep); localp = remotep = NULL; if (krb5_ret_int16 (sp, &ac->local_port) != 0) @@ -123,20 +123,20 @@ _gsskrb5_import_sec_context ( if (flags & SC_KEYBLOCK) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; - krb5_auth_con_setkey (_gsskrb5_context, ac, &keyblock); - krb5_free_keyblock_contents (_gsskrb5_context, &keyblock); + krb5_auth_con_setkey (context, ac, &keyblock); + krb5_free_keyblock_contents (context, &keyblock); } if (flags & SC_LOCAL_SUBKEY) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; - krb5_auth_con_setlocalsubkey (_gsskrb5_context, ac, &keyblock); - krb5_free_keyblock_contents (_gsskrb5_context, &keyblock); + krb5_auth_con_setlocalsubkey (context, ac, &keyblock); + krb5_free_keyblock_contents (context, &keyblock); } if (flags & SC_REMOTE_SUBKEY) { if (krb5_ret_keyblock (sp, &keyblock) != 0) goto failure; - krb5_auth_con_setremotesubkey (_gsskrb5_context, ac, &keyblock); - krb5_free_keyblock_contents (_gsskrb5_context, &keyblock); + krb5_auth_con_setremotesubkey (context, ac, &keyblock); + krb5_free_keyblock_contents (context, &keyblock); } if (krb5_ret_uint32 (sp, &ac->local_seqnumber)) goto failure; @@ -209,16 +209,16 @@ _gsskrb5_import_sec_context ( return GSS_S_COMPLETE; failure: - krb5_auth_con_free (_gsskrb5_context, + krb5_auth_con_free (context, ctx->auth_context); if (ctx->source != NULL) - krb5_free_principal(_gsskrb5_context, ctx->source); + krb5_free_principal(context, ctx->source); if (ctx->target != NULL) - krb5_free_principal(_gsskrb5_context, ctx->target); + krb5_free_principal(context, ctx->target); if (localp) - krb5_free_address (_gsskrb5_context, localp); + krb5_free_address (context, localp); if (remotep) - krb5_free_address (_gsskrb5_context, remotep); + krb5_free_address (context, remotep); if(ctx->order) _gssapi_msg_order_destroy(&ctx->order); HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); diff --git a/source4/heimdal/lib/gssapi/krb5/init.c b/source4/heimdal/lib/gssapi/krb5/init.c index cbef8740b7..3eece8e086 100644 --- a/source4/heimdal/lib/gssapi/krb5/init.c +++ b/source4/heimdal/lib/gssapi/krb5/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003, 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,79 +33,51 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: init.c,v 1.9 2006/10/07 22:14:58 lha Exp $"); +RCSID("$Id: init.c,v 1.10 2006/11/13 18:02:12 lha Exp $"); -static HEIMDAL_MUTEX _gsskrb5_context_mutex = HEIMDAL_MUTEX_INITIALIZER; +static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER; static int created_key; -static HEIMDAL_thread_key gssapi_context_key; +static HEIMDAL_thread_key context_key; static void -gssapi_destroy_thread_context(void *ptr) +destroy_context(void *ptr) { - struct gssapi_thr_context *ctx = ptr; + krb5_context context = ptr; - if (ctx == NULL) + if (context == NULL) return; - if (ctx->error_string) - free(ctx->error_string); - HEIMDAL_MUTEX_destroy(&ctx->mutex); - free(ctx); -} - - -struct gssapi_thr_context * -_gsskrb5_get_thread_context(int createp) -{ - struct gssapi_thr_context *ctx; - int ret; - - HEIMDAL_MUTEX_lock(&_gsskrb5_context_mutex); - - if (!created_key) - abort(); - ctx = HEIMDAL_getspecific(gssapi_context_key); - if (ctx == NULL) { - if (!createp) - goto fail; - ctx = malloc(sizeof(*ctx)); - if (ctx == NULL) - goto fail; - ctx->error_string = NULL; - HEIMDAL_MUTEX_init(&ctx->mutex); - HEIMDAL_setspecific(gssapi_context_key, ctx, ret); - if (ret) - goto fail; - } - HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex); - return ctx; - fail: - HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex); - if (ctx) - free(ctx); - return NULL; + krb5_free_context(context); } krb5_error_code -_gsskrb5_init (void) +_gsskrb5_init (krb5_context *context) { krb5_error_code ret = 0; - HEIMDAL_MUTEX_lock(&_gsskrb5_context_mutex); + HEIMDAL_MUTEX_lock(&context_mutex); - if(_gsskrb5_context == NULL) - ret = krb5_init_context (&_gsskrb5_context); - if (ret == 0 && !created_key) { - HEIMDAL_key_create(&gssapi_context_key, - gssapi_destroy_thread_context, - ret); + if (!created_key) { + HEIMDAL_key_create(&context_key, destroy_context, ret); if (ret) { - krb5_free_context(_gsskrb5_context); - _gsskrb5_context = NULL; - } else - created_key = 1; + HEIMDAL_MUTEX_unlock(&context_mutex); + return ret; + } + created_key = 1; } + HEIMDAL_MUTEX_unlock(&context_mutex); - HEIMDAL_MUTEX_unlock(&_gsskrb5_context_mutex); + *context = HEIMDAL_getspecific(context_key); + if (*context == NULL) { + + ret = krb5_init_context(context); + if (ret == 0) { + HEIMDAL_setspecific(context_key, *context, ret); + if (ret) { + krb5_free_context(*context); + *context = NULL; + } + } + } return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index 27d859ddd8..d5f183b0ba 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: init_sec_context.c,v 1.73 2006/11/07 17:40:01 lha Exp $"); +RCSID("$Id: init_sec_context.c,v 1.75 2006/12/13 10:33:20 lha Exp $"); /* * copy the addresses from `input_chan_bindings' (if any) to @@ -41,7 +41,8 @@ RCSID("$Id: init_sec_context.c,v 1.73 2006/11/07 17:40:01 lha Exp $"); */ static OM_uint32 -set_addresses (krb5_auth_context ac, +set_addresses (krb5_context context, + krb5_auth_context ac, const gss_channel_bindings_t input_chan_bindings) { /* Port numbers are expected to be in application_data.value, @@ -64,29 +65,31 @@ set_addresses (krb5_auth_context ac, ac->remote_port = *((int16_t *) input_chan_bindings->application_data.value + 1); - kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->acceptor_addrtype, + kret = _gsskrb5i_address_to_krb5addr(context, + input_chan_bindings->acceptor_addrtype, &input_chan_bindings->acceptor_address, ac->remote_port, &acceptor_addr); if (kret) return kret; - kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->initiator_addrtype, + kret = _gsskrb5i_address_to_krb5addr(context, + input_chan_bindings->initiator_addrtype, &input_chan_bindings->initiator_address, ac->local_port, &initiator_addr); if (kret) { - krb5_free_address (_gsskrb5_context, &acceptor_addr); + krb5_free_address (context, &acceptor_addr); return kret; } - kret = krb5_auth_con_setaddrs(_gsskrb5_context, + kret = krb5_auth_con_setaddrs(context, ac, &initiator_addr, /* local address */ &acceptor_addr); /* remote address */ - krb5_free_address (_gsskrb5_context, &initiator_addr); - krb5_free_address (_gsskrb5_context, &acceptor_addr); + krb5_free_address (context, &initiator_addr); + krb5_free_address (context, &acceptor_addr); #if 0 free(input_chan_bindings->application_data.value); @@ -101,6 +104,7 @@ OM_uint32 _gsskrb5_create_ctx( OM_uint32 * minor_status, gss_ctx_id_t * context_handle, + krb5_context context, const gss_channel_bindings_t input_chan_bindings, enum gss_ctx_id_t_state state) { @@ -127,23 +131,22 @@ _gsskrb5_create_ctx( ctx->order = NULL; HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); - kret = krb5_auth_con_init (_gsskrb5_context, &ctx->auth_context); + kret = krb5_auth_con_init (context, &ctx->auth_context); if (kret) { *minor_status = kret; - _gsskrb5_set_error_string (); HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); return GSS_S_FAILURE; } - kret = set_addresses(ctx->auth_context, input_chan_bindings); + kret = set_addresses(context, ctx->auth_context, input_chan_bindings); if (kret) { *minor_status = kret; HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); - krb5_auth_con_free(_gsskrb5_context, ctx->auth_context); + krb5_auth_con_free(context, ctx->auth_context); return GSS_S_BAD_BINDINGS; } @@ -152,7 +155,7 @@ _gsskrb5_create_ctx( * We need a sequence number */ - krb5_auth_con_addflags(_gsskrb5_context, + krb5_auth_con_addflags(context, ctx->auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE | KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED, @@ -167,6 +170,7 @@ _gsskrb5_create_ctx( static OM_uint32 gsskrb5_get_creds( OM_uint32 * minor_status, + krb5_context context, krb5_ccache ccache, gsskrb5_ctx ctx, krb5_const_principal target_name, @@ -188,7 +192,7 @@ gsskrb5_get_creds( if (time_req && time_req != GSS_C_INDEFINITE) { krb5_timestamp ts; - krb5_timeofday (_gsskrb5_context, &ts); + krb5_timeofday (context, &ts); this_cred.times.endtime = ts + time_req; } else { this_cred.times.endtime = 0; @@ -196,20 +200,20 @@ gsskrb5_get_creds( this_cred.session.keytype = KEYTYPE_NULL; - kret = krb5_get_credentials(_gsskrb5_context, + kret = krb5_get_credentials(context, 0, ccache, &this_cred, cred); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } ctx->lifetime = (*cred)->times.endtime; - ret = _gsskrb5_lifetime_left(minor_status, ctx->lifetime, &lifetime_rec); + ret = _gsskrb5_lifetime_left(minor_status, context, + ctx->lifetime, &lifetime_rec); if (ret) return ret; if (lifetime_rec == 0) { @@ -225,14 +229,15 @@ gsskrb5_get_creds( static OM_uint32 gsskrb5_initiator_ready( OM_uint32 * minor_status, - gsskrb5_ctx ctx) + gsskrb5_ctx ctx, + krb5_context context) { OM_uint32 ret; int32_t seq_number; int is_cfx = 0; OM_uint32 flags = ctx->flags; - krb5_auth_getremoteseqnumber (_gsskrb5_context, + krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number); @@ -255,7 +260,8 @@ gsskrb5_initiator_ready( */ static void -do_delegation (krb5_auth_context ac, +do_delegation (krb5_context context, + krb5_auth_context ac, krb5_ccache ccache, krb5_creds *cred, krb5_const_principal name, @@ -269,11 +275,11 @@ do_delegation (krb5_auth_context ac, memset (&creds, 0, sizeof(creds)); krb5_data_zero (fwd_data); - kret = krb5_cc_get_principal(_gsskrb5_context, ccache, &creds.client); + kret = krb5_cc_get_principal(context, ccache, &creds.client); if (kret) goto out; - kret = krb5_build_principal(_gsskrb5_context, + kret = krb5_build_principal(context, &creds.server, strlen(creds.client->realm), creds.client->realm, @@ -293,7 +299,7 @@ do_delegation (krb5_auth_context ac, name->name.name_string.len < 2) goto out; - kret = krb5_get_forwarded_creds(_gsskrb5_context, + kret = krb5_get_forwarded_creds(context, ac, ccache, KDCOptions2int(fwd_flags), @@ -308,9 +314,9 @@ do_delegation (krb5_auth_context ac, *flags |= GSS_C_DELEG_FLAG; if (creds.client) - krb5_free_principal(_gsskrb5_context, creds.client); + krb5_free_principal(context, creds.client); if (creds.server) - krb5_free_principal(_gsskrb5_context, creds.server); + krb5_free_principal(context, creds.server); } /* @@ -322,6 +328,7 @@ init_auth (OM_uint32 * minor_status, gsskrb5_cred initiator_cred_handle, gsskrb5_ctx ctx, + krb5_context context, krb5_const_principal name, const gss_OID mech_type, OM_uint32 req_flags, @@ -356,9 +363,8 @@ init_auth *actual_mech_type = GSS_KRB5_MECHANISM; if (initiator_cred_handle == NULL) { - kret = krb5_cc_default (_gsskrb5_context, &ccache); + kret = krb5_cc_default (context, &ccache); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; @@ -366,28 +372,27 @@ init_auth } else ccache = initiator_cred_handle->ccache; - kret = krb5_cc_get_principal (_gsskrb5_context, ccache, &ctx->source); + kret = krb5_cc_get_principal (context, ccache, &ctx->source); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } - kret = krb5_copy_principal (_gsskrb5_context, name, &ctx->target); + kret = krb5_copy_principal (context, name, &ctx->target); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } - ret = _gss_DES3_get_mic_compat(minor_status, ctx); + ret = _gss_DES3_get_mic_compat(minor_status, ctx, context); if (ret) goto failure; ret = gsskrb5_get_creds(minor_status, + context, ccache, ctx, ctx->target, @@ -400,8 +405,9 @@ init_auth ctx->lifetime = cred->times.endtime; ret = _gsskrb5_lifetime_left(minor_status, - ctx->lifetime, - &lifetime_rec); + context, + ctx->lifetime, + &lifetime_rec); if (ret) { goto failure; } @@ -412,15 +418,14 @@ init_auth goto failure; } - krb5_auth_con_setkey(_gsskrb5_context, + krb5_auth_con_setkey(context, ctx->auth_context, &cred->session); - kret = krb5_auth_con_generatelocalsubkey(_gsskrb5_context, + kret = krb5_auth_con_generatelocalsubkey(context, ctx->auth_context, &cred->session); if(kret) { - _gsskrb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; @@ -436,7 +441,7 @@ init_auth if (!cred->flags.b.ok_as_delegate) { krb5_boolean delegate; - krb5_appdefault_boolean(_gsskrb5_context, + krb5_appdefault_boolean(context, "gssapi", name->realm, "ok-as-delegate", FALSE, &delegate); if (delegate) @@ -446,7 +451,8 @@ init_auth flags = 0; ap_options = 0; if (req_flags & GSS_C_DELEG_FLAG) - do_delegation (ctx->auth_context, + do_delegation (context, + ctx->auth_context, ccache, cred, name, &fwd_data, &flags); if (req_flags & GSS_C_MUTUAL_FLAG) { @@ -471,9 +477,9 @@ init_auth flags |= GSS_C_EXTENDED_ERROR_FLAG; if (req_flags & GSS_C_CONF_FLAG) - flags |= GSS_C_CONF_FLAG; + flags |= GSS_C_CONF_FLAG; if (req_flags & GSS_C_INTEG_FLAG) - flags |= GSS_C_INTEG_FLAG; + flags |= GSS_C_INTEG_FLAG; flags |= GSS_C_TRANS_FLAG; @@ -493,7 +499,7 @@ init_auth enctype = ctx->auth_context->keyblock->keytype; - kret = krb5_build_authenticator (_gsskrb5_context, + kret = krb5_build_authenticator (context, ctx->auth_context, enctype, cred, @@ -503,13 +509,12 @@ init_auth KRB5_KU_AP_REQ_AUTH); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; } - kret = krb5_build_ap_req (_gsskrb5_context, + kret = krb5_build_ap_req (context, enctype, cred, ap_options, @@ -517,7 +522,6 @@ init_auth &outbuf); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; ret = GSS_S_FAILURE; goto failure; @@ -529,22 +533,22 @@ init_auth goto failure; krb5_data_free (&outbuf); - krb5_free_creds(_gsskrb5_context, cred); + krb5_free_creds(context, cred); free_Checksum(&cksum); if (initiator_cred_handle == NULL) - krb5_cc_close(_gsskrb5_context, ccache); + krb5_cc_close(context, ccache); if (flags & GSS_C_MUTUAL_FLAG) { ctx->state = INITIATOR_WAIT_FOR_MUTAL; return GSS_S_CONTINUE_NEEDED; } - return gsskrb5_initiator_ready(minor_status, ctx); + return gsskrb5_initiator_ready(minor_status, ctx, context); failure: if(cred) - krb5_free_creds(_gsskrb5_context, cred); + krb5_free_creds(context, cred); if (ccache && initiator_cred_handle == NULL) - krb5_cc_close(_gsskrb5_context, ccache); + krb5_cc_close(context, ccache); return ret; @@ -554,6 +558,7 @@ static OM_uint32 repl_mutual (OM_uint32 * minor_status, gsskrb5_ctx ctx, + krb5_context context, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, @@ -593,28 +598,27 @@ repl_mutual } } - kret = krb5_rd_rep (_gsskrb5_context, + kret = krb5_rd_rep (context, ctx->auth_context, &indata, &repl); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } - krb5_free_ap_rep_enc_part (_gsskrb5_context, + krb5_free_ap_rep_enc_part (context, repl); _gsskrb5i_is_cfx(ctx, &is_cfx); if (is_cfx) { krb5_keyblock *key = NULL; - kret = krb5_auth_con_getremotesubkey(_gsskrb5_context, + kret = krb5_auth_con_getremotesubkey(context, ctx->auth_context, &key); if (kret == 0 && key != NULL) { ctx->more_flags |= ACCEPTOR_SUBKEY; - krb5_free_keyblock (_gsskrb5_context, key); + krb5_free_keyblock (context, key); } } @@ -622,6 +626,7 @@ repl_mutual *minor_status = 0; if (time_rec) { ret = _gsskrb5_lifetime_left(minor_status, + context, ctx->lifetime, time_rec); } else { @@ -635,16 +640,15 @@ repl_mutual krb5_data outbuf; /* Do don't do sequence number for the mk-rep */ - krb5_auth_con_removeflags(_gsskrb5_context, + krb5_auth_con_removeflags(context, ctx->auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE, &con_flags); - kret = krb5_mk_rep(_gsskrb5_context, + kret = krb5_mk_rep(context, ctx->auth_context, &outbuf); if (kret) { - _gsskrb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; } @@ -652,13 +656,13 @@ repl_mutual output_token->length = outbuf.length; output_token->value = outbuf.data; - krb5_auth_con_removeflags(_gsskrb5_context, + krb5_auth_con_removeflags(context, ctx->auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE, NULL); } - return gsskrb5_initiator_ready(minor_status, ctx); + return gsskrb5_initiator_ready(minor_status, ctx, context); } /* @@ -681,12 +685,13 @@ OM_uint32 _gsskrb5_init_sec_context OM_uint32 * time_rec ) { + krb5_context context; gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle; krb5_const_principal name = (krb5_const_principal)target_name; gsskrb5_ctx ctx; OM_uint32 ret; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); output_token->length = 0; output_token->value = NULL; @@ -722,6 +727,7 @@ OM_uint32 _gsskrb5_init_sec_context ret = _gsskrb5_create_ctx(minor_status, context_handle, + context, input_chan_bindings, INITIATOR_START); if (ret) @@ -742,6 +748,7 @@ OM_uint32 _gsskrb5_init_sec_context ret = init_auth(minor_status, cred, ctx, + context, name, mech_type, req_flags, @@ -756,6 +763,7 @@ OM_uint32 _gsskrb5_init_sec_context case INITIATOR_WAIT_FOR_MUTAL: ret = repl_mutual(minor_status, ctx, + context, mech_type, req_flags, time_req, diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c index ef43e6852c..bdaa01b108 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_context.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_context.c,v 1.10 2006/10/07 22:15:03 lha Exp $"); +RCSID("$Id: inquire_context.c,v 1.11 2006/11/13 18:02:18 lha Exp $"); OM_uint32 _gsskrb5_inquire_context ( OM_uint32 * minor_status, @@ -47,6 +47,7 @@ OM_uint32 _gsskrb5_inquire_context ( int * open_context ) { + krb5_context context; OM_uint32 ret; gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle; gss_name_t name; @@ -56,6 +57,8 @@ OM_uint32 _gsskrb5_inquire_context ( if (targ_name) *targ_name = GSS_C_NO_NAME; + GSSAPI_KRB5_INIT (&context); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (src_name) { @@ -74,6 +77,7 @@ OM_uint32 _gsskrb5_inquire_context ( if (lifetime_rec) { ret = _gsskrb5_lifetime_left(minor_status, + context, ctx->lifetime, lifetime_rec); if (ret) diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c index 0593729365..74018559a0 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_cred.c,v 1.12 2006/10/07 22:15:06 lha Exp $"); +RCSID("$Id: inquire_cred.c,v 1.13 2006/11/13 18:02:21 lha Exp $"); OM_uint32 _gsskrb5_inquire_cred (OM_uint32 * minor_status, @@ -44,6 +44,7 @@ OM_uint32 _gsskrb5_inquire_cred gss_OID_set * mechanisms ) { + krb5_context context; gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL; gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL; gsskrb5_cred acred = NULL, icred = NULL; @@ -56,6 +57,8 @@ OM_uint32 _gsskrb5_inquire_cred if (mechanisms) *mechanisms = GSS_C_NO_OID_SET; + GSSAPI_KRB5_INIT (&context); + if (cred_handle == GSS_C_NO_CREDENTIAL) { ret = _gsskrb5_acquire_cred(minor_status, GSS_C_NO_NAME, @@ -105,7 +108,7 @@ OM_uint32 _gsskrb5_inquire_cred goto out; } else if (acred && acred->usage == GSS_C_ACCEPT) { krb5_principal princ; - *minor_status = krb5_sname_to_principal(_gsskrb5_context, NULL, + *minor_status = krb5_sname_to_principal(context, NULL, NULL, KRB5_NT_SRV_HST, &princ); if (*minor_status) { @@ -115,7 +118,7 @@ OM_uint32 _gsskrb5_inquire_cred *output_name = (gss_name_t)princ; } else { krb5_principal princ; - *minor_status = krb5_get_default_principal(_gsskrb5_context, + *minor_status = krb5_get_default_principal(context, &princ); if (*minor_status) { ret = GSS_S_FAILURE; @@ -131,6 +134,7 @@ OM_uint32 _gsskrb5_inquire_cred if (icred) ilife = icred->lifetime; ret = _gsskrb5_lifetime_left(minor_status, + context, min(alife,ilife), lifetime); if (ret) diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c index 26927c740c..1a36896019 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_cred_by_oid.c,v 1.4 2006/10/07 22:15:10 lha Exp $"); +RCSID("$Id: inquire_cred_by_oid.c,v 1.5 2006/11/13 18:02:24 lha Exp $"); OM_uint32 _gsskrb5_inquire_cred_by_oid (OM_uint32 * minor_status, @@ -40,11 +40,14 @@ OM_uint32 _gsskrb5_inquire_cred_by_oid const gss_OID desired_object, gss_buffer_set_t *data_set) { + krb5_context context; gsskrb5_cred cred = (gsskrb5_cred)cred_handle; krb5_error_code ret; gss_buffer_desc buffer; char *str; + GSSAPI_KRB5_INIT (&context); + if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) { *minor_status = EINVAL; return GSS_S_FAILURE; @@ -58,11 +61,10 @@ OM_uint32 _gsskrb5_inquire_cred_by_oid return GSS_S_FAILURE; } - ret = krb5_cc_get_full_name(_gsskrb5_context, cred->ccache, &str); + ret = krb5_cc_get_full_name(context, cred->ccache, &str); HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); if (ret) { *minor_status = ret; - _gsskrb5_set_error_string (); return GSS_S_FAILURE; } diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c index ee4210d74a..97e86a95c7 100644 --- a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c +++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: inquire_sec_context_by_oid.c,v 1.11 2006/11/07 14:34:35 lha Exp $"); +RCSID("$Id: inquire_sec_context_by_oid.c,v 1.12 2006/11/13 18:02:27 lha Exp $"); static int oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix) @@ -106,6 +106,7 @@ enum keytype { ACCEPTOR_KEY, INITIATOR_KEY, TOKEN_KEY }; static OM_uint32 inquire_sec_context_get_subkey (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, enum keytype keytype, gss_buffer_set_t *data_set) { @@ -127,19 +128,13 @@ static OM_uint32 inquire_sec_context_get_subkey HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); switch(keytype) { case ACCEPTOR_KEY: - ret = _gsskrb5i_get_acceptor_subkey(context_handle, &key); - if (ret) - _gsskrb5_set_error_string (); + ret = _gsskrb5i_get_acceptor_subkey(context_handle, context, &key); break; case INITIATOR_KEY: - ret = _gsskrb5i_get_initiator_subkey(context_handle, &key); - if (ret) - _gsskrb5_set_error_string (); + ret = _gsskrb5i_get_initiator_subkey(context_handle, context, &key); break; case TOKEN_KEY: - ret = _gsskrb5i_get_token_key(context_handle, &key); - if (ret) - _gsskrb5_set_error_string (); + ret = _gsskrb5i_get_token_key(context_handle, context, &key); break; default: _gsskrb5_set_status("%d is not a valid subkey type", keytype); @@ -156,17 +151,13 @@ static OM_uint32 inquire_sec_context_get_subkey } ret = krb5_store_keyblock(sp, *key); - krb5_free_keyblock (_gsskrb5_context, key); - if (ret) { - _gsskrb5_set_error_string (); + krb5_free_keyblock (context, key); + if (ret) goto out; - } ret = krb5_storage_to_data(sp, &data); - if (ret) { - _gsskrb5_set_error_string (); + if (ret) goto out; - } { gss_buffer_desc value; @@ -193,6 +184,7 @@ out: static OM_uint32 inquire_sec_context_authz_data (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, + krb5_context context, unsigned ad_type, gss_buffer_set_t *data_set) { @@ -211,13 +203,12 @@ static OM_uint32 inquire_sec_context_authz_data return GSS_S_NO_CONTEXT; } - ret = krb5_ticket_get_authorization_data_type(_gsskrb5_context, + ret = krb5_ticket_get_authorization_data_type(context, context_handle->ticket, ad_type, &data); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } @@ -276,6 +267,7 @@ static OM_uint32 inquire_sec_context_has_updated_spnego static OM_uint32 export_lucid_sec_context_v1(OM_uint32 *minor_status, gsskrb5_ctx context_handle, + krb5_context context, gss_buffer_set_t *data_set) { krb5_storage *sp = NULL; @@ -288,8 +280,6 @@ export_lucid_sec_context_v1(OM_uint32 *minor_status, *minor_status = 0; - GSSAPI_KRB5_INIT (); - HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); _gsskrb5i_is_cfx(context_handle, &is_cfx); @@ -307,12 +297,12 @@ export_lucid_sec_context_v1(OM_uint32 *minor_status, if (ret) goto out; ret = krb5_store_int32(sp, context_handle->lifetime); if (ret) goto out; - krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &number); ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ ret = krb5_store_uint32(sp, (uint32_t)number); - krb5_auth_getremoteseqnumber (_gsskrb5_context, + krb5_auth_getremoteseqnumber (context, context_handle->auth_context, &number); ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */ @@ -320,7 +310,7 @@ export_lucid_sec_context_v1(OM_uint32 *minor_status, ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0); if (ret) goto out; - ret = _gsskrb5i_get_token_key(context_handle, &key); + ret = _gsskrb5i_get_token_key(context_handle, context, &key); if (ret) goto out; if (is_cfx == 0) { @@ -387,7 +377,7 @@ export_lucid_sec_context_v1(OM_uint32 *minor_status, out: if (key) - krb5_free_keyblock (_gsskrb5_context, key); + krb5_free_keyblock (context, key); if (sp) krb5_storage_free(sp); if (ret) { @@ -485,7 +475,6 @@ out: if (sp) krb5_storage_free(sp); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; maj_stat = GSS_S_FAILURE; } @@ -501,6 +490,7 @@ OM_uint32 _gsskrb5_inquire_sec_context_by_oid const gss_OID desired_object, gss_buffer_set_t *data_set) { + krb5_context context; const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; unsigned suffix; @@ -509,6 +499,8 @@ OM_uint32 _gsskrb5_inquire_sec_context_by_oid return GSS_S_NO_CONTEXT; } + GSSAPI_KRB5_INIT (&context); + if (gss_oid_equal(desired_object, GSS_KRB5_GET_TKT_FLAGS_X)) { return inquire_sec_context_tkt_flags(minor_status, ctx, @@ -520,16 +512,19 @@ OM_uint32 _gsskrb5_inquire_sec_context_by_oid } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) { return inquire_sec_context_get_subkey(minor_status, ctx, + context, TOKEN_KEY, data_set); } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X)) { return inquire_sec_context_get_subkey(minor_status, ctx, + context, INITIATOR_KEY, data_set); } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X)) { return inquire_sec_context_get_subkey(minor_status, ctx, + context, ACCEPTOR_KEY, data_set); } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_AUTHTIME_X)) { @@ -539,6 +534,7 @@ OM_uint32 _gsskrb5_inquire_sec_context_by_oid &suffix)) { return inquire_sec_context_authz_data(minor_status, ctx, + context, suffix, data_set); } else if (oid_prefix_equal(desired_object, @@ -547,6 +543,7 @@ OM_uint32 _gsskrb5_inquire_sec_context_by_oid if (suffix == 1) return export_lucid_sec_context_v1(minor_status, ctx, + context, data_set); *minor_status = 0; return GSS_S_FAILURE; diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c index 99568c9dd0..411d689635 100644 --- a/source4/heimdal/lib/gssapi/krb5/process_context_token.c +++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: process_context_token.c,v 1.4 2006/10/07 22:15:19 lha Exp $"); +RCSID("$Id: process_context_token.c,v 1.5 2006/11/13 18:02:30 lha Exp $"); OM_uint32 _gsskrb5_process_context_token ( OM_uint32 *minor_status, @@ -41,6 +41,7 @@ OM_uint32 _gsskrb5_process_context_token ( const gss_buffer_t token_buffer ) { + krb5_context context; OM_uint32 ret = GSS_S_FAILURE; gss_buffer_desc empty_buffer; gss_qop_t qop_state; @@ -48,10 +49,13 @@ OM_uint32 _gsskrb5_process_context_token ( empty_buffer.length = 0; empty_buffer.value = NULL; + GSSAPI_KRB5_INIT (&context); + qop_state = GSS_C_QOP_DEFAULT; ret = _gsskrb5_verify_mic_internal(minor_status, (gsskrb5_ctx)context_handle, + context, token_buffer, &empty_buffer, GSS_C_QOP_DEFAULT, "\x01\x02"); diff --git a/source4/heimdal/lib/gssapi/krb5/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c index 662461ccfd..f6d98b29c6 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c @@ -33,13 +33,14 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_cred.c,v 1.13 2006/10/07 22:15:24 lha Exp $"); +RCSID("$Id: release_cred.c,v 1.14 2006/11/13 18:02:34 lha Exp $"); OM_uint32 _gsskrb5_release_cred (OM_uint32 * minor_status, gss_cred_id_t * cred_handle ) { + krb5_context context; gsskrb5_cred cred; *minor_status = 0; @@ -50,21 +51,21 @@ OM_uint32 _gsskrb5_release_cred cred = (gsskrb5_cred)*cred_handle; *cred_handle = GSS_C_NO_CREDENTIAL; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); if (cred->principal != NULL) - krb5_free_principal(_gsskrb5_context, cred->principal); + krb5_free_principal(context, cred->principal); if (cred->keytab != NULL) - krb5_kt_close(_gsskrb5_context, cred->keytab); + krb5_kt_close(context, cred->keytab); if (cred->ccache != NULL) { const krb5_cc_ops *ops; - ops = krb5_cc_get_ops(_gsskrb5_context, cred->ccache); + ops = krb5_cc_get_ops(context, cred->ccache); if (cred->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE) - krb5_cc_destroy(_gsskrb5_context, cred->ccache); + krb5_cc_destroy(context, cred->ccache); else - krb5_cc_close(_gsskrb5_context, cred->ccache); + krb5_cc_close(context, cred->ccache); } _gsskrb5_release_oid_set(NULL, &cred->mechanisms); HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); diff --git a/source4/heimdal/lib/gssapi/krb5/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c index a92ad939a5..cc9c0934f7 100644 --- a/source4/heimdal/lib/gssapi/krb5/release_name.c +++ b/source4/heimdal/lib/gssapi/krb5/release_name.c @@ -33,23 +33,24 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: release_name.c,v 1.10 2006/10/07 22:15:26 lha Exp $"); +RCSID("$Id: release_name.c,v 1.11 2006/11/13 18:02:37 lha Exp $"); OM_uint32 _gsskrb5_release_name (OM_uint32 * minor_status, gss_name_t * input_name ) { + krb5_context context; krb5_principal name = (krb5_principal)*input_name; - GSSAPI_KRB5_INIT (); - if (minor_status) *minor_status = 0; + GSSAPI_KRB5_INIT (&context); + *input_name = GSS_C_NO_NAME; - krb5_free_principal(_gsskrb5_context, name); + krb5_free_principal(context, name); return GSS_S_COMPLETE; } diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index 5807ef0166..849760ee4a 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -32,7 +32,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: set_cred_option.c,v 1.4 2006/10/24 20:14:13 lha Exp $"); +RCSID("$Id: set_cred_option.c,v 1.5 2006/11/13 18:02:39 lha Exp $"); static gss_OID_desc gss_krb5_import_cred_x_oid_desc = {9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */ @@ -41,6 +41,7 @@ gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc; static OM_uint32 import_cred(OM_uint32 *minor_status, + krb5_context context, gss_cred_id_t *cred_handle, const gss_buffer_t value) { @@ -71,7 +72,7 @@ import_cred(OM_uint32 *minor_status, goto out; } if (str[0]) { - ret = krb5_cc_resolve(_gsskrb5_context, str, &id); + ret = krb5_cc_resolve(context, str, &id); if (ret) { *minor_status = ret; major_stat = GSS_S_FAILURE; @@ -84,7 +85,7 @@ import_cred(OM_uint32 *minor_status, /* keytab principal name */ ret = krb5_ret_string(sp, &str); if (ret == 0 && str[0]) - ret = krb5_parse_name(_gsskrb5_context, str, &keytab_principal); + ret = krb5_parse_name(context, str, &keytab_principal); if (ret) { *minor_status = ret; major_stat = GSS_S_FAILURE; @@ -101,7 +102,7 @@ import_cred(OM_uint32 *minor_status, goto out; } if (str[0]) { - ret = krb5_kt_resolve(_gsskrb5_context, str, &keytab); + ret = krb5_kt_resolve(context, str, &keytab); if (ret) { *minor_status = ret; major_stat = GSS_S_FAILURE; @@ -115,11 +116,11 @@ import_cred(OM_uint32 *minor_status, keytab, cred_handle); out: if (id) - krb5_cc_close(_gsskrb5_context, id); + krb5_cc_close(context, id); if (keytab_principal) - krb5_free_principal(_gsskrb5_context, keytab_principal); + krb5_free_principal(context, keytab_principal); if (keytab) - krb5_kt_close(_gsskrb5_context, keytab); + krb5_kt_close(context, keytab); if (str) free(str); if (sp) @@ -136,7 +137,9 @@ _gsskrb5_set_cred_option const gss_OID desired_object, const gss_buffer_t value) { - GSSAPI_KRB5_INIT (); + krb5_context context; + + GSSAPI_KRB5_INIT (&context); if (value == GSS_C_NO_BUFFER) { *minor_status = EINVAL; @@ -144,7 +147,7 @@ _gsskrb5_set_cred_option } if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) { - return import_cred(minor_status, cred_handle, value); + return import_cred(minor_status, context, cred_handle, value); } *minor_status = EINVAL; diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c index dc1495efc1..4a5f60ce94 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c @@ -36,7 +36,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: set_sec_context_option.c,v 1.8 2006/11/08 23:06:42 lha Exp $"); +RCSID("$Id: set_sec_context_option.c,v 1.10 2006/12/14 11:02:16 lha Exp $"); static OM_uint32 get_bool(OM_uint32 *minor_status, @@ -58,9 +58,10 @@ _gsskrb5_set_sec_context_option const gss_OID desired_object, const gss_buffer_t value) { + krb5_context context; OM_uint32 maj_stat; - GSSAPI_KRB5_INIT (); + GSSAPI_KRB5_INIT (&context); if (value == GSS_C_NO_BUFFER) { *minor_status = EINVAL; @@ -96,7 +97,7 @@ _gsskrb5_set_sec_context_option if (maj_stat != GSS_S_COMPLETE) return maj_stat; - krb5_set_dns_canonicalize_hostname(_gsskrb5_context, flag); + krb5_set_dns_canonicalize_hostname(context, flag); return GSS_S_COMPLETE; } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) { @@ -128,14 +129,14 @@ _gsskrb5_set_sec_context_option return GSS_S_CALL_INACCESSIBLE_READ; } str = malloc(value->length + 1); - if (str) { + if (str == NULL) { *minor_status = 0; return GSS_S_UNAVAILABLE; } memcpy(str, value->value, value->length); str[value->length] = '\0'; - krb5_set_default_realm(_gsskrb5_context, str); + krb5_set_default_realm(context, str); free(str); *minor_status = 0; @@ -144,7 +145,7 @@ _gsskrb5_set_sec_context_option } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) { if (value == NULL || value->length == 0) { - krb5_set_send_to_kdc_func(_gsskrb5_context, NULL, NULL); + krb5_set_send_to_kdc_func(context, NULL, NULL); } else { struct gsskrb5_send_to_kdc c; @@ -153,7 +154,7 @@ _gsskrb5_set_sec_context_option return GSS_S_FAILURE; } memcpy(&c, value->value, sizeof(c)); - krb5_set_send_to_kdc_func(_gsskrb5_context, + krb5_set_send_to_kdc_func(context, (krb5_send_to_kdc_func)c.func, c.ptr); } diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c index 758390080c..3dd7618561 100644 --- a/source4/heimdal/lib/gssapi/krb5/unwrap.c +++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c @@ -33,7 +33,7 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: unwrap.c,v 1.38 2006/10/18 15:59:28 lha Exp $"); +RCSID("$Id: unwrap.c,v 1.39 2006/11/13 18:02:51 lha Exp $"); static OM_uint32 unwrap_des @@ -175,6 +175,7 @@ static OM_uint32 unwrap_des3 (OM_uint32 * minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int * conf_state, @@ -226,18 +227,16 @@ unwrap_des3 /* decrypt data */ krb5_data tmp; - ret = krb5_crypto_init(_gsskrb5_context, key, + ret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_decrypt(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL, + ret = krb5_decrypt(context, crypto, KRB5_KU_USAGE_SEAL, p, input_message_buffer->length - len, &tmp); - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } @@ -259,10 +258,9 @@ unwrap_des3 p -= 28; - ret = krb5_crypto_init(_gsskrb5_context, key, + ret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_FAILURE; @@ -271,15 +269,14 @@ unwrap_des3 DES_cblock ivec; memcpy(&ivec, p + 8, 8); - ret = krb5_decrypt_ivec (_gsskrb5_context, + ret = krb5_decrypt_ivec (context, crypto, KRB5_KU_USAGE_SEQ, p, 8, &seq_data, &ivec); } - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_FAILURE; @@ -325,21 +322,19 @@ unwrap_des3 csum.checksum.length = 20; csum.checksum.data = cksum; - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_verify_checksum (_gsskrb5_context, crypto, + ret = krb5_verify_checksum (context, crypto, KRB5_KU_USAGE_SIGN, p + 20, input_message_buffer->length - len + 8, &csum); - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } @@ -367,6 +362,7 @@ OM_uint32 _gsskrb5_unwrap ) { krb5_keyblock *key; + krb5_context context; OM_uint32 ret; krb5_keytype keytype; gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle; @@ -374,17 +370,18 @@ OM_uint32 _gsskrb5_unwrap output_message_buffer->value = NULL; output_message_buffer->length = 0; + GSSAPI_KRB5_INIT (&context); + if (qop_state != NULL) *qop_state = GSS_C_QOP_DEFAULT; HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - ret = _gsskrb5i_get_token_key(ctx, &key); + ret = _gsskrb5i_get_token_key(ctx, context, &key); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (context, key->keytype, &keytype); *minor_status = 0; @@ -395,22 +392,22 @@ OM_uint32 _gsskrb5_unwrap conf_state, qop_state, key); break; case KEYTYPE_DES3 : - ret = unwrap_des3 (minor_status, ctx, + ret = unwrap_des3 (minor_status, ctx, context, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_unwrap_arcfour (minor_status, ctx, + ret = _gssapi_unwrap_arcfour (minor_status, ctx, context, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; default : - ret = _gssapi_unwrap_cfx (minor_status, ctx, + ret = _gssapi_unwrap_cfx (minor_status, ctx, context, input_message_buffer, output_message_buffer, conf_state, qop_state, key); break; } - krb5_free_keyblock (_gsskrb5_context, key); + krb5_free_keyblock (context, key); return ret; } diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c index 920937cafc..29b3a7f4bb 100644 --- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c +++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c @@ -33,12 +33,13 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: verify_mic.c,v 1.36 2006/10/18 15:59:30 lha Exp $"); +RCSID("$Id: verify_mic.c,v 1.37 2006/11/13 18:02:54 lha Exp $"); static OM_uint32 verify_mic_des (OM_uint32 * minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -131,6 +132,7 @@ static OM_uint32 verify_mic_des3 (OM_uint32 * minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -164,10 +166,9 @@ verify_mic_des3 return GSS_S_BAD_MIC; p += 4; - ret = krb5_crypto_init(_gsskrb5_context, key, + ret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret){ - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } @@ -180,14 +181,13 @@ retry: else memcpy(ivec, p + 8, 8); - ret = krb5_decrypt_ivec (_gsskrb5_context, + ret = krb5_decrypt_ivec (context, crypto, KRB5_KU_USAGE_SEQ, p, 8, &seq_data, ivec); if (ret) { if (docompat++) { - _gsskrb5_set_error_string (); - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); *minor_status = ret; return GSS_S_FAILURE; } else @@ -197,7 +197,7 @@ retry: if (seq_data.length != 8) { krb5_data_free (&seq_data); if (docompat++) { - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); return GSS_S_BAD_MIC; } else goto retry; @@ -215,7 +215,7 @@ retry: krb5_data_free (&seq_data); if (cmp != 0) { - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); *minor_status = 0; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_BAD_MIC; @@ -223,7 +223,7 @@ retry: ret = _gssapi_msg_order_check(context_handle->order, seq_number); if (ret) { - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); *minor_status = 0; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return ret; @@ -233,7 +233,7 @@ retry: tmp = malloc (message_buffer->length + 8); if (tmp == NULL) { - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); *minor_status = ENOMEM; return GSS_S_FAILURE; @@ -246,21 +246,20 @@ retry: csum.checksum.length = 20; csum.checksum.data = p + 8; - ret = krb5_verify_checksum (_gsskrb5_context, crypto, + ret = krb5_verify_checksum (context, crypto, KRB5_KU_USAGE_SIGN, tmp, message_buffer->length + 8, &csum); free (tmp); if (ret) { - _gsskrb5_set_error_string (); - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); *minor_status = ret; HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_BAD_MIC; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); return GSS_S_COMPLETE; } @@ -268,6 +267,7 @@ OM_uint32 _gsskrb5_verify_mic_internal (OM_uint32 * minor_status, const gsskrb5_ctx context_handle, + krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, @@ -279,39 +279,40 @@ _gsskrb5_verify_mic_internal krb5_keytype keytype; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - ret = _gsskrb5i_get_token_key(context_handle, &key); + ret = _gsskrb5i_get_token_key(context_handle, context, &key); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } *minor_status = 0; - krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : - ret = verify_mic_des (minor_status, context_handle, + ret = verify_mic_des (minor_status, context_handle, context, message_buffer, token_buffer, qop_state, key, type); break; case KEYTYPE_DES3 : - ret = verify_mic_des3 (minor_status, context_handle, + ret = verify_mic_des3 (minor_status, context_handle, context, message_buffer, token_buffer, qop_state, key, type); break; case KEYTYPE_ARCFOUR : case KEYTYPE_ARCFOUR_56 : ret = _gssapi_verify_mic_arcfour (minor_status, context_handle, + context, message_buffer, token_buffer, qop_state, key, type); break; default : ret = _gssapi_verify_mic_cfx (minor_status, context_handle, + context, message_buffer, token_buffer, qop_state, key); break; } - krb5_free_keyblock (_gsskrb5_context, key); + krb5_free_keyblock (context, key); return ret; } @@ -325,13 +326,17 @@ _gsskrb5_verify_mic gss_qop_t * qop_state ) { + krb5_context context; OM_uint32 ret; + GSSAPI_KRB5_INIT (&context); + if (qop_state != NULL) *qop_state = GSS_C_QOP_DEFAULT; ret = _gsskrb5_verify_mic_internal(minor_status, - (gsskrb5_ctx)context_handle, + (gsskrb5_ctx)context_handle, + context, message_buffer, token_buffer, qop_state, "\x01\x01"); diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c index ebbc975b8a..79cfb48ed2 100644 --- a/source4/heimdal/lib/gssapi/krb5/wrap.c +++ b/source4/heimdal/lib/gssapi/krb5/wrap.c @@ -33,74 +33,80 @@ #include "krb5/gsskrb5_locl.h" -RCSID("$Id: wrap.c,v 1.37 2006/10/18 15:59:33 lha Exp $"); +RCSID("$Id: wrap.c,v 1.39 2006/11/14 09:49:56 lha Exp $"); /* * Return initiator subkey, or if that doesn't exists, the subkey. */ krb5_error_code -_gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key) +_gsskrb5i_get_initiator_subkey(const gsskrb5_ctx ctx, + krb5_context context, + krb5_keyblock **key) { krb5_error_code ret; *key = NULL; if (ctx->more_flags & LOCAL) { - ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context, + ret = krb5_auth_con_getlocalsubkey(context, ctx->auth_context, key); } else { - ret = krb5_auth_con_getremotesubkey(_gsskrb5_context, + ret = krb5_auth_con_getremotesubkey(context, ctx->auth_context, key); } - if (*key == NULL) - ret = krb5_auth_con_getkey(_gsskrb5_context, + if (ret == 0 && *key == NULL) + ret = krb5_auth_con_getkey(context, ctx->auth_context, key); - if (*key == NULL) { - _gsskrb5_set_status("No initiator subkey available"); + if (ret == 0 && *key == NULL) { + krb5_set_error_string(context, "No initiator subkey available"); return GSS_KRB5_S_KG_NO_SUBKEY; } return ret; } krb5_error_code -_gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx, krb5_keyblock **key) +_gsskrb5i_get_acceptor_subkey(const gsskrb5_ctx ctx, + krb5_context context, + krb5_keyblock **key) { krb5_error_code ret; *key = NULL; if (ctx->more_flags & LOCAL) { - ret = krb5_auth_con_getremotesubkey(_gsskrb5_context, + ret = krb5_auth_con_getremotesubkey(context, ctx->auth_context, key); } else { - ret = krb5_auth_con_getlocalsubkey(_gsskrb5_context, + ret = krb5_auth_con_getlocalsubkey(context, ctx->auth_context, key); } - if (*key == NULL) { - _gsskrb5_set_status("No acceptor subkey available"); + if (ret == 0 && *key == NULL) { + krb5_set_error_string(context, "No acceptor subkey available"); return GSS_KRB5_S_KG_NO_SUBKEY; } return ret; } OM_uint32 -_gsskrb5i_get_token_key(const gsskrb5_ctx ctx, krb5_keyblock **key) +_gsskrb5i_get_token_key(const gsskrb5_ctx ctx, + krb5_context context, + krb5_keyblock **key) { - _gsskrb5i_get_acceptor_subkey(ctx, key); + _gsskrb5i_get_acceptor_subkey(ctx, context, key); if(*key == NULL) { /* * Only use the initiator subkey or ticket session key if an * acceptor subkey was not required. */ if ((ctx->more_flags & ACCEPTOR_SUBKEY) == 0) - _gsskrb5i_get_initiator_subkey(ctx, key); + _gsskrb5i_get_initiator_subkey(ctx, context, key); } if (*key == NULL) { - _gsskrb5_set_status("No token key available"); + krb5_set_error_string(context, "No token key available"); return GSS_KRB5_S_KG_NO_SUBKEY; } return 0; @@ -140,20 +146,22 @@ _gsskrb5_wrap_size_limit ( OM_uint32 * max_input_size ) { + krb5_context context; krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; + GSSAPI_KRB5_INIT (&context); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - ret = _gsskrb5i_get_token_key(ctx, &key); + ret = _gsskrb5i_get_token_key(ctx, context, &key); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : @@ -161,7 +169,7 @@ _gsskrb5_wrap_size_limit ( break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_wrap_size_arcfour(minor_status, ctx, + ret = _gssapi_wrap_size_arcfour(minor_status, ctx, context, conf_req_flag, qop_req, req_output_size, max_input_size, key); break; @@ -169,12 +177,12 @@ _gsskrb5_wrap_size_limit ( ret = sub_wrap_size(req_output_size, max_input_size, 8, 34); break; default : - ret = _gssapi_wrap_size_cfx(minor_status, ctx, + ret = _gssapi_wrap_size_cfx(minor_status, ctx, context, conf_req_flag, qop_req, req_output_size, max_input_size, key); break; } - krb5_free_keyblock (_gsskrb5_context, key); + krb5_free_keyblock (context, key); *minor_status = 0; return ret; } @@ -183,6 +191,7 @@ static OM_uint32 wrap_des (OM_uint32 * minor_status, const gsskrb5_ctx ctx, + krb5_context context, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -257,9 +266,9 @@ wrap_des /* sequence number */ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - krb5_auth_con_getlocalseqnumber (_gsskrb5_context, - ctx->auth_context, - &seq_number); + krb5_auth_con_getlocalseqnumber (context, + ctx->auth_context, + &seq_number); p -= 16; p[0] = (seq_number >> 0) & 0xFF; @@ -274,7 +283,7 @@ wrap_des DES_cbc_encrypt ((void *)p, (void *)p, 8, &schedule, (DES_cblock *)(p + 8), DES_ENCRYPT); - krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + krb5_auth_con_setlocalseqnumber (context, ctx->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); @@ -309,6 +318,7 @@ static OM_uint32 wrap_des3 (OM_uint32 * minor_status, const gsskrb5_ctx ctx, + krb5_context context, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, @@ -365,9 +375,8 @@ wrap_des3 input_message_buffer->length); memset (p + 28 + 8 + input_message_buffer->length, padlength, padlength); - ret = krb5_crypto_init(_gsskrb5_context, key, 0, &crypto); + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) { - _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -375,16 +384,15 @@ wrap_des3 return GSS_S_FAILURE; } - ret = krb5_create_checksum (_gsskrb5_context, + ret = krb5_create_checksum (context, crypto, KRB5_KU_USAGE_SIGN, 0, p + 20, datalen + 8, &cksum); - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); if (ret) { - _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -400,7 +408,7 @@ wrap_des3 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); /* sequence number */ - krb5_auth_con_getlocalseqnumber (_gsskrb5_context, + krb5_auth_con_getlocalseqnumber (context, ctx->auth_context, &seq_number); @@ -413,7 +421,7 @@ wrap_des3 4); - ret = krb5_crypto_init(_gsskrb5_context, key, ETYPE_DES3_CBC_NONE, + ret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { free (output_message_buffer->value); @@ -427,15 +435,14 @@ wrap_des3 DES_cblock ivec; memcpy (&ivec, p + 8, 8); - ret = krb5_encrypt_ivec (_gsskrb5_context, + ret = krb5_encrypt_ivec (context, crypto, KRB5_KU_USAGE_SEQ, seq, 8, &encdata, &ivec); } - krb5_crypto_destroy (_gsskrb5_context, crypto); + krb5_crypto_destroy (context, crypto); if (ret) { - _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -448,7 +455,7 @@ wrap_des3 memcpy (p, encdata.data, encdata.length); krb5_data_free (&encdata); - krb5_auth_con_setlocalseqnumber (_gsskrb5_context, + krb5_auth_con_setlocalseqnumber (context, ctx->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); @@ -459,21 +466,19 @@ wrap_des3 if(conf_req_flag) { krb5_data tmp; - ret = krb5_crypto_init(_gsskrb5_context, key, + ret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE, &crypto); if (ret) { - _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; *minor_status = ret; return GSS_S_FAILURE; } - ret = krb5_encrypt(_gsskrb5_context, crypto, KRB5_KU_USAGE_SEAL, + ret = krb5_encrypt(context, crypto, KRB5_KU_USAGE_SEAL, p, datalen, &tmp); - krb5_crypto_destroy(_gsskrb5_context, crypto); + krb5_crypto_destroy(context, crypto); if (ret) { - _gsskrb5_set_error_string (); free (output_message_buffer->value); output_message_buffer->length = 0; output_message_buffer->value = NULL; @@ -501,44 +506,46 @@ OM_uint32 _gsskrb5_wrap gss_buffer_t output_message_buffer ) { + krb5_context context; krb5_keyblock *key; OM_uint32 ret; krb5_keytype keytype; const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle; + GSSAPI_KRB5_INIT (&context); + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - ret = _gsskrb5i_get_token_key(ctx, &key); + ret = _gsskrb5i_get_token_key(ctx, context, &key); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); if (ret) { - _gsskrb5_set_error_string (); *minor_status = ret; return GSS_S_FAILURE; } - krb5_enctype_to_keytype (_gsskrb5_context, key->keytype, &keytype); + krb5_enctype_to_keytype (context, key->keytype, &keytype); switch (keytype) { case KEYTYPE_DES : - ret = wrap_des (minor_status, ctx, conf_req_flag, + ret = wrap_des (minor_status, ctx, context, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; case KEYTYPE_DES3 : - ret = wrap_des3 (minor_status, ctx, conf_req_flag, + ret = wrap_des3 (minor_status, ctx, context, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; case KEYTYPE_ARCFOUR: case KEYTYPE_ARCFOUR_56: - ret = _gssapi_wrap_arcfour (minor_status, ctx, conf_req_flag, + ret = _gssapi_wrap_arcfour (minor_status, ctx, context, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; default : - ret = _gssapi_wrap_cfx (minor_status, ctx, conf_req_flag, + ret = _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer, key); break; } - krb5_free_keyblock (_gsskrb5_context, key); + krb5_free_keyblock (context, key); return ret; } diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c index 73207806a0..7df8a3483e 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_accept_sec_context.c,v 1.7 2006/11/10 03:30:12 lha Exp $"); +RCSID("$Id: gss_accept_sec_context.c,v 1.9 2006/12/15 20:12:20 lha Exp $"); static OM_uint32 parse_header(const gss_buffer_t input_token, gss_OID mech_oid) @@ -91,6 +91,8 @@ parse_header(const gss_buffer_t input_token, gss_OID mech_oid) static gss_OID_desc krb5_mechanism = {9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")}; +static gss_OID_desc ntlm_mechanism = + {10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a")}; static gss_OID_desc spnego_mechanism = {6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02")}; @@ -112,7 +114,14 @@ choose_mech(const gss_buffer_t input, gss_OID mech_oid) * Lets guess what mech is really is, callback function to mech ?? */ - if (input->length != 0 && ((const char *)input->value)[0] == 0x6E) { + if (input->length > 8 && + memcmp((const char *)input->value, "NTLMSSP\x00", 8) == 0) + { + *mech_oid = ntlm_mechanism; + return GSS_S_COMPLETE; + } else if (input->length != 0 && + ((const char *)input->value)[0] == 0x6E) + { /* Could be a raw AP-REQ (check for APPLICATION tag) */ *mech_oid = krb5_mechanism; return GSS_S_COMPLETE; diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c index ccaf91ba9d..0d50bbd92b 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c @@ -27,7 +27,23 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_init_sec_context.c,v 1.3 2006/07/06 22:30:09 lha Exp $"); +RCSID("$Id: gss_init_sec_context.c,v 1.4 2006/11/14 12:33:11 lha Exp $"); + +static gss_cred_id_t +_gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + struct _gss_mechanism_cred *mc; + + if (cred == NULL) + return GSS_C_NO_CREDENTIAL; + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (gss_oid_equal(mech_type, mc->gmc_mech_oid)) + return mc->gmc_cred; + } + return GSS_C_NO_CREDENTIAL; +} OM_uint32 gss_init_sec_context(OM_uint32 * minor_status, @@ -49,8 +65,6 @@ gss_init_sec_context(OM_uint32 * minor_status, struct _gss_name *name = (struct _gss_name *) target_name; struct _gss_mechanism_name *mn; struct _gss_context *ctx = (struct _gss_context *) *context_handle; - struct _gss_cred *cred = (struct _gss_cred *) initiator_cred_handle; - struct _gss_mechanism_cred *mc; gss_cred_id_t cred_handle; int allocated_ctx; gss_OID mech_type = input_mech_type; @@ -97,15 +111,7 @@ gss_init_sec_context(OM_uint32 * minor_status, /* * If we have a cred, find the cred for this mechanism. */ - cred_handle = GSS_C_NO_CREDENTIAL; - if (cred) { - SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { - if (gss_oid_equal(mech_type, mc->gmc_mech_oid)) { - cred_handle = mc->gmc_cred; - break; - } - } - } + cred_handle = _gss_mech_cred_find(initiator_cred_handle, mech_type); major_status = m->gm_init_sec_context(minor_status, cred_handle, diff --git a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c index 3d01ba69d4..b8fdefdca1 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c +++ b/source4/heimdal/lib/gssapi/mech/gss_mech_switch.c @@ -28,7 +28,7 @@ #include "mech_locl.h" #include -RCSID("$Id: gss_mech_switch.c,v 1.7 2006/10/09 11:13:30 lha Exp $"); +RCSID("$Id: gss_mech_switch.c,v 1.8 2006/12/15 20:05:43 lha Exp $"); #ifndef _PATH_GSS_MECH #define _PATH_GSS_MECH "/etc/gss/mech" @@ -169,6 +169,8 @@ add_builtin(gssapi_mech_interface mech) { struct _gss_mech_switch *m; OM_uint32 minor_status; + if (!mech) + return 0; m = malloc(sizeof(*m)); if (m == NULL) @@ -214,6 +216,7 @@ _gss_load_mech(void) add_builtin(__gss_krb5_initialize()); add_builtin(__gss_spnego_initialize()); + add_builtin(__gss_ntlm_initialize()); fp = fopen(_PATH_GSS_MECH, "r"); if (!fp) { diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c index f8e013da18..f813d72ac8 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c +++ b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c @@ -31,7 +31,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_set_cred_option.c,v 1.7 2006/07/01 08:50:49 lha Exp $"); +RCSID("$Id: gss_set_cred_option.c,v 1.8 2006/11/13 08:59:43 lha Exp $"); OM_uint32 gss_set_cred_option (OM_uint32 *minor_status, @@ -102,7 +102,7 @@ gss_set_cred_option (OM_uint32 *minor_status, major_status = m->gm_set_cred_option(minor_status, &mc->gmc_cred, object, value); - if (major_status == GSS_S_BAD_MECH) + if (major_status == GSS_S_COMPLETE) one_ok = 1; } } diff --git a/source4/heimdal/lib/gssapi/mech/gss_utils.c b/source4/heimdal/lib/gssapi/mech/gss_utils.c index 33ee033209..d674fb163b 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_utils.c +++ b/source4/heimdal/lib/gssapi/mech/gss_utils.c @@ -27,7 +27,7 @@ */ #include "mech_locl.h" -RCSID("$Id: gss_utils.c,v 1.2 2006/06/28 09:00:25 lha Exp $"); +RCSID("$Id: gss_utils.c,v 1.3 2006/12/18 13:01:25 lha Exp $"); OM_uint32 _gss_copy_oid(OM_uint32 *minor_status, @@ -46,6 +46,17 @@ _gss_copy_oid(OM_uint32 *minor_status, return (GSS_S_COMPLETE); } +OM_uint32 +_gss_free_oid(OM_uint32 *minor_status, gss_OID oid) +{ + *minor_status = 0; + if (oid->elements) { + free(oid->elements); + oid->elements = NULL; + oid->length = 0; + } + return (GSS_S_COMPLETE); +} OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status, diff --git a/source4/heimdal/lib/gssapi/mech/utils.h b/source4/heimdal/lib/gssapi/mech/utils.h index 75a507298c..42e92c3f42 100644 --- a/source4/heimdal/lib/gssapi/mech/utils.h +++ b/source4/heimdal/lib/gssapi/mech/utils.h @@ -24,9 +24,10 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libgssapi/utils.h,v 1.1 2005/12/29 14:40:20 dfr Exp $ - * $Id: utils.h,v 1.3 2006/07/20 01:48:25 lha Exp $ + * $Id: utils.h,v 1.4 2006/12/18 13:01:40 lha Exp $ */ +OM_uint32 _gss_free_oid(OM_uint32 *, gss_OID); OM_uint32 _gss_copy_oid(OM_uint32 *, const gss_OID, gss_OID); OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status, const gss_buffer_t from_buf, gss_buffer_t to_buf); diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c index 8a885a3e2f..2c86b3f794 100644 --- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * Portions Copyright (c) 2004 PADL Software Pty Ltd. * @@ -33,203 +33,85 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: accept_sec_context.c,v 1.6 2006/10/07 22:26:57 lha Exp $"); - -OM_uint32 -_gss_spnego_encode_response(OM_uint32 *minor_status, - const NegTokenResp *resp, - gss_buffer_t data, - u_char **ret_buf) -{ - OM_uint32 ret; - u_char *buf; - size_t buf_size, buf_len; - - buf_size = 1024; - buf = malloc(buf_size); - if (buf == NULL) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - do { - ret = encode_NegTokenResp(buf + buf_size - 1, - buf_size, - resp, &buf_len); - if (ret == 0) { - size_t tmp; - - ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, - buf_size - buf_len, - buf_len, - ASN1_C_CONTEXT, - CONS, - 1, - &tmp); - if (ret == 0) - buf_len += tmp; - } - if (ret) { - if (ret == ASN1_OVERFLOW) { - u_char *tmp; - - buf_size *= 2; - tmp = realloc (buf, buf_size); - if (tmp == NULL) { - *minor_status = ENOMEM; - free(buf); - return GSS_S_FAILURE; - } - buf = tmp; - } else { - *minor_status = ret; - free(buf); - return GSS_S_FAILURE; - } - } - } while (ret == ASN1_OVERFLOW); - - data->value = buf + buf_size - buf_len; - data->length = buf_len; - *ret_buf = buf; - - return GSS_S_COMPLETE; -} +RCSID("$Id: accept_sec_context.c,v 1.16 2006/12/19 12:10:35 lha Exp $"); static OM_uint32 send_reject (OM_uint32 *minor_status, gss_buffer_t output_token) { - NegTokenResp resp; - gss_buffer_desc data; - u_char *buf; - OM_uint32 ret; + NegotiationToken nt; + size_t size; + + nt.element = choice_NegotiationToken_negTokenResp; - ALLOC(resp.negResult, 1); - if (resp.negResult == NULL) { + ALLOC(nt.u.negTokenResp.negResult, 1); + if (nt.u.negTokenResp.negResult == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } - *(resp.negResult) = reject; - resp.supportedMech = NULL; - resp.responseToken = NULL; - resp.mechListMIC = NULL; + *(nt.u.negTokenResp.negResult) = reject; + nt.u.negTokenResp.supportedMech = NULL; + nt.u.negTokenResp.responseToken = NULL; + nt.u.negTokenResp.mechListMIC = NULL; - ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf); - free_NegTokenResp(&resp); - if (ret != GSS_S_COMPLETE) - return ret; + ASN1_MALLOC_ENCODE(NegotiationToken, + output_token->value, output_token->length, &nt, + &size, *minor_status); + free_NegotiationToken(&nt); + if (*minor_status != 0) + return GSS_S_FAILURE; - output_token->value = malloc(data.length); - if (output_token->value == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - } else { - output_token->length = data.length; - memcpy(output_token->value, data.value, output_token->length); - } - free(buf); - if (ret != GSS_S_COMPLETE) - return ret; return GSS_S_BAD_MECH; } -OM_uint32 -_gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status, - int includeMSCompatOID, - const gssspnego_cred cred_handle, - MechTypeList *mechtypelist, - gss_OID *preferred_mech) +static OM_uint32 +acceptor_approved(gss_name_t target_name, gss_OID mech) { - OM_uint32 ret; - gss_OID_set supported_mechs = GSS_C_NO_OID_SET; - int i, count; - - if (cred_handle != NULL) { - ret = gss_inquire_cred(minor_status, - cred_handle->negotiated_cred_id, - NULL, - NULL, - NULL, - &supported_mechs); - } else { - ret = gss_indicate_mechs(minor_status, &supported_mechs); - } + gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; + gss_OID_set oidset; + OM_uint32 junk, ret; - if (ret != GSS_S_COMPLETE) { - return ret; - } + if (target_name == GSS_C_NO_NAME) + return GSS_S_COMPLETE; - if (supported_mechs->count == 0) { - *minor_status = ENOENT; - gss_release_oid_set(minor_status, &supported_mechs); - return GSS_S_FAILURE; - } - - count = supported_mechs->count; - if (includeMSCompatOID) - count++; - - mechtypelist->len = 0; - mechtypelist->val = calloc(count, sizeof(MechType)); - if (mechtypelist->val == NULL) { - *minor_status = ENOMEM; - gss_release_oid_set(minor_status, &supported_mechs); - return GSS_S_FAILURE; - } - - for (i = 0; i < supported_mechs->count; i++) { - ret = _gss_spnego_add_mech_type(&supported_mechs->elements[i], - includeMSCompatOID, - mechtypelist); - if (ret != 0) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - break; - } - } - - if (ret == GSS_S_COMPLETE && preferred_mech != NULL) { - ret = gss_duplicate_oid(minor_status, - &supported_mechs->elements[0], - preferred_mech); - } - - if (ret != GSS_S_COMPLETE) { - free_MechTypeList(mechtypelist); - mechtypelist->len = 0; - mechtypelist->val = NULL; - } - gss_release_oid_set(minor_status, &supported_mechs); - - return ret; + gss_create_empty_oid_set(&junk, &oidset); + gss_add_oid_set_member(&junk, mech, &oidset); + + ret = gss_acquire_cred(&junk, target_name, GSS_C_INDEFINITE, oidset, + GSS_C_ACCEPT, &cred, NULL, NULL); + gss_release_oid_set(&junk, &oidset); + if (ret != GSS_S_COMPLETE) + return ret; + gss_release_cred(&junk, &cred); + + return GSS_S_COMPLETE; } static OM_uint32 send_supported_mechs (OM_uint32 *minor_status, gss_buffer_t output_token) { - NegTokenInit ni; + NegotiationTokenWin nt; char hostname[MAXHOSTNAMELEN], *p; gss_buffer_desc name_buf; gss_OID name_type; gss_name_t target_princ; gss_name_t canon_princ; - OM_uint32 ret, minor; - u_char *buf; - size_t buf_size, buf_len; + OM_uint32 minor; + size_t buf_len; gss_buffer_desc data; + OM_uint32 ret; - memset(&ni, 0, sizeof(ni)); + memset(&nt, 0, sizeof(nt)); - ni.reqFlags = NULL; - ni.mechToken = NULL; - ni.negHints = NULL; - ni.mechListMIC = NULL; + nt.element = choice_NegotiationTokenWin_negTokenInit; + nt.u.negTokenInit.reqFlags = NULL; + nt.u.negTokenInit.mechToken = NULL; + nt.u.negTokenInit.negHints = NULL; - ret = _gss_spnego_indicate_mechtypelist(minor_status, 1, - NULL, - &ni.mechTypes, NULL); + ret = _gss_spnego_indicate_mechtypelist(minor_status, GSS_C_NO_NAME, + acceptor_approved, 1, NULL, + &nt.u.negTokenInit.mechTypes, NULL); if (ret != GSS_S_COMPLETE) { return ret; } @@ -237,7 +119,7 @@ send_supported_mechs (OM_uint32 *minor_status, memset(&target_princ, 0, sizeof(target_princ)); if (gethostname(hostname, sizeof(hostname) - 1) != 0) { *minor_status = errno; - free_NegTokenInit(&ni); + free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } @@ -255,6 +137,7 @@ send_supported_mechs (OM_uint32 *minor_status, GSS_C_NO_OID, &target_princ); if (ret != GSS_S_COMPLETE) { + free_NegotiationTokenWin(&nt); return ret; } @@ -267,6 +150,7 @@ send_supported_mechs (OM_uint32 *minor_status, GSS_C_NO_OID, &canon_princ); if (ret != GSS_S_COMPLETE) { + free_NegotiationTokenWin(&nt); gss_release_name(&minor, &target_princ); return ret; } @@ -274,6 +158,7 @@ send_supported_mechs (OM_uint32 *minor_status, ret = gss_display_name(minor_status, canon_princ, &name_buf, &name_type); if (ret != GSS_S_COMPLETE) { + free_NegotiationTokenWin(&nt); gss_release_name(&minor, &canon_princ); gss_release_name(&minor, &target_princ); return ret; @@ -282,81 +167,38 @@ send_supported_mechs (OM_uint32 *minor_status, gss_release_name(&minor, &canon_princ); gss_release_name(&minor, &target_princ); - ALLOC(ni.negHints, 1); - if (ni.negHints == NULL) { + ALLOC(nt.u.negTokenInit.negHints, 1); + if (nt.u.negTokenInit.negHints == NULL) { *minor_status = ENOMEM; gss_release_buffer(&minor, &name_buf); - free_NegTokenInit(&ni); + free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } - ALLOC(ni.negHints->hintName, 1); - if (ni.negHints->hintName == NULL) { + ALLOC(nt.u.negTokenInit.negHints->hintName, 1); + if (nt.u.negTokenInit.negHints->hintName == NULL) { *minor_status = ENOMEM; gss_release_buffer(&minor, &name_buf); - free_NegTokenInit(&ni); + free_NegotiationTokenWin(&nt); return GSS_S_FAILURE; } - *(ni.negHints->hintName) = name_buf.value; + *(nt.u.negTokenInit.negHints->hintName) = name_buf.value; name_buf.value = NULL; - ni.negHints->hintAddress = NULL; + nt.u.negTokenInit.negHints->hintAddress = NULL; - buf_size = 1024; - buf = malloc(buf_size); - if (buf == NULL) { - free_NegTokenInit(&ni); - *minor_status = ENOMEM; - return GSS_S_FAILURE; + ASN1_MALLOC_ENCODE(NegotiationTokenWin, + data.value, data.length, &nt, &buf_len, ret); + free_NegotiationTokenWin(&nt); + if (ret) { + return ret; } + if (data.length != buf_len) + abort(); - do { - ret = encode_NegTokenInit(buf + buf_size - 1, - buf_size, - &ni, &buf_len); - if (ret == 0) { - size_t tmp; - - ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, - buf_size - buf_len, - buf_len, - ASN1_C_CONTEXT, - CONS, - 0, - &tmp); - if (ret == 0) - buf_len += tmp; - } - if (ret) { - if (ret == ASN1_OVERFLOW) { - u_char *tmp; - - buf_size *= 2; - tmp = realloc (buf, buf_size); - if (tmp == NULL) { - *minor_status = ENOMEM; - free(buf); - free_NegTokenInit(&ni); - return GSS_S_FAILURE; - } - buf = tmp; - } else { - *minor_status = ret; - free(buf); - free_NegTokenInit(&ni); - return GSS_S_FAILURE; - } - } - } while (ret == ASN1_OVERFLOW); + ret = gss_encapsulate_token(&data, GSS_SPNEGO_MECHANISM, output_token); - data.value = buf + buf_size - buf_len; - data.length = buf_len; - - ret = gss_encapsulate_token(&data, - GSS_SPNEGO_MECHANISM, - output_token); - free (buf); - free_NegTokenInit (&ni); + free (data.value); if (ret != GSS_S_COMPLETE) return ret; @@ -374,16 +216,17 @@ send_accept (OM_uint32 *minor_status, gss_buffer_t mech_buf, gss_buffer_t output_token) { - NegTokenResp resp; - gss_buffer_desc data; - u_char *buf; + NegotiationToken nt; OM_uint32 ret; gss_buffer_desc mech_mic_buf; + size_t size; - memset(&resp, 0, sizeof(resp)); + memset(&nt, 0, sizeof(nt)); - ALLOC(resp.negResult, 1); - if (resp.negResult == NULL) { + nt.element = choice_NegotiationToken_negTokenResp; + + ALLOC(nt.u.negTokenResp.negResult, 1); + if (nt.u.negTokenResp.negResult == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } @@ -392,79 +235,85 @@ send_accept (OM_uint32 *minor_status, if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0 && mech_buf != GSS_C_NO_BUFFER) - *(resp.negResult) = accept_incomplete; + *(nt.u.negTokenResp.negResult) = accept_incomplete; else - *(resp.negResult) = accept_completed; + *(nt.u.negTokenResp.negResult) = accept_completed; } else { if (initial_response && context_handle->require_mic) - *(resp.negResult) = request_mic; + *(nt.u.negTokenResp.negResult) = request_mic; else - *(resp.negResult) = accept_incomplete; + *(nt.u.negTokenResp.negResult) = accept_incomplete; } if (initial_response) { - ALLOC(resp.supportedMech, 1); - if (resp.supportedMech == NULL) { - free_NegTokenResp(&resp); + ALLOC(nt.u.negTokenResp.supportedMech, 1); + if (nt.u.negTokenResp.supportedMech == NULL) { + free_NegotiationToken(&nt); *minor_status = ENOMEM; return GSS_S_FAILURE; } ret = der_get_oid(context_handle->preferred_mech_type->elements, context_handle->preferred_mech_type->length, - resp.supportedMech, + nt.u.negTokenResp.supportedMech, NULL); if (ret) { - free_NegTokenResp(&resp); + free_NegotiationToken(&nt); *minor_status = ENOMEM; return GSS_S_FAILURE; } } else { - resp.supportedMech = NULL; + nt.u.negTokenResp.supportedMech = NULL; } if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0) { - ALLOC(resp.responseToken, 1); - if (resp.responseToken == NULL) { - free_NegTokenResp(&resp); + ALLOC(nt.u.negTokenResp.responseToken, 1); + if (nt.u.negTokenResp.responseToken == NULL) { + free_NegotiationToken(&nt); *minor_status = ENOMEM; return GSS_S_FAILURE; } - resp.responseToken->length = mech_token->length; - resp.responseToken->data = mech_token->value; + nt.u.negTokenResp.responseToken->length = mech_token->length; + nt.u.negTokenResp.responseToken->data = mech_token->value; mech_token->length = 0; mech_token->value = NULL; } else { - resp.responseToken = NULL; + nt.u.negTokenResp.responseToken = NULL; } if (mech_buf != GSS_C_NO_BUFFER) { - ALLOC(resp.mechListMIC, 1); - if (resp.mechListMIC == NULL) { - free_NegTokenResp(&resp); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - ret = gss_get_mic(minor_status, context_handle->negotiated_ctx_id, 0, mech_buf, &mech_mic_buf); - if (ret != GSS_S_COMPLETE) { - free_NegTokenResp(&resp); + if (ret == GSS_S_COMPLETE) { + ALLOC(nt.u.negTokenResp.mechListMIC, 1); + if (nt.u.negTokenResp.mechListMIC == NULL) { + gss_release_buffer(minor_status, &mech_mic_buf); + free_NegotiationToken(&nt); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + nt.u.negTokenResp.mechListMIC->length = mech_mic_buf.length; + nt.u.negTokenResp.mechListMIC->data = mech_mic_buf.value; + } else if (ret == GSS_S_UNAVAILABLE) { + nt.u.negTokenResp.mechListMIC = NULL; + } else { + free_NegotiationToken(&nt); return ret; } - resp.mechListMIC->length = mech_mic_buf.length; - resp.mechListMIC->data = mech_mic_buf.value; } else - resp.mechListMIC = NULL; + nt.u.negTokenResp.mechListMIC = NULL; - ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf); - if (ret != GSS_S_COMPLETE) { - free_NegTokenResp(&resp); - return ret; + ASN1_MALLOC_ENCODE(NegotiationToken, + output_token->value, output_token->length, + &nt, &size, ret); + if (ret) { + free_NegotiationToken(&nt); + *minor_status = ret; + return GSS_S_FAILURE; } /* @@ -472,23 +321,12 @@ send_accept (OM_uint32 *minor_status, * it is a SubsequentContextToken (note though RFC 1964 * specifies encapsulation for all _Kerberos_ tokens). */ - output_token->value = malloc(data.length); - if (output_token->value == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - } else { - output_token->length = data.length; - memcpy(output_token->value, data.value, output_token->length); - } - free(buf); - if (ret != GSS_S_COMPLETE) { - free_NegTokenResp(&resp); - return ret; - } - ret = (*(resp.negResult) == accept_completed) ? GSS_S_COMPLETE : - GSS_S_CONTINUE_NEEDED; - free_NegTokenResp(&resp); + if (*(nt.u.negTokenResp.negResult) == accept_completed) + ret = GSS_S_COMPLETE; + else + ret = GSS_S_CONTINUE_NEEDED; + free_NegotiationToken(&nt); return ret; } @@ -530,8 +368,164 @@ verify_mechlist_mic return ret; } -OM_uint32 -_gss_spnego_accept_sec_context +static OM_uint32 +select_mech(OM_uint32 *minor_status, MechType *mechType, int verify_p, + gss_OID *mech_p) +{ + char mechbuf[64]; + size_t mech_len; + gss_OID_desc oid; + OM_uint32 ret, junk; + + ret = der_put_oid ((unsigned char *)mechbuf + sizeof(mechbuf) - 1, + sizeof(mechbuf), + mechType, + &mech_len); + if (ret) { + return GSS_S_DEFECTIVE_TOKEN; + } + + oid.length = mech_len; + oid.elements = mechbuf + sizeof(mechbuf) - mech_len; + + if (gss_oid_equal(&oid, GSS_SPNEGO_MECHANISM)) { + return GSS_S_BAD_MECH; + } + + *minor_status = 0; + + /* Translate broken MS Kebreros OID */ + if (gss_oid_equal(&oid, &_gss_spnego_mskrb_mechanism_oid_desc)) { + gssapi_mech_interface mech; + + mech = __gss_get_mechanism(&_gss_spnego_krb5_mechanism_oid_desc); + if (mech == NULL) + return GSS_S_BAD_MECH; + + ret = gss_duplicate_oid(minor_status, + &_gss_spnego_mskrb_mechanism_oid_desc, + mech_p); + } else { + gssapi_mech_interface mech; + + mech = __gss_get_mechanism(&oid); + if (mech == NULL) + return GSS_S_BAD_MECH; + + ret = gss_duplicate_oid(minor_status, + &mech->gm_mech_oid, + mech_p); + } + + if (verify_p) { + gss_name_t name = GSS_C_NO_NAME; + gss_buffer_desc namebuf; + char *str = NULL, *host, hostname[MAXHOSTNAMELEN]; + + host = getenv("GSSAPI_SPNEGO_NAME"); + if (host == NULL || issuid()) { + if (gethostname(hostname, sizeof(hostname)) != 0) { + *minor_status = errno; + return GSS_S_FAILURE; + } + asprintf(&str, "host@%s", hostname); + host = str; + } + + namebuf.length = strlen(host); + namebuf.value = host; + + ret = gss_import_name(minor_status, &namebuf, + GSS_C_NT_HOSTBASED_SERVICE, &name); + if (str) + free(str); + if (ret != GSS_S_COMPLETE) + return ret; + + ret = acceptor_approved(name, *mech_p); + gss_release_name(&junk, &name); + } + + return ret; +} + + +static OM_uint32 +acceptor_complete(OM_uint32 * minor_status, + gssspnego_ctx ctx, + int *get_mic, + gss_buffer_t mech_buf, + gss_buffer_t mech_input_token, + gss_buffer_t mech_output_token, + heim_octet_string *mic, + gss_buffer_t output_token) +{ + OM_uint32 ret; + int require_mic, verify_mic; + gss_buffer_desc buf; + + buf.length = 0; + buf.value = NULL; + + ret = _gss_spnego_require_mechlist_mic(minor_status, ctx, &require_mic); + if (ret) + return ret; + + ctx->require_mic = require_mic; + + if (mic != NULL) + require_mic = 1; + + if (ctx->open && require_mic) { + if (mech_input_token == GSS_C_NO_BUFFER) { /* Even/One */ + verify_mic = 1; + *get_mic = 0; + } else if (mech_output_token != GSS_C_NO_BUFFER && + mech_output_token->length == 0) { /* Odd */ + *get_mic = verify_mic = 1; + } else { /* Even/One */ + verify_mic = 0; + *get_mic = 1; + } + + if (verify_mic || get_mic) { + int eret; + size_t buf_len; + + ASN1_MALLOC_ENCODE(MechTypeList, + mech_buf->value, mech_buf->length, + &ctx->initiator_mech_types, &buf_len, eret); + if (eret) { + *minor_status = eret; + return GSS_S_FAILURE; + } + if (buf.length != buf_len) + abort(); + } + + if (verify_mic) { + ret = verify_mechlist_mic(minor_status, ctx, mech_buf, mic); + if (ret) { + if (get_mic) + send_reject (minor_status, output_token); + if (buf.value) + free(buf.value); + return ret; + } + ctx->verified_mic = 1; + } + if (buf.value) + free(buf.value); + + } else + *get_mic = verify_mic = 0; + + return GSS_S_COMPLETE; +} + + +static OM_uint32 +acceptor_start (OM_uint32 * minor_status, gss_ctx_id_t * context_handle, const gss_cred_id_t acceptor_cred_handle, @@ -547,40 +541,21 @@ _gss_spnego_accept_sec_context { OM_uint32 ret, ret2, minor; NegTokenInit ni; - NegTokenResp na; - size_t ni_len, na_len; + size_t ni_len; int i; gss_buffer_desc data; size_t len, taglen; - int initialToken; - unsigned int negResult = accept_incomplete; gss_buffer_t mech_input_token = GSS_C_NO_BUFFER; - gss_buffer_t mech_output_token = GSS_C_NO_BUFFER; + gss_buffer_desc mech_output_token; gss_buffer_desc mech_buf; gss_OID preferred_mech_type = GSS_C_NO_OID; gssspnego_ctx ctx; gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle; + int get_mic = 0; + int first_ok = 0; - *minor_status = 0; - - output_token->length = 0; - output_token->value = NULL; - - if (src_name != NULL) - *src_name = GSS_C_NO_NAME; - - if (mech_type != NULL) - *mech_type = GSS_C_NO_OID; - - if (ret_flags != NULL) - *ret_flags = 0; - - if (time_rec != NULL) - *time_rec = 0; - - if (delegated_cred_handle != NULL) - *delegated_cred_handle = GSS_C_NO_CREDENTIAL; - + mech_output_token.value = NULL; + mech_output_token.length = 0; mech_buf.value = NULL; if (*context_handle == GSS_C_NO_CONTEXT) { @@ -590,8 +565,7 @@ _gss_spnego_accept_sec_context return ret; if (input_token_buffer->length == 0) { - return send_supported_mechs (minor_status, - output_token); + return send_supported_mechs (minor_status, output_token); } } @@ -604,16 +578,12 @@ _gss_spnego_accept_sec_context ret = gss_decapsulate_token (input_token_buffer, GSS_SPNEGO_MECHANISM, &data); - initialToken = (ret == GSS_S_COMPLETE); - - if (!initialToken) { - data.value = input_token_buffer->value; - data.length = input_token_buffer->length; - } + if (ret) + return ret; ret = der_match_tag_and_length(data.value, data.length, ASN1_C_CONTEXT, CONS, - initialToken ? 0 : 1, + 0, &len, &taglen); if (ret) { *minor_status = ret; @@ -625,70 +595,263 @@ _gss_spnego_accept_sec_context return GSS_S_FAILURE; } - if (initialToken) { - ret = decode_NegTokenInit((const unsigned char *)data.value + taglen, + ret = decode_NegTokenInit((const unsigned char *)data.value + taglen, len, &ni, &ni_len); - } else { - ret = decode_NegTokenResp((const unsigned char *)data.value + taglen, - len, &na, &na_len); - } if (ret) { *minor_status = ret; return GSS_S_DEFECTIVE_TOKEN; } - if (!initialToken && na.negResult != NULL) { - negResult = *(na.negResult); + if (ni.mechTypes.len < 1) { + free_NegTokenInit(&ni); + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; } - if (negResult == reject || negResult == request_mic) { - /* request_mic should only be sent by acceptor */ - free_NegTokenResp(&na); - return GSS_S_DEFECTIVE_TOKEN; + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + ret = copy_MechTypeList(&ni.mechTypes, &ctx->initiator_mech_types); + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + free_NegTokenInit(&ni); + *minor_status = ret; + return GSS_S_FAILURE; } - if (initialToken) { - for (i = 0; i < ni.mechTypes.len; ++i) { - /* Call glue layer to find first mech we support */ - ret = _gss_spnego_select_mech(minor_status, &ni.mechTypes.val[i], - &preferred_mech_type); + /* + * First we try the opportunistic token if we have support for it, + * don't try to verify we have credential for the token, + * gss_accept_sec_context will (hopefully) tell us that. + * If that failes, + */ + + ret = select_mech(minor_status, + &ni.mechTypes.val[0], + 0, + &preferred_mech_type); + + if (ret == 0 && ni.mechToken != NULL) { + gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL; + gss_cred_id_t mech_cred; + gss_buffer_desc ibuf; + + ibuf.length = ni.mechToken->length; + ibuf.value = ni.mechToken->data; + mech_input_token = &ibuf; + + if (acceptor_cred != NULL) + mech_cred = acceptor_cred->negotiated_cred_id; + else + mech_cred = GSS_C_NO_CREDENTIAL; + + if (ctx->mech_src_name != GSS_C_NO_NAME) + gss_release_name(&minor, &ctx->mech_src_name); + + if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL) + _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id); + + ret = gss_accept_sec_context(&minor, + &ctx->negotiated_ctx_id, + mech_cred, + mech_input_token, + input_chan_bindings, + &ctx->mech_src_name, + &ctx->negotiated_mech_type, + &mech_output_token, + &ctx->mech_flags, + &ctx->mech_time_rec, + &mech_delegated_cred); + if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { + if (delegated_cred_handle) + ret = _gss_spnego_alloc_cred(minor_status, + mech_delegated_cred, + delegated_cred_handle); + else + gss_release_cred(&ret2, &mech_delegated_cred); + + ctx->preferred_mech_type = preferred_mech_type; + ctx->negotiated_mech_type = preferred_mech_type; + if (ret == GSS_S_COMPLETE) + ctx->open = 1; + + ret = acceptor_complete(minor_status, + ctx, + &get_mic, + &mech_buf, + mech_input_token, + &mech_output_token, + ni.mechListMIC, + output_token); + if (ret != GSS_S_COMPLETE) + goto out; + + first_ok = 1; + } + } + + /* + * If opportunistic token failed, lets try the other mechs. + */ + + if (!first_ok) { + + /* Call glue layer to find first mech we support */ + for (i = 1; i < ni.mechTypes.len; ++i) { + ret = select_mech(minor_status, + &ni.mechTypes.val[i], + 1, + &preferred_mech_type); if (ret == 0) break; } if (preferred_mech_type == GSS_C_NO_OID) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); free_NegTokenInit(&ni); return GSS_S_BAD_MECH; } + + ctx->preferred_mech_type = preferred_mech_type; + ctx->negotiated_mech_type = preferred_mech_type; } - HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + /* + * The initial token always have a response + */ - if (initialToken) { - ctx->preferred_mech_type = preferred_mech_type; - ctx->initiator_mech_types.len = ni.mechTypes.len; - ctx->initiator_mech_types.val = ni.mechTypes.val; - ni.mechTypes.len = 0; - ni.mechTypes.val = NULL; + ret = send_accept (minor_status, + ctx, + &mech_output_token, + 1, + get_mic ? &mech_buf : NULL, + output_token); + if (ret) + goto out; + +out: + if (mech_output_token.value != NULL) + gss_release_buffer(&minor, &mech_output_token); + if (mech_buf.value != NULL) { + free(mech_buf.value); + mech_buf.value = NULL; + } + free_NegTokenInit(&ni); + + if (ret == GSS_S_COMPLETE) { + if (src_name != NULL && ctx->mech_src_name != NULL) { + spnego_name name; + + name = calloc(1, sizeof(*name)); + if (name) { + name->mech = ctx->mech_src_name; + ctx->mech_src_name = NULL; + *src_name = (gss_name_t)name; + } else + *src_name = GSS_C_NO_NAME; + } + if (delegated_cred_handle != NULL) { + *delegated_cred_handle = ctx->delegated_cred_id; + ctx->delegated_cred_id = GSS_C_NO_CREDENTIAL; + } + } + + if (mech_type != NULL) + *mech_type = ctx->negotiated_mech_type; + if (ret_flags != NULL) + *ret_flags = ctx->mech_flags; + if (time_rec != NULL) + *time_rec = ctx->mech_time_rec; + + if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return ret; } + _gss_spnego_internal_delete_sec_context(&minor, context_handle, + GSS_C_NO_BUFFER); + + return ret; +} + + +static OM_uint32 +acceptor_continue + (OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + const gss_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token_buffer, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t * src_name, + gss_OID * mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec, + gss_cred_id_t *delegated_cred_handle + ) +{ + OM_uint32 ret, ret2, minor; + NegTokenResp na; + size_t na_len; + gss_buffer_desc data; + size_t len, taglen; + unsigned int negResult = accept_incomplete; + gss_buffer_t mech_input_token = GSS_C_NO_BUFFER; + gss_buffer_t mech_output_token = GSS_C_NO_BUFFER; + gss_buffer_desc mech_buf; + gssspnego_ctx ctx; + gssspnego_cred acceptor_cred = (gssspnego_cred)acceptor_cred_handle; + + mech_buf.value = NULL; + + ctx = (gssspnego_ctx)*context_handle; + + /* + * The GSS-API encapsulation is only present on the initial + * context token (negTokenInit). + */ + + data.value = input_token_buffer->value; + data.length = input_token_buffer->length; + + ret = der_match_tag_and_length(data.value, data.length, + ASN1_C_CONTEXT, CONS, + 1, + &len, &taglen); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + if (len > data.length - taglen) { + *minor_status = ASN1_OVERRUN; + return GSS_S_FAILURE; + } + + ret = decode_NegTokenResp((const unsigned char *)data.value + taglen, + len, &na, &na_len); + if (ret) { + *minor_status = ret; + return GSS_S_DEFECTIVE_TOKEN; + } + + if (na.negResult != NULL) { + negResult = *(na.negResult); + } + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + { gss_buffer_desc ibuf, obuf; - int require_mic, verify_mic, get_mic; + int require_mic, get_mic; int require_response; heim_octet_string *mic; - if (initialToken) { - if (ni.mechToken != NULL) { - ibuf.length = ni.mechToken->length; - ibuf.value = ni.mechToken->data; - mech_input_token = &ibuf; - } + if (na.responseToken != NULL) { + ibuf.length = na.responseToken->length; + ibuf.value = na.responseToken->data; + mech_input_token = &ibuf; } else { - if (na.responseToken != NULL) { - ibuf.length = na.responseToken->length; - ibuf.value = na.responseToken->data; - mech_input_token = &ibuf; - } + ibuf.value = NULL; + ibuf.length = 0; } if (mech_input_token != GSS_C_NO_BUFFER) { @@ -737,10 +900,7 @@ _gss_spnego_accept_sec_context mech_output_token = &obuf; } if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) { - if (initialToken) - free_NegTokenInit(&ni); - else - free_NegTokenResp(&na); + free_NegTokenResp(&na); send_reject (minor_status, output_token); HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; @@ -758,50 +918,19 @@ _gss_spnego_accept_sec_context ctx->require_mic = require_mic; - mic = initialToken ? ni.mechListMIC : na.mechListMIC; + mic = na.mechListMIC; if (mic != NULL) require_mic = 1; - if (ctx->open && require_mic) { - if (mech_input_token == GSS_C_NO_BUFFER) { /* Even/One */ - verify_mic = 1; - get_mic = 0; - } else if (mech_output_token != GSS_C_NO_BUFFER && - mech_output_token->length == 0) { /* Odd */ - get_mic = verify_mic = 1; - } else { /* Even/One */ - verify_mic = 0; - get_mic = 1; - } - - if (verify_mic || get_mic) { - int eret; - size_t buf_len; - - ASN1_MALLOC_ENCODE(MechTypeList, - mech_buf.value, mech_buf.length, - &ctx->initiator_mech_types, &buf_len, eret); - if (eret) { - ret2 = GSS_S_FAILURE; - *minor_status = eret; - goto out; - } - if (mech_buf.length != buf_len) - abort(); - } - - if (verify_mic) { - ret2 = verify_mechlist_mic(minor_status, ctx, &mech_buf, mic); - if (ret2) { - if (get_mic) - send_reject (minor_status, output_token); - goto out; - } - - ctx->verified_mic = 1; - } - } else - verify_mic = get_mic = 0; + if (ret == GSS_S_COMPLETE) + ret = acceptor_complete(minor_status, + ctx, + &get_mic, + &mech_buf, + mech_input_token, + mech_output_token, + na.mechListMIC, + output_token); if (ctx->mech_flags & GSS_C_DCE_STYLE) require_response = (negResult != accept_completed); @@ -814,12 +943,13 @@ _gss_spnego_accept_sec_context */ if ((mech_output_token != GSS_C_NO_BUFFER && mech_output_token->length != 0) + || (ctx->open && negResult == accept_incomplete) || require_response || get_mic) { ret2 = send_accept (minor_status, ctx, mech_output_token, - initialToken, + 0, get_mic ? &mech_buf : NULL, output_token); if (ret2) @@ -833,10 +963,7 @@ _gss_spnego_accept_sec_context gss_release_buffer(&minor, mech_output_token); if (mech_buf.value != NULL) free(mech_buf.value); - if (initialToken) - free_NegTokenInit(&ni); - else - free_NegTokenResp(&na); + free_NegTokenResp(&na); } if (ret == GSS_S_COMPLETE) { @@ -871,3 +998,48 @@ _gss_spnego_accept_sec_context return ret; } +OM_uint32 +_gss_spnego_accept_sec_context + (OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + const gss_cred_id_t acceptor_cred_handle, + const gss_buffer_t input_token_buffer, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t * src_name, + gss_OID * mech_type, + gss_buffer_t output_token, + OM_uint32 * ret_flags, + OM_uint32 * time_rec, + gss_cred_id_t *delegated_cred_handle + ) +{ + _gss_accept_sec_context_t *func; + + *minor_status = 0; + + output_token->length = 0; + output_token->value = NULL; + + if (src_name != NULL) + *src_name = GSS_C_NO_NAME; + if (mech_type != NULL) + *mech_type = GSS_C_NO_OID; + if (ret_flags != NULL) + *ret_flags = 0; + if (time_rec != NULL) + *time_rec = 0; + if (delegated_cred_handle != NULL) + *delegated_cred_handle = GSS_C_NO_CREDENTIAL; + + + if (*context_handle == GSS_C_NO_CONTEXT) + func = acceptor_start; + else + func = acceptor_continue; + + + return (*func)(minor_status, context_handle, acceptor_cred_handle, + input_token_buffer, input_chan_bindings, + src_name, mech_type, output_token, ret_flags, + time_rec, delegated_cred_handle); +} diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c index aeae088258..786eac1340 100644 --- a/source4/heimdal/lib/gssapi/spnego/compat.c +++ b/source4/heimdal/lib/gssapi/spnego/compat.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: compat.c,v 1.6 2006/10/07 22:26:59 lha Exp $"); +RCSID("$Id: compat.c,v 1.9 2006/12/18 17:52:26 lha Exp $"); /* * Apparently Microsoft got the OID wrong, and used @@ -42,10 +42,10 @@ RCSID("$Id: compat.c,v 1.6 2006/10/07 22:26:59 lha Exp $"); * prefer to deal with this here rather than inside the * Kerberos mechanism. */ -static gss_OID_desc gss_mskrb_mechanism_oid_desc = +gss_OID_desc _gss_spnego_mskrb_mechanism_oid_desc = {9, (void *)"\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"}; -static gss_OID_desc gss_krb5_mechanism_oid_desc = +gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc = {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"}; /* @@ -191,8 +191,8 @@ _gss_spnego_require_mechlist_mic(OM_uint32 *minor_status, if (*require_mic) { if (gss_oid_equal(ctx->negotiated_mech_type, ctx->preferred_mech_type)) { *require_mic = 0; - } else if (gss_oid_equal(ctx->negotiated_mech_type, &gss_krb5_mechanism_oid_desc) && - gss_oid_equal(ctx->preferred_mech_type, &gss_mskrb_mechanism_oid_desc)) { + } else if (gss_oid_equal(ctx->negotiated_mech_type, &_gss_spnego_krb5_mechanism_oid_desc) && + gss_oid_equal(ctx->preferred_mech_type, &_gss_spnego_mskrb_mechanism_oid_desc)) { *require_mic = 0; } } @@ -200,86 +200,122 @@ _gss_spnego_require_mechlist_mic(OM_uint32 *minor_status, return GSS_S_COMPLETE; } -int _gss_spnego_add_mech_type(gss_OID mech_type, - int includeMSCompatOID, - MechTypeList *mechtypelist) +static int +add_mech_type(gss_OID mech_type, + int includeMSCompatOID, + MechTypeList *mechtypelist) { + MechType mech; int ret; if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM)) return 0; if (includeMSCompatOID && - gss_oid_equal(mech_type, &gss_krb5_mechanism_oid_desc)) { - ret = der_get_oid(gss_mskrb_mechanism_oid_desc.elements, - gss_mskrb_mechanism_oid_desc.length, - &mechtypelist->val[mechtypelist->len], + gss_oid_equal(mech_type, &_gss_spnego_krb5_mechanism_oid_desc)) { + ret = der_get_oid(_gss_spnego_mskrb_mechanism_oid_desc.elements, + _gss_spnego_mskrb_mechanism_oid_desc.length, + &mech, NULL); if (ret) return ret; - mechtypelist->len++; + ret = add_MechTypeList(mechtypelist, &mech); + free_MechType(&mech); + if (ret) + return ret; } - ret = der_get_oid(mech_type->elements, - mech_type->length, - &mechtypelist->val[mechtypelist->len], - NULL); + ret = der_get_oid(mech_type->elements, mech_type->length, &mech, NULL); if (ret) return ret; - mechtypelist->len++; - - return 0; + ret = add_MechTypeList(mechtypelist, &mech); + free_MechType(&mech); + return ret; } + OM_uint32 -_gss_spnego_select_mech(OM_uint32 *minor_status, - MechType *mechType, - gss_OID *mech_p) +_gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status, + gss_name_t target_name, + OM_uint32 (*func)(gss_name_t, gss_OID), + int includeMSCompatOID, + const gssspnego_cred cred_handle, + MechTypeList *mechtypelist, + gss_OID *preferred_mech) { - char mechbuf[64]; - size_t mech_len; - gss_OID_desc oid; + gss_OID_set supported_mechs = GSS_C_NO_OID_SET; + gss_OID first_mech = GSS_C_NO_OID; OM_uint32 ret; - - ret = der_put_oid ((unsigned char *)mechbuf + sizeof(mechbuf) - 1, - sizeof(mechbuf), - mechType, - &mech_len); - if (ret) { - return GSS_S_DEFECTIVE_TOKEN; + int i; + + mechtypelist->len = 0; + mechtypelist->val = NULL; + + if (cred_handle != NULL) { + ret = gss_inquire_cred(minor_status, + cred_handle->negotiated_cred_id, + NULL, + NULL, + NULL, + &supported_mechs); + } else { + ret = gss_indicate_mechs(minor_status, &supported_mechs); } - oid.length = mech_len; - oid.elements = mechbuf + sizeof(mechbuf) - mech_len; - - if (gss_oid_equal(&oid, GSS_SPNEGO_MECHANISM)) { - return GSS_S_BAD_MECH; + if (ret != GSS_S_COMPLETE) { + return ret; } - *minor_status = 0; - - /* Translate broken MS Kebreros OID */ - if (gss_oid_equal(&oid, &gss_mskrb_mechanism_oid_desc)) { - gssapi_mech_interface mech; - - mech = __gss_get_mechanism(&gss_krb5_mechanism_oid_desc); - if (mech == NULL) - return GSS_S_BAD_MECH; + if (supported_mechs->count == 0) { + *minor_status = ENOENT; + gss_release_oid_set(minor_status, &supported_mechs); + return GSS_S_FAILURE; + } - ret = gss_duplicate_oid(minor_status, - &gss_mskrb_mechanism_oid_desc, - mech_p); - } else { - gssapi_mech_interface mech; + ret = (*func)(target_name, GSS_KRB5_MECHANISM); + if (ret == GSS_S_COMPLETE) { + ret = add_mech_type(GSS_KRB5_MECHANISM, + includeMSCompatOID, + mechtypelist); + if (!GSS_ERROR(ret)) + first_mech = GSS_KRB5_MECHANISM; + } + ret = GSS_S_COMPLETE; + + for (i = 0; i < supported_mechs->count; i++) { + OM_uint32 subret; + if (gss_oid_equal(&supported_mechs->elements[i], GSS_SPNEGO_MECHANISM)) + continue; + if (gss_oid_equal(&supported_mechs->elements[i], GSS_KRB5_MECHANISM)) + continue; + + subret = (*func)(target_name, &supported_mechs->elements[i]); + if (subret != GSS_S_COMPLETE) + continue; + + ret = add_mech_type(&supported_mechs->elements[i], + includeMSCompatOID, + mechtypelist); + if (ret != 0) { + *minor_status = ret; + ret = GSS_S_FAILURE; + break; + } + if (first_mech == GSS_C_NO_OID) + first_mech = &supported_mechs->elements[i]; + } - mech = __gss_get_mechanism(&oid); - if (mech == NULL) - return GSS_S_BAD_MECH; + if (mechtypelist->len == 0) { + gss_release_oid_set(minor_status, &supported_mechs); + *minor_status = 0; + return GSS_S_BAD_MECH; + } - ret = gss_duplicate_oid(minor_status, - &mech->gm_mech_oid, - mech_p); + if (preferred_mech != NULL) { + ret = gss_duplicate_oid(minor_status, first_mech, preferred_mech); + if (ret != GSS_S_COMPLETE) + free_MechTypeList(mechtypelist); } + gss_release_oid_set(minor_status, &supported_mechs); return ret; } - diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c index 902ddbbdf9..57bc45a492 100644 --- a/source4/heimdal/lib/gssapi/spnego/context_stubs.c +++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c @@ -32,7 +32,7 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: context_stubs.c,v 1.8 2006/10/07 22:27:01 lha Exp $"); +RCSID("$Id: context_stubs.c,v 1.9 2006/12/18 12:59:44 lha Exp $"); static OM_uint32 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs) @@ -282,7 +282,21 @@ OM_uint32 _gss_spnego_compare_name int * name_equal ) { - return gss_compare_name(minor_status, name1, name2, name_equal); + spnego_name n1 = (spnego_name)name1; + spnego_name n2 = (spnego_name)name2; + + *name_equal = 0; + + if (!gss_oid_equal(&n1->type, &n2->type)) + return GSS_S_COMPLETE; + if (n1->value.length != n2->value.length) + return GSS_S_COMPLETE; + if (memcmp(n1->value.value, n2->value.value, n2->value.length) != 0) + return GSS_S_COMPLETE; + + *name_equal = 1; + + return GSS_S_COMPLETE; } OM_uint32 _gss_spnego_display_name @@ -292,19 +306,51 @@ OM_uint32 _gss_spnego_display_name gss_OID * output_name_type ) { - return gss_display_name(minor_status, input_name, + spnego_name name = (spnego_name)input_name; + + *minor_status = 0; + + if (name->mech == GSS_C_NO_NAME) + return GSS_S_FAILURE; + + return gss_display_name(minor_status, name->mech, output_name_buffer, output_name_type); } OM_uint32 _gss_spnego_import_name (OM_uint32 * minor_status, - const gss_buffer_t input_name_buffer, - const gss_OID input_name_type, + const gss_buffer_t name_buffer, + const gss_OID name_type, gss_name_t * output_name ) { - return gss_import_name(minor_status, input_name_buffer, - input_name_type, output_name); + spnego_name name; + OM_uint32 maj_stat; + + *minor_status = 0; + + name = calloc(1, sizeof(*name)); + if (name == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + maj_stat = _gss_copy_oid(minor_status, name_type, &name->type); + if (maj_stat) { + free(name); + return GSS_S_FAILURE; + } + + maj_stat = _gss_copy_buffer(minor_status, name_buffer, &name->value); + if (maj_stat) { + gss_name_t rname = (gss_name_t)name; + _gss_spnego_release_name(minor_status, &rname); + return GSS_S_FAILURE; + } + name->mech = GSS_C_NO_NAME; + *output_name = (gss_name_t)name; + + return GSS_S_COMPLETE; } OM_uint32 _gss_spnego_export_name @@ -313,8 +359,17 @@ OM_uint32 _gss_spnego_export_name gss_buffer_t exported_name ) { - return gss_export_name(minor_status, input_name, - exported_name); + spnego_name name; + *minor_status = 0; + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + name = (spnego_name)input_name; + if (name->mech == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + return gss_export_name(minor_status, name->mech, exported_name); } OM_uint32 _gss_spnego_release_name @@ -322,7 +377,20 @@ OM_uint32 _gss_spnego_release_name gss_name_t * input_name ) { - return gss_release_name(minor_status, input_name); + *minor_status = 0; + + if (*input_name != GSS_C_NO_NAME) { + OM_uint32 junk; + spnego_name name = (spnego_name)*input_name; + _gss_free_oid(&junk, &name->type); + gss_release_buffer(&junk, &name->value); + if (name->mech != GSS_C_NO_NAME) + gss_release_name(&junk, &name->mech); + free(name); + + *input_name = GSS_C_NO_NAME; + } + return GSS_S_COMPLETE; } OM_uint32 _gss_spnego_inquire_context ( diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c index 5a652fdb2e..a221281a70 100644 --- a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c @@ -33,7 +33,39 @@ #include "spnego/spnego_locl.h" -RCSID("$Id: init_sec_context.c,v 1.6 2006/10/14 10:09:15 lha Exp $"); +RCSID("$Id: init_sec_context.c,v 1.11 2006/12/18 15:42:03 lha Exp $"); + +/* + * Is target_name an sane target for `mech´. + */ + +static OM_uint32 +initiator_approved(gss_name_t target_name, gss_OID mech) +{ + OM_uint32 min_stat, maj_stat; + gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; + gss_buffer_desc out; + + maj_stat = gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &ctx, + target_name, + mech, + 0, + GSS_C_INDEFINITE, + GSS_C_NO_CHANNEL_BINDINGS, + GSS_C_NO_BUFFER, + NULL, + &out, + NULL, + NULL); + if (GSS_ERROR(maj_stat)) + return GSS_S_BAD_MECH; + gss_release_buffer(&min_stat, &out); + gss_delete_sec_context(&min_stat, &ctx, NULL); + + return GSS_S_COMPLETE; +} /* * Send a reply. Note that we only need to send a reply if we @@ -50,11 +82,10 @@ spnego_reply_internal(OM_uint32 *minor_status, gss_buffer_t mech_token, gss_buffer_t output_token) { - NegTokenResp resp; + NegotiationToken nt; gss_buffer_desc mic_buf; OM_uint32 ret; - gss_buffer_desc data; - u_char *buf; + size_t size; if (mech_buf == GSS_C_NO_BUFFER && mech_token->length == 0) { output_token->length = 0; @@ -63,85 +94,83 @@ spnego_reply_internal(OM_uint32 *minor_status, return context_handle->open ? GSS_S_COMPLETE : GSS_S_FAILURE; } - memset(&resp, 0, sizeof(resp)); + memset(&nt, 0, sizeof(nt)); - ALLOC(resp.negResult, 1); - if (resp.negResult == NULL) { + nt.element = choice_NegotiationToken_negTokenResp; + + ALLOC(nt.u.negTokenResp.negResult, 1); + if (nt.u.negTokenResp.negResult == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } - resp.supportedMech = NULL; + nt.u.negTokenResp.supportedMech = NULL; output_token->length = 0; output_token->value = NULL; if (mech_token->length == 0) { - resp.responseToken = NULL; - *(resp.negResult) = accept_completed; + nt.u.negTokenResp.responseToken = NULL; + *(nt.u.negTokenResp.negResult) = accept_completed; } else { - ALLOC(resp.responseToken, 1); - if (resp.responseToken == NULL) { - free_NegTokenResp(&resp); + ALLOC(nt.u.negTokenResp.responseToken, 1); + if (nt.u.negTokenResp.responseToken == NULL) { + free_NegotiationToken(&nt); *minor_status = ENOMEM; return GSS_S_FAILURE; } - resp.responseToken->length = mech_token->length; - resp.responseToken->data = mech_token->value; + nt.u.negTokenResp.responseToken->length = mech_token->length; + nt.u.negTokenResp.responseToken->data = mech_token->value; mech_token->length = 0; mech_token->value = NULL; - *(resp.negResult) = accept_incomplete; + *(nt.u.negTokenResp.negResult) = accept_incomplete; } if (mech_buf != GSS_C_NO_BUFFER) { - ALLOC(resp.mechListMIC, 1); - if (resp.mechListMIC == NULL) { - free_NegTokenResp(&resp); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } ret = gss_get_mic(minor_status, context_handle->negotiated_ctx_id, 0, mech_buf, &mic_buf); - if (ret) { - free_NegTokenResp(&resp); + if (ret == GSS_S_COMPLETE) { + ALLOC(nt.u.negTokenResp.mechListMIC, 1); + if (nt.u.negTokenResp.mechListMIC == NULL) { + gss_release_buffer(minor_status, &mic_buf); + free_NegotiationToken(&nt); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + nt.u.negTokenResp.mechListMIC->length = mic_buf.length; + nt.u.negTokenResp.mechListMIC->data = mic_buf.value; + } else if (ret == GSS_S_UNAVAILABLE) { + nt.u.negTokenResp.mechListMIC = NULL; + } if (ret) { + free_NegotiationToken(&nt); *minor_status = ENOMEM; return GSS_S_FAILURE; } - - resp.mechListMIC->length = mic_buf.length; - resp.mechListMIC->data = mic_buf.value; } else { - resp.mechListMIC = NULL; + nt.u.negTokenResp.mechListMIC = NULL; } - ret = _gss_spnego_encode_response (minor_status, &resp, - &data, &buf); + ASN1_MALLOC_ENCODE(NegotiationToken, + output_token->value, output_token->length, + &nt, &size, ret); if (ret) { - free_NegTokenResp(&resp); - return ret; - } - - output_token->value = malloc(data.length); - if (output_token->value == NULL) { - *minor_status = ENOMEM; - ret = GSS_S_FAILURE; - } else { - output_token->length = data.length; - memcpy(output_token->value, data.value, output_token->length); + free_NegotiationToken(&nt); + *minor_status = ret; + return GSS_S_FAILURE; } - free(buf); - if (*(resp.negResult) == accept_completed) + if (*(nt.u.negTokenResp.negResult) == accept_completed) ret = GSS_S_COMPLETE; else ret = GSS_S_CONTINUE_NEEDED; - free_NegTokenResp(&resp); + free_NegotiationToken(&nt); return ret; } @@ -172,12 +201,16 @@ spnego_initial size_t ni_len; gss_ctx_id_t context; gssspnego_ctx ctx; + spnego_name name = (spnego_name)target_name; + + *minor_status = 0; memset (&ni, 0, sizeof(ni)); *context_handle = GSS_C_NO_CONTEXT; - *minor_status = 0; + if (target_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; sub = _gss_spnego_alloc_sec_context(&minor, &context); if (GSS_ERROR(sub)) { @@ -190,7 +223,17 @@ spnego_initial ctx->local = 1; - sub = _gss_spnego_indicate_mechtypelist(&minor, 0, + sub = gss_import_name(&minor, &name->value, &name->type, &ctx->target_name); + if (GSS_ERROR(sub)) { + *minor_status = minor; + _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); + return sub; + } + + sub = _gss_spnego_indicate_mechtypelist(&minor, + ctx->target_name, + initiator_approved, + 0, cred, &ni.mechTypes, &ctx->preferred_mech_type); @@ -212,8 +255,8 @@ spnego_initial (cred != NULL) ? cred->negotiated_cred_id : GSS_C_NO_CREDENTIAL, &ctx->negotiated_ctx_id, - target_name, - GSS_C_NO_OID, + ctx->target_name, + ctx->preferred_mech_type, req_flags, time_req, input_chan_bindings, @@ -228,6 +271,8 @@ spnego_initial _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); return sub; } + if (sub == GSS_S_COMPLETE) + ctx->maybe_open = 1; if (mech_token.length != 0) { ALLOC(ni.mechToken, 1); @@ -345,8 +390,6 @@ spnego_reply { OM_uint32 ret, minor; NegTokenResp resp; - u_char oidbuf[17]; - size_t oidlen; size_t len, taglen; gss_OID_desc mech; int require_mic; @@ -385,34 +428,73 @@ spnego_reply if (resp.negResult == NULL || *(resp.negResult) == reject - || resp.supportedMech == NULL) { + /* || resp.supportedMech == NULL */ + ) + { free_NegTokenResp(&resp); return GSS_S_BAD_MECH; } - ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1, - sizeof(oidbuf), - resp.supportedMech, - &oidlen); - if (ret || (oidlen == GSS_SPNEGO_MECHANISM->length && - memcmp(oidbuf + sizeof(oidbuf) - oidlen, - GSS_SPNEGO_MECHANISM->elements, - oidlen) == 0)) { + /* + * Pick up the mechanism that the acceptor selected, only allow it + * to be sent in packet. + */ + + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); + + if (resp.supportedMech) { + + if (ctx->oidlen) { + free_NegTokenResp(&resp); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return GSS_S_BAD_MECH; + } + ret = der_put_oid(ctx->oidbuf + sizeof(ctx->oidbuf) - 1, + sizeof(ctx->oidbuf), + resp.supportedMech, + &ctx->oidlen); /* Avoid recursively embedded SPNEGO */ + if (ret || (ctx->oidlen == GSS_SPNEGO_MECHANISM->length && + memcmp(ctx->oidbuf + sizeof(ctx->oidbuf) - ctx->oidlen, + GSS_SPNEGO_MECHANISM->elements, + ctx->oidlen) == 0)) + { + free_NegTokenResp(&resp); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); + return GSS_S_BAD_MECH; + } + + /* check if the acceptor took our optimistic token */ + if (ctx->oidlen != ctx->preferred_mech_type->length || + memcmp(ctx->oidbuf + sizeof(ctx->oidbuf) - ctx->oidlen, + ctx->preferred_mech_type->elements, + ctx->oidlen) != 0) + { + gss_delete_sec_context(&minor, &ctx->negotiated_ctx_id, + GSS_C_NO_BUFFER); + ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT; + } + } else if (ctx->oidlen == 0) { free_NegTokenResp(&resp); + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return GSS_S_BAD_MECH; } - HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); - - if (resp.responseToken != NULL) { + if (resp.responseToken != NULL || + ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) { gss_buffer_desc mech_input_token; - mech_input_token.length = resp.responseToken->length; - mech_input_token.value = resp.responseToken->data; + if (resp.responseToken) { + mech_input_token.length = resp.responseToken->length; + mech_input_token.value = resp.responseToken->data; + } else { + mech_input_token.length = 0; + mech_input_token.value = NULL; + } - mech.length = oidlen; - mech.elements = oidbuf + sizeof(oidbuf) - oidlen; + + mech.length = ctx->oidlen; + mech.elements = ctx->oidbuf + sizeof(ctx->oidbuf) - ctx->oidlen; /* Fall through as if the negotiated mechanism was requested explicitly */ @@ -420,7 +502,7 @@ spnego_reply (cred != NULL) ? cred->negotiated_cred_id : GSS_C_NO_CREDENTIAL, &ctx->negotiated_ctx_id, - target_name, + ctx->target_name, &mech, req_flags, time_req, @@ -439,6 +521,9 @@ spnego_reply if (ret == GSS_S_COMPLETE) { ctx->open = 1; } + } else if (*(resp.negResult) == accept_completed) { + if (ctx->maybe_open) + ctx->open = 1; } if (*(resp.negResult) == request_mic) { diff --git a/source4/heimdal/lib/gssapi/spnego/spnego-private.h b/source4/heimdal/lib/gssapi/spnego/spnego-private.h index df50f65580..d80db0018a 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego-private.h +++ b/source4/heimdal/lib/gssapi/spnego/spnego-private.h @@ -46,12 +46,6 @@ _gss_spnego_add_cred ( OM_uint32 * /*initiator_time_rec*/, OM_uint32 * acceptor_time_rec ); -int -_gss_spnego_add_mech_type ( - gss_OID /*mech_type*/, - int /*includeMSCompatOID*/, - MechTypeList */*mechtypelist*/); - OM_uint32 _gss_spnego_alloc_cred ( OM_uint32 */*minor_status*/, @@ -111,13 +105,6 @@ _gss_spnego_duplicate_name ( const gss_name_t /*src_name*/, gss_name_t * dest_name ); -OM_uint32 -_gss_spnego_encode_response ( - OM_uint32 */*minor_status*/, - const NegTokenResp */*resp*/, - gss_buffer_t /*data*/, - u_char **/*ret_buf*/); - OM_uint32 _gss_spnego_export_name ( OM_uint32 * /*minor_status*/, @@ -141,8 +128,8 @@ _gss_spnego_get_mic ( OM_uint32 _gss_spnego_import_name ( OM_uint32 * /*minor_status*/, - const gss_buffer_t /*input_name_buffer*/, - const gss_OID /*input_name_type*/, + const gss_buffer_t /*name_buffer*/, + const gss_OID /*name_type*/, gss_name_t * output_name ); OM_uint32 @@ -154,6 +141,8 @@ _gss_spnego_import_sec_context ( OM_uint32 _gss_spnego_indicate_mechtypelist ( OM_uint32 */*minor_status*/, + gss_name_t /*target_name*/, + OM_uint32 (*/*func*/)(gss_name_t, gss_OID), int /*includeMSCompatOID*/, const gssspnego_cred /*cred_handle*/, MechTypeList */*mechtypelist*/, @@ -270,12 +259,6 @@ _gss_spnego_seal ( int * /*conf_state*/, gss_buffer_t output_message_buffer ); -OM_uint32 -_gss_spnego_select_mech ( - OM_uint32 */*minor_status*/, - MechType */*mechType*/, - gss_OID */*mech_p*/); - OM_uint32 _gss_spnego_set_sec_context_option ( OM_uint32 * /*minor_status*/, diff --git a/source4/heimdal/lib/gssapi/spnego/spnego.asn1 b/source4/heimdal/lib/gssapi/spnego/spnego.asn1 index 187ce0a0a6..76fafa356c 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego.asn1 +++ b/source4/heimdal/lib/gssapi/spnego/spnego.asn1 @@ -1,4 +1,4 @@ --- $Id: spnego.asn1,v 1.1.1.1 2006/06/28 08:34:45 lha Exp $ +-- $Id: spnego.asn1,v 1.3 2006/12/18 18:28:49 lha Exp $ SPNEGO DEFINITIONS ::= BEGIN @@ -22,14 +22,21 @@ NegHints ::= SEQUENCE { hintAddress [1] OCTET STRING OPTIONAL } +NegTokenInitWin ::= SEQUENCE { + mechTypes [0] MechTypeList, + reqFlags [1] ContextFlags OPTIONAL, + mechToken [2] OCTET STRING OPTIONAL, + negHints [3] NegHints OPTIONAL + } + NegTokenInit ::= SEQUENCE { mechTypes [0] MechTypeList, reqFlags [1] ContextFlags OPTIONAL, mechToken [2] OCTET STRING OPTIONAL, - negHints [3] NegHints OPTIONAL, - mechListMIC [4] OCTET STRING OPTIONAL + mechListMIC [3] OCTET STRING OPTIONAL } + -- NB: negResult is not OPTIONAL in the new SPNEGO spec but -- Windows clients do not always send it NegTokenResp ::= SEQUENCE { @@ -48,4 +55,8 @@ NegotiationToken ::= CHOICE { negTokenResp[1] NegTokenResp } +NegotiationTokenWin ::= CHOICE { + negTokenInit[0] NegTokenInitWin +} + END diff --git a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h index 255e07d056..45dff04313 100644 --- a/source4/heimdal/lib/gssapi/spnego/spnego_locl.h +++ b/source4/heimdal/lib/gssapi/spnego/spnego_locl.h @@ -30,7 +30,7 @@ * SUCH DAMAGE. */ -/* $Id: spnego_locl.h,v 1.12 2006/11/07 19:53:40 lha Exp $ */ +/* $Id: spnego_locl.h,v 1.15 2006/12/18 15:42:03 lha Exp $ */ #ifndef SPNEGO_LOCL_H #define SPNEGO_LOCL_H @@ -67,6 +67,7 @@ #include #include "spnego_asn1.h" +#include "mech/utils.h" #include #include @@ -86,13 +87,29 @@ typedef struct { OM_uint32 mech_time_rec; gss_name_t mech_src_name; gss_cred_id_t delegated_cred_id; - int open : 1; - int local : 1; - int require_mic : 1; - int verified_mic : 1; + unsigned int open : 1; + unsigned int local : 1; + unsigned int require_mic : 1; + unsigned int verified_mic : 1; + unsigned int maybe_open : 1; HEIMDAL_MUTEX ctx_id_mutex; + + gss_name_t target_name; + + u_char oidbuf[17]; + size_t oidlen; + } *gssspnego_ctx; +typedef struct { + gss_OID_desc type; + gss_buffer_desc value; + gss_name_t mech; +} *spnego_name; + +extern gss_OID_desc _gss_spnego_mskrb_mechanism_oid_desc; +extern gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc; + #include #endif /* SPNEGO_LOCL_H */ -- cgit