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:
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user