gss_ctx_id_t context_handle,
OM_uint32 *time_rec)
{
- time_t now, lifetime;
-
if (context_handle == GSS_C_NO_CONTEXT) {
return GSS_S_NO_CONTEXT;
}
*minor = 0;
- time(&now);
- lifetime = context_handle->expiryTime - now;
- if (lifetime <= 0) {
- *time_rec = 0;
- return GSS_S_CONTEXT_EXPIRED;
+ if (context_handle->expiryTime == 0) {
+ *time_rec = GSS_C_INDEFINITE;
+ } else {
+ time_t now, lifetime;
+
+ time(&now);
+ lifetime = context_handle->expiryTime - now;
+ if (lifetime <= 0) {
+ *time_rec = 0;
+ return GSS_S_CONTEXT_EXPIRED;
+ }
+ *time_rec = lifetime;
}
- *time_rec = lifetime;
return GSS_S_COMPLETE;
}
gss_buffer_t input_token,
gss_buffer_t output_token)
{
- GSSEAP_NOT_IMPLEMENTED;
+ OM_uint32 major, tmpMinor;
+ time_t now;
+
+ if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
+ /* first time */
+ req_flags &= GSS_C_TRANS_FLAG | GSS_C_REPLAY_FLAG | GSS_C_DCE_STYLE;
+ ctx->gssFlags |= req_flags;
+
+ time(&now);
+
+ if (time_req == 0 || time_req == GSS_C_INDEFINITE)
+ ctx->expiryTime = 0;
+ else
+ ctx->expiryTime = now + time_req;
+
+ major = gss_duplicate_name(minor, cred->name, &ctx->initiatorName);
+ if (GSS_ERROR(major))
+ goto cleanup;
+
+ major = gss_duplicate_name(minor, target_name, &ctx->acceptorName);
+ if (GSS_ERROR(major))
+ goto cleanup;
+
+ if (mech_type == GSS_C_NULL_OID ||
+ oidEqual(mech_type, GSS_EAP_MECHANISM)) {
+ major = gssEapDefaultMech(minor, &ctx->mechanismUsed);
+ } else if (gssEapIsMechanismOid(mech_type)) {
+ if (!gssEapInternalizeOid(mech_type, &ctx->mechanismUsed))
+ major = duplicateOid(minor, mech_type, &ctx->mechanismUsed);
+ } else {
+ major = GSS_S_BAD_MECH;
+ }
+ if (GSS_ERROR(major))
+ goto cleanup;
+ }
+
+cleanup:
+ return major;
}
static eap_gss_initiator_sm eapGssSm[] = {
major = gssEapAllocContext(minor, &ctx);
if (GSS_ERROR(major))
goto cleanup;
+
+ *pCtx = ctx;
}
for (; ctx->state != EAP_STATE_ESTABLISHED; ctx->state++) {
}
}
- if (actual_mech_type != NULL)
- *actual_mech_type = ctx->mechanismUsed;
+ if (actual_mech_type != NULL) {
+ if (!gssEapInternalizeOid(ctx->mechanismUsed, actual_mech_type))
+ duplicateOid(&tmpMinor, ctx->mechanismUsed, actual_mech_type);
+ }
if (ret_flags != NULL)
*ret_flags = ctx->gssFlags;
if (time_rec != NULL)
cleanup:
if (GSS_ERROR(major))
- gssEapReleaseContext(&tmpMinor, &ctx);
+ gssEapReleaseContext(&tmpMinor, pCtx);
return major;
}
}
if (lifetime_rec != NULL) {
- time_t now = time(NULL);
- time_t lifetime;
+ time_t now, lifetime;
- if (ctx->expiryTime == ~0)
+ if (ctx->expiryTime == 0) {
lifetime = GSS_C_INDEFINITE;
- else
+ } else {
+ now = time(NULL);
lifetime = now - ctx->expiryTime;
-
- if (lifetime < 0)
- lifetime = 0;
+ if (lifetime < 0)
+ lifetime = 0;
+ }
*lifetime_rec = lifetime;
}
}
if (pLifetime != NULL) {
- time_t now = time(NULL);
- time_t lifetime;
+ time_t now, lifetime;
- if (cred->expiryTime == ~0)
+ if (cred->expiryTime == 0) {
lifetime = GSS_C_INDEFINITE;
- else
+ } else {
+ now = time(NULL);
lifetime = now - cred->expiryTime;
-
- if (lifetime < 0)
- lifetime = 0;
+ if (lifetime < 0)
+ lifetime = 0;
+ }
*pLifetime = lifetime;
}
OM_uint32 major;
gss_OID internalizedOid = GSS_C_NO_OID;
- gssEapInternalizeOid(*oid, &internalizedOid);
-
- if (*oid != internalizedOid) {
+ if (gssEapInternalizeOid(*oid, &internalizedOid)) {
/* OID was internalized, so we can mark it as "freed" */
*oid = GSS_C_NO_OID;
return GSS_S_COMPLETE;
} while (0)
/* util_mech.c */
-void
+int
gssEapInternalizeOid(const gss_OID oid,
gss_OID *const pInternalizedOid);
int *suffix) ;
OM_uint32
+duplicateOid(OM_uint32 *minor_status,
+ const gss_OID_desc * const oid,
+ gss_OID *new_oid);
+
+OM_uint32
duplicateOidSet(OM_uint32 *minor,
const gss_OID_set src,
gss_OID_set *dst);
ctx->state = EAP_STATE_AUTHENTICATE;
+ /*
+ * Integrity, confidentiality, sequencing and replay detection are
+ * always available. Regardless of what flags are requested in
+ * GSS_Init_sec_context, implementations MUST set the flag corresponding
+ * to these services in the output of GSS_Init_sec_context and
+ * GSS_Accept_sec_context.
+ */
+ ctx->gssFlags = GSS_C_INTEG_FLAG |
+ GSS_C_CONF_FLAG |
+ GSS_C_SEQUENCE_FLAG |
+ GSS_C_REPLAY_FLAG;
+
*pCtx = ctx;
return GSS_S_COMPLETE;
return GSS_S_FAILURE;
}
- cred->expiryTime = ~0;
-
*pCred = cred;
*minor = 0;
return GSS_S_BAD_MECH;
}
- gssEapInternalizeOid(&mechs->elements[0], oid);
- if (*oid == &mechs->elements[0]) {
+ if (!gssEapInternalizeOid(&mechs->elements[0], oid)) {
/* don't double-free if we didn't internalize it */
mechs->elements[0].length = 0;
mechs->elements[0].elements = NULL;
return GSS_S_COMPLETE;
}
-void
+int
gssEapInternalizeOid(const gss_OID oid,
gss_OID *const pInternalizedOid)
{
if (*pInternalizedOid == GSS_C_NO_OID) {
*pInternalizedOid = oid;
+ return 0;
}
+
+ return 1;
}
#include "gssapiP_eap.h"
-#if 0
OM_uint32
-copyOid(OM_uint32 *minor_status,
- const gss_OID_desc * const oid,
- gss_OID *new_oid)
+duplicateOid(OM_uint32 *minor,
+ const gss_OID_desc * const oid,
+ gss_OID *newOid)
{
- gss_OID p;
+ gss_OID p;
- *minor_status = 0;
+ *minor = 0;
+ *newOid = GSS_C_NO_OID;
- p = (gss_OID) malloc(sizeof(gss_OID_desc));
- if (!p) {
- *minor_status = ENOMEM;
+ p = (gss_OID)GSSEAP_MALLOC(sizeof(*p));
+ if (p == NULL) {
+ *minor = ENOMEM;
return GSS_S_FAILURE;
}
p->length = oid->length;
- p->elements = malloc(p->length);
- if (!p->elements) {
- free(p);
+ p->elements = GSSEAP_MALLCO(p->length);
+ if (p->elements == NULL) {
+ GSSEAP_FREE(p);
return GSS_S_FAILURE;
}
+
memcpy(p->elements, oid->elements, p->length);
- *new_oid = p;
- return(GSS_S_COMPLETE);
+ *newOid = p;
+
+ return GSS_S_COMPLETE;
}
-#endif
/* Compose an OID of a prefix and an integer suffix */
OM_uint32
-composeOid(OM_uint32 *minor_status,
+composeOid(OM_uint32 *minor,
const char *prefix,
size_t prefix_len,
int suffix,
unsigned char *op;
if (oid == GSS_C_NO_OID) {
- *minor_status = EINVAL;
+ *minor = EINVAL;
return GSS_S_FAILURE;
}
if (oid->length < prefix_len) {
- *minor_status = ERANGE;
+ *minor = ERANGE;
return GSS_S_FAILURE;
}
suffix = osuffix;
if (oid->length < prefix_len + nbytes) {
- *minor_status = ERANGE;
+ *minor = ERANGE;
return GSS_S_FAILURE;
}
oid->length = prefix_len + nbytes;
- *minor_status = 0;
+ *minor = 0;
return GSS_S_COMPLETE;
}
OM_uint32
-decomposeOid(OM_uint32 *minor_status,
+decomposeOid(OM_uint32 *minor,
const char *prefix,
size_t prefix_len,
gss_OID_desc *oid,
for (i = 0; i < slen; i++) {
*suffix = (*suffix << 7) | (op[i] & 0x7f);
if (i + 1 != slen && (op[i] & 0x80) == 0) {
- *minor_status = EINVAL;
+ *minor = EINVAL;
return GSS_S_FAILURE;
}
}