merge most of the initiator part from the samba patch by Stefan Metzmacher and Andrew Bartlet (still missing DCE/RPC support)
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@18147 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -64,10 +64,22 @@ typedef struct {
|
|||||||
COMPAT_OLD_DES3_SELECTED = 8,
|
COMPAT_OLD_DES3_SELECTED = 8,
|
||||||
ACCEPTOR_SUBKEY = 16
|
ACCEPTOR_SUBKEY = 16
|
||||||
} more_flags;
|
} more_flags;
|
||||||
|
enum gss_ctx_id_t_state {
|
||||||
|
/* initiator states */
|
||||||
|
INITIATOR_START,
|
||||||
|
INITIATOR_WAIT_FOR_MUTAL,
|
||||||
|
INITIATOR_READY,
|
||||||
|
/* acceptor states */
|
||||||
|
ACCEPTOR_START,
|
||||||
|
ACCEPTOR_WAIT_FOR_DCESTYLE,
|
||||||
|
ACCEPTOR_READY
|
||||||
|
} state;
|
||||||
struct krb5_ticket *ticket;
|
struct krb5_ticket *ticket;
|
||||||
OM_uint32 lifetime;
|
OM_uint32 lifetime;
|
||||||
HEIMDAL_MUTEX ctx_id_mutex;
|
HEIMDAL_MUTEX ctx_id_mutex;
|
||||||
struct gss_msg_order *order;
|
struct gss_msg_order *order;
|
||||||
|
krb5_keyblock *service_keyblock;
|
||||||
|
krb5_data fwd_data;
|
||||||
} *gsskrb5_ctx;
|
} *gsskrb5_ctx;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -97,6 +97,173 @@ set_addresses (krb5_auth_context ac,
|
|||||||
return kret;
|
return kret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OM_uint32
|
||||||
|
_gsskrb5_create_ctx(
|
||||||
|
OM_uint32 * minor_status,
|
||||||
|
gss_ctx_id_t * context_handle,
|
||||||
|
const gss_channel_bindings_t input_chan_bindings,
|
||||||
|
enum gss_ctx_id_t_state state)
|
||||||
|
{
|
||||||
|
krb5_error_code kret;
|
||||||
|
gsskrb5_ctx ctx;
|
||||||
|
|
||||||
|
*context_handle = NULL;
|
||||||
|
|
||||||
|
ctx = malloc(sizeof(*ctx));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
*minor_status = ENOMEM;
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
}
|
||||||
|
ctx->auth_context = NULL;
|
||||||
|
ctx->source = NULL;
|
||||||
|
ctx->target = NULL;
|
||||||
|
ctx->state = state;
|
||||||
|
ctx->flags = 0;
|
||||||
|
ctx->more_flags = 0;
|
||||||
|
ctx->service_keyblock = NULL;
|
||||||
|
ctx->ticket = NULL;
|
||||||
|
krb5_data_zero(&ctx->fwd_data);
|
||||||
|
ctx->lifetime = GSS_C_INDEFINITE;
|
||||||
|
ctx->order = NULL;
|
||||||
|
HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
|
||||||
|
|
||||||
|
kret = krb5_auth_con_init (_gsskrb5_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);
|
||||||
|
if (kret) {
|
||||||
|
*minor_status = kret;
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
|
||||||
|
|
||||||
|
krb5_auth_con_free(_gsskrb5_context, ctx->auth_context);
|
||||||
|
|
||||||
|
return GSS_S_BAD_BINDINGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need a sequence number
|
||||||
|
*/
|
||||||
|
|
||||||
|
krb5_auth_con_addflags(_gsskrb5_context,
|
||||||
|
ctx->auth_context,
|
||||||
|
KRB5_AUTH_CONTEXT_DO_SEQUENCE |
|
||||||
|
KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
*context_handle = (gss_ctx_id_t)ctx;
|
||||||
|
|
||||||
|
return GSS_S_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static OM_uint32
|
||||||
|
gsskrb5_get_creds(
|
||||||
|
OM_uint32 * minor_status,
|
||||||
|
krb5_ccache ccache,
|
||||||
|
gsskrb5_ctx ctx,
|
||||||
|
krb5_const_principal target_name,
|
||||||
|
OM_uint32 time_req,
|
||||||
|
OM_uint32 * time_rec,
|
||||||
|
krb5_creds ** cred)
|
||||||
|
{
|
||||||
|
OM_uint32 ret;
|
||||||
|
krb5_error_code kret;
|
||||||
|
krb5_creds this_cred;
|
||||||
|
OM_uint32 lifetime_rec;
|
||||||
|
|
||||||
|
*cred = NULL;
|
||||||
|
|
||||||
|
kret = krb5_cc_get_principal(_gsskrb5_context, ccache, &ctx->source);
|
||||||
|
if (kret) {
|
||||||
|
_gsskrb5_set_error_string ();
|
||||||
|
*minor_status = kret;
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
kret = krb5_copy_principal(_gsskrb5_context, target_name, &ctx->target);
|
||||||
|
if (kret) {
|
||||||
|
_gsskrb5_set_error_string ();
|
||||||
|
*minor_status = kret;
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&this_cred, 0, sizeof(this_cred));
|
||||||
|
this_cred.client = ctx->source;
|
||||||
|
this_cred.server = ctx->target;
|
||||||
|
|
||||||
|
if (time_req && time_req != GSS_C_INDEFINITE) {
|
||||||
|
krb5_timestamp ts;
|
||||||
|
|
||||||
|
krb5_timeofday (_gsskrb5_context, &ts);
|
||||||
|
this_cred.times.endtime = ts + time_req;
|
||||||
|
} else {
|
||||||
|
this_cred.times.endtime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_cred.session.keytype = KEYTYPE_NULL;
|
||||||
|
|
||||||
|
kret = krb5_get_credentials(_gsskrb5_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);
|
||||||
|
if (ret) return ret;
|
||||||
|
|
||||||
|
if (lifetime_rec == 0) {
|
||||||
|
*minor_status = 0;
|
||||||
|
return GSS_S_CONTEXT_EXPIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_rec) *time_rec = lifetime_rec;
|
||||||
|
|
||||||
|
return GSS_S_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OM_uint32
|
||||||
|
gsskrb5_initiator_ready(
|
||||||
|
OM_uint32 * minor_status,
|
||||||
|
gsskrb5_ctx ctx)
|
||||||
|
{
|
||||||
|
OM_uint32 ret;
|
||||||
|
int32_t seq_number;
|
||||||
|
int is_cfx = 0;
|
||||||
|
OM_uint32 flags = ctx->flags;
|
||||||
|
|
||||||
|
krb5_auth_getremoteseqnumber (_gsskrb5_context,
|
||||||
|
ctx->auth_context,
|
||||||
|
&seq_number);
|
||||||
|
|
||||||
|
_gsskrb5i_is_cfx(ctx, &is_cfx);
|
||||||
|
|
||||||
|
ret = _gssapi_msg_order_create(minor_status,
|
||||||
|
&ctx->order,
|
||||||
|
_gssapi_msg_order_f(flags),
|
||||||
|
seq_number, 0, is_cfx);
|
||||||
|
if (ret) return ret;
|
||||||
|
|
||||||
|
ctx->state = INITIATOR_READY;
|
||||||
|
ctx->more_flags |= OPEN;
|
||||||
|
|
||||||
|
return GSS_S_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle delegated creds in init-sec-context
|
* handle delegated creds in init-sec-context
|
||||||
*/
|
*/
|
||||||
@@ -168,7 +335,7 @@ static OM_uint32
|
|||||||
init_auth
|
init_auth
|
||||||
(OM_uint32 * minor_status,
|
(OM_uint32 * minor_status,
|
||||||
gsskrb5_cred initiator_cred_handle,
|
gsskrb5_cred initiator_cred_handle,
|
||||||
gss_ctx_id_t * context_handle,
|
gsskrb5_ctx ctx,
|
||||||
krb5_const_principal name,
|
krb5_const_principal name,
|
||||||
const gss_OID mech_type,
|
const gss_OID mech_type,
|
||||||
OM_uint32 req_flags,
|
OM_uint32 req_flags,
|
||||||
@@ -184,7 +351,7 @@ init_auth
|
|||||||
OM_uint32 ret = GSS_S_FAILURE;
|
OM_uint32 ret = GSS_S_FAILURE;
|
||||||
krb5_error_code kret;
|
krb5_error_code kret;
|
||||||
krb5_flags ap_options;
|
krb5_flags ap_options;
|
||||||
krb5_creds this_cred, *cred = NULL;
|
krb5_creds *cred = NULL;
|
||||||
krb5_data outbuf;
|
krb5_data outbuf;
|
||||||
krb5_ccache ccache = NULL;
|
krb5_ccache ccache = NULL;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
@@ -193,52 +360,12 @@ init_auth
|
|||||||
krb5_enctype enctype;
|
krb5_enctype enctype;
|
||||||
krb5_data fwd_data;
|
krb5_data fwd_data;
|
||||||
OM_uint32 lifetime_rec;
|
OM_uint32 lifetime_rec;
|
||||||
gsskrb5_ctx ctx;
|
|
||||||
|
|
||||||
krb5_data_zero(&outbuf);
|
krb5_data_zero(&outbuf);
|
||||||
krb5_data_zero(&fwd_data);
|
krb5_data_zero(&fwd_data);
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
|
|
||||||
ctx = malloc(sizeof(*ctx));
|
|
||||||
if (ctx == NULL) {
|
|
||||||
*minor_status = ENOMEM;
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->auth_context = NULL;
|
|
||||||
ctx->source = NULL;
|
|
||||||
ctx->target = NULL;
|
|
||||||
ctx->flags = 0;
|
|
||||||
ctx->more_flags = 0;
|
|
||||||
ctx->ticket = NULL;
|
|
||||||
ctx->lifetime = GSS_C_INDEFINITE;
|
|
||||||
ctx->order = NULL;
|
|
||||||
HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
|
|
||||||
|
|
||||||
kret = krb5_auth_con_init (_gsskrb5_context,
|
|
||||||
&ctx->auth_context);
|
|
||||||
if (kret) {
|
|
||||||
_gsskrb5_set_error_string ();
|
|
||||||
*minor_status = kret;
|
|
||||||
ret = GSS_S_FAILURE;
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
kret = set_addresses (ctx->auth_context,
|
|
||||||
input_chan_bindings);
|
|
||||||
if (kret) {
|
|
||||||
*minor_status = kret;
|
|
||||||
ret = GSS_S_BAD_BINDINGS;
|
|
||||||
goto failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
krb5_auth_con_addflags(_gsskrb5_context,
|
|
||||||
ctx->auth_context,
|
|
||||||
KRB5_AUTH_CONTEXT_DO_SEQUENCE |
|
|
||||||
KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (actual_mech_type)
|
if (actual_mech_type)
|
||||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
*actual_mech_type = GSS_KRB5_MECHANISM;
|
||||||
|
|
||||||
@@ -276,30 +403,15 @@ init_auth
|
|||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
|
|
||||||
memset(&this_cred, 0, sizeof(this_cred));
|
ret = gsskrb5_get_creds(minor_status,
|
||||||
this_cred.client = ctx->source;
|
ccache,
|
||||||
this_cred.server = ctx->target;
|
ctx,
|
||||||
if (time_req && time_req != GSS_C_INDEFINITE) {
|
ctx->target,
|
||||||
krb5_timestamp ts;
|
time_req,
|
||||||
|
time_rec,
|
||||||
krb5_timeofday (_gsskrb5_context, &ts);
|
&cred);
|
||||||
this_cred.times.endtime = ts + time_req;
|
if (ret)
|
||||||
} else
|
|
||||||
this_cred.times.endtime = 0;
|
|
||||||
this_cred.session.keytype = KEYTYPE_NULL;
|
|
||||||
|
|
||||||
kret = krb5_get_credentials (_gsskrb5_context,
|
|
||||||
0,
|
|
||||||
ccache,
|
|
||||||
&this_cred,
|
|
||||||
&cred);
|
|
||||||
|
|
||||||
if (kret) {
|
|
||||||
_gsskrb5_set_error_string ();
|
|
||||||
*minor_status = kret;
|
|
||||||
ret = GSS_S_FAILURE;
|
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
|
||||||
|
|
||||||
ctx->lifetime = cred->times.endtime;
|
ctx->lifetime = cred->times.endtime;
|
||||||
|
|
||||||
@@ -364,6 +476,16 @@ init_auth
|
|||||||
flags |= GSS_C_SEQUENCE_FLAG;
|
flags |= GSS_C_SEQUENCE_FLAG;
|
||||||
if (req_flags & GSS_C_ANON_FLAG)
|
if (req_flags & GSS_C_ANON_FLAG)
|
||||||
; /* XXX */
|
; /* XXX */
|
||||||
|
if (req_flags & GSS_C_DCE_STYLE) {
|
||||||
|
/* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */
|
||||||
|
flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG;
|
||||||
|
ap_options |= AP_OPTS_MUTUAL_REQUIRED;
|
||||||
|
}
|
||||||
|
if (req_flags & GSS_C_IDENTIFY_FLAG)
|
||||||
|
flags |= GSS_C_IDENTIFY_FLAG;
|
||||||
|
if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)
|
||||||
|
flags |= GSS_C_EXTENDED_ERROR_FLAG;
|
||||||
|
|
||||||
flags |= GSS_C_CONF_FLAG;
|
flags |= GSS_C_CONF_FLAG;
|
||||||
flags |= GSS_C_INTEG_FLAG;
|
flags |= GSS_C_INTEG_FLAG;
|
||||||
flags |= GSS_C_TRANS_FLAG;
|
flags |= GSS_C_TRANS_FLAG;
|
||||||
@@ -426,60 +548,25 @@ init_auth
|
|||||||
krb5_cc_close(_gsskrb5_context, ccache);
|
krb5_cc_close(_gsskrb5_context, ccache);
|
||||||
|
|
||||||
if (flags & GSS_C_MUTUAL_FLAG) {
|
if (flags & GSS_C_MUTUAL_FLAG) {
|
||||||
*context_handle = (gss_ctx_id_t)ctx;
|
ctx->state = INITIATOR_WAIT_FOR_MUTAL;
|
||||||
return GSS_S_CONTINUE_NEEDED;
|
return GSS_S_CONTINUE_NEEDED;
|
||||||
} else {
|
|
||||||
int32_t seq_number;
|
|
||||||
int is_cfx = 0;
|
|
||||||
|
|
||||||
krb5_auth_getremoteseqnumber (_gsskrb5_context,
|
|
||||||
ctx->auth_context,
|
|
||||||
&seq_number);
|
|
||||||
|
|
||||||
_gsskrb5i_is_cfx(ctx, &is_cfx);
|
|
||||||
|
|
||||||
ret = _gssapi_msg_order_create(minor_status,
|
|
||||||
&ctx->order,
|
|
||||||
_gssapi_msg_order_f(flags),
|
|
||||||
seq_number, 0, is_cfx);
|
|
||||||
if (ret)
|
|
||||||
goto failure;
|
|
||||||
|
|
||||||
if (time_rec)
|
|
||||||
*time_rec = lifetime_rec;
|
|
||||||
|
|
||||||
ctx->more_flags |= OPEN;
|
|
||||||
*context_handle = (gss_ctx_id_t)ctx;
|
|
||||||
return GSS_S_COMPLETE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return gsskrb5_initiator_ready(minor_status, ctx);
|
||||||
failure:
|
failure:
|
||||||
krb5_auth_con_free (_gsskrb5_context,
|
|
||||||
ctx->auth_context);
|
|
||||||
krb5_data_free (&outbuf);
|
|
||||||
if(cred)
|
if(cred)
|
||||||
krb5_free_creds(_gsskrb5_context, cred);
|
krb5_free_creds(_gsskrb5_context, cred);
|
||||||
if (ccache && initiator_cred_handle == NULL)
|
if (ccache && initiator_cred_handle == NULL)
|
||||||
krb5_cc_close(_gsskrb5_context, ccache);
|
krb5_cc_close(_gsskrb5_context, ccache);
|
||||||
if(ctx->source)
|
|
||||||
krb5_free_principal (_gsskrb5_context,
|
|
||||||
ctx->source);
|
|
||||||
if(ctx->target)
|
|
||||||
krb5_free_principal (_gsskrb5_context,
|
|
||||||
ctx->target);
|
|
||||||
if(ctx->order)
|
|
||||||
_gssapi_msg_order_destroy(&ctx->order);
|
|
||||||
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
|
|
||||||
free(ctx);
|
|
||||||
*context_handle = GSS_C_NO_CONTEXT;
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static OM_uint32
|
static OM_uint32
|
||||||
repl_mutual
|
repl_mutual
|
||||||
(OM_uint32 * minor_status,
|
(OM_uint32 * minor_status,
|
||||||
const gsskrb5_cred initiator_cred_handle,
|
gsskrb5_ctx ctx,
|
||||||
gss_ctx_id_t * context_handle,
|
|
||||||
const gss_OID mech_type,
|
const gss_OID mech_type,
|
||||||
OM_uint32 req_flags,
|
OM_uint32 req_flags,
|
||||||
OM_uint32 time_req,
|
OM_uint32 time_req,
|
||||||
@@ -497,20 +584,16 @@ repl_mutual
|
|||||||
krb5_data indata;
|
krb5_data indata;
|
||||||
krb5_ap_rep_enc_part *repl;
|
krb5_ap_rep_enc_part *repl;
|
||||||
int is_cfx = 0;
|
int is_cfx = 0;
|
||||||
gsskrb5_ctx ctx = (gsskrb5_ctx) *context_handle;
|
|
||||||
|
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
output_token->value = NULL;
|
output_token->value = NULL;
|
||||||
|
|
||||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
|
||||||
|
|
||||||
if (actual_mech_type)
|
if (actual_mech_type)
|
||||||
*actual_mech_type = GSS_KRB5_MECHANISM;
|
*actual_mech_type = GSS_KRB5_MECHANISM;
|
||||||
|
|
||||||
ret = _gsskrb5_decapsulate (minor_status, input_token, &indata,
|
ret = _gsskrb5_decapsulate (minor_status, input_token, &indata,
|
||||||
"\x02\x00", GSS_KRB5_MECHANISM);
|
"\x02\x00", GSS_KRB5_MECHANISM);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
|
||||||
/* XXX - Handle AP_ERROR */
|
/* XXX - Handle AP_ERROR */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -520,7 +603,6 @@ repl_mutual
|
|||||||
&indata,
|
&indata,
|
||||||
&repl);
|
&repl);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
|
||||||
_gsskrb5_set_error_string ();
|
_gsskrb5_set_error_string ();
|
||||||
*minor_status = kret;
|
*minor_status = kret;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
@@ -539,12 +621,24 @@ repl_mutual
|
|||||||
_gssapi_msg_order_f(ctx->flags),
|
_gssapi_msg_order_f(ctx->flags),
|
||||||
seq_number, 0, is_cfx);
|
seq_number, 0, is_cfx);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->more_flags |= OPEN;
|
ctx->more_flags |= OPEN;
|
||||||
|
|
||||||
|
if (is_cfx) {
|
||||||
|
krb5_keyblock *key = NULL;
|
||||||
|
|
||||||
|
kret = krb5_auth_con_getremotesubkey(_gsskrb5_context,
|
||||||
|
ctx->auth_context,
|
||||||
|
&key);
|
||||||
|
if (kret == 0 && key != NULL) {
|
||||||
|
ctx->more_flags |= ACCEPTOR_SUBKEY;
|
||||||
|
krb5_free_keyblock (_gsskrb5_context, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
if (time_rec) {
|
if (time_rec) {
|
||||||
ret = _gsskrb5_lifetime_left(minor_status,
|
ret = _gsskrb5_lifetime_left(minor_status,
|
||||||
@@ -555,7 +649,6 @@ repl_mutual
|
|||||||
}
|
}
|
||||||
if (ret_flags)
|
if (ret_flags)
|
||||||
*ret_flags = ctx->flags;
|
*ret_flags = ctx->flags;
|
||||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -582,12 +675,19 @@ OM_uint32 _gsskrb5_init_sec_context
|
|||||||
{
|
{
|
||||||
gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle;
|
gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle;
|
||||||
krb5_const_principal name = (krb5_const_principal)target_name;
|
krb5_const_principal name = (krb5_const_principal)target_name;
|
||||||
|
gsskrb5_ctx ctx;
|
||||||
|
OM_uint32 ret;
|
||||||
|
|
||||||
GSSAPI_KRB5_INIT ();
|
GSSAPI_KRB5_INIT ();
|
||||||
|
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
output_token->value = NULL;
|
output_token->value = NULL;
|
||||||
|
|
||||||
|
if (context_handle == NULL) {
|
||||||
|
*minor_status = 0;
|
||||||
|
return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret_flags)
|
if (ret_flags)
|
||||||
*ret_flags = 0;
|
*ret_flags = 0;
|
||||||
if (time_rec)
|
if (time_rec)
|
||||||
@@ -604,12 +704,50 @@ OM_uint32 _gsskrb5_init_sec_context
|
|||||||
!gss_oid_equal(mech_type, GSS_KRB5_MECHANISM))
|
!gss_oid_equal(mech_type, GSS_KRB5_MECHANISM))
|
||||||
return GSS_S_BAD_MECH;
|
return GSS_S_BAD_MECH;
|
||||||
|
|
||||||
|
if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
|
||||||
|
OM_uint32 ret;
|
||||||
|
|
||||||
if (input_token == GSS_C_NO_BUFFER || input_token->length == 0)
|
if (*context_handle != GSS_C_NO_CONTEXT) {
|
||||||
return init_auth (minor_status,
|
*minor_status = 0;
|
||||||
cred,
|
return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
|
||||||
context_handle,
|
}
|
||||||
name,
|
|
||||||
|
ret = _gsskrb5_create_ctx(minor_status,
|
||||||
|
context_handle,
|
||||||
|
input_chan_bindings,
|
||||||
|
INITIATOR_START);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*context_handle == GSS_C_NO_CONTEXT) {
|
||||||
|
*minor_status = 0;
|
||||||
|
return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = (gsskrb5_ctx) *context_handle;
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||||
|
|
||||||
|
switch (ctx->state) {
|
||||||
|
case INITIATOR_START:
|
||||||
|
ret = init_auth(minor_status,
|
||||||
|
cred,
|
||||||
|
ctx,
|
||||||
|
name,
|
||||||
|
mech_type,
|
||||||
|
req_flags,
|
||||||
|
time_req,
|
||||||
|
input_chan_bindings,
|
||||||
|
input_token,
|
||||||
|
actual_mech_type,
|
||||||
|
output_token,
|
||||||
|
ret_flags,
|
||||||
|
time_rec);
|
||||||
|
break;
|
||||||
|
case INITIATOR_WAIT_FOR_MUTAL:
|
||||||
|
ret = repl_mutual(minor_status,
|
||||||
|
ctx,
|
||||||
mech_type,
|
mech_type,
|
||||||
req_flags,
|
req_flags,
|
||||||
time_req,
|
time_req,
|
||||||
@@ -619,17 +757,24 @@ OM_uint32 _gsskrb5_init_sec_context
|
|||||||
output_token,
|
output_token,
|
||||||
ret_flags,
|
ret_flags,
|
||||||
time_rec);
|
time_rec);
|
||||||
else
|
break;
|
||||||
return repl_mutual(minor_status,
|
case INITIATOR_READY:
|
||||||
cred,
|
*minor_status = 0;
|
||||||
context_handle,
|
ret = GSS_S_BAD_STATUS;
|
||||||
mech_type,
|
break;
|
||||||
req_flags,
|
default:
|
||||||
time_req,
|
*minor_status = 0;
|
||||||
input_chan_bindings,
|
ret = GSS_S_BAD_STATUS;
|
||||||
input_token,
|
break;
|
||||||
actual_mech_type,
|
}
|
||||||
output_token,
|
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||||
ret_flags,
|
|
||||||
time_rec);
|
/* destroy context in case of error */
|
||||||
|
if (GSS_ERROR(ret)) {
|
||||||
|
OM_uint32 min2;
|
||||||
|
_gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user