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:
Love Hornquist Astrand
2009-08-26 22:32:50 -07:00
parent 559103b218
commit 022e7d4319
7 changed files with 44 additions and 155 deletions

View File

@@ -161,6 +161,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
struct _gss_mechanism_cred *mc;
gss_cred_id_t acceptor_mc, delegated_mc;
gss_name_t src_mn;
gss_OID mech_ret_type = NULL;
*minor_status = 0;
if (src_name)
@@ -228,7 +229,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
input_token,
input_chan_bindings,
&src_mn,
mech_type,
&mech_ret_type,
output_token,
&mech_ret_flags,
time_rec,
@@ -241,6 +242,9 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
return (major_status);
}
if (mech_type)
*mech_type = mech_ret_type;
if (src_name && src_mn) {
/*
* Make a new name and mark it as an MN.
@@ -262,6 +266,15 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
m->gm_release_cred(minor_status, &delegated_mc);
if (ret_flags)
*ret_flags &= ~GSS_C_DELEG_FLAG;
} else if (gss_oid_equal(mech_ret_type, &m->gm_mech_oid) == 0) {
/*
* If the returned mech_type is not the same
* as the mech, assume its pseudo mech type
* and the returned type is already a
* mech-glue object
*/
*delegated_cred_handle = delegated_mc;
} else if (delegated_mc) {
struct _gss_cred *dcred;
struct _gss_mechanism_cred *dmc;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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;

View File

@@ -483,7 +483,7 @@ main(int argc, char **argv)
OM_uint32 min_stat, maj_stat;
gss_ctx_id_t cctx, sctx;
void *ctx;
gss_OID nameoid, mechoid, actual_mech;
gss_OID nameoid, mechoid, actual_mech, actual_mech2;
gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL;
setprogname(argv[0]);
@@ -775,7 +775,7 @@ main(int argc, char **argv)
gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL;
gss_buffer_desc cb;
loop(mechoid, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech, &cred2);
loop(actual_mech, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech2, &cred2);
gss_delete_sec_context(&min_stat, &cctx, NULL);
gss_delete_sec_context(&min_stat, &sctx, NULL);
@@ -797,7 +797,7 @@ main(int argc, char **argv)
gss_release_buffer(&min_stat, &cb);
gss_release_cred(&min_stat, &deleg_cred);
loop(mechoid, nameoid, argv[0], cred2, &cctx, &sctx, &actual_mech, &deleg_cred);
loop(actual_mech, nameoid, argv[0], cred2, &cctx, &sctx, &actual_mech2, &deleg_cred);
gss_release_cred(&min_stat, &cred2);
}