Some work on SAML
authorLuke Howard <lukeh@padl.com>
Sun, 12 Sep 2010 13:45:47 +0000 (15:45 +0200)
committerLuke Howard <lukeh@padl.com>
Sun, 12 Sep 2010 13:45:47 +0000 (15:45 +0200)
15 files changed:
Makefile.am
acinclude.m4
configure.ac
duplicate_name.c
get_name_attribute.c
gssapiP_eap.h
inquire_name.c
set_name_attribute.c
util.h
util_name.c
util_radius.c
util_radius.h
util_saml.c [deleted file]
util_saml.cpp [new file with mode: 0644]
util_saml.h

index 7cbe203..e7886e8 100644 (file)
@@ -4,11 +4,15 @@ gssdir = $(libdir)/gss
 
 gss_LTLIBRARIES = libmech_eap.la
 
-libmech_eap_la_CFLAGS  = -DBUILD_GSSEAP_LIB -g -Wall -fno-strict-aliasing \
-                         @EAP_CFLAGS@ @KRB5_CFLAGS@ @TARGET_CFLAGS@
-libmech_eap_la_LDFLAGS = -export-symbols mech_eap.exports -version-info 0:0:0 \
-                         @EAP_LDFLAGS@ @KRB5_LDFLAGS@ @TARGET_LDFLAGS@
-libmech_eap_la_LIBADD  = @EAP_LIBS@ @KRB5_LIBS@
+libmech_eap_la_CPPFLAGS = -DBUILD_GSSEAP_LIB
+libmech_eap_la_CFLAGS   = -g -Wall -fno-strict-aliasing \
+                           @EAP_CFLAGS@ @KRB5_CFLAGS@ @TARGET_CFLAGS@
+libmech_eap_la_CXXFLAGS = -g -Wall \
+                           @EAP_CFLAGS@ @KRB5_CFLAGS@ @SHIBSP_CXXFLAGS@ \
+                           @TARGET_CFLAGS@
+libmech_eap_la_LDFLAGS  = -export-symbols mech_eap.exports -version-info 0:0:0 \
+                           @EAP_LDFLAGS@ @KRB5_LDFLAGS@ @TARGET_LDFLAGS@
+libmech_eap_la_LIBADD   = @EAP_LIBS@ @KRB5_LIBS@
 
 libmech_eap_la_SOURCES =                       \
        accept_sec_context.c                    \
@@ -65,7 +69,7 @@ libmech_eap_la_SOURCES =                      \
        util_oid.c                              \
        util_ordering.c                         \
        util_radius.c                           \
-       util_saml.c                             \
+       util_saml.cpp                           \
        util_token.c                            \
        verify_mic.c                            \
        wrap.c                                  \
index f91ab0d..7de99cc 100644 (file)
@@ -102,3 +102,41 @@ else
        AC_SUBST(EAP_LIBS)
 fi
 ])dnl
+
+AC_DEFUN([AX_CHECK_SHIBSP],
+[AC_MSG_CHECKING(for Shibboleth implementation)
+SHIBSP_DIR=
+found_shibsp="no"
+AC_ARG_WITH(shibsp,
+    AC_HELP_STRING([--with-shibsp],
+       [Use shibspboleth (in specified installation directory)]),
+    [check_shibsp_dir="$withval"],
+    [check_shibsp_dir=])
+for dir in $check_shibsp_dir /usr /usr/local ; do
+   shibspdir="$dir"
+   if test -f "$dir/include/shibsp/SPConfig.h"; then
+     found_shibsp="yes";
+     SHIBSP_DIR="${shibspdir}"
+     SHIBSP_CXXFLAGS="-I$shibspdir/include";
+     break;
+   fi
+done
+AC_MSG_RESULT($found_shibsp)
+if test x_$found_shibsp != x_yes; then
+   AC_MSG_ERROR([
+----------------------------------------------------------------------
+  Cannot find Shibboleth/OpenSAML libraries.
+
+  Please install Shibboleth or specify installation directory with
+  --with-shibsp=(dir).
+----------------------------------------------------------------------
+])
+else
+       printf "Shibboleth found in $shibspdir\n";
+       SHIBSP_LIBS="-lshibspsp -lsaml -lxml-security-c -lxmltooling -lxerces-c";
+       SHIBSP_LDFLAGS="-L$shibspdir/lib";
+       AC_SUBST(SHIBSP_CXXFLAGS)
+       AC_SUBST(SHIBSP_LDFLAGS)
+       AC_SUBST(SHIBSP_LIBS)
+fi
+])dnl
index ee0ae6b..82bc27a 100644 (file)
@@ -6,6 +6,7 @@ LT_PREREQ([2.2])
 LT_INIT([dlopen disable-static])
 
 AC_PROG_CC
