- hook up libradius, AVP parsing logic
- better handling of mechanism-specific error namespace
- better interfaces for initiator EAP configuration/credential management
+- libradius library handle is a global variable
+- radius expiry time
assert(ctx->acceptorName == GSS_C_NO_NAME);
if (cred != GSS_C_NO_CREDENTIAL && cred->name != GSS_C_NO_NAME) {
- major = gss_duplicate_name(minor, cred->name, &ctx->acceptorName);
+ major = gssEapDuplicateName(minor, cred->name, &ctx->acceptorName);
if (GSS_ERROR(major))
return major;
}
major = addAvpFromBuffer(minor, ctx->acceptorCtx.radHandle, avps,
VENDOR_ATTR_GSS_ACCEPTOR_SERVICE_NAME,
- VENDOR_ID_GSS_EAP,
+ VENDOR_ID_UKERNA,
&nameBuf);
if (GSS_ERROR(major))
return major;
major = addAvpFromBuffer(minor, ctx->acceptorCtx.radHandle, avps,
VENDOR_ATTR_GSS_ACCEPTOR_HOST_NAME,
- VENDOR_ID_GSS_EAP,
+ VENDOR_ID_UKERNA,
&nameBuf);
if (GSS_ERROR(major))
return major;
major = addAvpFromBuffer(minor, ctx->acceptorCtx.radHandle, avps,
VENDOR_ATTR_GSS_ACCEPTOR_REALM_NAME,
- VENDOR_ID_GSS_EAP,
+ VENDOR_ID_UKERNA,
&nameBuf);
if (GSS_ERROR(major))
return major;
if (major == GSS_S_COMPLETE) {
if (src_name != NULL && ctx->initiatorName != GSS_C_NO_NAME) {
- major = gss_duplicate_name(&tmpMinor, ctx->initiatorName, src_name);
+ major = gssEapDuplicateName(&tmpMinor, ctx->initiatorName, src_name);
if (GSS_ERROR(major))
goto cleanup;
}
if (time_rec != NULL)
- gss_context_time(&tmpMinor, ctx, time_rec);
+ gssEapContextTime(&tmpMinor, ctx, time_rec);
}
assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED);
mechs.count = 1;
mechs.elements = desired_mech;
- major = gss_acquire_cred(minor,
- desired_name,
- time_req,
- &mechs,
- cred_usage,
- output_cred_handle,
- actual_mechs,
- &time_rec);
+ major = gssEapAcquireCred(minor,
+ desired_name,
+ GSS_C_NO_BUFFER,
+ time_req,
+ &mechs,
+ cred_usage,
+ output_cred_handle,
+ actual_mechs,
+ &time_rec);
if (initiator_time_rec != NULL)
*initiator_time_rec = time_rec;
mechs.count = 1;
mechs.elements = desired_mech;
- major = gss_acquire_cred_with_password(minor,
- desired_name,
- password,
- time_req,
- &mechs,
- cred_usage,
- output_cred_handle,
- actual_mechs,
- &time_rec);
+ major = gssEapAcquireCred(minor,
+ desired_name,
+ password,
+ time_req,
+ &mechs,
+ cred_usage,
+ output_cred_handle,
+ actual_mechs,
+ &time_rec);
if (initiator_time_rec != NULL)
*initiator_time_rec = time_rec;
return GSS_S_BAD_MECH;
}
- return gss_duplicate_name(minor, input_name, output_name);
+ return gssEapDuplicateName(minor, input_name, output_name);
}
gss_ctx_id_t context_handle,
OM_uint32 *time_rec)
{
- if (context_handle == GSS_C_NO_CONTEXT) {
- return GSS_S_NO_CONTEXT;
- }
-
- if (!CTX_IS_ESTABLISHED(context_handle)) {
- return GSS_S_NO_CONTEXT;
- }
-
- *minor = 0;
-
- 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;
- }
-
- return GSS_S_COMPLETE;
+ return gssEapContextTime(minor, context_handle, time_rec);
}
gss_buffer_t output_name_buffer,
gss_OID *output_name_type)
{
- OM_uint32 major, tmpMinor;
- krb5_context krbContext;
- char *krbName;
-
- GSSEAP_KRB_INIT(&krbContext);
-
- output_name_buffer->length = 0;
- output_name_buffer->value = NULL;
-
- if (name == GSS_C_NO_NAME) {
- *minor = EINVAL;
- return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
- }
-
- *minor = krb5_unparse_name(krbContext, name->krbPrincipal, &krbName);
- if (*minor != 0) {
- return GSS_S_FAILURE;
- }
-
- major = makeStringBuffer(minor, krbName, output_name_buffer);
- if (GSS_ERROR(major)) {
- krb5_free_unparsed_name(krbContext, krbName);
- return major;
- }
-
- krb5_free_unparsed_name(krbContext, krbName);
-
- if (output_name_type != NULL)
- *output_name_type = GSS_EAP_NT_PRINCIPAL_NAME;
-
- return GSS_S_COMPLETE;
+ return gssEapDisplayName(minor, name, output_name_buffer,
+ output_name_type);
}
const gss_name_t input_name,
gss_name_t *dest_name)
{
- OM_uint32 major, tmpMinor;
- krb5_context krbContext;
- gss_name_t name;
-
- if (input_name == GSS_C_NO_NAME) {
- *minor = EINVAL;
- return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
- }
-
- GSSEAP_KRB_INIT(&krbContext);
-
- major = gssEapAllocName(minor, &name);
- if (GSS_ERROR(major)) {
- return major;
- }
-
- /* Lock mutex for copying mutable attributes */
- GSSEAP_MUTEX_LOCK(&input_name->mutex);
-
- *minor = krb5_copy_principal(krbContext, input_name->krbPrincipal,
- &name->krbPrincipal);
- if (*minor != 0) {
- major = GSS_S_FAILURE;
- goto cleanup;
- }
-
- if (input_name->attrCtx != NULL) {
- major = gssEapDuplicateAttrContext(minor, input_name, name);
- if (GSS_ERROR(major))
- goto cleanup;
- }
-
- *dest_name = name;
-
-cleanup:
- GSSEAP_MUTEX_UNLOCK(&input_name->mutex);
-
- if (GSS_ERROR(major)) {
- gssEapReleaseName(&tmpMinor, &name);
- }
-
- return major;
+ return gssEapDuplicateName(minor, input_name, dest_name);
}
gss_ctx_id_t ctx,
gss_buffer_t token)
{
+ /* XXX we also need to serialise the current server name */
return duplicateBuffer(minor, &ctx->acceptorCtx.state, token);
}
int iov_count,
enum gss_eap_token_type toktype);
+OM_uint32
+gssEapWrapIovLength(OM_uint32 *minor,
+ gss_ctx_id_t ctx,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count);
+
#endif /* _GSSAPIP_EAP_H_ */
size_t remain = *pRemain;
gss_buffer_desc buf;
+ /* XXX we also need to deserialise the current server name */
+
if (remain < 4) {
*minor = ERANGE;
return GSS_S_DEFECTIVE_TOKEN;
else
ctx->expiryTime = now + timeReq;
- major = gss_duplicate_name(minor, cred->name, &ctx->initiatorName);
+ major = gssEapDuplicateName(minor, cred->name, &ctx->initiatorName);
if (GSS_ERROR(major))
return major;
- major = gss_duplicate_name(minor, target, &ctx->acceptorName);
+ major = gssEapDuplicateName(minor, target, &ctx->acceptorName);
if (GSS_ERROR(major))
return major;
if (ret_flags != NULL)
*ret_flags = ctx->gssFlags;
if (time_rec != NULL)
- gss_context_time(&tmpMinor, ctx, time_rec);
+ gssEapContextTime(&tmpMinor, ctx, time_rec);
assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED);
}
if (src_name != NULL) {
- major = gss_duplicate_name(minor, ctx->initiatorName, src_name);
+ major = gssEapDuplicateName(minor, ctx->initiatorName, src_name);
if (GSS_ERROR(major))
goto cleanup;
}
if (targ_name != NULL) {
- major = gss_duplicate_name(minor, ctx->acceptorName, targ_name);
+ major = gssEapDuplicateName(minor, ctx->acceptorName, targ_name);
if (GSS_ERROR(major))
goto cleanup;
}
OM_uint32 major = GSS_S_COMPLETE;
if (name != NULL) {
- major = gss_duplicate_name(minor, cred->name, name);
+ major = gssEapDuplicateName(minor, cred->name, name);
if (GSS_ERROR(major))
goto cleanup;
}
iov[1].buffer.value = NULL;
iov[1].buffer.length = 0;
- major = gss_unwrap_iov(minor, ctx, conf_state, qop_state, iov, 2);
+ major = gssEapUnwrapOrVerifyMIC(minor, ctx, conf_state, qop_state,
+ iov, 2, TOK_TYPE_WRAP);
if (major == GSS_S_COMPLETE) {
*output_message_buffer = iov[1].buffer;
} else {
enum gss_eap_token_type tokenType,
gss_buffer_t innerInputToken);
+OM_uint32
+gssEapContextTime(OM_uint32 *minor,
+ gss_ctx_id_t context_handle,
+ OM_uint32 *time_rec);
+
+OM_uint32
+gssEapDisplayName(OM_uint32 *minor,
+ gss_name_t name,
+ gss_buffer_t output_name_buffer,
+ gss_OID *output_name_type);
+
/* util_cred.c */
OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred);
OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred);
const gss_buffer_t input_name_buffer,
gss_name_t *output_name,
unsigned int flags);
+OM_uint32
+gssEapDuplicateName(OM_uint32 *minor,
+ const gss_name_t input_name,
+ gss_name_t *dest_name);
/* util_oid.c */
OM_uint32
*minor = 0;
return GSS_S_COMPLETE;
}
+
+OM_uint32
+gssEapContextTime(OM_uint32 *minor,
+ gss_ctx_id_t context_handle,
+ OM_uint32 *time_rec)
+{
+ if (context_handle == GSS_C_NO_CONTEXT) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (!CTX_IS_ESTABLISHED(context_handle)) {
+ return GSS_S_NO_CONTEXT;
+ }
+
+ *minor = 0;
+
+ 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;
+ }
+
+ return GSS_S_COMPLETE;
+}
}
if (desiredName != GSS_C_NO_NAME) {
- major = gss_duplicate_name(minor, desiredName, &cred->name);
+ major = gssEapDuplicateName(minor, desiredName, &cred->name);
if (GSS_ERROR(major))
goto cleanup;
} else {
buf.value = getlogin(); /* XXX */
buf.length = strlen((char *)buf.value);
- major = gss_import_name(minor, &buf,
- GSS_C_NT_USER_NAME, &cred->name);
+ major = gssEapImportName(minor, &buf,
+ GSS_C_NT_USER_NAME, &cred->name);
if (GSS_ERROR(major))
goto cleanup;
}
return major;
}
+
+OM_uint32
+gssEapDuplicateName(OM_uint32 *minor,
+ const gss_name_t input_name,
+ gss_name_t *dest_name)
+{
+ OM_uint32 major, tmpMinor;
+ krb5_context krbContext;
+ gss_name_t name;
+
+ if (input_name == GSS_C_NO_NAME) {
+ *minor = EINVAL;
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+ }
+
+ GSSEAP_KRB_INIT(&krbContext);
+
+ major = gssEapAllocName(minor, &name);
+ if (GSS_ERROR(major)) {
+ return major;
+ }
+
+ /* Lock mutex for copying mutable attributes */
+ GSSEAP_MUTEX_LOCK(&input_name->mutex);
+
+ *minor = krb5_copy_principal(krbContext, input_name->krbPrincipal,
+ &name->krbPrincipal);
+ if (*minor != 0) {
+ major = GSS_S_FAILURE;
+ goto cleanup;
+ }
+
+ if (input_name->attrCtx != NULL) {
+ major = gssEapDuplicateAttrContext(minor, input_name, name);
+ if (GSS_ERROR(major))
+ goto cleanup;
+ }
+
+ *dest_name = name;
+
+cleanup:
+ GSSEAP_MUTEX_UNLOCK(&input_name->mutex);
+
+ if (GSS_ERROR(major)) {
+ gssEapReleaseName(&tmpMinor, &name);
+ }
+
+ return major;
+}
+
+OM_uint32
+gssEapDisplayName(OM_uint32 *minor,
+ gss_name_t name,
+ gss_buffer_t output_name_buffer,
+ gss_OID *output_name_type)
+{
+ OM_uint32 major, tmpMinor;
+ krb5_context krbContext;
+ char *krbName;
+
+ GSSEAP_KRB_INIT(&krbContext);
+
+ output_name_buffer->length = 0;
+ output_name_buffer->value = NULL;
+
+ if (name == GSS_C_NO_NAME) {
+ *minor = EINVAL;
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
+ }
+
+ *minor = krb5_unparse_name(krbContext, name->krbPrincipal, &krbName);
+ if (*minor != 0) {
+ return GSS_S_FAILURE;
+ }
+
+ major = makeStringBuffer(minor, krbName, output_name_buffer);
+ if (GSS_ERROR(major)) {
+ krb5_free_unparsed_name(krbContext, krbName);
+ return major;
+ }
+
+ krb5_free_unparsed_name(krbContext, krbName);
+
+ if (output_name_type != NULL)
+ *output_name_type = GSS_EAP_NT_PRINCIPAL_NAME;
+
+ return GSS_S_COMPLETE;
+}
default:
break;
}
- case VENDOR_ID_GSS_EAP:
+ case VENDOR_ID_UKERNA:
ret = true;
break;
default:
VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
};
-#define VENDOR_ID_GSS_EAP 5322 /* XXX TODO assign */
+#define VENDOR_ID_UKERNA 25622
-enum { VENDOR_ATTR_GSS_ACCEPTOR_SERVICE_NAME = 1,
+enum { VENDOR_ATTR_GSS_ACCEPTOR_SERVICE_NAME = 128,
VENDOR_ATTR_GSS_ACCEPTOR_HOST_NAME,
VENDOR_ATTR_GSS_ACCEPTOR_REALM_NAME,
VENDOR_ATTR_SAML_AAA_ASSERTION
#include <sstream>
#include <xercesc/util/XMLUniDefs.hpp>
+#include <xmltooling/unicode.h>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/XMLHelper.h>
+#include <xmltooling/util/ParserPool.h>
+#include <xmltooling/util/DateTime.h>
#include <saml/saml1/core/Assertions.h>
#include <saml/saml2/core/Assertions.h>
if (!gss_eap_attr_provider::initFromGssContext(manager, gssCred, gssCtx))
return false;
+ /*
+ * XXX TODO we need to support draft-howlett-radius-saml-attr-00
+ */
radius = static_cast<const gss_eap_radius_attr_provider *>
(m_manager->getProvider(ATTR_TYPE_RADIUS));
if (radius != NULL &&
radius->getFragmentedAttribute(VENDOR_ATTR_SAML_AAA_ASSERTION,
- VENDOR_ID_GSS_EAP,
+ VENDOR_ID_UKERNA,
&authenticated, &complete, &value)) {
setAssertion(&value, authenticated);
gss_release_buffer(&minor, &value);
if (assertion != NULL) {
#if 0
- m_assertion = dynamic_cast<saml2::Assertion *>(assertion->clone());
+ XMLObject *tmp = assertion->clone();
+ m_assertion = dynamic_cast<saml2::Assertion *>(tmp);
+// m_assertion = dynamic_cast<saml2::Assertion *>(assertion->clone());
#else
m_assertion = (saml2::Assertion *)((void *)assertion->clone());
#endif
#include <shibsp/exceptions.h>
#include <shibsp/attribute/SimpleAttribute.h>
-#include <shibsp/handler/AssertionConsumerService.h>
#include <shibresolver/resolver.h>
+#include <sstream>
+
#include "gssapiP_eap.h"
using namespace shibsp;
using namespace shibresolver;
using namespace opensaml::saml2md;
using namespace opensaml;
-using namespace xmltooling::logging;
using namespace xmltooling;
-using namespace xercesc;
using namespace std;
gss_eap_shib_attr_provider::gss_eap_shib_attr_provider(void)
resolver = ShibbolethResolver::create();
if (gssCred != GSS_C_NO_CREDENTIAL &&
- gss_display_name(&minor, gssCred->name, &nameBuf, NULL) == GSS_S_COMPLETE)
+ gssEapDisplayName(&minor, gssCred->name, &nameBuf, NULL) == GSS_S_COMPLETE)
resolver->setApplicationID((const char *)nameBuf.value);
m_authenticated = false;
delete resolver;
-#if 0
- gss_buffer_desc testattr = {
- sizeof("urn:greet:greeting") - 1, (void *)"urn:greet:greeting" };
- gss_buffer_desc testval =
- { sizeof("Hello, GSS EAP.") - 1, (void *)"Hello, GSS EAP." };
- setAttribute(true, &testattr, &testval);
-#endif /* GSSEAP_DEBUG */
-
return true;
}
unsigned char *p;
int i;
+ if (!CTX_IS_ESTABLISHED(ctx))
+ return GSS_S_NO_CONTEXT;
+
iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
iov[0].buffer.value = NULL;
iov[0].buffer.length = 0;
iov[3].buffer.value = NULL;
iov[3].buffer.length = 0;
- major = gss_wrap_iov_length(minor, ctx, conf_req_flag, qop_req,
+ major = gssEapWrapIovLength(minor, ctx, conf_req_flag, qop_req,
NULL, iov, 4);
if (GSS_ERROR(major)) {
return major;
p += iov[i].buffer.length;
}
- major = gss_wrap_iov(minor, ctx, conf_req_flag, qop_req, conf_state, iov, 4);
+ major = gssEapWrapOrGetMIC(minor, ctx, conf_req_flag, conf_state,
+ iov, 4, TOK_TYPE_WRAP);
if (GSS_ERROR(major)) {
gss_release_buffer(&tmpMinor, output_message_buffer);
}
return GSS_S_NO_CONTEXT;
return gssEapWrapOrGetMIC(minor, ctx, conf_req_flag, conf_state,
- iov, iov_count, TOK_TYPE_WRAP);
+ iov, iov_count, TOK_TYPE_WRAP);
}
while (0)
OM_uint32
-gss_wrap_iov_length(OM_uint32 *minor,
+gssEapWrapIovLength(OM_uint32 *minor,
gss_ctx_id_t ctx,
int conf_req_flag,
gss_qop_t qop_req,
*minor = 0;
return GSS_S_COMPLETE;
}
+
+OM_uint32
+gss_wrap_iov_length(OM_uint32 *minor,
+ gss_ctx_id_t ctx,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ return gssEapWrapIovLength(minor, ctx, conf_req_flag, qop_req,
+ conf_state, iov, iov_count);
+}
iov[3].buffer.value = NULL;
iov[3].buffer.length = 0;
- major = gss_wrap_iov_length(minor, ctx, conf_req_flag, qop_req,
+ major = gssEapWrapIovLength(minor, ctx, conf_req_flag, qop_req,
NULL, iov, 4);
if (GSS_ERROR(major)) {
return major;