summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi/krb5/init_sec_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/gssapi/krb5/init_sec_context.c')
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c1366
1 files changed, 683 insertions, 683 deletions
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 3e3f0192ab..40bc0bcbd4 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -1,3 +1,4 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
/*
* Copyright 2000,2002, 2003, 2007 by the Massachusetts Institute of Technology.
* All Rights Reserved.
@@ -6,7 +7,7 @@
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
- *
+ *
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
@@ -20,11 +21,11 @@
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
*/
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -34,7 +35,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -46,14 +47,14 @@
/*
* Copyright (C) 1998 by the FundsXpress, INC.
- *
+ *
* All rights reserved.
- *
+ *
* Export of this software from the United States of America may require
* a specific license from the United States Government. It is the
* responsibility of any person or organization contemplating export to
* obtain such a license before exporting.
- *
+ *
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
@@ -64,7 +65,7 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
@@ -92,7 +93,7 @@ int krb5_gss_dbg_client_expcreds = 0;
* ccache.
*/
static krb5_error_code get_credentials(context, cred, server, now,
- endtime, out_creds)
+ endtime, out_creds)
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_principal server;
@@ -100,24 +101,24 @@ static krb5_error_code get_credentials(context, cred, server, now,
krb5_timestamp endtime;
krb5_creds **out_creds;
{
- krb5_error_code code;
- krb5_creds in_creds;
+ krb5_error_code code;
+ krb5_creds in_creds;
k5_mutex_assert_locked(&cred->lock);
memset((char *) &in_creds, 0, sizeof(krb5_creds));
if ((code = krb5_copy_principal(context, cred->princ, &in_creds.client)))
- goto cleanup;
+ goto cleanup;
if ((code = krb5_copy_principal(context, server, &in_creds.server)))
- goto cleanup;
+ goto cleanup;
in_creds.times.endtime = endtime;
in_creds.keyblock.enctype = 0;
code = krb5_get_credentials(context, 0, cred->ccache,
- &in_creds, out_creds);
+ &in_creds, out_creds);
if (code)
- goto cleanup;
+ goto cleanup;
/*
* Enforce a stricter limit (without timeskew forgiveness at the
@@ -125,16 +126,16 @@ static krb5_error_code get_credentials(context, cred, server, now,
* non-forgiving.
*/
if (!krb5_gss_dbg_client_expcreds && *out_creds != NULL &&
- (*out_creds)->times.endtime < now) {
- code = KRB5KRB_AP_ERR_TKT_EXPIRED;
- goto cleanup;
+ (*out_creds)->times.endtime < now) {
+ code = KRB5KRB_AP_ERR_TKT_EXPIRED;
+ goto cleanup;
}
-
+
cleanup:
if (in_creds.client)
- krb5_free_principal(context, in_creds.client);
+ krb5_free_principal(context, in_creds.client);
if (in_creds.server)
- krb5_free_principal(context, in_creds.server);
+ krb5_free_principal(context, in_creds.server);
return code;
}
struct gss_checksum_data {
@@ -149,7 +150,7 @@ struct gss_checksum_data {
#endif
static krb5_error_code KRB5_CALLCONV
make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
- void *cksum_data, krb5_data **out)
+ void *cksum_data, krb5_data **out)
{
krb5_error_code code;
krb5_int32 con_flags;
@@ -163,48 +164,48 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
/* build the checksum field */
if (data->ctx->gss_flags & GSS_C_DELEG_FLAG) {
- /* first get KRB_CRED message, so we know its length */
+ /* first get KRB_CRED message, so we know its length */
- /* clear the time check flag that was set in krb5_auth_con_init() */
- krb5_auth_con_getflags(context, auth_context, &con_flags);
- krb5_auth_con_setflags(context, auth_context,
- con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
+ /* clear the time check flag that was set in krb5_auth_con_init() */
+ krb5_auth_con_getflags(context, auth_context, &con_flags);
+ krb5_auth_con_setflags(context, auth_context,
+ con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
- code = krb5_fwd_tgt_creds(context, auth_context, 0,
- data->cred->princ, data->ctx->there,
- data->cred->ccache, 1,
- &credmsg);
+ code = krb5_fwd_tgt_creds(context, auth_context, 0,
+ data->cred->princ, data->ctx->there,
+ data->cred->ccache, 1,
+ &credmsg);
- /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
- krb5_auth_con_setflags(context, auth_context, con_flags);
+ /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
+ krb5_auth_con_setflags(context, auth_context, con_flags);
- if (code) {
- /* don't fail here; just don't accept/do the delegation
+ if (code) {
+ /* don't fail here; just don't accept/do the delegation
request */
- data->ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
+ data->ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
- data->checksum_data.length = 24;
- } else {
- if (credmsg.length+28 > KRB5_INT16_MAX) {
- krb5_free_data_contents(context, &credmsg);
- return(KRB5KRB_ERR_FIELD_TOOLONG);
- }
+ data->checksum_data.length = 24;
+ } else {
+ if (credmsg.length+28 > KRB5_INT16_MAX) {
+ krb5_free_data_contents(context, &credmsg);
+ return(KRB5KRB_ERR_FIELD_TOOLONG);
+ }
- data->checksum_data.length = 28+credmsg.length;
- }
+ data->checksum_data.length = 28+credmsg.length;
+ }
} else {
- data->checksum_data.length = 24;
+ data->checksum_data.length = 24;
}
#ifdef CFX_EXERCISE
if (data->ctx->auth_context->keyblock != NULL
- && data->ctx->auth_context->keyblock->enctype == 18) {
- srand(time(0) ^ getpid());
- /* Our ftp client code stupidly assumes a base64-encoded
- version of the token will fit in 10K, so don't make this
- too big. */
- junk = rand() & 0xff;
+ && data->ctx->auth_context->keyblock->enctype == 18) {
+ srand(time(0) ^ getpid());
+ /* Our ftp client code stupidly assumes a base64-encoded
+ version of the token will fit in 10K, so don't make this
+ too big. */
+ junk = rand() & 0xff;
} else
- junk = 0;
+ junk = 0;
#else
junk = 0;
#endif
@@ -215,10 +216,10 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
(maybe) KRB_CRED msg */
if ((data->checksum_data.data =
- (char *) xmalloc(data->checksum_data.length)) == NULL) {
- if (credmsg.data)
- krb5_free_data_contents(context, &credmsg);
- return(ENOMEM);
+ (char *) xmalloc(data->checksum_data.length)) == NULL) {
+ if (credmsg.data)
+ krb5_free_data_contents(context, &credmsg);
+ return(ENOMEM);
}
ptr = data->checksum_data.data;
@@ -231,19 +232,19 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context,
xfree(data->md5.contents);
if (credmsg.data) {
- TWRITE_INT16(ptr, KRB5_GSS_FOR_CREDS_OPTION, 0);
- TWRITE_INT16(ptr, credmsg.length, 0);
- TWRITE_STR(ptr, (unsigned char *) credmsg.data, credmsg.length);
+ TWRITE_INT16(ptr, KRB5_GSS_FOR_CREDS_OPTION, 0);
+ TWRITE_INT16(ptr, credmsg.length, 0);
+ TWRITE_STR(ptr, (unsigned char *) credmsg.data, credmsg.length);
- /* free credmsg data */
- krb5_free_data_contents(context, &credmsg);
+ /* free credmsg data */
+ krb5_free_data_contents(context, &credmsg);
}
if (junk)
- memset(ptr, 'i', junk);
+ memset(ptr, 'i', junk);
*out = &data->checksum_data;
return 0;
}
-
+
static krb5_error_code
make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
krb5_context context;
@@ -273,7 +274,7 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
return(code);
krb5_auth_con_set_req_cksumtype(context, ctx->auth_context,
- CKSUMTYPE_KG_CB);
+ CKSUMTYPE_KG_CB);
cksum_struct.md5 = md5;
cksum_struct.ctx = ctx;
cksum_struct.cred = cred;
@@ -283,15 +284,15 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_MD5:
case ENCTYPE_DES3_CBC_SHA1:
- code = make_gss_checksum(context, ctx->auth_context, &cksum_struct,
- &checksum_data);
- if (code)
- goto cleanup;
- break;
+ code = make_gss_checksum(context, ctx->auth_context, &cksum_struct,
+ &checksum_data);
+ if (code)
+ goto cleanup;
+ break;
default:
- krb5_auth_con_set_checksum_func(context, ctx->auth_context,
- make_gss_checksum, &cksum_struct);
- break;
+ krb5_auth_con_set_checksum_func(context, ctx->auth_context,
+ make_gss_checksum, &cksum_struct);
+ break;
}
@@ -300,51 +301,51 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
mk_req_flags = AP_OPTS_USE_SUBKEY;
if (ctx->gss_flags & GSS_C_MUTUAL_FLAG)
- mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
+ mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
- checksum_data, k_cred, &ap_req);
+ checksum_data, k_cred, &ap_req);
krb5_free_data_contents(context, &cksum_struct.checksum_data);
if (code)
- goto cleanup;
+ goto cleanup;
+
+ /* store the interesting stuff from creds and authent */
+ ctx->endtime = k_cred->times.endtime;
+ ctx->krb_flags = k_cred->ticket_flags;
- /* store the interesting stuff from creds and authent */
- ctx->endtime = k_cred->times.endtime;
- ctx->krb_flags = k_cred->ticket_flags;
+ /* build up the token */
- /* build up the token */
+ /* allocate space for the token */
+ tlen = g_token_size((gss_OID) mech_type, ap_req.length);
- /* allocate space for the token */
- tlen = g_token_size((gss_OID) mech_type, ap_req.length);
+ if ((t = (unsigned char *) xmalloc(tlen)) == NULL) {
+ code = ENOMEM;
+ goto cleanup;
+ }
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
+ /* fill in the buffer */
- /* fill in the buffer */
+ ptr = t;
- ptr = t;
+ g_make_token_header(mech_type, ap_req.length,
+ &ptr, KG_TOK_CTX_AP_REQ);
- g_make_token_header(mech_type, ap_req.length,
- &ptr, KG_TOK_CTX_AP_REQ);
+ TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length);
- TWRITE_STR(ptr, (unsigned char *) ap_req.data, ap_req.length);
+ /* pass it back */
- /* pass it back */
+ token->length = tlen;
+ token->value = (void *) t;
- token->length = tlen;
- token->value = (void *) t;
+ code = 0;
- code = 0;
-
- cleanup:
- if (checksum_data && checksum_data->data)
- krb5_free_data_contents(context, checksum_data);
- if (ap_req.data)
- krb5_free_data_contents(context, &ap_req);
+cleanup:
+ if (checksum_data && checksum_data->data)
+ krb5_free_data_contents(context, checksum_data);
+ if (ap_req.data)
+ krb5_free_data_contents(context, &ap_req);
- return (code);
+ return (code);
}
/*
@@ -354,87 +355,87 @@ make_ap_req_v1(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
*/
static OM_uint32
setup_enc(
- OM_uint32 *minor_status,
- krb5_gss_ctx_id_rec *ctx,
- krb5_context context)
+ OM_uint32 *minor_status,
+ krb5_gss_ctx_id_rec *ctx,
+ krb5_context context)
{
- krb5_error_code code;
- unsigned int i;
- krb5int_access kaccess;
-
- code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
- if (code)
- goto fail;
-
- ctx->have_acceptor_subkey = 0;
- ctx->proto = 0;
- ctx->cksumtype = 0;
- switch(ctx->subkey->enctype) {
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_MD4:
- case ENCTYPE_DES_CBC_CRC:
- ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = SGN_ALG_DES_MAC_MD5;
- ctx->cksum_size = 8;
- ctx->sealalg = SEAL_ALG_DES;
-
- /* The encryption key is the session key XOR
- 0xf0f0f0f0f0f0f0f0. */
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
- goto fail;
-
- for (i=0; i<ctx->enc->length; i++)
- ctx->enc->contents[i] ^= 0xf0;
-
- goto copy_subkey_to_seq;
-
- case ENCTYPE_DES3_CBC_SHA1:
- /* MIT extension */
- ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
- ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
- ctx->cksum_size = 20;
- ctx->sealalg = SEAL_ALG_DES3KD;
-
- copy_subkey:
- code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
- if (code)
- goto fail;
- copy_subkey_to_seq:
- code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
- if (code) {
- krb5_free_keyblock (context, ctx->enc);
- goto fail;
- }
- break;
-
- case ENCTYPE_ARCFOUR_HMAC:
- /* Microsoft extension */
- ctx->signalg = SGN_ALG_HMAC_MD5 ;
- ctx->cksum_size = 8;
- ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
-
- goto copy_subkey;
-
- default:
- /* Fill some fields we shouldn't be using on this path
- with garbage. */
- ctx->signalg = -10;
- ctx->sealalg = -10;
-
- ctx->proto = 1;
- code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype,
- &ctx->cksumtype);
- if (code)
- goto fail;
- code = krb5_c_checksum_length(context, ctx->cksumtype,
- &ctx->cksum_size);
- if (code)
- goto fail;
- goto copy_subkey;
- }
+ krb5_error_code code;
+ unsigned int i;
+ krb5int_access kaccess;
+
+ code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+ if (code)
+ goto fail;
+
+ ctx->have_acceptor_subkey = 0;
+ ctx->proto = 0;
+ ctx->cksumtype = 0;
+ switch(ctx->subkey->enctype) {
+ case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_MD4:
+ case ENCTYPE_DES_CBC_CRC:
+ ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_DES;
+
+ /* The encryption key is the session key XOR
+ 0xf0f0f0f0f0f0f0f0. */
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+ goto fail;
+
+ for (i=0; i<ctx->enc->length; i++)
+ ctx->enc->contents[i] ^= 0xf0;
+
+ goto copy_subkey_to_seq;
+
+ case ENCTYPE_DES3_CBC_SHA1:
+ /* MIT extension */
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
+
+ copy_subkey:
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+ if (code)
+ goto fail;
+ copy_subkey_to_seq:
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+ if (code) {
+ krb5_free_keyblock (context, ctx->enc);
+ goto fail;
+ }
+ break;
+
+ case ENCTYPE_ARCFOUR_HMAC:
+ /* Microsoft extension */
+ ctx->signalg = SGN_ALG_HMAC_MD5 ;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_MICROSOFT_RC4 ;
+
+ goto copy_subkey;
+
+ default:
+ /* Fill some fields we shouldn't be using on this path
+ with garbage. */
+ ctx->signalg = -10;
+ ctx->sealalg = -10;
+
+ ctx->proto = 1;
+ code = (*kaccess.krb5int_c_mandatory_cksumtype)(context, ctx->subkey->enctype,
+ &ctx->cksumtype);
+ if (code)
+ goto fail;
+ code = krb5_c_checksum_length(context, ctx->cksumtype,
+ &ctx->cksum_size);
+ if (code)
+ goto fail;
+ goto copy_subkey;
+ }
fail:
- *minor_status = code;
- return GSS_S_FAILURE;
+ *minor_status = code;
+ return GSS_S_FAILURE;
}
/*
@@ -444,204 +445,204 @@ fail:
*/
static OM_uint32
new_connection(
- OM_uint32 *minor_status,
- krb5_gss_cred_id_t cred,
- gss_ctx_id_t *context_handle,
- gss_name_t target_name,
- gss_OID mech_type,
- OM_uint32 req_flags,
- OM_uint32 time_req,
- gss_channel_bindings_t input_chan_bindings,
- gss_buffer_t input_token,
- gss_OID *actual_mech_type,
- gss_buffer_t output_token,
- OM_uint32 *ret_flags,
- OM_uint32 *time_rec,
- krb5_context context,
- int default_mech)
+ OM_uint32 *minor_status,
+ krb5_gss_cred_id_t cred,
+ gss_ctx_id_t *context_handle,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ gss_channel_bindings_t input_chan_bindings,
+ gss_buffer_t input_token,
+ gss_OID *actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ krb5_context context,
+ int default_mech)
{
- OM_uint32 major_status;
- krb5_error_code code;
- krb5_creds *k_cred;
- krb5_gss_ctx_id_rec *ctx, *ctx_free;
- krb5_timestamp now;
- gss_buffer_desc token;
-
- k5_mutex_assert_locked(&cred->lock);
- major_status = GSS_S_FAILURE;
- token.length = 0;
- token.value = NULL;
-
- /* make sure the cred is usable for init */
-
- if ((cred->usage != GSS_C_INITIATE) &&
- (cred->usage != GSS_C_BOTH)) {
- *minor_status = 0;
- return(GSS_S_NO_CRED);
- }
-
- /* complain if the input token is non-null */
-
- if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- /* create the ctx */
-
- if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
- == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- /* fill in the ctx */
- memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
- ctx_free = ctx;
- if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
- goto fail;
- krb5_auth_con_setflags(context, ctx->auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE);
-
- /* limit the encryption types negotiated (if requested) */
- if (cred->req_enctypes) {
- if ((code = krb5_set_default_tgs_enctypes(context,
- cred->req_enctypes))) {
- goto fail;
- }
- }
-
- ctx->initiate = 1;
- ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
- GSS_C_TRANS_FLAG |
- ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
- GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
- ctx->seed_init = 0;
- ctx->big_endian = 0; /* all initiators do little-endian, as per spec */
- ctx->seqstate = 0;
-
- if ((code = krb5_timeofday(context, &now)))
- goto fail;
-
- if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
- ctx->endtime = 0;
- } else {
- ctx->endtime = now + time_req;
- }
-
- if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
- goto fail;
-
- if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
- &ctx->there)))
- goto fail;
-
- code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, &k_cred);
- if (code)
- goto fail;
-
- if (default_mech) {
- mech_type = (gss_OID) gss_mech_krb5;
- }
-
- if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
- != GSS_S_COMPLETE) {
- code = *minor_status;
- goto fail;
- }
- /*
- * Now try to make it static if at all possible....
- */
- ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
-
- {
- /* gsskrb5 v1 */
- krb5_ui_4 seq_temp;
- if ((code = make_ap_req_v1(context, ctx,
- cred, k_cred, input_chan_bindings,
- mech_type, &token))) {
- if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
- (code == KG_EMPTY_CCACHE))
- major_status = GSS_S_NO_CRED;
- if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
- major_status = GSS_S_CREDENTIALS_EXPIRED;
- goto fail;
- }
-
- krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &seq_temp);
- ctx->seq_send = seq_temp;
- krb5_auth_con_getsendsubkey(context, ctx->auth_context,
- &ctx->subkey);
- }
-
- major_status = setup_enc(minor_status, ctx, context);
-
- if (k_cred) {
- krb5_free_creds(context, k_cred);
- k_cred = 0;
- }
-
- /* at this point, the context is constructed and valid,
- hence, releaseable */
-
- /* intern the context handle */
-
- if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
- code = G_VALIDATE_FAILED;
- goto fail;
- }
- *context_handle = (gss_ctx_id_t) ctx;
- ctx_free = 0;
-
- /* compute time_rec */
- if (time_rec) {
- if ((code = krb5_timeofday(context, &now)))
- goto fail;
- *time_rec = ctx->endtime - now;
- }
-
- /* set the other returns */
- *output_token = token;
-
- if (ret_flags)
- *ret_flags = ctx->gss_flags;
-
- if (actual_mech_type)
- *actual_mech_type = mech_type;
-
- /* return successfully */
-
- *minor_status = 0;
- if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
- ctx->established = 0;
- return(GSS_S_CONTINUE_NEEDED);
- } else {
- ctx->seq_recv = ctx->seq_send;
- g_order_init(&(ctx->seqstate), ctx->seq_recv,
- (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
- (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
- ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
- ctx->established = 1;
- return(GSS_S_COMPLETE);
- }
+ OM_uint32 major_status;
+ krb5_error_code code;
+ krb5_creds *k_cred;
+ krb5_gss_ctx_id_rec *ctx, *ctx_free;
+ krb5_timestamp now;
+ gss_buffer_desc token;
+
+ k5_mutex_assert_locked(&cred->lock);
+ major_status = GSS_S_FAILURE;
+ token.length = 0;
+ token.value = NULL;
+
+ /* make sure the cred is usable for init */
+
+ if ((cred->usage != GSS_C_INITIATE) &&
+ (cred->usage != GSS_C_BOTH)) {
+ *minor_status = 0;
+ return(GSS_S_NO_CRED);
+ }
+
+ /* complain if the input token is non-null */
+
+ if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
+ *minor_status = 0;
+ return(GSS_S_DEFECTIVE_TOKEN);
+ }
+
+ /* create the ctx */
+
+ if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))
+ == NULL) {
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+
+ /* fill in the ctx */
+ memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
+ ctx_free = ctx;
+ if ((code = krb5_auth_con_init(context, &ctx->auth_context)))
+ goto fail;
+ krb5_auth_con_setflags(context, ctx->auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+
+ /* limit the encryption types negotiated (if requested) */
+ if (cred->req_enctypes) {
+ if ((code = krb5_set_default_tgs_enctypes(context,
+ cred->req_enctypes))) {
+ goto fail;
+ }
+ }
+
+ ctx->initiate = 1;
+ ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
+ GSS_C_TRANS_FLAG |
+ ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+ GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG)));
+ ctx->seed_init = 0;
+ ctx->big_endian = 0; /* all initiators do little-endian, as per spec */
+ ctx->seqstate = 0;
+
+ if ((code = krb5_timeofday(context, &now)))
+ goto fail;
+
+ if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
+ ctx->endtime = 0;
+ } else {
+ ctx->endtime = now + time_req;
+ }
+
+ if ((code = krb5_copy_principal(context, cred->princ, &ctx->here)))
+ goto fail;
+
+ if ((code = krb5_copy_principal(context, (krb5_principal) target_name,
+ &ctx->there)))
+ goto fail;
+
+ code = get_credentials(context, cred, ctx->there, now,
+ ctx->endtime, &k_cred);
+ if (code)
+ goto fail;
+
+ if (default_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
+ }
+
+ if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
+ != GSS_S_COMPLETE) {
+ code = *minor_status;
+ goto fail;
+ }
+ /*
+ * Now try to make it static if at all possible....
+ */
+ ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
+
+ {
+ /* gsskrb5 v1 */
+ krb5_ui_4 seq_temp;
+ if ((code = make_ap_req_v1(context, ctx,
+ cred, k_cred, input_chan_bindings,
+ mech_type, &token))) {
+ if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
+ (code == KG_EMPTY_CCACHE))
+ major_status = GSS_S_NO_CRED;
+ if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
+ major_status = GSS_S_CREDENTIALS_EXPIRED;
+ goto fail;
+ }
+
+ krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &seq_temp);
+ ctx->seq_send = seq_temp;
+ krb5_auth_con_getsendsubkey(context, ctx->auth_context,
+ &ctx->subkey);
+ }
+
+ major_status = setup_enc(minor_status, ctx, context);
+
+ if (k_cred) {
+ krb5_free_creds(context, k_cred);
+ k_cred = 0;
+ }
+
+ /* at this point, the context is constructed and valid,
+ hence, releaseable */
+
+ /* intern the context handle */
+
+ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
+ code = G_VALIDATE_FAILED;
+ goto fail;
+ }
+ *context_handle = (gss_ctx_id_t) ctx;
+ ctx_free = 0;
+
+ /* compute time_rec */
+ if (time_rec) {
+ if ((code = krb5_timeofday(context, &now)))
+ goto fail;
+ *time_rec = ctx->endtime - now;
+ }
+
+ /* set the other returns */
+ *output_token = token;
+
+ if (ret_flags)
+ *ret_flags = ctx->gss_flags;
+
+ if (actual_mech_type)
+ *actual_mech_type = mech_type;
+
+ /* return successfully */
+
+ *minor_status = 0;
+ if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) {
+ ctx->established = 0;
+ return(GSS_S_CONTINUE_NEEDED);
+ } else {
+ ctx->seq_recv = ctx->seq_send;
+ g_order_init(&(ctx->seqstate), ctx->seq_recv,
+ (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+ (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
+ ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
+ ctx->established = 1;
+ return(GSS_S_COMPLETE);
+ }
fail:
- if (ctx_free) {
- if (ctx_free->auth_context)
- krb5_auth_con_free(context, ctx_free->auth_context);
- if (ctx_free->here)
- krb5_free_principal(context, ctx_free->here);
- if (ctx_free->there)
- krb5_free_principal(context, ctx_free->there);
- if (ctx_free->subkey)
- krb5_free_keyblock(context, ctx_free->subkey);
- xfree(ctx_free);
- } else
- (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
-
- *minor_status = code;
- return (major_status);
+ if (ctx_free) {
+ if (ctx_free->auth_context)
+ krb5_auth_con_free(context, ctx_free->auth_context);
+ if (ctx_free->here)
+ krb5_free_principal(context, ctx_free->here);
+ if (ctx_free->there)
+ krb5_free_principal(context, ctx_free->there);
+ if (ctx_free->subkey)
+ krb5_free_keyblock(context, ctx_free->subkey);
+ xfree(ctx_free);
+ } else
+ (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+
+ *minor_status = code;
+ return (major_status);
}
/*
@@ -651,180 +652,180 @@ fail:
*/
static OM_uint32
mutual_auth(
- OM_uint32 *minor_status,
- gss_ctx_id_t *context_handle,
- gss_name_t target_name,
- gss_OID mech_type,
- OM_uint32 req_flags,
- OM_uint32 time_req,
- gss_channel_bindings_t input_chan_bindings,
- gss_buffer_t input_token,
- gss_OID *actual_mech_type,
- gss_buffer_t output_token,
- OM_uint32 *ret_flags,
- OM_uint32 *time_rec,
- krb5_context context)
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ gss_channel_bindings_t input_chan_bindings,
+ gss_buffer_t input_token,
+ gss_OID *actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ krb5_context context)
{
- OM_uint32 major_status;
- unsigned char *ptr;
- char *sptr;
- krb5_data ap_rep;
- krb5_ap_rep_enc_part *ap_rep_data;
- krb5_timestamp now;
- krb5_gss_ctx_id_rec *ctx;
- krb5_error *krb_error;
- krb5_error_code code;
- krb5int_access kaccess;
-
- major_status = GSS_S_FAILURE;
-
- code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
- if (code)
- goto fail;
-
- /* validate the context handle */
- /*SUPPRESS 29*/
- if (! kg_validate_ctx_id(*context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
-
- ctx = (krb5_gss_ctx_id_t) *context_handle;
-
- /* make sure the context is non-established, and that certain
- arguments are unchanged */
-
- if ((ctx->established) ||
- ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
- code = KG_CONTEXT_ESTABLISHED;
- goto fail;
- }
-
- if (! krb5_principal_compare(context, ctx->there,
- (krb5_principal) target_name)) {
- (void)krb5_gss_delete_sec_context(minor_status,
- context_handle, NULL);
- code = 0;
- major_status = GSS_S_BAD_NAME;
- goto fail;
- }
-
- /* verify the token and leave the AP_REP message in ap_rep */
-
- if (input_token == GSS_C_NO_BUFFER) {
- (void)krb5_gss_delete_sec_context(minor_status,
- context_handle, NULL);
- code = 0;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
-
- ptr = (unsigned char *) input_token->value;
-
- if (g_verify_token_header(ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_AP_REP,
- input_token->length, 1)) {
- if (g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_ERROR,
- input_token->length, 1) == 0) {
-
- /* Handle a KRB_ERROR message from the server */
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
- code = krb5_rd_error(context, &ap_rep, &krb_error);
- if (code)
- goto fail;
- if (krb_error->error)
- code = krb_error->error + ERROR_TABLE_BASE_krb5;
- else
- code = 0;
- krb5_free_error(context, krb_error);
- goto fail;
- } else {
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
- }
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
- /* decode the ap_rep */
- if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
- &ap_rep_data))) {
- /*
- * XXX A hack for backwards compatiblity.
- * To be removed in 1999 -- proven
- */
- krb5_auth_con_setuseruserkey(context, ctx->auth_context,
- ctx->subkey);
- if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
- &ap_rep_data)))
- goto fail;
- }
-
- /* store away the sequence number */
- ctx->seq_recv = ap_rep_data->seq_number;
- g_order_init(&(ctx->seqstate), ctx->seq_recv,
- (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
- (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto);
-
- if (ctx->proto == 1 && ap_rep_data->subkey) {
- /* Keep acceptor's subkey. */
- ctx->have_acceptor_subkey = 1;
- code = krb5_copy_keyblock(context, ap_rep_data->subkey,
- &ctx->acceptor_subkey);
- if (code)
- goto fail;
- code = (*kaccess.krb5int_c_mandatory_cksumtype)(context,
- ctx->acceptor_subkey->enctype,
- &ctx->acceptor_subkey_cksumtype);
- if (code)
- goto fail;
- }
-
- /* free the ap_rep_data */
- krb5_free_ap_rep_enc_part(context, ap_rep_data);
-
- /* set established */
- ctx->established = 1;
-
- /* set returns */
-
- if (time_rec) {
- if ((code = krb5_timeofday(context, &now)))
- goto fail;
- *time_rec = ctx->endtime - now;
- }
-
- if (ret_flags)
- *ret_flags = ctx->gss_flags;
-
- if (actual_mech_type)
- *actual_mech_type = mech_type;
-
- /* success */
-
- *minor_status = 0;
- return GSS_S_COMPLETE;
+ OM_uint32 major_status;
+ unsigned char *ptr;
+ char *sptr;
+ krb5_data ap_rep;
+ krb5_ap_rep_enc_part *ap_rep_data;
+ krb5_timestamp now;
+ krb5_gss_ctx_id_rec *ctx;
+ krb5_error *krb_error;
+ krb5_error_code code;
+ krb5int_access kaccess;
+
+ major_status = GSS_S_FAILURE;
+
+ code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
+ if (code)
+ goto fail;
+
+ /* validate the context handle */
+ /*SUPPRESS 29*/
+ if (! kg_validate_ctx_id(*context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
+
+ ctx = (krb5_gss_ctx_id_t) *context_handle;
+
+ /* make sure the context is non-established, and that certain
+ arguments are unchanged */
+
+ if ((ctx->established) ||
+ ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) {
+ code = KG_CONTEXT_ESTABLISHED;
+ goto fail;
+ }
+
+ if (! krb5_principal_compare(context, ctx->there,
+ (krb5_principal) target_name)) {
+ (void)krb5_gss_delete_sec_context(minor_status,
+ context_handle, NULL);
+ code = 0;
+ major_status = GSS_S_BAD_NAME;
+ goto fail;
+ }
+
+ /* verify the token and leave the AP_REP message in ap_rep */
+
+ if (input_token == GSS_C_NO_BUFFER) {
+ (void)krb5_gss_delete_sec_context(minor_status,
+ context_handle, NULL);
+ code = 0;
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto fail;
+ }
+
+ ptr = (unsigned char *) input_token->value;
+
+ if (g_verify_token_header(ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_AP_REP,
+ input_token->length, 1)) {
+ if (g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_ERROR,
+ input_token->length, 1) == 0) {
+
+ /* Handle a KRB_ERROR message from the server */
+
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+ code = krb5_rd_error(context, &ap_rep, &krb_error);
+ if (code)
+ goto fail;
+ if (krb_error->error)
+ code = krb_error->error + ERROR_TABLE_BASE_krb5;
+ else
+ code = 0;
+ krb5_free_error(context, krb_error);
+ goto fail;
+ } else {
+ *minor_status = 0;
+ return(GSS_S_DEFECTIVE_TOKEN);
+ }
+ }
+
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+ /* decode the ap_rep */
+ if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+ &ap_rep_data))) {
+ /*
+ * XXX A hack for backwards compatiblity.
+ * To be removed in 1999 -- proven
+ */
+ krb5_auth_con_setuseruserkey(context, ctx->auth_context,
+ ctx->subkey);
+ if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep,
+ &ap_rep_data)))
+ goto fail;
+ }
+
+ /* store away the sequence number */
+ ctx->seq_recv = ap_rep_data->seq_number;
+ g_order_init(&(ctx->seqstate), ctx->seq_recv,
+ (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+ (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto);
+
+ if (ctx->proto == 1 && ap_rep_data->subkey) {
+ /* Keep acceptor's subkey. */
+ ctx->have_acceptor_subkey = 1;
+ code = krb5_copy_keyblock(context, ap_rep_data->subkey,
+ &ctx->acceptor_subkey);
+ if (code)
+ goto fail;
+ code = (*kaccess.krb5int_c_mandatory_cksumtype)(context,
+ ctx->acceptor_subkey->enctype,
+ &ctx->acceptor_subkey_cksumtype);
+ if (code)
+ goto fail;
+ }
+
+ /* free the ap_rep_data */
+ krb5_free_ap_rep_enc_part(context, ap_rep_data);
+
+ /* set established */
+ ctx->established = 1;
+
+ /* set returns */
+
+ if (time_rec) {
+ if ((code = krb5_timeofday(context, &now)))
+ goto fail;
+ *time_rec = ctx->endtime - now;
+ }
+
+ if (ret_flags)
+ *ret_flags = ctx->gss_flags;
+
+ if (actual_mech_type)
+ *actual_mech_type = mech_type;
+
+ /* success */
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
fail:
- (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
+ (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL);
- *minor_status = code;
- return (major_status);
+ *minor_status = code;
+ return (major_status);
}
OM_uint32
krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
- context_handle, target_name, mech_type,
- req_flags, time_req, input_chan_bindings,
- input_token, actual_mech_type, output_token,
- ret_flags, time_rec)
+ context_handle, target_name, mech_type,
+ req_flags, time_req, input_chan_bindings,
+ input_token, actual_mech_type, output_token,
+ ret_flags, time_rec)
OM_uint32 *minor_status;
gss_cred_id_t claimant_cred_handle;
gss_ctx_id_t *context_handle;
@@ -839,142 +840,142 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
OM_uint32 *ret_flags;
OM_uint32 *time_rec;
{
- krb5_context context;
- krb5_gss_cred_id_t cred;
- int err;
- krb5_error_code kerr;
- int default_mech = 0;
- OM_uint32 major_status;
- OM_uint32 tmp_min_stat;
-
- if (*context_handle == GSS_C_NO_CONTEXT) {
- kerr = krb5_gss_init_context(&context);
- if (kerr) {
- *minor_status = kerr;
- return GSS_S_FAILURE;
- }
- if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) {
- save_error_info(*minor_status, context);
- krb5_free_context(context);
- return GSS_S_FAILURE;
- }
- } else {
- context = ((krb5_gss_ctx_id_rec *)*context_handle)->k5_context;
- }
-
- /* set up return values so they can be "freed" successfully */
-
- major_status = GSS_S_FAILURE; /* Default major code */
- output_token->length = 0;
- output_token->value = NULL;
- if (actual_mech_type)
- *actual_mech_type = NULL;
-
- /* verify that the target_name is valid and usable */
-
- if (! kg_validate_name(target_name)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- save_error_info(*minor_status, context);
- if (*context_handle == GSS_C_NO_CONTEXT)
- krb5_free_context(context);
- return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
- }
-
- /* verify the credential, or use the default */
- /*SUPPRESS 29*/
- if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
- major_status = kg_get_defcred(minor_status, (gss_cred_id_t *)&cred);
- if (major_status && GSS_ERROR(major_status)) {
- if (*context_handle == GSS_C_NO_CONTEXT)
- krb5_free_context(context);
- return(major_status);
- }
- } else {
- major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
- if (GSS_ERROR(major_status)) {
- save_error_info(*minor_status, context);
- if (*context_handle == GSS_C_NO_CONTEXT)
- krb5_free_context(context);
- return(major_status);
- }
- cred = (krb5_gss_cred_id_t) claimant_cred_handle;
- }
- kerr = k5_mutex_lock(&cred->lock);
- if (kerr) {
- krb5_free_context(context);
- *minor_status = kerr;
- return GSS_S_FAILURE;
- }
-
- /* verify the mech_type */
-
- err = 0;
- if (mech_type == GSS_C_NULL_OID) {
- default_mech = 1;
- if (cred->rfc_mech) {
- mech_type = (gss_OID) gss_mech_krb5;
- } else if (cred->prerfc_mech) {
- mech_type = (gss_OID) gss_mech_krb5_old;
- } else {
- err = 1;
- }
- } else if (g_OID_equal(mech_type, gss_mech_krb5)) {
- if (!cred->rfc_mech)
- err = 1;
- } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
- if (!cred->prerfc_mech)
- err = 1;
- } else if (g_OID_equal(mech_type, gss_mech_krb5_wrong)) {
- if (!cred->rfc_mech)
- err = 1;
- } else {
- err = 1;
- }
-
- if (err) {
- k5_mutex_unlock(&cred->lock);
- if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
- krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
- *minor_status = 0;
- if (*context_handle == GSS_C_NO_CONTEXT)
- krb5_free_context(context);
- return(GSS_S_BAD_MECH);
- }
-
- /* is this a new connection or not? */
-
- /*SUPPRESS 29*/
- if (*context_handle == GSS_C_NO_CONTEXT) {
- major_status = new_connection(minor_status, cred, context_handle,
- target_name, mech_type, req_flags,
- time_req, input_chan_bindings,
- input_token, actual_mech_type,
- output_token, ret_flags, time_rec,
- context, default_mech);
- k5_mutex_unlock(&cred->lock);
- if (*context_handle == GSS_C_NO_CONTEXT) {
- save_error_info (*minor_status, context);
- krb5_free_context(context);
- } else
- ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context;
- } else {
- /* mutual_auth doesn't care about the credentials */
- k5_mutex_unlock(&cred->lock);
- major_status = mutual_auth(minor_status, context_handle,
- target_name, mech_type, req_flags,
- time_req, input_chan_bindings,
- input_token, actual_mech_type,
- output_token, ret_flags, time_rec,
- context);
- /* If context_handle is now NO_CONTEXT, mutual_auth called
- delete_sec_context, which would've zapped the krb5 context
- too. */
- }
-
- if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
- krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t *)&cred);
-
- return(major_status);
+ krb5_context context;
+ krb5_gss_cred_id_t cred;
+ int err;
+ krb5_error_code kerr;
+ int default_mech = 0;
+ OM_uint32 major_status;
+ OM_uint32 tmp_min_stat;
+
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ kerr = krb5_gss_init_context(&context);
+ if (kerr) {
+ *minor_status = kerr;
+ return GSS_S_FAILURE;
+ }
+ if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) {
+ save_error_info(*minor_status, context);
+ krb5_free_context(context);
+ return GSS_S_FAILURE;
+ }
+ } else {
+ context = ((krb5_gss_ctx_id_rec *)*context_handle)->k5_context;
+ }
+
+ /* set up return values so they can be "freed" successfully */
+
+ major_status = GSS_S_FAILURE; /* Default major code */
+ output_token->length = 0;
+ output_token->value = NULL;
+ if (actual_mech_type)
+ *actual_mech_type = NULL;
+
+ /* verify that the target_name is valid and usable */
+
+ if (! kg_validate_name(target_name)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ save_error_info(*minor_status, context);
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ krb5_free_context(context);
+ return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+ }
+
+ /* verify the credential, or use the default */
+ /*SUPPRESS 29*/
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+ major_status = kg_get_defcred(minor_status, (gss_cred_id_t *)&cred);
+ if (major_status && GSS_ERROR(major_status)) {
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ krb5_free_context(context);
+ return(major_status);
+ }
+ } else {
+ major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
+ if (GSS_ERROR(major_status)) {
+ save_error_info(*minor_status, context);
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ krb5_free_context(context);
+ return(major_status);
+ }
+ cred = (krb5_gss_cred_id_t) claimant_cred_handle;
+ }
+ kerr = k5_mutex_lock(&cred->lock);
+ if (kerr) {
+ krb5_free_context(context);
+ *minor_status = kerr;
+ return GSS_S_FAILURE;
+ }
+
+ /* verify the mech_type */
+
+ err = 0;
+ if (mech_type == GSS_C_NULL_OID) {
+ default_mech = 1;
+ if (cred->rfc_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
+ } else if (cred->prerfc_mech) {
+ mech_type = (gss_OID) gss_mech_krb5_old;
+ } else {
+ err = 1;
+ }
+ } else if (g_OID_equal(mech_type, gss_mech_krb5)) {
+ if (!cred->rfc_mech)
+ err = 1;
+ } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
+ if (!cred->prerfc_mech)
+ err = 1;
+ } else if (g_OID_equal(mech_type, gss_mech_krb5_wrong)) {
+ if (!cred->rfc_mech)
+ err = 1;
+ } else {
+ err = 1;
+ }
+
+ if (err) {
+ k5_mutex_unlock(&cred->lock);
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+ krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
+ *minor_status = 0;
+ if (*context_handle == GSS_C_NO_CONTEXT)
+ krb5_free_context(context);
+ return(GSS_S_BAD_MECH);
+ }
+
+ /* is this a new connection or not? */
+
+ /*SUPPRESS 29*/
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ major_status = new_connection(minor_status, cred, context_handle,
+ target_name, mech_type, req_flags,
+ time_req, input_chan_bindings,
+ input_token, actual_mech_type,
+ output_token, ret_flags, time_rec,
+ context, default_mech);
+ k5_mutex_unlock(&cred->lock);
+ if (*context_handle == GSS_C_NO_CONTEXT) {
+ save_error_info (*minor_status, context);
+ krb5_free_context(context);
+ } else
+ ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context;
+ } else {
+ /* mutual_auth doesn't care about the credentials */
+ k5_mutex_unlock(&cred->lock);
+ major_status = mutual_auth(minor_status, context_handle,
+ target_name, mech_type, req_flags,
+ time_req, input_chan_bindings,
+ input_token, actual_mech_type,
+ output_token, ret_flags, time_rec,
+ context);
+ /* If context_handle is now NO_CONTEXT, mutual_auth called
+ delete_sec_context, which would've zapped the krb5 context
+ too. */
+ }
+
+ if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+ krb5_gss_release_cred(&tmp_min_stat, (gss_cred_id_t *)&cred);
+
+ return(major_status);
}
#ifndef _WIN32
@@ -992,16 +993,16 @@ krb5_gss_init_context (krb5_context *ctxp)
err = gssint_initialize_library();
if (err)
- return err;
+ return err;
#ifndef _WIN32
err = k5_mutex_lock(&kg_kdc_flag_mutex);
if (err)
- return err;
+ return err;
is_kdc = kdc_flag;
k5_mutex_unlock(&kg_kdc_flag_mutex);
if (is_kdc)
- return krb5int_init_context_kdc(ctxp);
+ return krb5int_init_context_kdc(ctxp);
#endif
return krb5_init_context(ctxp);
@@ -1015,13 +1016,12 @@ krb5_gss_use_kdc_context()
err = gssint_initialize_library();
if (err)
- return err;
+ return err;
err = k5_mutex_lock(&kg_kdc_flag_mutex);
if (err)
- return err;
+ return err;
kdc_flag = 1;
k5_mutex_unlock(&kg_kdc_flag_mutex);
return 0;
}
#endif
-