+AC_PROG_CXX
 
 dnl Check if we're on Solaris and set CFLAGS accordingly
 dnl AC_CANONICAL_TARGET
@@ -28,5 +29,6 @@ AC_SUBST(TARGET_CFLAGS)
 AC_SUBST(TARGET_LDFLAGS)
 AX_CHECK_KRB5
 AX_CHECK_EAP
+AX_CHECK_SHIBSP
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
index 6ad33a0..3f52acb 100644 (file)
@@ -63,15 +63,16 @@ gss_duplicate_name(OM_uint32 *minor,
         goto cleanup;
     }
 
-    if (input_name->avps != NULL) {
-        major = radiusDuplicateAVPs(minor, input_name->avps, &name->avps);
+    if (input_name->radiusCtx != NULL) {
+        major = radiusDuplicateAttrContext(minor, input_name->radiusCtx,
+                                           &name->radiusCtx);
         if (GSS_ERROR(major))
             goto cleanup;
     }
 
-    if (input_name->assertion != NULL) {
-        major = samlDuplicateAssertion(minor, input_name->assertion,
-                                       &name->assertion);
+    if (input_name->samlCtx != NULL) {
+        major = samlDuplicateAttrContext(minor, input_name->samlCtx,
+                                         &name->samlCtx);
         if (GSS_ERROR(major))
             goto cleanup;
     }
index 0987f15..e12dffb 100644 (file)
@@ -68,17 +68,17 @@ gss_get_name_attribute(OM_uint32 *minor,
     type = gssEapAttributePrefixToType(&prefix);
     switch (type) {
     case ATTR_TYPE_SAML_AAA_ASSERTION:
-        major = samlExportAssertion(minor, name->assertion, value);
+        major = samlGetAssertion(minor, name->samlCtx, value);
         break;
     case ATTR_TYPE_SAML_ATTR:
-        major = samlGetAttribute(minor, name->assertion, &suffix,
+        major = samlGetAttribute(minor, name->samlCtx, &suffix,
                                  authenticated, complete,
                                  value, display_value, more);
         break;
     case ATTR_TYPE_RADIUS_AVP:
-        major = radiusGetAVP(minor, name->avps, &suffix,
-                             authenticated, complete,
-                             value, display_value, more);
+        major = radiusGetAttribute(minor, name->radiusCtx, &suffix,
+                                   authenticated, complete,
+                                   value, display_value, more);
         break;
     default:
         *minor = ENOENT;
index 3a2dd80..db39ccf 100644 (file)
@@ -46,6 +46,9 @@
 #include "gssapi_eap.h"
 #include "util.h"
 
+/* Kerberos includes */
+#include <krb5.h>
+
 /* EAP includes */
 #include <common.h>
 #include <eap_peer/eap.h>
@@ -53,9 +56,6 @@
 #include <crypto/tls.h>                     /* XXX testing implementation only */
 #include <wpabuf.h>
 
-/* Kerberos includes */
-#include <krb5.h>
-
 #define NAME_FLAG_NAI                       0x00000001
 #define NAME_FLAG_SERVICE                   0x00000002
 #define NAME_FLAG_SAML                      0x00000010
 #define NAME_HAS_ATTRIBUTES(name)           ((name)->flags & \
                                              (NAME_FLAG_SAML | NAME_FLAG_RADIUS))
 
-struct eap_gss_saml_assertion;
-struct eap_gss_avp_list;
+struct eap_gss_saml_attr_ctx;
+struct eap_gss_radius_attr_ctx;
 
 struct gss_name_struct {
     GSSEAP_MUTEX mutex; /* mutex protecting attributes */
     OM_uint32 flags;
     krb5_principal krbPrincipal; /* this is immutable */
-    struct eap_gss_saml_assertion *assertion;
-    struct eap_gss_avp_list *avps;
+    struct eap_gss_saml_attr_ctx *samlCtx;
+    struct eap_gss_radius_attr_ctx *radiusCtx;
 };
 
 #define CRED_FLAG_INITIATE                  0x00000001
index 47f694b..6407cba 100644 (file)
@@ -93,7 +93,7 @@ OM_uint32 gss_inquire_name(OM_uint32 *minor,
 
     args.attrs = *attrs;
 
-    if (name->assertion != NULL) {
+    if (name->samlCtx != NULL) {
         args.prefix = gssEapAttributeTypeToPrefix(ATTR_TYPE_SAML_AAA_ASSERTION);
 
         major = addAttribute(minor, &args, GSS_C_NO_BUFFER);
@@ -101,14 +101,16 @@ OM_uint32 gss_inquire_name(OM_uint32 *minor,
             goto cleanup;
 
         args.prefix = gssEapAttributeTypeToPrefix(ATTR_TYPE_SAML_ATTR);
-        major = samlGetAttributeTypes(minor, name->assertion, &args, addAttribute);
+        major = samlGetAttributeTypes(minor, name->samlCtx,
+                                      &args, addAttribute);
         if (GSS_ERROR(major))
             goto cleanup;
     }
 
-    if (name->avps != NULL) {
+    if (name->radiusCtx != NULL) {
         args.prefix = gssEapAttributeTypeToPrefix(ATTR_TYPE_RADIUS_AVP);
-        major = radiusGetAttributeTypes(minor, name->avps, &args, addAttribute);
+        major = radiusGetAttributeTypes(minor, name->radiusCtx,
+                                        &args, addAttribute);
         if (GSS_ERROR(major))
             goto cleanup;
     }
index c2b13c3..a8a4a56 100644 (file)
@@ -57,12 +57,12 @@ gss_set_name_attribute(OM_uint32 *minor,
     type = gssEapAttributePrefixToType(&prefix);
     switch (type) {
     case ATTR_TYPE_SAML_ATTR:
-        major = samlSetAttribute(minor, name->assertion,
+        major = samlSetAttribute(minor, name->samlCtx,
                                  complete, &suffix, value);
         break;
     case ATTR_TYPE_RADIUS_AVP:
-        major = radiusSetAVP(minor, name->avps,
-                             complete, &suffix, value);
+        major = radiusSetAttribute(minor, name->radiusCtx,
+                                   complete, &suffix, value);
         break;
     default:
         *minor = ENOENT;
diff --git a/util.h b/util.h
index ea0d820..bc88681 100644 (file)
--- a/util.h
+++ b/util.h
 #ifndef _UTIL_H_
 #define _UTIL_H_ 1
 
+#include <string.h>
+#include <errno.h>
+
 #include <krb5.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "util_saml.h"
 #include "util_radius.h"
 
@@ -504,4 +511,9 @@ store_oid(gss_OID oid, void *vp)
 
     return store_buffer(&buf, vp, FALSE);
 }
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _UTIL_H_ */
index eef8ff5..8f25002 100644 (file)
@@ -106,8 +106,8 @@ gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName)
     GSSEAP_KRB_INIT(&krbContext);
     krb5_free_principal(krbContext, name->krbPrincipal);
 
-    radiusReleaseAVPs(&tmpMinor, &name->avps);
-    samlReleaseAssertion(&tmpMinor, &name->assertion);
+    radiusReleaseAttrContext(&tmpMinor, &name->radiusCtx);
+    samlReleaseAttrContext(&tmpMinor, &name->samlCtx);
 
     GSSEAP_MUTEX_DESTROY(&name->mutex);
     GSSEAP_FREE(name);
index cb1934c..992350b 100644 (file)
 
 #include "gssapiP_eap.h"
 
-struct eap_gss_avp_list {
+struct eap_gss_radius_attr_ctx {
 };
 
 OM_uint32
-radiusDuplicateAVPs(OM_uint32 *minor,
-                    const struct eap_gss_avp_list *in,
-                    struct eap_gss_avp_list **out)
+radiusDuplicateAttrContext(OM_uint32 *minor,
+                           const struct eap_gss_radius_attr_ctx *in,
+                           struct eap_gss_radius_attr_ctx **out)
 {
     GSSEAP_NOT_IMPLEMENTED;
 }
 
 OM_uint32
-radiusReleaseAVPs(OM_uint32 *minor,
-                  struct eap_gss_avp_list **avps)
+radiusReleaseAttrContext(OM_uint32 *minor,
+                         struct eap_gss_radius_attr_ctx **pCtx)
 {
-    if (*avps != NULL) {
+    if (*pCtx != NULL) {
         GSSEAP_NOT_IMPLEMENTED;
-        *avps = NULL;
+        *pCtx = NULL;
     }
 }
 
 OM_uint32
 radiusGetAttributeTypes(OM_uint32 *minor,
-                        const struct eap_gss_avp_list *avps,
+                        const struct eap_gss_radius_attr_ctx *ctx,
                         void *data,
                         OM_uint32 (*addAttribute)(OM_uint32 *,
                                                   void *, gss_buffer_t))
@@ -64,24 +64,24 @@ radiusGetAttributeTypes(OM_uint32 *minor,
 }
 
 OM_uint32
-radiusGetAVP(OM_uint32 *minor,
-             const struct eap_gss_avp_list *avps,
-             gss_buffer_t attr,
-             int *authenticated,
-             int *complete,
-             gss_buffer_t value,
-             gss_buffer_t display_value,
-             int *more)
+radiusGetAttribute(OM_uint32 *minor,
+                   const struct eap_gss_radius_attr_ctx *ctx,
+                   gss_buffer_t attr,
+                   int *authenticated,
+                   int *complete,
+                   gss_buffer_t value,
+                   gss_buffer_t display_value,
+                   int *more)
 {
     GSSEAP_NOT_IMPLEMENTED;
 }
 
 OM_uint32
-radiusSetAVP(OM_uint32 *minor,
-             struct eap_gss_avp_list *avps,
-             int complete,
-             gss_buffer_t attr,
-             gss_buffer_t value)
+radiusSetAttribute(OM_uint32 *minor,
+                   struct eap_gss_radius_attr_ctx *ctx,
+                   int complete,
+                   gss_buffer_t attr,
+                   gss_buffer_t value)
 {
     GSSEAP_NOT_IMPLEMENTED;
 }
index 4f9a841..f789830 100644 (file)
  * SUCH DAMAGE.
  */
 
-#include "gssapiP_eap.h"
-
 #ifndef _UTIL_RADIUS_H_
 #define _UTIL_RADIUS_H_ 1
 
-struct eap_gss_avp_list;
+struct eap_gss_radius_attr_ctx;
 
 OM_uint32
-radiusDuplicateAVPs(OM_uint32 *minor,
-                    const struct eap_gss_avp_list *in,
-                    struct eap_gss_avp_list **out);
+radiusDuplicateAttrContext(OM_uint32 *minor,
+                           const struct eap_gss_radius_attr_ctx *in,
+                           struct eap_gss_radius_attr_ctx **out);
 
 OM_uint32
-radiusReleaseAVPs(OM_uint32 *minor,
-                  struct eap_gss_avp_list **avps);
+radiusReleaseAttrContext(OM_uint32 *minor,
+                         struct eap_gss_radius_attr_ctx **ctx);
 
 OM_uint32
 radiusGetAttributeTypes(OM_uint32 *minor,
-                        const struct eap_gss_avp_list *assertion,
+                        const struct eap_gss_radius_attr_ctx *ctx,
                         void *data,
                         OM_uint32 (*addAttribute)(OM_uint32 *, void *, gss_buffer_t));
 
 OM_uint32
-radiusGetAVP(OM_uint32 *minor,
-             const struct eap_gss_avp_list *avps,
-             gss_buffer_t attr,
-             int *authenticated,
-             int *complete,
-             gss_buffer_t value,
-             gss_buffer_t display_value,
-             int *more);
+radiusGetAttribute(OM_uint32 *minor,
+                   const struct eap_gss_radius_attr_ctx *ctx,
+                   gss_buffer_t attr,
+                   int *authenticated,
+                   int *complete,
+                   gss_buffer_t value,
+                   gss_buffer_t display_value,
+                   int *more);
 
 OM_uint32
-radiusSetAVP(OM_uint32 *minor,
-             struct eap_gss_avp_list *avps,
-             int complete,
-             gss_buffer_t attr,
-             gss_buffer_t value);
+radiusSetAttribute(OM_uint32 *minor,
+                   struct eap_gss_radius_attr_ctx *ctx,
+                   int complete,
+                   gss_buffer_t attr,
+                   gss_buffer_t value);
 
 #endif /* _UTIL_RADIUS_H_ */
diff --git a/util_saml.c b/util_saml.c
deleted file mode 100644 (file)
index e86b232..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2010, JANET(UK)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of JANET(UK) nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "gssapiP_eap.h"
-
-OM_uint32
-samlDuplicateAssertion(OM_uint32 *minor,
-                       const struct eap_gss_saml_assertion *in,
-                       struct eap_gss_saml_assertion **out)
-{
-    GSSEAP_NOT_IMPLEMENTED;
-}
-
-OM_uint32
-samlReleaseAssertion(OM_uint32 *minor,
-                     struct eap_gss_saml_assertion **assertion)
-{
-    if (*assertion != NULL) {
-        GSSEAP_NOT_IMPLEMENTED;
-        *assertion = NULL;
-    }
-}
-
-OM_uint32
-samlImportAssertion(OM_uint32 *minor,
-                    gss_buffer_t buffer,
-                    struct eap_gss_saml_assertion *pAssertion)
-{
-    GSSEAP_NOT_IMPLEMENTED;
-}
-
-OM_uint32
-samlExportAssertion(OM_uint32 *minor,
-                    struct eap_gss_saml_assertion *assertion,
-                    gss_buffer_t buffer)
-{
-    GSSEAP_NOT_IMPLEMENTED;
-}
-
-OM_uint32
-samlGetAttributeTypes(OM_uint32 *minor,
-                      const struct eap_gss_saml_assertion *assertion,
-                      void *data,
-                      OM_uint32 (*addAttribute)(OM_uint32 *, void *, gss_buffer_t))
-{
-    GSSEAP_NOT_IMPLEMENTED;
-}
-
-OM_uint32
-samlGetAttribute(OM_uint32 *minor,
-                 const struct eap_gss_saml_assertion *assertion,
-                 gss_buffer_t attr,
-                 int *authenticated,
-                 int *complete,
-                 gss_buffer_t value,
-                 gss_buffer_t display_value,
-                 int *more)
-{
-    GSSEAP_NOT_IMPLEMENTED;
-}
-
-OM_uint32
-samlSetAttribute(OM_uint32 *minor,
-                 struct eap_gss_saml_assertion *assertion,
-                 int complete,
-                 gss_buffer_t attr,
-                 gss_buffer_t value)
-{
-    GSSEAP_NOT_IMPLEMENTED;
-}
diff --git a/util_saml.cpp b/util_saml.cpp
new file mode 100644 (file)
index 0000000..6256579
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2010, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright 2001-2009 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_ext.h>
+#include "util.h"
+
+#include <shibsp/Application.h>
+#include <shibsp/exceptions.h>
+#include <shibsp/SPConfig.h>
+#include <shibsp/ServiceProvider.h>
+#include <shibsp/attribute/Attribute.h>
+#include <shibsp/attribute/resolver/ResolutionContext.h>
+#include <shibsp/handler/AssertionConsumerService.h>
+#include <shibsp/metadata/MetadataProviderCriteria.h>
+#include <shibsp/util/SPConstants.h>
+
+#include <saml/saml1/core/Assertions.h>
+#include <saml/saml2/core/Assertions.h>
+#include <saml/saml2/metadata/Metadata.h>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/XMLHelper.h>
+
+using namespace shibsp;
+using namespace opensaml::saml2md;
+using namespace opensaml;
+using namespace xmltooling::logging;
+using namespace xmltooling;
+using namespace xercesc;
+using namespace std;
+
+class GSSEAPResolver : public shibsp::AssertionConsumerService
+{
+public:
+    GSSEAPResolver(const DOMElement *e, const char *appId)
+        : shibsp::AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".GSSEAPResolver")) {
+    }
+    virtual ~GSSEAPResolver() {}
+
+    ResolutionContext* resolveAttributes (
+        const Application& application,
+        const RoleDescriptor* issuer,
+        const XMLCh* protocol,
+        const saml1::NameIdentifier* v1nameid,
+        const saml2::NameID* nameid,
+        const XMLCh* authncontext_class,
+        const XMLCh* authncontext_decl,
+        const vector<const Assertion*>* tokens
+        ) const {
+            return shibsp::AssertionConsumerService::resolveAttributes(
+                    application, issuer, protocol, v1nameid,
+                    nameid, authncontext_class, authncontext_decl, tokens
+            );
+    }
+
+private:
+    void implementProtocol(
+        const Application& application,
+        const HTTPRequest& httpRequest,
+        HTTPResponse& httpResponse,
+        SecurityPolicy& policy,
+        const PropertySet* settings,
+        const XMLObject& xmlObject
+        ) const {
+            throw FatalProfileException("Should never be called.");
+    }
+};
+
+class SHIBSP_DLLLOCAL DummyContext : public ResolutionContext
+{
+public:
+    DummyContext(const vector<Attribute*>& attributes) : m_attributes(attributes) {
+    }
+
+    virtual ~DummyContext() {
+        for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<Attribute>());
+    }
+
+    vector<Attribute*>& getResolvedAttributes() {
+        return m_attributes;
+    }
+    vector<Assertion*>& getResolvedAssertions() {
+        return m_tokens;
+    }
+
+private:
+    vector<Attribute*> m_attributes;
+    static vector<Assertion*> m_tokens; // never any tokens, so just share an empty vector
+};
+
+struct eap_gss_saml_attr_ctx {
+    ResolutionContext *resCtx;
+    gss_buffer_desc assertion;
+};
+
+static OM_uint32
+samlAllocAttrContext(OM_uint32 *minor,
+                     struct eap_gss_saml_attr_ctx **pCtx)
+{
+    struct eap_gss_saml_attr_ctx *ctx;
+
+    ctx = (struct eap_gss_saml_attr_ctx *)GSSEAP_CALLOC(1, sizeof(*ctx));
+    if (ctx == NULL) {
+        *minor = ENOMEM;
+        return GSS_S_FAILURE;
+    }
+
+    *pCtx = ctx;
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+samlImportAssertion(OM_uint32 *minor,
+                    gss_buffer_t buffer,
+                    saml2::Assertion **pAssertion)
+{
+    *pAssertion = NULL;
+
+    try {
+        DOMDocument *doc;
+        const XMLObjectBuilder *b;
+        DOMElement *elem;
+        XMLObject *xobj;
+        string samlBuf((char *)buffer->value, buffer->length);
+        istringstream samlIn(samlBuf);
+
+        doc = XMLToolingConfig::getConfig().getParser().parse(samlIn);
+        b = XMLObjectBuilder::getDefaultBuilder();
+        elem = doc->getDocumentElement();
+        xobj = b->buildOneFromElement(elem, true);
+
+        *pAssertion = dynamic_cast<saml2::Assertion *>(xobj);
+        if (*pAssertion == NULL) {
+            /* TODO minor_status */
+            return GSS_S_BAD_NAME;
+        }
+    } catch (exception &e){
+        /* TODO minor_status */
+        return GSS_S_BAD_NAME;
+    }
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32
+samlDuplicateAttrContext(OM_uint32 *minor,
+                         const struct eap_gss_saml_attr_ctx *in,
+                         struct eap_gss_saml_attr_ctx **out)
+{
+    OM_uint32 major, tmpMinor;
+    struct eap_gss_saml_attr_ctx *ctx;
+
+    major = samlAllocAttrContext(minor, &ctx);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    major = duplicateBuffer(minor, (gss_buffer_t)&in->assertion, &ctx->assertion);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    ctx->resCtx = new DummyContext(in->resCtx->getResolvedAttributes());
+
+cleanup:
+    if (GSS_ERROR(major))
+        samlReleaseAttrContext(&tmpMinor, &ctx);
+
+    return major;
+}
+
+OM_uint32
+samlReleaseAttrContext(OM_uint32 *minor,
+                       struct eap_gss_saml_attr_ctx **pCtx)
+{
+    struct eap_gss_saml_attr_ctx *ctx = *pCtx;
+
+    if (ctx != NULL) {
+        delete ctx->resCtx;
+        gss_release_buffer(minor, &ctx->assertion);
+        GSSEAP_FREE(ctx);
+        *pCtx = NULL;
+    }
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32
+samlCreateAttrContext(OM_uint32 *minor,
+                      gss_buffer_t buffer,
+                      gss_name_t acceptorName,
+                      struct eap_gss_saml_attr_ctx **pCtx)
+{
+    OM_uint32 major, tmpMinor;
+    struct eap_gss_saml_attr_ctx *ctx;
+    SPConfig &conf = SPConfig::getConfig();
+    ServiceProvider *sp;
+    const Application *app;
+    MetadataProvider *m;
+    gss_buffer_desc nameBuf;
+    const XMLCh *issuer = NULL;
+    saml2::NameID *subjectName = NULL;
+    saml2::Assertion *assertion;
+
+    nameBuf.length = 0;
+    nameBuf.value = NULL;
+
+    conf.setFeatures(SPConfig::Metadata             |
+                     SPConfig::Trust                |
+                     SPConfig::AttributeResolution  |
+                     SPConfig::Credentials          |
+                     SPConfig::OutOfProcess);
+    if (!conf.init())
+        return GSS_S_FAILURE;
+    if (!conf.instantiate())
+        return GSS_S_FAILURE;
+
+    sp = conf.getServiceProvider();
+    sp->lock();
+
+    major = gss_display_name(minor, acceptorName, &nameBuf, NULL);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    app = sp->getApplication((const char *)nameBuf.value);
+    if (app == NULL) {
+        major = GSS_S_FAILURE;
+        goto cleanup;
+    }
+
+    major = samlAllocAttrContext(minor, &ctx);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    major = duplicateBuffer(minor, buffer, &ctx->assertion);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    major = samlImportAssertion(minor, &ctx->assertion, &assertion);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    if (assertion->getIssuer() != NULL)
+        issuer = assertion->getIssuer()->getName();
+    if (assertion->getSubject() != NULL)
+        subjectName = assertion->getSubject()->getNameID();
+
+    try {
+        m = app->getMetadataProvider();
+        xmltooling::Locker mlocker(m);
+        MetadataProviderCriteria mc(*app, issuer,
+                                    &IDPSSODescriptor::ELEMENT_QNAME,
+                                    samlconstants::SAML20P_NS);
+        pair<const EntityDescriptor *, const RoleDescriptor *> site =
+            m->getEntityDescriptor(mc);
+        if (!site.first) {
+            auto_ptr_char temp(issuer);
+            throw MetadataException("Unable to locate metadata for IdP ($1).",
+                                    params(1,temp.get()));
+        }
+        vector<const Assertion*> tokens(1, assertion);
+        GSSEAPResolver gssResolver(NULL, (const char *)nameBuf.value);
+        ctx->resCtx = gssResolver.resolveAttributes(*app, site.second,
+                                                    samlconstants::SAML20P_NS,
+                                                    NULL, subjectName, NULL,
+                                                    NULL, &tokens);
+    } catch (exception &ex) {
+        major = GSS_S_BAD_NAME;
+        goto cleanup;
+    }
+
+    major = GSS_S_COMPLETE;
+    *pCtx = ctx;
+
+cleanup:
+    sp->unlock();
+    conf.term();
+
+    if (GSS_ERROR(major))
+        samlReleaseAttrContext(&tmpMinor, &ctx);
+    gss_release_buffer(&tmpMinor, &nameBuf);
+
+    return major;
+}
+
+OM_uint32
+samlGetAttributeTypes(OM_uint32 *minor,
+                      const struct eap_gss_saml_attr_ctx *ctx,
+                      void *data,
+                      OM_uint32 (*addAttribute)(OM_uint32 *, void *, gss_buffer_t))
+{
+    OM_uint32 major = GSS_S_COMPLETE;
+
+    if (ctx == NULL)
+        return GSS_S_COMPLETE;
+
+    for (vector<Attribute*>::const_iterator a = ctx->resCtx->getResolvedAttributes().begin();
+        a != ctx->resCtx->getResolvedAttributes().end();
+        ++a)
+    {
+        gss_buffer_desc attribute;
+
+        attribute.value = (void *)((*a)->getId());
+        attribute.length = strlen((char *)attribute.value);
+
+        major = addAttribute(minor, data, &attribute);
+        if (GSS_ERROR(major))
+            break;
+    }
+
+    return major;
+}
+
+OM_uint32
+samlGetAttribute(OM_uint32 *minor,
+                 const struct eap_gss_saml_attr_ctx *ctx,
+                 gss_buffer_t attr,
+                 int *authenticated,
+                 int *complete,
+                 gss_buffer_t value,
+                 gss_buffer_t display_value,
+                 int *more)
+{
+    OM_uint32 major;
+    Attribute *shibAttr = NULL;
+    gss_buffer_desc buf;
+
+    if (ctx == NULL)
+        return GSS_S_UNAVAILABLE;
+
+    for (vector<Attribute *>::const_iterator a = ctx->resCtx->getResolvedAttributes().begin();
+         a != ctx->resCtx->getResolvedAttributes().end();
+         ++a) {
+        for (vector<string>::const_iterator s = (*a)->getAliases().begin();
+             s != (*a)->getAliases().end();
+             ++s) {
+            if (attr->length == strlen((*s).c_str()) &&
+                memcmp((*s).c_str(), attr->value, attr->length) == 0) {
+                shibAttr = *a;
+                break;
+            }
+        }
+        if (shibAttr != NULL)
+            break;
+    }
+
+    if (shibAttr == NULL)
+        return GSS_S_UNAVAILABLE;
+
+    if (*more == -1) {
+        *more = 0;
+    } else if (*more >= (int)shibAttr->valueCount()) {
+        *more = 0;
+        return GSS_S_COMPLETE;
+    }
+
+    buf.value = (void *)shibAttr->getString(*more);
+    buf.length = strlen((char *)buf.value);
+
+    major = duplicateBuffer(minor, &buf, value);
+    if (GSS_ERROR(major))
+        return major;
+    *authenticated = TRUE;
+    *complete = FALSE;
+
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32
+samlSetAttribute(OM_uint32 *minor,
+                 struct eap_gss_saml_attr_ctx *ctx,
+                 int complete,
+                 gss_buffer_t attr,
+                 gss_buffer_t value)
+{
+    return GSS_S_UNAVAILABLE;
+}
+
+OM_uint32
+samlGetAssertion(OM_uint32 *minor,
+                 struct eap_gss_saml_attr_ctx *ctx,
+                 gss_buffer_t buffer)
+{
+    if (ctx == NULL)
+        return GSS_S_UNAVAILABLE;
+
+    return duplicateBuffer(minor, &ctx->assertion, buffer);
+}
+
+OM_uint32
+samlExportAttrContext(OM_uint32 *minor,
+                      struct eap_gss_saml_attr_ctx *ctx,
+                      gss_buffer_t buffer)
+{
+    GSSEAP_NOT_IMPLEMENTED;
+}
+
+OM_uint32
+samlImportAttrContext(OM_uint32 *minor,
+                      gss_buffer_t buffer,
+                      struct eap_gss_saml_attr_ctx **ppCtx)
+{
+    GSSEAP_NOT_IMPLEMENTED;
+}
index 300f822..1115eb5 100644 (file)
  * SUCH DAMAGE.
  */
 
-#include "gssapiP_eap.h"
-
 #ifndef _UTIL_SAML_H_
 #define _UTIL_SAML_H_ 1
 
-struct eap_gss_saml_assertion;
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-OM_uint32
-samlDuplicateAssertion(OM_uint32 *minor,
-                       const struct eap_gss_saml_assertion *in,
-                       struct eap_gss_saml_assertion **out);
+struct eap_gss_saml_attr_ctx;
 
 OM_uint32
-samlImportAssertion(OM_uint32 *minor,
-                    gss_buffer_t buffer,
-                    struct eap_gss_saml_assertion *pAssertion);
+samlDuplicateAttrContext(OM_uint32 *minor,
+                         const struct eap_gss_saml_attr_ctx *in,
+                         struct eap_gss_saml_attr_ctx **out);
 
 OM_uint32
-samlExportAssertion(OM_uint32 *minor,
-                    struct eap_gss_saml_assertion *assertion,
-                    gss_buffer_t buffer);
+samlCreateAttrContext(OM_uint32 *minor,
+                      gss_cred_id_t acceptorCred,
+                      gss_name_t initiatorName,
+                      gss_buffer_t buffer,
+                      struct eap_gss_saml_attr_ctx **pCtx);
 
 OM_uint32
-samlReleaseAssertion(OM_uint32 *minor,
-                     struct eap_gss_saml_assertion **assertion);
+samlReleaseAttrContext(OM_uint32 *minor,
+                       struct eap_gss_saml_attr_ctx **ctx);
 
 OM_uint32
 samlGetAttributeTypes(OM_uint32 *minor,
-                      const struct eap_gss_saml_assertion *assertion,
+                      const struct eap_gss_saml_attr_ctx *ctx,
                       void *data,
                       OM_uint32 (*addAttribute)(OM_uint32 *, void *, gss_buffer_t));
 
 OM_uint32
 samlGetAttribute(OM_uint32 *minor,
-                 const struct eap_gss_saml_assertion *assertion,
+                 const struct eap_gss_saml_attr_ctx *ctx,
                  gss_buffer_t attr,
                  int *authenticated,
                  int *complete,
@@ -74,9 +73,28 @@ samlGetAttribute(OM_uint32 *minor,
 
 OM_uint32
 samlSetAttribute(OM_uint32 *minor,
-                 struct eap_gss_saml_assertion *assertion,
+                 struct eap_gss_saml_attr_ctx *ctx,
                  int complete,
                  gss_buffer_t attr,
                  gss_buffer_t value);
 
+OM_uint32
+samlGetAssertion(OM_uint32 *minor,
+                 struct eap_gss_saml_attr_ctx *ctx,
+                 gss_buffer_t buffer);
+
+OM_uint32
+samlExportAttrContext(OM_uint32 *minor,
+                      struct eap_gss_saml_attr_ctx *ctx,
+                      gss_buffer_t buffer);
+
+OM_uint32
+samlImportAttrContext(OM_uint32 *minor,
+                      gss_buffer_t buffer,
+                      struct eap_gss_saml_attr_ctx **pCtx);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _UTIL_SAML_H_ */