static JSONObject avpToJson(rs_const_avp *vp) { JSONObject obj; gss_eap_attrid attrid; GSSEAP_ASSERT(rs_avp_length(vp) <= RS_MAX_STRING_LEN); switch (rs_avp_typeof(vp)) { case RS_TYPE_INTEGER: obj.set("value", rs_avp_integer_value(vp)); break; case RS_TYPE_DATE: obj.set("value", rs_avp_date_value(vp)); break; case RS_TYPE_STRING: obj.set("value", rs_avp_string_value(vp)); break; default: { char *b64; if (base64Encode(rs_avp_octets_value_const_ptr(vp), rs_avp_length(vp), &b64) < 0) throw std::bad_alloc(); obj.set("value", b64); GSSEAP_FREE(b64); break; } } attrid = avpToAttrId(vp); obj.set("type", attrid.second); if (attrid.first != 0) obj.set("vendor", attrid.first); return obj; }
static OM_uint32 gssEapRadiusGetAvp(OM_uint32 *minor, rs_avp *vps, const gss_eap_attrid &attrid, gss_buffer_t buffer, int concat) { rs_const_avp *vp; int err; if (buffer != GSS_C_NO_BUFFER) { buffer->length = 0; buffer->value = NULL; } vp = rs_avp_find_const(vps, attrid.second, attrid.first); if (vp == NULL) { *minor = GSSEAP_NO_SUCH_ATTR; return GSS_S_UNAVAILABLE; } if (buffer != GSS_C_NO_BUFFER) { if (concat) rs_avp_fragmented_value(vp, NULL, &buffer->length); else buffer->length = rs_avp_length(vp); buffer->value = GSSEAP_MALLOC(buffer->length); if (buffer->value == NULL) { *minor = ENOMEM; return GSS_S_FAILURE; } if (concat) err = rs_avp_fragmented_value(vp, (unsigned char *)buffer->value, &buffer->length); else err = rs_avp_octets_value(vp, (unsigned char *)buffer->value, &buffer->length); if (err != 0) { *minor = RS_MAP_ERROR(err); return GSS_S_FAILURE; } } *minor = 0; return GSS_S_COMPLETE; }
/* * 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) { OM_uint32 major, tmpMinor; rs_const_avp *vp; gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; /* Cache encryption type derived from selected mechanism OID */ major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType); if (GSS_ERROR(major)) return major; gssEapReleaseName(&tmpMinor, &ctx->initiatorName); major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_USER_NAME, 0, &vp); if (major == GSS_S_COMPLETE && rs_avp_length(vp) != 0) { rs_avp_octets_value_byref((rs_avp *)vp, (unsigned char **)&nameBuf.value, &nameBuf.length); } else { ctx->gssFlags |= GSS_C_ANON_FLAG; } major = gssEapImportName(minor, &nameBuf, (ctx->gssFlags & GSS_C_ANON_FLAG) ? GSS_C_NT_ANONYMOUS : GSS_C_NT_USER_NAME, ctx->mechanismUsed, &ctx->initiatorName); if (GSS_ERROR(major)) return major; major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_MS_MPPE_SEND_KEY, VENDORPEC_MICROSOFT, &vp); if (GSS_ERROR(major)) { *minor = GSSEAP_KEY_UNAVAILABLE; return GSS_S_UNAVAILABLE; } major = gssEapDeriveRfc3961Key(minor, rs_avp_octets_value_const_ptr(vp), rs_avp_length(vp), ctx->encryptionType, &ctx->rfc3961Key); if (GSS_ERROR(major)) return major; major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key, &ctx->checksumType); if (GSS_ERROR(major)) return major; major = sequenceInit(minor, &ctx->seqState, ctx->recvSeq, ((ctx->gssFlags & GSS_C_REPLAY_FLAG) != 0), ((ctx->gssFlags & GSS_C_SEQUENCE_FLAG) != 0), TRUE); if (GSS_ERROR(major)) return major; major = gssEapCreateAttrContext(minor, cred, ctx, &ctx->initiatorName->attrCtx, &ctx->expiryTime); if (GSS_ERROR(major)) return major; if (ctx->expiryTime != 0 && ctx->expiryTime < time(NULL)) { *minor = GSSEAP_CRED_EXPIRED; return GSS_S_CREDENTIALS_EXPIRED; } *minor = 0; return GSS_S_COMPLETE; }
/* * 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) { OM_uint32 major, tmpMinor; #ifdef MECH_EAP VALUE_PAIR *vp; gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; /* Cache encryption type derived from selected mechanism OID */ major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType); #else /* Cache encryption type specified by IdP */ major = krbStringToEnctype(gl_encryption_type, &ctx->encryptionType); #endif if (GSS_ERROR(major)) return major; #ifdef MECH_EAP gssEapReleaseName(&tmpMinor, &ctx->initiatorName); major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_USER_NAME, 0, &vp); if (major == GSS_S_COMPLETE && vp->length) { nameBuf.length = vp->length; nameBuf.value = vp->vp_strvalue; } else { ctx->gssFlags |= GSS_C_ANON_FLAG; } major = gssEapImportName(minor, &nameBuf, (ctx->gssFlags & GSS_C_ANON_FLAG) ? GSS_C_NT_ANONYMOUS : GSS_C_NT_USER_NAME, ctx->mechanismUsed, &ctx->initiatorName); if (GSS_ERROR(major)) return major; major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_MS_MPPE_SEND_KEY, VENDORPEC_MS, &vp); if (GSS_ERROR(major)) { *minor = GSSEAP_KEY_UNAVAILABLE; return GSS_S_UNAVAILABLE; } major = gssEapDeriveRfc3961Key(minor, rs_avp_octets_value_const_ptr(vp), rs_avp_length(vp), ctx->encryptionType, &ctx->rfc3961Key); #else major = gssEapDeriveRfc3961Key(minor, gl_generated_key, strlen(gl_generated_key), ctx->encryptionType, &ctx->rfc3961Key); #endif if (GSS_ERROR(major)) return major; major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key, &ctx->checksumType); if (GSS_ERROR(major)) return major; major = sequenceInit(minor, &ctx->seqState, ctx->recvSeq, ((ctx->gssFlags & GSS_C_REPLAY_FLAG) != 0), ((ctx->gssFlags & GSS_C_SEQUENCE_FLAG) != 0), TRUE); if (GSS_ERROR(major)) return major; #ifdef MECH_EAP major = gssEapCreateAttrContext(minor, cred, ctx, &ctx->initiatorName->attrCtx, &ctx->expiryTime); if (GSS_ERROR(major)) return major; #else ctx->expiryTime = 0; /* indefinite */ #endif if (ctx->expiryTime != 0 && ctx->expiryTime < time(NULL)) { *minor = GSSEAP_CRED_EXPIRED; return GSS_S_CREDENTIALS_EXPIRED; } #ifndef MECH_EAP ctx->gssFlags |= GSS_C_PROT_READY_FLAG; #endif *minor = 0; return GSS_S_COMPLETE; }