#endif
/*
- * Mark a context as ready for cryptographic operations
+ * Mark an acceptor context as ready for cryptographic operations
*/
static OM_uint32
acceptReadyEap(OM_uint32 *minor, gss_ctx_id_t ctx, gss_cred_id_t cred)
ctx->initiatorName->attrCtx = gssEapCreateAttrContext(cred, ctx);
+ *minor = 0;
return GSS_S_COMPLETE;
}
+/*
+ * Emit a identity EAP request to force the initiator (peer) to identify
+ * itself.
+ */
static OM_uint32
eapGssSmAcceptIdentity(OM_uint32 *minor,
gss_ctx_id_t ctx,
} pkt;
gss_buffer_desc pktBuffer;
- if (inputToken != GSS_C_NO_BUFFER && inputToken->length != 0)
+ if (inputToken != GSS_C_NO_BUFFER && inputToken->length != 0) {
+ *minor = GSSEAP_WRONG_SIZE;
return GSS_S_DEFECTIVE_TOKEN;
+ }
assert(ctx->acceptorName == GSS_C_NO_NAME);
ctx->state = EAP_STATE_AUTHENTICATE;
+ *minor = 0;
return GSS_S_CONTINUE_NEEDED;
}
+/*
+ * Pass the asserted acceptor identity to the authentication server.
+ */
static OM_uint32
setAcceptorIdentity(OM_uint32 *minor,
gss_ctx_id_t ctx,
gss_buffer_desc nameBuf;
krb5_context krbContext = NULL;
krb5_principal krbPrinc;
- struct rs_handle *rh = ctx->acceptorCtx.radHandle;
+ struct rs_context *rc = ctx->acceptorCtx.radContext;
- assert(rh != NULL);
+ assert(rc != NULL);
- /* Awaits further specification */
- if (ctx->acceptorName == GSS_C_NO_NAME)
+ if (ctx->acceptorName == GSS_C_NO_NAME) {
+ *minor = 0;
return GSS_S_COMPLETE;
+ }
+
+ if ((ctx->acceptorName->flags & NAME_FLAG_SERVICE) == 0) {
+ *minor = GSSEAP_BAD_SERVICE_NAME;
+ return GSS_S_BAD_NAME;
+ }
GSSEAP_KRB_INIT(&krbContext);
krbPrinc = ctx->acceptorName->krbPrincipal;
assert(krbPrinc != NULL);
-
- if (krb5_princ_size(krbContext, krbPrinc) < 2)
- return GSS_S_BAD_NAME;
+ assert(krb5_princ_size(krbContext, krbPrinc) >= 2);
/* Acceptor-Service-Name */
krbDataToGssBuffer(krb5_princ_component(krbContext, krbPrinc, 0), &nameBuf);
return major;
}
+ *minor = 0;
return GSS_S_COMPLETE;
}
+/*
+ * Allocate a RadSec handle
+ */
static OM_uint32
createRadiusHandle(OM_uint32 *minor,
gss_cred_id_t cred,
struct rs_alloc_scheme ralloc;
struct rs_error *err;
- assert(actx->radHandle == NULL);
+ assert(actx->radContext == NULL);
assert(actx->radConn == NULL);
- if (rs_context_create(&actx->radHandle, RS_DICT_FILE) != 0) {
- *minor = GSSEAP_RADSEC_INIT_FAILURE;
+ if (rs_context_create(&actx->radContext, RS_DICT_FILE) != 0) {
+ *minor = GSSEAP_RADSEC_CONTEXT_FAILURE;
return GSS_S_FAILURE;
}
ralloc.free = GSSEAP_FREE;
ralloc.realloc = GSSEAP_REALLOC;
- rs_context_set_alloc_scheme(actx->radHandle, &ralloc);
+ rs_context_set_alloc_scheme(actx->radContext, &ralloc);
- if (rs_context_read_config(actx->radHandle, configFile) != 0) {
- err = rs_err_ctx_pop(actx->radHandle);
+ if (rs_context_read_config(actx->radContext, configFile) != 0) {
+ err = rs_err_ctx_pop(actx->radContext);
goto fail;
}
- if (rs_conn_create(actx->radHandle, &actx->radConn, configStanza) != 0) {
+ if (rs_conn_create(actx->radContext, &actx->radConn, configStanza) != 0) {
err = rs_err_conn_pop(actx->radConn);
goto fail;
}
return gssEapRadiusMapError(minor, err);
}
+/*
+ * Process a EAP response from the initiator.
+ */
static OM_uint32
eapGssSmAcceptAuthenticate(OM_uint32 *minor,
gss_ctx_id_t ctx,
gss_buffer_t outputToken)
{
OM_uint32 major, tmpMinor;
- struct rs_handle *rh;
struct rs_connection *rconn;
struct rs_request *request = NULL;
struct rs_packet *req = NULL, *resp = NULL;
struct radius_packet *frreq, *frresp;
int sendAcceptorIdentity = 0;
- if (ctx->acceptorCtx.radHandle == NULL) {
+ if (ctx->acceptorCtx.radContext == NULL) {
/* May be NULL from an imported partial context */
major = createRadiusHandle(minor, cred, ctx);
if (GSS_ERROR(major))
sendAcceptorIdentity = 1;
}
- rh = ctx->acceptorCtx.radHandle;
rconn = ctx->acceptorCtx.radConn;
if (rs_packet_create_acc_request(rconn, &req, NULL, NULL) != 0) {
if (frresp->code == PW_ACCESS_CHALLENGE) {
major = gssEapRadiusGetAvp(minor, frresp->vps, PW_STATE, 0,
&ctx->acceptorCtx.state, TRUE);
- if (major != GSS_S_UNAVAILABLE && GSS_ERROR(major))
+ if (GSS_ERROR(major) && *minor != GSSEAP_NO_SUCH_ATTR)
goto cleanup;
} else {
ctx->acceptorCtx.vps = frresp->vps;
ctx->state = EAP_STATE_EXTENSIONS_REQ;
}
+ *minor = 0;
major = GSS_S_CONTINUE_NEEDED;
cleanup:
ctx->state = EAP_STATE_EXTENSIONS_RESP;
+ *minor = 0;
return GSS_S_CONTINUE_NEEDED;
}
ctx->state = EAP_STATE_ESTABLISHED;
+ *minor = 0;
return GSS_S_COMPLETE;
}
case GSSEAP_WRONG_SIZE:
case GSSEAP_WRONG_MECH:
case GSSEAP_BAD_TOK_HEADER:
+ case GSSEAP_TOK_TRUNC:
case GSSEAP_BAD_DIRECTION:
case GSSEAP_WRONG_TOK_ID:
+ case GSSEAP_REFLECT:
case GSSEAP_CRIT_EXT_UNAVAILABLE:
case GSSEAP_MISSING_REQUIRED_EXT:
case GSSEAP_KEY_UNAVAILABLE:
case GSSEAP_MISSING_EAP_REQUEST:
break;
default:
- /* Don't return system error codes */
if (IS_RADIUS_ERROR(minorStatus))
+ /* Squash RADIUS error codes */
minorStatus = GSSEAP_GENERIC_RADIUS_ERROR;
else
+ /* Don't return system error codes */
return GSS_S_COMPLETE;
}
output_token->value = NULL;
if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
+ *minor = GSSEAP_TOK_TRUNC;
return GSS_S_DEFECTIVE_TOKEN;
}
goto cleanup;
if (!gssEapCredAvailable(cred, ctx->mechanismUsed)) {
- *minor = GSSEAP_WRONG_MECH;
+ *minor = GSSEAP_CRED_MECH_MISMATCH;
major = GSS_S_BAD_MECH;
goto cleanup;
}
input_chan_bindings,
&innerOutputToken);
if (GSS_ERROR(major)) {
- /* Generate an error token */
+ /* Possibly generate an error token */
tmpMajor = makeErrorToken(&tmpMinor, major, *minor, &innerOutputToken);
if (GSS_ERROR(tmpMajor)) {
major = tmpMajor;
if (GSS_ERROR(major))
goto cleanup;
}
- if (time_rec != NULL)
- gssEapContextTime(&tmpMinor, ctx, time_rec);
+ if (time_rec != NULL) {
+ major = gssEapContextTime(&tmpMinor, ctx, time_rec);
+ if (GSS_ERROR(major))
+ goto cleanup;
+ }
}
assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED);
ctx->state = EAP_STATE_ESTABLISHED;
+ *minor = 0;
return GSS_S_COMPLETE;
}