Return unwrapped delegated credentials if the actual mech is not the called mech
Assumes that pseudo mechs are are of how mechglue credentails look like and return credentials like that. Pointed out on krbdev by Nicolas Williams
This commit is contained in:
@@ -496,7 +496,6 @@ acceptor_start
|
||||
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;
|
||||
|
||||
@@ -564,25 +563,18 @@ acceptor_start
|
||||
&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(&junk, &ctx->mech_src_name);
|
||||
|
||||
ret = gss_accept_sec_context(minor_status,
|
||||
&ctx->negotiated_ctx_id,
|
||||
mech_cred,
|
||||
acceptor_cred_handle,
|
||||
mech_input_token,
|
||||
input_chan_bindings,
|
||||
&ctx->mech_src_name,
|
||||
@@ -590,18 +582,10 @@ acceptor_start
|
||||
&mech_output_token,
|
||||
&ctx->mech_flags,
|
||||
&ctx->mech_time_rec,
|
||||
&mech_delegated_cred);
|
||||
|
||||
if (mech_delegated_cred && delegated_cred_handle) {
|
||||
_gss_spnego_alloc_cred(&junk,
|
||||
mech_delegated_cred,
|
||||
delegated_cred_handle);
|
||||
} else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL)
|
||||
gss_release_cred(&junk, &mech_delegated_cred);
|
||||
delegated_cred_handle);
|
||||
|
||||
if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
|
||||
ctx->preferred_mech_type = preferred_mech_type;
|
||||
ctx->negotiated_mech_type = preferred_mech_type;
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
ctx->open = 1;
|
||||
|
||||
@@ -646,7 +630,6 @@ acceptor_start
|
||||
}
|
||||
|
||||
ctx->preferred_mech_type = preferred_mech_type;
|
||||
ctx->negotiated_mech_type = preferred_mech_type;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -719,7 +702,7 @@ acceptor_continue
|
||||
gss_cred_id_t *delegated_cred_handle
|
||||
)
|
||||
{
|
||||
OM_uint32 ret, ret2, minor, junk;
|
||||
OM_uint32 ret, ret2, minor;
|
||||
NegotiationToken nt;
|
||||
size_t nt_len;
|
||||
NegTokenResp *na;
|
||||
@@ -728,7 +711,6 @@ acceptor_continue
|
||||
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;
|
||||
|
||||
@@ -774,20 +756,13 @@ acceptor_continue
|
||||
}
|
||||
|
||||
if (mech_input_token != GSS_C_NO_BUFFER) {
|
||||
gss_cred_id_t mech_cred;
|
||||
gss_cred_id_t mech_delegated_cred = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
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);
|
||||
|
||||
ret = gss_accept_sec_context(&minor,
|
||||
&ctx->negotiated_ctx_id,
|
||||
mech_cred,
|
||||
acceptor_cred_handle,
|
||||
mech_input_token,
|
||||
input_chan_bindings,
|
||||
&ctx->mech_src_name,
|
||||
@@ -795,14 +770,7 @@ acceptor_continue
|
||||
&obuf,
|
||||
&ctx->mech_flags,
|
||||
&ctx->mech_time_rec,
|
||||
&mech_delegated_cred);
|
||||
|
||||
if (mech_delegated_cred && delegated_cred_handle) {
|
||||
_gss_spnego_alloc_cred(&junk,
|
||||
mech_delegated_cred,
|
||||
delegated_cred_handle);
|
||||
} else if (mech_delegated_cred != GSS_C_NO_CREDENTIAL)
|
||||
gss_release_cred(&junk, &mech_delegated_cred);
|
||||
delegated_cred_handle);
|
||||
|
||||
if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) {
|
||||
mech_output_token = &obuf;
|
||||
|
@@ -236,7 +236,7 @@ _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,
|
||||
const gss_cred_id_t cred_handle,
|
||||
MechTypeList *mechtypelist,
|
||||
gss_OID *preferred_mech)
|
||||
{
|
||||
@@ -248,9 +248,9 @@ _gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status,
|
||||
mechtypelist->len = 0;
|
||||
mechtypelist->val = NULL;
|
||||
|
||||
if (cred_handle != NULL) {
|
||||
if (cred_handle) {
|
||||
ret = gss_inquire_cred(minor_status,
|
||||
cred_handle->negotiated_cred_id,
|
||||
cred_handle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@@ -37,50 +37,20 @@ RCSID("$Id$");
|
||||
OM_uint32
|
||||
_gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
|
||||
{
|
||||
gssspnego_cred cred;
|
||||
OM_uint32 ret;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
if (*cred_handle == GSS_C_NO_CREDENTIAL) {
|
||||
if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL)
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
cred = (gssspnego_cred)*cred_handle;
|
||||
|
||||
ret = gss_release_cred(minor_status, &cred->negotiated_cred_id);
|
||||
ret = gss_release_cred(minor_status, cred_handle);
|
||||
|
||||
free(cred);
|
||||
*cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gss_spnego_alloc_cred(OM_uint32 *minor_status,
|
||||
gss_cred_id_t mech_cred_handle,
|
||||
gss_cred_id_t *cred_handle)
|
||||
{
|
||||
gssspnego_cred cred;
|
||||
|
||||
if (*cred_handle != GSS_C_NO_CREDENTIAL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
cred = calloc(1, sizeof(*cred));
|
||||
if (cred == NULL) {
|
||||
*cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
cred->negotiated_cred_id = mech_cred_handle;
|
||||
|
||||
*cred_handle = (gss_cred_id_t)cred;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, just a simple wrapper that avoids recursion. When
|
||||
* we support gss_{get,set}_neg_mechs() we will need to expose
|
||||
@@ -103,8 +73,6 @@ OM_uint32 _gss_spnego_acquire_cred
|
||||
gss_OID_set_desc actual_desired_mechs;
|
||||
gss_OID_set mechs;
|
||||
int i, j;
|
||||
gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
gssspnego_cred cred;
|
||||
|
||||
*output_cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
@@ -140,22 +108,14 @@ OM_uint32 _gss_spnego_acquire_cred
|
||||
}
|
||||
actual_desired_mechs.count = j;
|
||||
|
||||
ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL,
|
||||
&cred_handle);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
goto out;
|
||||
|
||||
cred = (gssspnego_cred)cred_handle;
|
||||
ret = gss_acquire_cred(minor_status, name,
|
||||
time_req, &actual_desired_mechs,
|
||||
cred_usage,
|
||||
&cred->negotiated_cred_id,
|
||||
output_cred_handle,
|
||||
actual_mechs, time_rec);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
goto out;
|
||||
|
||||
*output_cred_handle = cred_handle;
|
||||
|
||||
out:
|
||||
gss_release_name(minor_status, &name);
|
||||
gss_release_oid_set(&tmp, &mechs);
|
||||
@@ -163,7 +123,7 @@ out:
|
||||
free(actual_desired_mechs.elements);
|
||||
}
|
||||
if (ret != GSS_S_COMPLETE) {
|
||||
_gss_spnego_release_cred(&tmp, &cred_handle);
|
||||
_gss_spnego_release_cred(&tmp, output_cred_handle);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -178,7 +138,6 @@ OM_uint32 _gss_spnego_inquire_cred
|
||||
gss_OID_set * mechanisms
|
||||
)
|
||||
{
|
||||
gssspnego_cred cred;
|
||||
spnego_name sname = NULL;
|
||||
OM_uint32 ret;
|
||||
|
||||
@@ -195,10 +154,8 @@ OM_uint32 _gss_spnego_inquire_cred
|
||||
}
|
||||
}
|
||||
|
||||
cred = (gssspnego_cred)cred_handle;
|
||||
|
||||
ret = gss_inquire_cred(minor_status,
|
||||
cred->negotiated_cred_id,
|
||||
cred_handle,
|
||||
sname ? &sname->mech : NULL,
|
||||
lifetime,
|
||||
cred_usage,
|
||||
@@ -228,37 +185,23 @@ OM_uint32 _gss_spnego_add_cred (
|
||||
OM_uint32 * acceptor_time_rec
|
||||
)
|
||||
{
|
||||
gss_cred_id_t spnego_output_cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
OM_uint32 ret, tmp;
|
||||
gssspnego_cred input_cred, output_cred;
|
||||
|
||||
*output_cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
ret = _gss_spnego_alloc_cred(minor_status, GSS_C_NO_CREDENTIAL,
|
||||
&spnego_output_cred_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
input_cred = (gssspnego_cred)input_cred_handle;
|
||||
output_cred = (gssspnego_cred)spnego_output_cred_handle;
|
||||
|
||||
ret = gss_add_cred(minor_status,
|
||||
input_cred->negotiated_cred_id,
|
||||
input_cred_handle,
|
||||
desired_name,
|
||||
desired_mech,
|
||||
cred_usage,
|
||||
initiator_time_req,
|
||||
acceptor_time_req,
|
||||
&output_cred->negotiated_cred_id,
|
||||
output_cred_handle,
|
||||
actual_mechs,
|
||||
initiator_time_rec,
|
||||
acceptor_time_rec);
|
||||
if (ret) {
|
||||
_gss_spnego_release_cred(&tmp, &spnego_output_cred_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
*output_cred_handle = spnego_output_cred_handle;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -273,7 +216,6 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech (
|
||||
gss_cred_usage_t * cred_usage
|
||||
)
|
||||
{
|
||||
gssspnego_cred cred;
|
||||
spnego_name sname = NULL;
|
||||
OM_uint32 ret;
|
||||
|
||||
@@ -290,10 +232,8 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech (
|
||||
}
|
||||
}
|
||||
|
||||
cred = (gssspnego_cred)cred_handle;
|
||||
|
||||
ret = gss_inquire_cred_by_mech(minor_status,
|
||||
cred->negotiated_cred_id,
|
||||
cred_handle,
|
||||
mech_type,
|
||||
sname ? &sname->mech : NULL,
|
||||
initiator_lifetime,
|
||||
@@ -317,17 +257,15 @@ OM_uint32 _gss_spnego_inquire_cred_by_oid
|
||||
const gss_OID desired_object,
|
||||
gss_buffer_set_t *data_set)
|
||||
{
|
||||
gssspnego_cred cred;
|
||||
OM_uint32 ret;
|
||||
|
||||
if (cred_handle == GSS_C_NO_CREDENTIAL) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_NO_CRED;
|
||||
}
|
||||
cred = (gssspnego_cred)cred_handle;
|
||||
|
||||
ret = gss_inquire_cred_by_oid(minor_status,
|
||||
cred->negotiated_cred_id,
|
||||
cred_handle,
|
||||
desired_object,
|
||||
data_set);
|
||||
|
||||
@@ -340,16 +278,13 @@ _gss_spnego_set_cred_option (OM_uint32 *minor_status,
|
||||
const gss_OID object,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
gssspnego_cred cred;
|
||||
|
||||
if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_NO_CRED;
|
||||
}
|
||||
|
||||
cred = (gssspnego_cred)*cred_handle;
|
||||
return gss_set_cred_option(minor_status,
|
||||
&cred->negotiated_cred_id,
|
||||
cred_handle,
|
||||
object,
|
||||
value);
|
||||
}
|
||||
@@ -360,9 +295,7 @@ _gss_spnego_export_cred (OM_uint32 *minor_status,
|
||||
gss_cred_id_t cred_handle,
|
||||
gss_buffer_t value)
|
||||
{
|
||||
gssspnego_cred cred = (gssspnego_cred)cred_handle;
|
||||
|
||||
return gss_export_cred(minor_status, cred->negotiated_cred_id, value);
|
||||
return gss_export_cred(minor_status, cred_handle, value);
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
@@ -370,23 +303,6 @@ _gss_spnego_import_cred (OM_uint32 *minor_status,
|
||||
gss_buffer_t value,
|
||||
gss_cred_id_t *cred_handle)
|
||||
{
|
||||
gssspnego_cred cred;
|
||||
OM_uint32 major;
|
||||
|
||||
*cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
cred = calloc(1, sizeof(*cred));
|
||||
if (cred == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
major = gss_import_cred(minor_status, value, &cred->negotiated_cred_id);
|
||||
if (major == GSS_S_COMPLETE)
|
||||
*cred_handle = (gss_cred_id_t)cred;
|
||||
else
|
||||
free(cred);
|
||||
|
||||
return major;
|
||||
return gss_import_cred(minor_status, value, cred_handle);
|
||||
}
|
||||
|
||||
|
@@ -179,7 +179,7 @@ spnego_reply_internal(OM_uint32 *minor_status,
|
||||
static OM_uint32
|
||||
spnego_initial
|
||||
(OM_uint32 * minor_status,
|
||||
gssspnego_cred cred,
|
||||
gss_cred_id_t cred,
|
||||
gss_ctx_id_t * context_handle,
|
||||
const gss_name_t target_name,
|
||||
const gss_OID mech_type,
|
||||
@@ -254,8 +254,7 @@ spnego_initial
|
||||
|
||||
/* generate optimistic token */
|
||||
sub = gss_init_sec_context(&minor,
|
||||
(cred != NULL) ? cred->negotiated_cred_id :
|
||||
GSS_C_NO_CREDENTIAL,
|
||||
cred,
|
||||
&ctx->negotiated_ctx_id,
|
||||
ctx->target_name,
|
||||
ctx->preferred_mech_type,
|
||||
@@ -377,7 +376,7 @@ spnego_initial
|
||||
static OM_uint32
|
||||
spnego_reply
|
||||
(OM_uint32 * minor_status,
|
||||
const gssspnego_cred cred,
|
||||
const gss_cred_id_t cred,
|
||||
gss_ctx_id_t * context_handle,
|
||||
const gss_name_t target_name,
|
||||
const gss_OID mech_type,
|
||||
@@ -498,8 +497,7 @@ spnego_reply
|
||||
/* Fall through as if the negotiated mechanism
|
||||
was requested explicitly */
|
||||
ret = gss_init_sec_context(&minor,
|
||||
(cred != NULL) ? cred->negotiated_cred_id :
|
||||
GSS_C_NO_CREDENTIAL,
|
||||
cred,
|
||||
&ctx->negotiated_ctx_id,
|
||||
ctx->target_name,
|
||||
&mech,
|
||||
@@ -629,11 +627,9 @@ OM_uint32 _gss_spnego_init_sec_context
|
||||
OM_uint32 * time_rec
|
||||
)
|
||||
{
|
||||
gssspnego_cred cred = (gssspnego_cred)initiator_cred_handle;
|
||||
|
||||
if (*context_handle == GSS_C_NO_CONTEXT)
|
||||
return spnego_initial (minor_status,
|
||||
cred,
|
||||
initiator_cred_handle,
|
||||
context_handle,
|
||||
target_name,
|
||||
mech_type,
|
||||
@@ -647,7 +643,7 @@ OM_uint32 _gss_spnego_init_sec_context
|
||||
time_rec);
|
||||
else
|
||||
return spnego_reply (minor_status,
|
||||
cred,
|
||||
initiator_cred_handle,
|
||||
context_handle,
|
||||
target_name,
|
||||
mech_type,
|
||||
|
@@ -73,10 +73,6 @@
|
||||
|
||||
#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
|
||||
|
||||
typedef struct {
|
||||
gss_cred_id_t negotiated_cred_id;
|
||||
} *gssspnego_cred;
|
||||
|
||||
typedef struct {
|
||||
MechTypeList initiator_mech_types;
|
||||
gss_OID preferred_mech_type;
|
||||
|
Reference in New Issue
Block a user