Merge branch 'windows'
authorLuke Howard <lukeh@padl.com>
Wed, 14 Sep 2011 06:11:37 +0000 (16:11 +1000)
committerLuke Howard <lukeh@padl.com>
Wed, 14 Sep 2011 06:11:37 +0000 (16:11 +1000)
Conflicts:
moonshot/configure.ac
moonshot/mech_eap/Makefile.am
moonshot/mech_eap/accept_sec_context.c
moonshot/mech_eap/acquire_cred.c
moonshot/mech_eap/add_cred.c
moonshot/mech_eap/add_cred_with_password.c
moonshot/mech_eap/canonicalize_name.c
moonshot/mech_eap/compare_name.c
moonshot/mech_eap/context_time.c
moonshot/mech_eap/delete_name_attribute.c
moonshot/mech_eap/delete_sec_context.c
moonshot/mech_eap/display_name.c
moonshot/mech_eap/display_name_ext.c
moonshot/mech_eap/display_status.c
moonshot/mech_eap/duplicate_name.c
moonshot/mech_eap/eap_mech.c
moonshot/mech_eap/export_name.c
moonshot/mech_eap/export_name_composite.c
moonshot/mech_eap/export_sec_context.c
moonshot/mech_eap/get_mic.c
moonshot/mech_eap/get_name_attribute.c
moonshot/mech_eap/gssapiP_eap.h
moonshot/mech_eap/import_name.c
moonshot/mech_eap/import_sec_context.c
moonshot/mech_eap/indicate_mechs.c
moonshot/mech_eap/init_sec_context.c
moonshot/mech_eap/inquire_attrs_for_mech.c
moonshot/mech_eap/inquire_context.c
moonshot/mech_eap/inquire_cred.c
moonshot/mech_eap/inquire_cred_by_oid.c
moonshot/mech_eap/inquire_mech_for_saslname.c
moonshot/mech_eap/inquire_mechs_for_name.c
moonshot/mech_eap/inquire_name.c
moonshot/mech_eap/inquire_names_for_mech.c
moonshot/mech_eap/inquire_saslname_for_mech.c
moonshot/mech_eap/inquire_sec_context_by_oid.c
moonshot/mech_eap/map_name_to_any.c
moonshot/mech_eap/process_context_token.c
moonshot/mech_eap/pseudo_random.c
moonshot/mech_eap/release_any_name_mapping.c
moonshot/mech_eap/release_cred.c
moonshot/mech_eap/release_name.c
moonshot/mech_eap/set_name_attribute.c
moonshot/mech_eap/set_sec_context_option.c
moonshot/mech_eap/store_cred.c
moonshot/mech_eap/unwrap.c
moonshot/mech_eap/unwrap_iov.c
moonshot/mech_eap/util.h
moonshot/mech_eap/util_context.c
moonshot/mech_eap/util_cred.c
moonshot/mech_eap/util_krb.c
moonshot/mech_eap/util_name.c
moonshot/mech_eap/util_tld.c
moonshot/mech_eap/verify_mic.c
moonshot/mech_eap/wrap.c
moonshot/mech_eap/wrap_iov.c
moonshot/mech_eap/wrap_iov_length.c
moonshot/mech_eap/wrap_size_limit.c

83 files changed:
libradsec
moonshot/acinclude.m4
moonshot/configure.ac
moonshot/mech_eap/Makefile.am
moonshot/mech_eap/TODO
moonshot/mech_eap/accept_sec_context.c
moonshot/mech_eap/acquire_cred.c
moonshot/mech_eap/acquire_cred_with_password.c
moonshot/mech_eap/add_cred.c
moonshot/mech_eap/add_cred_with_password.c
moonshot/mech_eap/authorize_localname.c
moonshot/mech_eap/canonicalize_name.c
moonshot/mech_eap/compare_name.c
moonshot/mech_eap/context_time.c
moonshot/mech_eap/delete_name_attribute.c
moonshot/mech_eap/delete_sec_context.c
moonshot/mech_eap/display_name.c
moonshot/mech_eap/display_name_ext.c
moonshot/mech_eap/display_status.c
moonshot/mech_eap/duplicate_name.c
moonshot/mech_eap/eap_mech.c
moonshot/mech_eap/export_name.c
moonshot/mech_eap/export_name_composite.c
moonshot/mech_eap/export_sec_context.c
moonshot/mech_eap/get_mic.c
moonshot/mech_eap/get_name_attribute.c
moonshot/mech_eap/gssapiP_eap.h
moonshot/mech_eap/gssapi_eap.h
moonshot/mech_eap/gsseap_err.et
moonshot/mech_eap/import_name.c
moonshot/mech_eap/import_sec_context.c
moonshot/mech_eap/indicate_mechs.c
moonshot/mech_eap/init_sec_context.c
moonshot/mech_eap/inquire_attrs_for_mech.c
moonshot/mech_eap/inquire_context.c
moonshot/mech_eap/inquire_cred.c
moonshot/mech_eap/inquire_cred_by_mech.c
moonshot/mech_eap/inquire_cred_by_oid.c
moonshot/mech_eap/inquire_mech_for_saslname.c
moonshot/mech_eap/inquire_mechs_for_name.c
moonshot/mech_eap/inquire_name.c
moonshot/mech_eap/inquire_names_for_mech.c
moonshot/mech_eap/inquire_saslname_for_mech.c
moonshot/mech_eap/inquire_sec_context_by_oid.c
moonshot/mech_eap/map_name_to_any.c
moonshot/mech_eap/mech_eap-noacceptor.exports [new file with mode: 0644]
moonshot/mech_eap/mech_eap.exports
moonshot/mech_eap/mech_invoke.c
moonshot/mech_eap/process_context_token.c
moonshot/mech_eap/pseudo_random.c
moonshot/mech_eap/release_any_name_mapping.c
moonshot/mech_eap/release_cred.c
moonshot/mech_eap/release_name.c
moonshot/mech_eap/release_oid.c
moonshot/mech_eap/set_cred_option.c
moonshot/mech_eap/set_name_attribute.c
moonshot/mech_eap/set_sec_context_option.c
moonshot/mech_eap/store_cred.c
moonshot/mech_eap/unwrap.c
moonshot/mech_eap/unwrap_iov.c
moonshot/mech_eap/util.h
moonshot/mech_eap/util_attr.cpp
moonshot/mech_eap/util_attr.h
moonshot/mech_eap/util_context.c
moonshot/mech_eap/util_cred.c
moonshot/mech_eap/util_crypt.c
moonshot/mech_eap/util_json.cpp
moonshot/mech_eap/util_json.h
moonshot/mech_eap/util_krb.c
moonshot/mech_eap/util_moonshot.c [new file with mode: 0644]
moonshot/mech_eap/util_name.c
moonshot/mech_eap/util_radius.h
moonshot/mech_eap/util_saml.cpp
moonshot/mech_eap/util_shib.cpp
moonshot/mech_eap/util_sm.c
moonshot/mech_eap/util_tld.c
moonshot/mech_eap/util_token.c
moonshot/mech_eap/vasprintf.c [deleted file]
moonshot/mech_eap/verify_mic.c
moonshot/mech_eap/wrap.c
moonshot/mech_eap/wrap_iov.c
moonshot/mech_eap/wrap_iov_length.c
moonshot/mech_eap/wrap_size_limit.c

index b6cbbcf..ade6c4f 160000 (submodule)
--- a/libradsec
+++ b/libradsec
@@ -1 +1 @@
-Subproject commit b6cbbcfa4b40bbbf29cfe62f35e9f672684d37d0
+Subproject commit ade6c4fa17f837504a3902296d4b4f636e28b51e
index 336332a..ea542db 100644 (file)
@@ -1,5 +1,13 @@
 dnl Based on the one from the Boinc project by Reinhard
 
+AC_DEFUN([AX_CHECK_WINDOWS],
+[AC_MSG_CHECKING(for windows)
+target_windows="no"
+AC_CHECK_HEADER(windows.h,[target_windows="yes"],[target_windows="no"])
+AC_MSG_RESULT($target_windows)
+AM_CONDITIONAL(TARGET_WINDOWS,test "x$target_windows" = "xyes")
+])dnl
+
 AC_DEFUN([AX_CHECK_KRB5],
 [AC_MSG_CHECKING(for GSS-API and Kerberos implementation)
 KRB5_DIR=
@@ -9,23 +17,22 @@ AC_ARG_WITH(krb5,
        [Use krb5 (in specified installation directory)]),
     [check_krb5_dir="$withval"],
     [check_krb5_dir=])
-AM_COND_IF(TARGET_WINDOWS,[
-   found_krb5="yes"
-   krb5dir=$check_krb5_dir
-   KRB5_CFLAGS=-I"$check_krb5_dir/include"
-   KRB5_LIBS="-L$check_krb5_dir/lib/ -lkrb5_32 -lgssapi32"
-   COMPILE_ET=
-],
-[for dir in $check_krb5_dir $prefix /usr /usr/local ; do
+for dir in $check_krb5_dir $prefix /usr /usr/local ; do
    krb5dir="$dir"
    if test -x "$dir/bin/krb5-config"; then
      found_krb5="yes";
-     KRB5_CFLAGS=`$dir/bin/krb5-config gssapi --cflags`;
-     KRB5_LIBS=`$dir/bin/krb5-config gssapi --libs`;
-     COMPILE_ET="$dir/bin/compile_et";
+     if test "x$target_windows" = "xyes"; then
+        KRB5_CFLAGS=-I"$check_krb5_dir/include";
+        KRB5_LIBS="-L$check_krb5_dir/lib/ -lkrb5_32 -lgssapi32";
+        COMPILE_ET="$check_krb5_dir/bin/compile_et";
+     else
+        KRB5_CFLAGS=`$dir/bin/krb5-config gssapi --cflags`;
+        KRB5_LIBS=`$dir/bin/krb5-config gssapi --libs`;
+        COMPILE_ET="$dir/bin/compile_et";
+     fi
      break;
    fi
-done])
+done
 AC_MSG_RESULT($found_krb5)
 if test x_$found_krb5 != x_yes; then
    AC_MSG_ERROR([
@@ -136,7 +143,7 @@ AC_MSG_RESULT($found_shibsp)
 if test x_$found_shibsp != x_yes; then
    AC_MSG_ERROR([
 ----------------------------------------------------------------------
-  Cannot find Shibboleth/OpenSAML libraries.
+  Cannot find Shibboleth libraries.
 
   Please install Shibboleth or specify installation directory with
   --with-shibsp=(dir).
@@ -144,11 +151,12 @@ if test x_$found_shibsp != x_yes; then
 ])
 else
        printf "Shibboleth found in $shibspdir\n";
-       SHIBSP_LIBS="-lshibsp  -lsaml -lxml-security-c -lxmltooling -lxerces-c";
+       SHIBSP_LIBS="-lshibsp -lsaml -lxml-security-c -lxmltooling -lxerces-c";
        SHIBSP_LDFLAGS="-L$shibspdir/lib";
        AC_SUBST(SHIBSP_CXXFLAGS)
        AC_SUBST(SHIBSP_LDFLAGS)
        AC_SUBST(SHIBSP_LIBS)
+       AC_DEFINE_UNQUOTED([HAVE_SHIBSP], 1, [Define is Shibboleth SP is available])
 fi
 ])dnl
 
@@ -161,6 +169,7 @@ AC_ARG_WITH(shibresolver,
        [Use Shibboleth resolver (in specified installation directory)]),
     [check_shibresolver_dir="$withval"],
     [check_shibresolver_dir=])
+if test x_$check_shibresolver_dir != x_no; then
 for dir in $check_shibresolver_dir $prefix /usr /usr/local ; do
    shibresolverdir="$dir"
    if test -f "$dir/include/shibresolver/resolver.h"; then
@@ -170,11 +179,14 @@ for dir in $check_shibresolver_dir $prefix /usr /usr/local ; do
      break;
    fi
 done
+fi
 AC_MSG_RESULT($found_shibresolver)
+if test x_$check_shibresolver_dir != x_no; then
 if test x_$found_shibresolver != x_yes; then
-   AC_MSG_ERROR([
+   AC_MSG_WARN([
 ----------------------------------------------------------------------
-  Cannot find Shibboleth resolver libraries.
+  Cannot find Shibboleth resolver libraries, building without
+  Shibboleth support.
 
   Please install Shibboleth or specify installation directory with
   --with-shibresolver=(dir).
@@ -187,17 +199,53 @@ else
        AC_SUBST(SHIBRESOLVER_CXXFLAGS)
        AC_SUBST(SHIBRESOLVER_LDFLAGS)
        AC_SUBST(SHIBRESOLVER_LIBS)
+       AC_DEFINE_UNQUOTED([HAVE_SHIBRESOLVER], 1, [Define is Shibboleth resolver is available])
+fi
 fi
 ])dnl
 
-AC_DEFUN([AX_CHECK_WINDOWS],
-[AC_MSG_CHECKING(for windows)
-target_windows="no"
-AC_CHECK_HEADER(windows.h,[target_windows="yes"],[target_windows="no"])
-AC_MSG_RESULT($target_windows)
-AM_CONDITIONAL(TARGET_WINDOWS,test "x$target_windows" = "xyes")
-])dnl
+AC_DEFUN([AX_CHECK_OPENSAML],
+[AC_MSG_CHECKING(for OpenSAML implementation)
+OPENSAML_DIR=
+found_opensaml="no"
+AC_ARG_WITH(opensaml,
+    AC_HELP_STRING([--with-opensaml],
+       [Use OpenSAML (in specified installation directory)]),
+    [check_opensaml_dir="$withval"],
+    [check_opensaml_dir=])
+if test x_$check_opensaml_dir != x_no; then
+for dir in $check_opensaml_dir $prefix /usr /usr/local ; do
+   opensamldir="$dir"
+   if test -f "$dir/include/saml/Assertion.h"; then
+     found_opensaml="yes";
+     OPENSAML_DIR="${opensamldir}"
+     OPENSAML_CXXFLAGS="-I$opensamldir/include";
+     break;
+   fi
+done
+fi
+AC_MSG_RESULT($found_opensaml)
+if test x_$check_opensaml_dir != x_no; then
+if test x_$found_opensaml != x_yes; then
+   AC_MSG_WARN([
+----------------------------------------------------------------------
+  Cannot find OpenSAML libraries, building without OpenSAML support.
 
+  Please install OpenSAML or specify installation directory with
+  --with-opensaml=(dir).
+----------------------------------------------------------------------
+])
+else
+       printf "OpenSAML found in $opensamldir\n";
+       OPENSAML_LIBS="-lsaml -lxml-security-c -lxmltooling -lxerces-c";
+       OPENSAML_LDFLAGS="-L$opensamldir/lib";
+       AC_SUBST(OPENSAML_CXXFLAGS)
+       AC_SUBST(OPENSAML_LDFLAGS)
+       AC_SUBST(OPENSAML_LIBS)
+       AC_DEFINE_UNQUOTED([HAVE_OPENSAML], 1, [Define is OpenSAML is available])
+fi
+fi
+])dnl
 
 AC_DEFUN([AX_CHECK_RADSEC],
 [AC_MSG_CHECKING(for radsec)
@@ -274,3 +322,43 @@ else
        AC_SUBST(JANSSON_LIBS)
 fi
 ])dnl
+
+AC_DEFUN([AX_CHECK_LIBMOONSHOT],
+[AC_MSG_CHECKING(for Moonshot identity selector implementation)
+LIBMOONSHOT_DIR=
+found_libmoonshot="no"
+AC_ARG_WITH(libmoonshot,
+    AC_HELP_STRING([--with-libmoonshot],
+       [Use libmoonshot (in specified installation directory)]),
+    [check_libmoonshot_dir="$withval"],
+    [check_libmoonshot_dir=])
+for dir in $check_libmoonshot_dir $prefix /usr /usr/local ../../moonshot-ui/libmoonshot ; do
+   libmoonshotdir="$dir"
+   if test -f "$dir/include/libmoonshot.h"; then
+     found_libmoonshot="yes";
+     LIBMOONSHOT_DIR="${libmoonshotdir}"
+     LIBMOONSHOT_CFLAGS="-I$libmoonshotdir/include";
+     break;
+   fi
+done
+AC_MSG_RESULT($found_libmoonshot)
+if test x_$found_libmoonshot != x_yes; then
+   AC_MSG_ERROR([
+----------------------------------------------------------------------
+  Cannot find Moonshot identity selector libraries.
+
+  Please install wpa_supplicant or specify installation directory with
+  --with-libmoonshot=(dir).
+----------------------------------------------------------------------
+])
+else
+       printf "libmoonshot found in $libmoonshotdir\n";
+       LIBMOONSHOT_LIBS="-lmoonshot";
+       LIBMOONSHOT_LDFLAGS="-L$libmoonshot/lib";
+       AC_SUBST(LIBMOONSHOT_CFLAGS)
+       AC_SUBST(LIBMOONSHOT_LDFLAGS)
+       AC_SUBST(LIBMOONSHOT_LIBS)
+       AC_CHECK_LIB(moonshot, moonshot_get_identity, [AC_DEFINE_UNQUOTED([HAVE_MOONSHOT_GET_IDENTITY], 1, [Define if Moonshot identity selector is available])], [], "$LIBMOONSHOT_LIBS")
+fi
+])dnl
+
index 5948d74..3d77b93 100644 (file)
@@ -7,7 +7,7 @@ AC_GNU_SOURCE
 AM_INIT_AUTOMAKE
 AM_PROG_CC_C_O
 AM_MAINTAINER_MODE()
-LT_PREREQ([2.4])
+LT_PREREQ([2.2])
 LT_INIT([dlopen disable-static win32-dll])
 
 dnl AC_PROG_CC
@@ -71,13 +71,20 @@ AC_SUBST(TARGET_CFLAGS)
 AC_SUBST(TARGET_LDFLAGS)
 AX_CHECK_WINDOWS
 AX_CHECK_KRB5
-AM_CONDITIONAL(HEIMDAL, test "x$heimdal" != "xno")
-dnl AX_CHECK_EAP
-if test "x$acceptor" = "xyes" ; then
+AX_CHECK_OPENSAML
+AM_CONDITIONAL(OPENSAML, test "x_$check_opensaml_dir" != "x_no")
+
+AX_CHECK_SHIBRESOLVER
+AM_CONDITIONAL(SHIBRESOLVER, test "x_$check_shibresolver_dir" != "x_no")
+if test x_$found_shibresolver = x_yes; then
   AX_CHECK_SHIBSP
-  AX_CHECK_SHIBRESOLVER
+fi
+
+if test "x$acceptor" = "xyes" ; then
   AX_CHECK_RADSEC
   AX_CHECK_JANSSON
 fi
+
+AX_CHECK_LIBMOONSHOT
 AC_CONFIG_FILES([Makefile libeap/Makefile mech_eap/Makefile])
 AC_OUTPUT
index 4ccdabe..ba6e8dd 100644 (file)
@@ -6,8 +6,15 @@ gssinclude_HEADERS = gssapi_eap.h
 EAP_CFLAGS = -I$(srcdir)/../libeap/src -I$(srcdir)/../libeap/src/common -I$(srcdir)/../libeap/src/eap_common  \
        -I$(srcdir)/../libeap/src/utils
 
+if GSSEAP_ENABLE_ACCEPTOR
+GSSEAP_EXPORTS = mech_eap.exports
+else
+GSSEAP_EXPORTS = mech_eap-noacceptor.exports
+endif
+
 gssdir = $(libdir)/gss
 gss_LTLIBRARIES = mech_eap.la
+
 if TARGET_WINDOWS
 EAP_CFLAGS += -DCONFIG_WIN32_DEFAULTS -DUSE_INTERNAL_CRYPTO
 OS_LIBS = -lshell32 -ladvapi32 -lws2_32 -lcomerr32
@@ -21,16 +28,22 @@ mech_eap_la_CXXFLAGS = -Werror -Wall -Wunused-parameter
 endif
 
 mech_eap_la_CPPFLAGS = -DBUILD_GSSEAP_LIB -DSYSCONFDIR=\"${sysconfdir}\" -DDATAROOTDIR=\"${datarootdir}\"
-mech_eap_la_CFLAGS   += @KRB5_CFLAGS@ @RADSEC_CFLAGS@ @TARGET_CFLAGS@ $(EAP_CFLAGS)
-mech_eap_la_CXXFLAGS += @KRB5_CFLAGS@ @RADSEC_CFLAGS@ @SHIBRESOLVER_CXXFLAGS@ @SHIBSP_CXXFLAGS@ @TARGET_CFLAGS@ $(EAP_CFLAGS)
+mech_eap_la_CFLAGS   = -Werror -Wall -Wunused-parameter \
+                       @KRB5_CFLAGS@  @RADSEC_CFLAGS@ @TARGET_CFLAGS@ $(EAP_CFLAGS)
+mech_eap_la_CXXFLAGS = -Werror -Wall -Wunused-parameter \
+                       @KRB5_CFLAGS@  @RADSEC_CFLAGS@ \
+                       @OPENSAML_CXXFLAGS@ @SHIBRESOLVER_CXXFLAGS@ @SHIBSP_CXXFLAGS@ \
+                       @TARGET_CFLAGS@ $(EAP_CFLAGS)
 mech_eap_la_LDFLAGS  = -avoid-version -module \
-                       -export-symbols $(srcdir)/mech_eap.exports -no-undefined \
+                       -export-symbols $(GSSEAP_EXPORTS) -no-undefined \
                        @RADSEC_LDFLAGS@ @TARGET_LDFLAGS@
-mech_eap_la_LIBADD   = @KRB5_LIBS@ ../libeap/libeap.la @RADSEC_LIBS@ \
-                      @SHIBRESOLVER_LIBS@ @SHIBSP_LIBS@ @JANSSON_LIBS@ $(OS_LIBS) $(LTLIBOBJS)
+if TARGET_WINDOWS
+mech_eap_la_LDFLAGS += -debug
+endif
 
+mech_eap_la_LIBADD   = @KRB5_LIBS@ ../libeap/libeap.la @RADSEC_LIBS@ \
+                      @OPENSAML_LIBS@ @SHIBRESOLVER_LIBS@ @SHIBSP_LIBS@ @JANSSON_LIBS@
 mech_eap_la_SOURCES =                          \
-       accept_sec_context.c                    \
        acquire_cred.c                          \
        acquire_cred_with_password.c            \
        add_cred.c                              \
@@ -39,7 +52,6 @@ mech_eap_la_SOURCES =                         \
        canonicalize_name.c                     \
        compare_name.c                          \
        context_time.c                          \
-       delete_name_attribute.c                 \
        delete_sec_context.c                    \
        display_name.c                          \
        display_name_ext.c                      \
@@ -47,10 +59,8 @@ mech_eap_la_SOURCES =                        \
        duplicate_name.c                        \
        eap_mech.c                              \
        export_name.c                           \
-       export_name_composite.c                 \
        export_sec_context.c                    \
        get_mic.c                               \
-       get_name_attribute.c                    \
        gsseap_err.c                            \
        import_name.c                           \
        import_sec_context.c                    \
@@ -67,21 +77,17 @@ mech_eap_la_SOURCES =                       \
        inquire_names_for_mech.c                \
        inquire_saslname_for_mech.c             \
        inquire_sec_context_by_oid.c            \
-       map_name_to_any.c                       \
        process_context_token.c                 \
        pseudo_random.c                         \
        radsec_err.c                            \
-       release_any_name_mapping.c              \
        release_cred.c                          \
        release_name.c                          \
        release_oid.c                           \
-       set_name_attribute.c                    \
        set_cred_option.c                       \
        set_sec_context_option.c                \
        store_cred.c                            \
        unwrap.c                                \
        unwrap_iov.c                            \
-       util_base64.c                           \
        util_buffer.c                           \
        util_context.c                          \
        util_cksum.c                            \
@@ -90,6 +96,7 @@ mech_eap_la_SOURCES =                         \
        util_krb.c                              \
        util_lucid.c                            \
        util_mech.c                             \
+       util_moonshot.c                         \
        util_name.c                             \
        util_oid.c                              \
        util_ordering.c                         \
@@ -102,12 +109,33 @@ mech_eap_la_SOURCES =                     \
        wrap_iov_length.c                       \
        wrap_size_limit.c
 
-BUILT_SOURCES = gsseap_err.c radsec_err.c
-
 if GSSEAP_ENABLE_ACCEPTOR
-mech_eap_la_SOURCES += util_attr.cpp util_json.cpp util_radius.cpp util_shib.cpp util_saml.cpp
+
+mech_eap_la_SOURCES +=                         \
+       accept_sec_context.c                    \
+       delete_name_attribute.c                 \
+       export_name_composite.c                 \
+       get_name_attribute.c                    \
+       map_name_to_any.c                       \
+       release_any_name_mapping.c              \
+       set_name_attribute.c                    \
+       util_attr.cpp                           \
+       util_base64.c                           \
+       util_json.cpp                           \
+       util_radius.cpp
+
+if OPENSAML
+mech_eap_la_SOURCES += util_saml.cpp
 endif
 
+if SHIBRESOLVER
+mech_eap_la_SOURCES += util_shib.cpp
+endif
+
+endif
+
+BUILT_SOURCES = gsseap_err.c radsec_err.c
+
 if GSSEAP_ENABLE_REAUTH
 mech_eap_la_SOURCES += util_reauth.c
 
@@ -124,9 +152,6 @@ radius_ad_la_SOURCES = util_adshim.c
 endif
 endif
 
-if TARGET_WINDOWS
-mech_eap_la_LDFLAGS += -debug
-else
 gsseap_err.h gsseap_err.c: gsseap_err.et
        $(COMPILE_ET) $<
 
@@ -137,4 +162,3 @@ radsec_err.c: radsec_err.h
 
 clean-generic:
        rm -f gsseap_err.[ch] radsec_err.[ch]
-endif
index 0e4d9fd..567deed 100644 (file)
@@ -1,12 +1,5 @@
 - integration with initiator-side EAP channel bindings
-- integration with final supplicant architecture
-- test Heimdal port
-
-- fix ABNF: no slash in the case where there is no host
 - always intern OIDs so they never need to be freed
-
-- handle many-to-many Shibboleth attribute mappings; need to encode
-  both attribute and value index into more
+- handle many-to-many Shibboleth attribute mappings; need to encode both attribute and value index into more
 - add --with-xerces option
-- proper acquire_cred_ext implementation
-- MIC on flags token (merge ext-mic branch)
+- proper acquire_cred_ext implementation pending specification
index 7d3dfed..d010e34 100644 (file)
@@ -36,7 +36,7 @@
  */
 
 #include "gssapiP_eap.h"
-#ifdef GSSEAP_ENABLE_ACCEPTOR
+
 #ifdef GSSEAP_ENABLE_REAUTH
 static OM_uint32
 eapGssSmAcceptGssReauth(OM_uint32 *minor,
@@ -431,10 +431,10 @@ createRadiusHandle(OM_uint32 *minor,
         return GSS_S_FAILURE;
     }
 
-    if (cred->radiusConfigFile != NULL)
-        configFile = cred->radiusConfigFile;
-    if (cred->radiusConfigStanza != NULL)
-        configStanza = cred->radiusConfigStanza;
+    if (cred->radiusConfigFile.value != NULL)
+        configFile = (const char *)cred->radiusConfigFile.value;
+    if (cred->radiusConfigStanza.value != NULL)
+        configStanza = (const char *)cred->radiusConfigStanza.value;
 
     ralloc.calloc  = GSSEAP_CALLOC;
     ralloc.malloc  = GSSEAP_MALLOC;
@@ -616,6 +616,40 @@ cleanup:
 }
 
 static OM_uint32
+eapGssSmAcceptGssFlags(OM_uint32 *minor,
+                       gss_cred_id_t cred GSSEAP_UNUSED,
+                       gss_ctx_id_t ctx,
+                       gss_name_t target GSSEAP_UNUSED,
+                       gss_OID mech GSSEAP_UNUSED,
+                       OM_uint32 reqFlags GSSEAP_UNUSED,
+                       OM_uint32 timeReq GSSEAP_UNUSED,
+                       gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
+                       gss_buffer_t inputToken,
+                       gss_buffer_t outputToken GSSEAP_UNUSED,
+                       OM_uint32 *smFlags GSSEAP_UNUSED)
+{
+    unsigned char *p;
+    OM_uint32 initiatorGssFlags;
+
+    assert((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0);
+
+    if (inputToken->length < 4) {
+        *minor = GSSEAP_TOK_TRUNC;
+        return GSS_S_DEFECTIVE_TOKEN;
+    }
+
+    /* allow flags to grow for future expansion */
+    p = (unsigned char *)inputToken->value + inputToken->length - 4;
+
+    initiatorGssFlags = load_uint32_be(p);
+    initiatorGssFlags &= GSSEAP_WIRE_FLAGS_MASK;
+
+    ctx->gssFlags |= initiatorGssFlags;
+
+    return GSS_S_CONTINUE_NEEDED;
+}
+
+static OM_uint32
 eapGssSmAcceptGssChannelBindings(OM_uint32 *minor,
                                  gss_cred_id_t cred GSSEAP_UNUSED,
                                  gss_ctx_id_t ctx,
@@ -628,20 +662,26 @@ eapGssSmAcceptGssChannelBindings(OM_uint32 *minor,
                                  gss_buffer_t outputToken GSSEAP_UNUSED,
                                  OM_uint32 *smFlags GSSEAP_UNUSED)
 {
-    OM_uint32 major, tmpMinor;
+    OM_uint32 major;
     gss_iov_buffer_desc iov[2];
 
     iov[0].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
     iov[0].buffer.length = 0;
     iov[0].buffer.value = NULL;
 
-    iov[1].type = GSS_IOV_BUFFER_TYPE_STREAM;
-    iov[1].buffer = *inputToken;
+    iov[1].type = GSS_IOV_BUFFER_TYPE_STREAM | GSS_IOV_BUFFER_FLAG_ALLOCATED;
+
+    /* XXX necessary because decrypted in place and we verify it later */
+    major = duplicateBuffer(minor, inputToken, &iov[1].buffer);
+    if (GSS_ERROR(major))
+        return major;
 
     major = gssEapUnwrapOrVerifyMIC(minor, ctx, NULL, NULL,
                                     iov, 2, TOK_TYPE_WRAP);
-    if (GSS_ERROR(major))
+    if (GSS_ERROR(major)) {
+        gssEapReleaseIov(iov, 2);
         return major;
+    }
 
     if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS &&
         !bufferEqual(&iov[0].buffer, &chanBindings->application_data)) {
@@ -652,11 +692,36 @@ eapGssSmAcceptGssChannelBindings(OM_uint32 *minor,
         *minor = 0;
     }
 
-    gss_release_buffer(&tmpMinor, &iov[0].buffer);
+    gssEapReleaseIov(iov, 2);
 
     return major;
 }
 
+static OM_uint32
+eapGssSmAcceptInitiatorMIC(OM_uint32 *minor,
+                           gss_cred_id_t cred GSSEAP_UNUSED,
+                           gss_ctx_id_t ctx,
+                           gss_name_t target GSSEAP_UNUSED,
+                           gss_OID mech GSSEAP_UNUSED,
+                           OM_uint32 reqFlags GSSEAP_UNUSED,
+                           OM_uint32 timeReq GSSEAP_UNUSED,
+                           gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
+                           gss_buffer_t inputToken,
+                           gss_buffer_t outputToken GSSEAP_UNUSED,
+                           OM_uint32 *smFlags GSSEAP_UNUSED)
+{
+    OM_uint32 major;
+
+    major = gssEapVerifyTokenMIC(minor, ctx, inputToken);
+    if (GSS_ERROR(major))
+        return major;
+
+    GSSEAP_SM_TRANSITION_NEXT(ctx);
+
+    *minor = 0;
+    return GSS_S_CONTINUE_NEEDED;
+}
+
 #ifdef GSSEAP_ENABLE_REAUTH
 static OM_uint32
 eapGssSmAcceptReauthCreds(OM_uint32 *minor,
@@ -688,42 +753,28 @@ eapGssSmAcceptReauthCreds(OM_uint32 *minor,
 #endif
 
 static OM_uint32
-eapGssSmAcceptCompleteInitiatorExts(OM_uint32 *minor,
-                                    gss_cred_id_t cred GSSEAP_UNUSED,
-                                    gss_ctx_id_t ctx,
-                                    gss_name_t target GSSEAP_UNUSED,
-                                    gss_OID mech GSSEAP_UNUSED,
-                                    OM_uint32 reqFlags GSSEAP_UNUSED,
-                                    OM_uint32 timeReq GSSEAP_UNUSED,
-                                    gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
-                                    gss_buffer_t inputToken GSSEAP_UNUSED,
-                                    gss_buffer_t outputToken GSSEAP_UNUSED,
-                                    OM_uint32 *smFlags GSSEAP_UNUSED)
+eapGssSmAcceptAcceptorMIC(OM_uint32 *minor,
+                          gss_cred_id_t cred GSSEAP_UNUSED,
+                          gss_ctx_id_t ctx,
+                          gss_name_t target GSSEAP_UNUSED,
+                          gss_OID mech GSSEAP_UNUSED,
+                          OM_uint32 reqFlags GSSEAP_UNUSED,
+                          OM_uint32 timeReq GSSEAP_UNUSED,
+                          gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
+                          gss_buffer_t inputToken GSSEAP_UNUSED,
+                          gss_buffer_t outputToken,
+                          OM_uint32 *smFlags)
 {
-    GSSEAP_SM_TRANSITION_NEXT(ctx);
-
-    *minor = 0;
+    OM_uint32 major;
 
-    return GSS_S_CONTINUE_NEEDED;
-}
+    major = gssEapMakeTokenMIC(minor, ctx, outputToken);
+    if (GSS_ERROR(major))
+        return major;
 
-static OM_uint32
-eapGssSmAcceptCompleteAcceptorExts(OM_uint32 *minor,
-                                   gss_cred_id_t cred GSSEAP_UNUSED,
-                                   gss_ctx_id_t ctx,
-                                   gss_name_t target GSSEAP_UNUSED,
-                                   gss_OID mech GSSEAP_UNUSED,
-                                   OM_uint32 reqFlags GSSEAP_UNUSED,
-                                   OM_uint32 timeReq GSSEAP_UNUSED,
-                                   gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
-                                   gss_buffer_t inputToken GSSEAP_UNUSED,
-                                   gss_buffer_t outputToken GSSEAP_UNUSED,
-                                   OM_uint32 *smFlags)
-{
     GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED);
 
     *minor = 0;
-    *smFlags |= SM_FLAG_FORCE_SEND_TOKEN;
+    *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL;
 
     return GSS_S_COMPLETE;
 }
@@ -769,6 +820,13 @@ static struct gss_eap_sm eapGssAcceptorSm[] = {
         eapGssSmAcceptAuthenticate
     },
     {
+        ITOK_TYPE_GSS_FLAGS,
+        ITOK_TYPE_NONE,
+        GSSEAP_STATE_INITIATOR_EXTS,
+        0,
+        eapGssSmAcceptGssFlags
+    },
+    {
         ITOK_TYPE_GSS_CHANNEL_BINDINGS,
         ITOK_TYPE_NONE,
         GSSEAP_STATE_INITIATOR_EXTS,
@@ -776,11 +834,11 @@ static struct gss_eap_sm eapGssAcceptorSm[] = {
         eapGssSmAcceptGssChannelBindings,
     },
     {
-        ITOK_TYPE_NONE,
+        ITOK_TYPE_INITIATOR_MIC,
         ITOK_TYPE_NONE,
         GSSEAP_STATE_INITIATOR_EXTS,
-        0,
-        eapGssSmAcceptCompleteInitiatorExts,
+        SM_ITOK_FLAG_REQUIRED,
+        eapGssSmAcceptInitiatorMIC,
     },
 #ifdef GSSEAP_ENABLE_REAUTH
     {
@@ -793,85 +851,54 @@ static struct gss_eap_sm eapGssAcceptorSm[] = {
 #endif
     {
         ITOK_TYPE_NONE,
-        ITOK_TYPE_NONE,
+        ITOK_TYPE_ACCEPTOR_MIC,
         GSSEAP_STATE_ACCEPTOR_EXTS,
         0,
-        eapGssSmAcceptCompleteAcceptorExts
+        eapGssSmAcceptAcceptorMIC
     },
 };
-#endif /* GSSEAP_ENABLE_ACCEPTOR */
 
-#ifdef GSSEAP_ENABLE_ACCEPTOR
-#define ACCEPTOR_PARAM(p) p
-#else
-#define ACCEPTOR_PARAM(p) UNUSED_PARAM(p)
-#endif
-
-OM_uint32 KRB5_CALLCONV
-gss_accept_sec_context(OM_uint32 *ACCEPTOR_PARAM(minor),
-                       gss_ctx_id_t *ACCEPTOR_PARAM(context_handle),
-                       gss_cred_id_t ACCEPTOR_PARAM(cred),
-                       gss_buffer_t ACCEPTOR_PARAM(input_token),
-                       gss_channel_bindings_t ACCEPTOR_PARAM(input_chan_bindings),
-                       gss_name_t *ACCEPTOR_PARAM(src_name),
-                       gss_OID *ACCEPTOR_PARAM(mech_type),
-                       gss_buffer_t ACCEPTOR_PARAM(output_token),
-                       OM_uint32 *ACCEPTOR_PARAM(ret_flags),
-                       OM_uint32 *ACCEPTOR_PARAM(time_rec),
-                       gss_cred_id_t *ACCEPTOR_PARAM(delegated_cred_handle))
+OM_uint32
+gssEapAcceptSecContext(OM_uint32 *minor,
+                       gss_ctx_id_t ctx,
+                       gss_cred_id_t cred,
+                       gss_buffer_t input_token,
+                       gss_channel_bindings_t input_chan_bindings,
+                       gss_name_t *src_name,
+                       gss_OID *mech_type,
+                       gss_buffer_t output_token,
+                       OM_uint32 *ret_flags,
+                       OM_uint32 *time_rec,
+                       gss_cred_id_t *delegated_cred_handle)
 {
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     OM_uint32 major, tmpMinor;
-    gss_ctx_id_t ctx = *context_handle;
-
-    *minor = 0;
-
-    output_token->length = 0;
-    output_token->value = NULL;
-
-    if (src_name != NULL)
-        *src_name = GSS_C_NO_NAME;
-
-    if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
-        *minor = GSSEAP_TOK_TRUNC;
-        return GSS_S_DEFECTIVE_TOKEN;
-    }
 
-    if (ctx == GSS_C_NO_CONTEXT) {
-        major = gssEapAllocContext(minor, &ctx);
-        if (GSS_ERROR(major))
-            return major;
-
-        *context_handle = ctx;
-    }
-
-    GSSEAP_MUTEX_LOCK(&ctx->mutex);
-       
     if (cred == GSS_C_NO_CREDENTIAL) {
-        if (ctx->defaultCred == GSS_C_NO_CREDENTIAL) {
+        if (ctx->cred == GSS_C_NO_CREDENTIAL) {
             major = gssEapAcquireCred(minor,
                                       GSS_C_NO_NAME,
-                                      GSS_C_NO_BUFFER,
                                       GSS_C_INDEFINITE,
                                       GSS_C_NO_OID_SET,
                                       GSS_C_ACCEPT,
-                                      &ctx->defaultCred,
+                                      &ctx->cred,
                                       NULL,
                                       NULL);
             if (GSS_ERROR(major))
                 goto cleanup;
         }
 
-        cred = ctx->defaultCred;
+        cred = ctx->cred;
     }
 
     GSSEAP_MUTEX_LOCK(&cred->mutex);
 
-    if (cred->name != GSS_C_NO_NAME) {
-        major = gssEapDuplicateName(minor, cred->name, &ctx->acceptorName);
-        if (GSS_ERROR(major))
-            goto cleanup;
-    }
+    /*
+     * Calling gssEapInquireCred() forces the default acceptor credential name
+     * to be resolved.
+     */
+    major = gssEapInquireCred(minor, cred, &ctx->acceptorName, NULL, NULL, NULL);
+    if (GSS_ERROR(major))
+        goto cleanup;
 
     major = gssEapSmStep(minor,
                          cred,
@@ -921,18 +948,10 @@ gss_accept_sec_context(OM_uint32 *ACCEPTOR_PARAM(minor),
 cleanup:
     if (cred != GSS_C_NO_CREDENTIAL)
         GSSEAP_MUTEX_UNLOCK(&cred->mutex);
-    GSSEAP_MUTEX_UNLOCK(&ctx->mutex);
-
-    if (GSS_ERROR(major))
-        gssEapReleaseContext(&tmpMinor, context_handle);
 
     return major;
-#else
-       return GSS_S_UNAVAILABLE;
-#endif /* GSSEAP_ENABLE_ACCEPTOR */
 }
 
-#ifdef GSSEAP_ENABLE_ACCEPTOR
 #ifdef GSSEAP_ENABLE_REAUTH
 static OM_uint32
 acceptReadyKrb(OM_uint32 *minor,
@@ -1014,4 +1033,62 @@ eapGssSmAcceptGssReauth(OM_uint32 *minor,
     return major;
 }
 #endif /* GSSEAP_ENABLE_REAUTH */
-#endif /* GSSEAP_ENABLE_ACCEPTOR */
\ No newline at end of file
+
+OM_uint32 GSSAPI_CALLCONV
+gss_accept_sec_context(OM_uint32 *minor,
+                       gss_ctx_id_t *context_handle,
+                       gss_cred_id_t cred,
+                       gss_buffer_t input_token,
+                       gss_channel_bindings_t input_chan_bindings,
+                       gss_name_t *src_name,
+                       gss_OID *mech_type,
+                       gss_buffer_t output_token,
+                       OM_uint32 *ret_flags,
+                       OM_uint32 *time_rec,
+                       gss_cred_id_t *delegated_cred_handle)
+{
+    OM_uint32 major, tmpMinor;
+    gss_ctx_id_t ctx = *context_handle;
+
+    *minor = 0;
+
+    output_token->length = 0;
+    output_token->value = NULL;
+
+    if (src_name != NULL)
+        *src_name = GSS_C_NO_NAME;
+
+    if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
+        *minor = GSSEAP_TOK_TRUNC;
+        return GSS_S_DEFECTIVE_TOKEN;
+    }
+
+    if (ctx == GSS_C_NO_CONTEXT) {
+        major = gssEapAllocContext(minor, &ctx);
+        if (GSS_ERROR(major))
+            return major;
+
+        *context_handle = ctx;
+    }
+
+    GSSEAP_MUTEX_LOCK(&ctx->mutex);
+
+    major = gssEapAcceptSecContext(minor,
+                                   ctx,
+                                   cred,
+                                   input_token,
+                                   input_chan_bindings,
+                                   src_name,
+                                   mech_type,
+                                   output_token,
+                                   ret_flags,
+                                   time_rec,
+                                   delegated_cred_handle);
+
+    GSSEAP_MUTEX_UNLOCK(&ctx->mutex);
+
+    if (GSS_ERROR(major))
+        gssEapReleaseContext(&tmpMinor, context_handle);
+
+    return major;
+}
index 5ae30f9..ae2648e 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_acquire_cred(OM_uint32 *minor,
                  gss_name_t desired_name,
                  OM_uint32 time_req,
@@ -46,7 +46,7 @@ gss_acquire_cred(OM_uint32 *minor,
                  gss_OID_set *actual_mechs,
                  OM_uint32 *time_rec)
 {
-    return gssEapAcquireCred(minor, desired_name, GSS_C_NO_BUFFER,
+    return gssEapAcquireCred(minor, desired_name,
                              time_req, desired_mechs, cred_usage,
                              output_cred_handle, actual_mechs, time_rec);
 }
index c0f4159..8e08358 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
 gssspi_acquire_cred_with_password(OM_uint32 *minor,
                                   const gss_name_t desired_name,
                                   const gss_buffer_t password,
@@ -47,7 +47,21 @@ gssspi_acquire_cred_with_password(OM_uint32 *minor,
                                   gss_OID_set *actual_mechs,
                                   OM_uint32 *time_rec)
 {
-    return gssEapAcquireCred(minor, desired_name, password,
-                             time_req, desired_mechs, cred_usage,
-                             output_cred_handle, actual_mechs, time_rec);
+    OM_uint32 major, tmpMinor;
+
+    major = gssEapAcquireCred(minor, desired_name,
+                              time_req, desired_mechs, cred_usage,
+                              output_cred_handle, actual_mechs, time_rec);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    major = gssEapSetCredPassword(minor, *output_cred_handle, password);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+cleanup:
+    if (GSS_ERROR(major))
+        gssEapReleaseCred(&tmpMinor, output_cred_handle);
+
+    return major;
 }
index 81c74b2..64d97c0 100644 (file)
@@ -41,7 +41,7 @@
  * apart from the mechanism glue layer. However, Heimdal does call into the
  * mechanism here.
  */
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_add_cred(OM_uint32 *minor,
              gss_cred_id_t input_cred_handle GSSEAP_UNUSED,
              gss_name_t desired_name,
@@ -71,7 +71,6 @@ gss_add_cred(OM_uint32 *minor,
 
     major = gssEapAcquireCred(minor,
                               desired_name,
-                              GSS_C_NO_BUFFER,
                               time_req,
                               &mechs,
                               cred_usage,
index 7b7ac1c..b982f0d 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_add_cred_with_password(OM_uint32 *minor,
                            const gss_cred_id_t input_cred_handle GSSEAP_UNUSED,
                            const gss_name_t desired_name,
@@ -50,7 +50,7 @@ gss_add_cred_with_password(OM_uint32 *minor,
                            OM_uint32 *initiator_time_rec,
                            OM_uint32 *acceptor_time_rec)
 {
-    OM_uint32 major;
+    OM_uint32 major, tmpMinor;
     OM_uint32 time_req, time_rec = 0;
     gss_OID_set_desc mechs;
 
@@ -67,18 +67,27 @@ gss_add_cred_with_password(OM_uint32 *minor,
 
     major = gssEapAcquireCred(minor,
                               desired_name,
-                              password,
                               time_req,
                               &mechs,
                               cred_usage,
                               output_cred_handle,
                               actual_mechs,
                               &time_rec);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    major = gssEapSetCredPassword(minor, *output_cred_handle, password);
+    if (GSS_ERROR(major))
+        goto cleanup;
 
     if (initiator_time_rec != NULL)
         *initiator_time_rec = time_rec;
     if (acceptor_time_rec != NULL)
         *acceptor_time_rec = time_rec;
 
+cleanup:
+    if (GSS_ERROR(major))
+        gssEapReleaseCred(&tmpMinor, output_cred_handle);
+
     return major;
 }
index ef5788e..0037e2b 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
 gssspi_authorize_localname(OM_uint32 *minor,
                            const gss_name_t name GSSEAP_UNUSED,
                            gss_const_buffer_t local_user GSSEAP_UNUSED,
index a84dafb..5e66798 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_canonicalize_name(OM_uint32 *minor,
                       const gss_name_t input_name,
                       const gss_OID mech_type,
index 7e0e499..edadf3e 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_compare_name(OM_uint32 *minor,
                  gss_name_t name1,
                  gss_name_t name2,
index c6d75a1..ae47d6c 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_context_time(OM_uint32 *minor,
                  gss_ctx_id_t ctx,
                  OM_uint32 *time_rec)
index 2d91283..fe0ff8f 100644 (file)
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_delete_name_attribute(OM_uint32 *minor,
                           gss_name_t name,
                           gss_buffer_t attr)
 {
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     OM_uint32 major;
 
     *minor = 0;
@@ -58,7 +57,4 @@ gss_delete_name_attribute(OM_uint32 *minor,
     GSSEAP_MUTEX_UNLOCK(&name->mutex);
 
     return major;
-#else
-       return GSS_S_UNAVAILABLE;
-#endif
 }
index 9619ead..7913e45 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_delete_sec_context(OM_uint32 *minor,
                        gss_ctx_id_t *context_handle,
                        gss_buffer_t output_token)
index b0cb4ba..2d87e66 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_display_name(OM_uint32 *minor,
                  gss_name_t name,
                  gss_buffer_t output_name_buffer,
index ec9efbe..d6791d4 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_display_name_ext(OM_uint32 *minor,
                      gss_name_t name GSSEAP_UNUSED,
                      gss_OID display_as_name_type GSSEAP_UNUSED,
index 89d8628..6eac550 100644 (file)
@@ -43,7 +43,7 @@ struct gss_eap_status_info {
 };
 
 void
-gssEapDestroyStatusInfo(struct gss_eap_status_infop)
+gssEapDestroyStatusInfo(struct gss_eap_status_info *p)
 {
     struct gss_eap_status_info *next;
 
@@ -65,10 +65,10 @@ static void
 saveStatusInfoNoCopy(OM_uint32 minor, char *message)
 {
     struct gss_eap_status_info **next = NULL, *p=NULL;
+    struct gss_eap_thread_local_data *tld = gssEapGetThreadLocalData();
 
-    struct gss_eap_thread_local_data* tld = gssEapGetThreadLocalData();
     if (tld != NULL) {
-        for (p = tld->status_info; p != NULL; p = p->next) {
+        for (p = tld->statusInfo; p != NULL; p = p->next) {
             if (p->code == minor) {
                 /* Set message in-place */
                 if (p->message != NULL)
@@ -78,9 +78,9 @@ saveStatusInfoNoCopy(OM_uint32 minor, char *message)
             }
             next = &p->next;
         }
-
         p = GSSEAP_CALLOC(1, sizeof(*p));
     }
+
     if (p == NULL) {
         if (message != NULL)
             GSSEAP_FREE(message);
@@ -93,18 +93,17 @@ saveStatusInfoNoCopy(OM_uint32 minor, char *message)
     if (next != NULL)
         *next = p;
     else
-        tld->status_info = p;
+        tld->statusInfo = p;
 }
 
 static const char *
 getStatusInfo(OM_uint32 minor)
 {
     struct gss_eap_status_info *p;
-    struct gss_eap_thread_local_data *tld=gssEapGetThreadLocalData();
+    struct gss_eap_thread_local_data *tld = gssEapGetThreadLocalData();
+
     if (tld != NULL) {
-        for (p = tld->status_info;
-             p != NULL;
-             p = p->next) {
+        for (p = tld->statusInfo; p != NULL; p = p->next) {
             if (p->code == minor)
                 return p->message;
         }
@@ -115,6 +114,22 @@ getStatusInfo(OM_uint32 minor)
 void
 gssEapSaveStatusInfo(OM_uint32 minor, const char *format, ...)
 {
+#ifdef WIN32
+    OM_uint32 tmpMajor, tmpMinor;
+    char buf[BUFSIZ];
+    gss_buffer_desc s = GSS_C_EMPTY_BUFFER;
+    va_list ap;
+
+    if (format != NULL) {
+        va_start(ap, format);
+        snprintf(buf, sizeof(buf), format, ap);
+        va_end(ap);
+    }
+
+    tmpMajor = makeStringBuffer(&tmpMinor, buf, &s);
+    if (!GSS_ERROR(tmpMajor))
+        saveStatusInfoNoCopy(minor, (char *)s.value);
+#else
     char *s = NULL;
     int n;
     va_list ap;
@@ -122,19 +137,19 @@ gssEapSaveStatusInfo(OM_uint32 minor, const char *format, ...)
     if (format != NULL) {
         va_start(ap, format);
         n = vasprintf(&s, format, ap);
+        if (n == -1)
+            s = NULL;
         va_end(ap);
     }
 
     saveStatusInfoNoCopy(minor, s);
+#endif /* WIN32 */
 }
 
-OM_uint32 KRB5_CALLCONV
-gss_display_status(OM_uint32 *minor,
-                   OM_uint32 status_value,
-                   int status_type,
-                   gss_OID mech_type,
-                   OM_uint32 *message_context,
-                   gss_buffer_t status_string)
+OM_uint32
+gssEapDisplayStatus(OM_uint32 *minor,
+                    OM_uint32 status_value,
+                    gss_buffer_t status_string)
 {
     OM_uint32 major;
     krb5_context krbContext = NULL;
@@ -143,18 +158,6 @@ gss_display_status(OM_uint32 *minor,
     status_string->length = 0;
     status_string->value = NULL;
 
-    if (!gssEapIsMechanismOid(mech_type)) {
-        *minor = GSSEAP_WRONG_MECH;
-        return GSS_S_BAD_MECH;
-    }
-
-    if (status_type != GSS_C_MECH_CODE ||
-        *message_context != 0) {
-        /* we rely on the mechglue for GSS_C_GSS_CODE */
-        *minor = 0;
-        return GSS_S_BAD_STATUS;
-    }
-
     errMsg = getStatusInfo(status_value);
     if (errMsg == NULL) {
         GSSEAP_KRB_INIT(&krbContext);
@@ -175,3 +178,26 @@ gss_display_status(OM_uint32 *minor,
 
     return major;
 }
+
+OM_uint32 GSSAPI_CALLCONV
+gss_display_status(OM_uint32 *minor,
+                   OM_uint32 status_value,
+                   int status_type,
+                   gss_OID mech_type,
+                   OM_uint32 *message_context,
+                   gss_buffer_t status_string)
+{
+    if (!gssEapIsMechanismOid(mech_type)) {
+        *minor = GSSEAP_WRONG_MECH;
+        return GSS_S_BAD_MECH;
+    }
+
+    if (status_type != GSS_C_MECH_CODE ||
+        *message_context != 0) {
+        /* we rely on the mechglue for GSS_C_GSS_CODE */
+        *minor = 0;
+        return GSS_S_BAD_STATUS;
+    }
+
+    return gssEapDisplayStatus(minor, status_value, status_string);
+}
index 1d65c16..303619e 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_duplicate_name(OM_uint32 *minor,
                    const gss_name_t input_name,
                    gss_name_t *dest_name)
index 995a8ee..0b64df9 100644 (file)
@@ -165,10 +165,10 @@ gssEapInitLibRadsec(OM_uint32 *minor)
     return GSS_S_COMPLETE;
 }
 
-static void gssEapInitiatorInit(void) GSSEAP_CONSTRUCTOR;
-static void gssEapFinalize(void) GSSEAP_DESTRUCTOR;
+void gssEapInitiatorInit(void) GSSEAP_CONSTRUCTOR;
+void gssEapFinalize(void) GSSEAP_DESTRUCTOR;
 
-static void
+void
 gssEapInitiatorInit(void)
 {
     OM_uint32 major, minor;
@@ -188,11 +188,13 @@ gssEapInitiatorInit(void)
 #endif
 }
 
-static void
+void
 gssEapFinalize(void)
 {
+#ifdef GSSEAP_ENABLE_ACCEPTOR
     OM_uint32 minor;
 
     gssEapAttrProvidersFinalize(&minor);
+#endif
     eap_peer_unregister_methods();
 }
index 086bfca..d91033f 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_export_name(OM_uint32 *minor,
                 const gss_name_t input_name,
                 gss_buffer_t exported_name)
index 7b70e35..b2a90ae 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_export_name_composite(OM_uint32 *minor,
                           gss_name_t input_name,
                           gss_buffer_t exported_name)
index 98003d5..50f90f7 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include "gssapiP_eap.h"
+
 #ifdef GSSEAP_ENABLE_ACCEPTOR
 static OM_uint32
 gssEapExportPartialContext(OM_uint32 *minor,
@@ -135,6 +136,7 @@ gssEapExportSecContext(OM_uint32 *minor,
         if (GSS_ERROR(major))
             goto cleanup;
     }
+
 #ifdef GSSEAP_ENABLE_ACCEPTOR
     /*
      * The partial context is only transmitted for unestablished acceptor
@@ -208,7 +210,7 @@ cleanup:
     return major;
 }
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_export_sec_context(OM_uint32 *minor,
                        gss_ctx_id_t *context_handle,
                        gss_buffer_t interprocess_token)
index 1ac8d93..7161e9c 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_get_mic(OM_uint32 *minor,
             gss_ctx_id_t ctx,
             gss_qop_t qop_req,
index a77577b..a885823 100644 (file)
@@ -36,7 +36,7 @@
  * Wrapper for retrieving a naming attribute.
  */
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_get_name_attribute(OM_uint32 *minor,
                        gss_name_t name,
                        gss_buffer_t attr,
@@ -46,7 +46,6 @@ gss_get_name_attribute(OM_uint32 *minor,
                        gss_buffer_t display_value,
                        int *more)
 {
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     OM_uint32 major;
 
     *minor = 0;
@@ -65,7 +64,4 @@ gss_get_name_attribute(OM_uint32 *minor,
     GSSEAP_MUTEX_UNLOCK(&name->mutex);
 
     return major;
-#else
-       return GSS_S_UNAVAILABLE;
-#endif
 }
index a2ce5d6..cd5315d 100644 (file)
 #include <assert.h>
 #include <string.h>
 #include <errno.h>
-#if defined(HAVE_UNISTD_H)
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
+#endif
+#ifdef HAVE_STDARG_H
 #include <stdarg.h>
+#endif
 #include <time.h>
-#if defined(HAVE_SYS_PARAM_H)
+#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
 
+#ifdef WIN32
+#ifndef MAXHOSTNAMELEN
+# include <WinSock2.h>
+# define MAXHOSTNAMELEN NI_MAXHOST
+#endif
+#endif
+
 /* GSS headers */
 #include <gssapi/gssapi.h>
 #include <gssapi/gssapi_krb5.h>
@@ -87,19 +98,16 @@ extern "C" {
 #include <freeradius/libradius.h>
 #include <freeradius/radius.h>
 
-////Because freeradius/autoconf.h is evil!
-////#undef uint16_t
-////#undef uint32_t
-////#undef uint8_t
 #undef pid_t
 
+/* libradsec headers */
 #include <radsec/radsec.h>
 #include <radsec/request.h>
 #ifdef __cplusplus
 #undef operator
 }
 #endif
-#endif /*GSSEAP_ENABLE_ACCEPTOR*/
+#endif /* GSSEAP_ENABLE_ACCEPTOR */
 
 #include "gsseap_err.h"
 #include "radsec_err.h"
@@ -127,14 +135,16 @@ struct gss_name_struct
     OM_uint32 flags;
     gss_OID mechanismUsed; /* this is immutable */
     krb5_principal krbPrincipal; /* this is immutable */
+#ifdef GSSEAP_ENABLE_ACCEPTOR
     struct gss_eap_attr_ctx *attrCtx;
+#endif
 };
 
 #define CRED_FLAG_INITIATE                  0x00010000
 #define CRED_FLAG_ACCEPT                    0x00020000
-#define CRED_FLAG_DEFAULT_IDENTITY          0x00040000
-#define CRED_FLAG_PASSWORD                  0x00080000
-#define CRED_FLAG_DEFAULT_CCACHE            0x00100000
+#define CRED_FLAG_PASSWORD                  0x00040000
+#define CRED_FLAG_DEFAULT_CCACHE            0x00080000
+#define CRED_FLAG_RESOLVED                  0x00100000
 #define CRED_FLAG_PUBLIC_MASK               0x0000FFFF
 
 #ifdef HAVE_HEIMDAL_VERSION
@@ -146,11 +156,15 @@ struct gss_cred_id_struct
     GSSEAP_MUTEX mutex;
     OM_uint32 flags;
     gss_name_t name;
+    gss_name_t target; /* for initiator */
     gss_buffer_desc password;
     gss_OID_set mechanisms;
     time_t expiryTime;
-    char *radiusConfigFile;
-    char *radiusConfigStanza;
+    gss_buffer_desc radiusConfigFile;
+    gss_buffer_desc radiusConfigStanza;
+    gss_buffer_desc caCertificate;
+    gss_buffer_desc subjectNameConstraint;
+    gss_buffer_desc subjectAltNameConstraint;
 #ifdef GSSEAP_ENABLE_REAUTH
     krb5_ccache krbCredCache;
     gss_cred_id_t reauthCred;
@@ -212,7 +226,7 @@ struct gss_ctx_id_struct
     time_t expiryTime;
     uint64_t sendSeq, recvSeq;
     void *seqState;
-    gss_cred_id_t defaultCred;
+    gss_cred_id_t cred;
     union {
         struct gss_eap_initiator_ctx initiator;
         #define initiatorCtx         ctxU.initiator
@@ -225,6 +239,8 @@ struct gss_ctx_id_struct
         #define reauthCtx            ctxU.reauth
 #endif
     } ctxU;
+    const struct gss_eap_token_buffer_set *inputTokens;
+    const struct gss_eap_token_buffer_set *outputTokens;
 };
 
 #define TOK_FLAG_SENDER_IS_ACCEPTOR         0x01
@@ -236,6 +252,36 @@ struct gss_ctx_id_struct
 #define KEY_USAGE_INITIATOR_SEAL            24
 #define KEY_USAGE_INITIATOR_SIGN            25
 
+/* accept_sec_context.c */
+OM_uint32
+gssEapAcceptSecContext(OM_uint32 *minor,
+                       gss_ctx_id_t ctx,
+                       gss_cred_id_t cred,
+                       gss_buffer_t input_token,
+                       gss_channel_bindings_t input_chan_bindings,
+                       gss_name_t *src_name,
+                       gss_OID *mech_type,
+                       gss_buffer_t output_token,
+                       OM_uint32 *ret_flags,
+                       OM_uint32 *time_rec,
+                       gss_cred_id_t *delegated_cred_handle);
+
+/* init_sec_context.c */
+OM_uint32
+gssEapInitSecContext(OM_uint32 *minor,
+                     gss_cred_id_t cred,
+                     gss_ctx_id_t ctx,
+                     gss_name_t target_name,
+                     gss_OID mech_type,
+                     OM_uint32 req_flags,
+                     OM_uint32 time_req,
+                     gss_channel_bindings_t input_chan_bindings,
+                     gss_buffer_t input_token,
+                     gss_OID *actual_mech_type,
+                     gss_buffer_t output_token,
+                     OM_uint32 *ret_flags,
+                     OM_uint32 *time_rec);
+
 /* wrap_iov.c */
 OM_uint32
 gssEapWrapOrGetMIC(OM_uint32 *minor,
@@ -279,9 +325,18 @@ rfc4121Flags(gss_ctx_id_t ctx, int receiving);
 void
 gssEapSaveStatusInfo(OM_uint32 minor, const char *format, ...);
 
+OM_uint32
+gssEapDisplayStatus(OM_uint32 *minor,
+                    OM_uint32 status_value,
+                    gss_buffer_t status_string);
+
 #define IS_WIRE_ERROR(err)              ((err) > GSSEAP_RESERVED && \
                                          (err) <= GSSEAP_RADIUS_PROT_FAILURE)
 
+/* upper bound of RADIUS error range must be kept in sync with radsec.h */
+#define IS_RADIUS_ERROR(err)            ((err) >= ERROR_TABLE_BASE_rse && \
+                                         (err) <= ERROR_TABLE_BASE_rse + 20)
+
 /* export_sec_context.c */
 OM_uint32
 gssEapExportSecContext(OM_uint32 *minor,
@@ -289,6 +344,13 @@ gssEapExportSecContext(OM_uint32 *minor,
                        gss_buffer_t token);
 
 
+/* eap_mech.c */
+void
+gssEapInitiatorInit(void);
+
+void
+gssEapFinalize(void);
+
 #ifdef __cplusplus
 }
 #endif
index 9f713ec..588665b 100644 (file)
@@ -71,6 +71,13 @@ extern gss_OID GSS_EAP_CRED_SET_RADIUS_CONFIG_STANZA;
 extern gss_OID GSS_EAP_CRED_SET_CRED_FLAG;
 
 /*
+ * Password; for mechanism glues that do not support
+ * gss_acquire_cred_with_password(), this can be set
+ * on an existing credentials handle.
+ */
+extern gss_OID GSS_EAP_CRED_SET_CRED_PASSWORD;
+
+/*
  * Credentials flag indicating the local attributes
  * processing should be skipped.
  */
index 6bcfff0..f8ec5ef 100644 (file)
@@ -82,6 +82,18 @@ error_code GSSEAP_CRED_EXPIRED,                 "Attributes indicate credentials
 error_code GSSEAP_BAD_CRED_OPTION,              "Bad credential option"
 error_code GSSEAP_NO_DEFAULT_IDENTITY,          "Default credentials identity unavailable"
 error_code GSSEAP_NO_DEFAULT_CRED,              "Missing default password or other credentials"
+error_code GSSEAP_CRED_RESOLVED,                "Credential is already fully resolved"
+
+#
+# Local identity service errors
+#
+error_code GSSEAP_UNABLE_TO_START_IDENTITY_SERVICE,     "Unable to start identity service"
+error_code GSSEAP_NO_IDENTITY_SELECTED,                 "No identity selected"
+error_code GSSEAP_IDENTITY_SERVICE_INSTALL_ERROR,       "Identity service installation error"
+error_code GSSEAP_IDENTITY_SERVICE_OS_ERROR,            "Identity service OS error"
+error_code GSSEAP_IDENTITY_SERVICE_IPC_ERROR,           "Identity service IPC error"
+error_code GSSEAP_IDENTITY_SERVICE_UNKNOWN_ERROR,       "Unknown identity service error"
+
 #
 # Wrap/unwrap/PRF errors
 #
index fbde67d..8049e01 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_import_name(OM_uint32 *minor,
                 gss_buffer_t import_name_buffer,
                 gss_OID input_name_type,
index 8854bf4..a2a712c 100644 (file)
@@ -305,6 +305,7 @@ gssEapImportContext(OM_uint32 *minor,
     major = sequenceInternalize(minor, &ctx->seqState, &p, &remain);
     if (GSS_ERROR(major))
         return major;
+
 #ifdef GSSEAP_ENABLE_ACCEPTOR
     /*
      * The partial context should only be expected for unestablished
@@ -316,11 +317,11 @@ gssEapImportContext(OM_uint32 *minor,
         if (GSS_ERROR(major))
             return major;
     }
-#endif
 
 #ifdef GSSEAP_DEBUG
     assert(remain == 0);
 #endif
+#endif /* GSSEAP_ENABLE_ACCEPTOR */
 
     major = GSS_S_COMPLETE;
     *minor = 0;
@@ -328,7 +329,7 @@ gssEapImportContext(OM_uint32 *minor,
     return major;
 }
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_import_sec_context(OM_uint32 *minor,
                        gss_buffer_t interprocess_token,
                        gss_ctx_id_t *context_handle)
index 24b6f85..d4d275e 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_indicate_mechs(OM_uint32 *minor,
                    gss_OID_set *mech_set)
 {
index 023f70e..e5bc107 100644 (file)
@@ -195,15 +195,14 @@ extern int wpa_debug_level;
 #endif
 
 static OM_uint32
-peerConfigInit(OM_uint32 *minor,
-               gss_cred_id_t cred,
-               gss_ctx_id_t ctx)
+peerConfigInit(OM_uint32 *minor, gss_ctx_id_t ctx)
 {
     OM_uint32 major;
     krb5_context krbContext;
     struct eap_peer_config *eapPeerConfig = &ctx->initiatorCtx.eapPeerConfig;
     gss_buffer_desc identity = GSS_C_EMPTY_BUFFER;
     gss_buffer_desc realm = GSS_C_EMPTY_BUFFER;
+    gss_cred_id_t cred = ctx->cred;
 
     eapPeerConfig->identity = NULL;
     eapPeerConfig->identity_len = 0;
@@ -254,6 +253,11 @@ peerConfigInit(OM_uint32 *minor,
     eapPeerConfig->password = (unsigned char *)cred->password.value;
     eapPeerConfig->password_len = cred->password.length;
 
+    /* certs */
+    eapPeerConfig->ca_cert = (unsigned char *)cred->caCertificate.value;
+    eapPeerConfig->subject_match = (unsigned char *)cred->subjectNameConstraint.value;
+    eapPeerConfig->altsubject_match = (unsigned char *)cred->subjectAltNameConstraint.value;
+
     *minor = 0;
     return GSS_S_COMPLETE;
 }
@@ -341,7 +345,6 @@ initReady(OM_uint32 *minor, gss_ctx_id_t ctx, OM_uint32 reqFlags)
 
 static OM_uint32
 initBegin(OM_uint32 *minor,
-          gss_cred_id_t cred,
           gss_ctx_id_t ctx,
           gss_name_t target,
           gss_OID mech,
@@ -350,6 +353,7 @@ initBegin(OM_uint32 *minor,
           gss_channel_bindings_t chanBindings GSSEAP_UNUSED)
 {
     OM_uint32 major;
+    gss_cred_id_t cred = ctx->cred;
 
     assert(cred != GSS_C_NO_CREDENTIAL);
 
@@ -634,7 +638,7 @@ eapGssSmInitIdentity(OM_uint32 *minor,
 
 static OM_uint32
 eapGssSmInitAuthenticate(OM_uint32 *minor,
-                         gss_cred_id_t cred,
+                         gss_cred_id_t cred GSSEAP_UNUSED,
                          gss_ctx_id_t ctx,
                          gss_name_t target GSSEAP_UNUSED,
                          gss_OID mech GSSEAP_UNUSED,
@@ -647,14 +651,13 @@ eapGssSmInitAuthenticate(OM_uint32 *minor,
 {
     OM_uint32 major;
     OM_uint32 tmpMinor;
-    int code;
     struct wpabuf *resp = NULL;
 
     *minor = 0;
 
     assert(inputToken != GSS_C_NO_BUFFER);
 
-    major = peerConfigInit(minor, cred, ctx);
+    major = peerConfigInit(minor, ctx);
     if (GSS_ERROR(major))
         goto cleanup;
 
@@ -668,7 +671,7 @@ eapGssSmInitAuthenticate(OM_uint32 *minor,
 
     major = GSS_S_CONTINUE_NEEDED;
 
-    code = eap_peer_sm_step(ctx->initiatorCtx.eap);
+    eap_peer_sm_step(ctx->initiatorCtx.eap);
     if (ctx->flags & CTX_FLAG_EAP_RESP) {
         ctx->flags &= ~(CTX_FLAG_EAP_RESP);
 
@@ -715,6 +718,30 @@ cleanup:
 }
 
 static OM_uint32
+eapGssSmInitGssFlags(OM_uint32 *minor,
+                     gss_cred_id_t cred GSSEAP_UNUSED,
+                     gss_ctx_id_t ctx,
+                     gss_name_t target GSSEAP_UNUSED,
+                     gss_OID mech GSSEAP_UNUSED,
+                     OM_uint32 reqFlags GSSEAP_UNUSED,
+                     OM_uint32 timeReq GSSEAP_UNUSED,
+                     gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
+                     gss_buffer_t inputToken GSSEAP_UNUSED,
+                     gss_buffer_t outputToken,
+                     OM_uint32 *smFlags GSSEAP_UNUSED)
+{
+    unsigned char wireFlags[4];
+    gss_buffer_desc flagsBuf;
+
+    store_uint32_be(ctx->gssFlags & GSSEAP_WIRE_FLAGS_MASK, wireFlags);
+
+    flagsBuf.length = sizeof(wireFlags);
+    flagsBuf.value = wireFlags;
+
+    return duplicateBuffer(minor, &flagsBuf, outputToken);
+}
+
+static OM_uint32
 eapGssSmInitGssChannelBindings(OM_uint32 *minor,
                                gss_cred_id_t cred GSSEAP_UNUSED,
                                gss_ctx_id_t ctx,
@@ -746,6 +773,33 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor,
     return GSS_S_CONTINUE_NEEDED;
 }
 
+static OM_uint32
+eapGssSmInitInitiatorMIC(OM_uint32 *minor,
+                         gss_cred_id_t cred GSSEAP_UNUSED,
+                         gss_ctx_id_t ctx,
+                         gss_name_t target GSSEAP_UNUSED,
+                         gss_OID mech GSSEAP_UNUSED,
+                         OM_uint32 reqFlags GSSEAP_UNUSED,
+                         OM_uint32 timeReq GSSEAP_UNUSED,
+                         gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
+                         gss_buffer_t inputToken GSSEAP_UNUSED,
+                         gss_buffer_t outputToken,
+                         OM_uint32 *smFlags)
+{
+    OM_uint32 major;
+
+    major = gssEapMakeTokenMIC(minor, ctx, outputToken);
+    if (GSS_ERROR(major))
+        return major;
+
+    GSSEAP_SM_TRANSITION_NEXT(ctx);
+
+    *minor = 0;
+    *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL;
+
+    return GSS_S_CONTINUE_NEEDED;
+}
 #ifdef GSSEAP_ENABLE_REAUTH
 static OM_uint32
 eapGssSmInitReauthCreds(OM_uint32 *minor,
@@ -774,39 +828,24 @@ eapGssSmInitReauthCreds(OM_uint32 *minor,
 #endif /* GSSEAP_ENABLE_REAUTH */
 
 static OM_uint32
-eapGssSmInitCompleteInitiatorExts(OM_uint32 *minor,
-                                  gss_cred_id_t cred GSSEAP_UNUSED,
-                                  gss_ctx_id_t ctx,
-                                  gss_name_t target GSSEAP_UNUSED,
-                                  gss_OID mech GSSEAP_UNUSED,
-                                  OM_uint32 reqFlags GSSEAP_UNUSED,
-                                  OM_uint32 timeReq GSSEAP_UNUSED,
-                                  gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
-                                  gss_buffer_t inputToken GSSEAP_UNUSED,
-                                  gss_buffer_t outputToken GSSEAP_UNUSED,
-                                  OM_uint32 *smFlags)
+eapGssSmInitAcceptorMIC(OM_uint32 *minor,
+                        gss_cred_id_t cred GSSEAP_UNUSED,
+                        gss_ctx_id_t ctx,
+                        gss_name_t target GSSEAP_UNUSED,
+                        gss_OID mech GSSEAP_UNUSED,
+                        OM_uint32 reqFlags GSSEAP_UNUSED,
+                        OM_uint32 timeReq GSSEAP_UNUSED,
+                        gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
+                        gss_buffer_t inputToken,
+                        gss_buffer_t outputToken GSSEAP_UNUSED,
+                        OM_uint32 *smFlags GSSEAP_UNUSED)
 {
-    GSSEAP_SM_TRANSITION_NEXT(ctx);
-
-    *minor = 0;
-    *smFlags |= SM_FLAG_FORCE_SEND_TOKEN;
+    OM_uint32 major;
 
-    return GSS_S_CONTINUE_NEEDED;
-}
+    major = gssEapVerifyTokenMIC(minor, ctx, inputToken);
+    if (GSS_ERROR(major))
+        return major;
 
-static OM_uint32
-eapGssSmInitCompleteAcceptorExts(OM_uint32 *minor,
-                                 gss_cred_id_t cred GSSEAP_UNUSED,
-                                 gss_ctx_id_t ctx,
-                                 gss_name_t target GSSEAP_UNUSED,
-                                 gss_OID mech GSSEAP_UNUSED,
-                                 OM_uint32 reqFlags GSSEAP_UNUSED,
-                                 OM_uint32 timeReq GSSEAP_UNUSED,
-                                 gss_channel_bindings_t chanBindings GSSEAP_UNUSED,
-                                 gss_buffer_t inputToken GSSEAP_UNUSED,
-                                 gss_buffer_t outputToken GSSEAP_UNUSED,
-                                 OM_uint32 *smFlags GSSEAP_UNUSED)
-{
     GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED);
 
     *minor = 0;
@@ -866,6 +905,13 @@ static struct gss_eap_sm eapGssInitiatorSm[] = {
     },
     {
         ITOK_TYPE_NONE,
+        ITOK_TYPE_GSS_FLAGS,
+        GSSEAP_STATE_INITIATOR_EXTS,
+        0,
+        eapGssSmInitGssFlags
+    },
+    {
+        ITOK_TYPE_NONE,
         ITOK_TYPE_GSS_CHANNEL_BINDINGS,
         GSSEAP_STATE_INITIATOR_EXTS,
         SM_ITOK_FLAG_REQUIRED,
@@ -873,10 +919,10 @@ static struct gss_eap_sm eapGssInitiatorSm[] = {
     },
     {
         ITOK_TYPE_NONE,
-        ITOK_TYPE_NONE,
+        ITOK_TYPE_INITIATOR_MIC,
         GSSEAP_STATE_INITIATOR_EXTS,
-        0,
-        eapGssSmInitCompleteInitiatorExts
+        SM_ITOK_FLAG_REQUIRED,
+        eapGssSmInitInitiatorMIC
     },
 #ifdef GSSEAP_ENABLE_REAUTH
     {
@@ -889,18 +935,18 @@ static struct gss_eap_sm eapGssInitiatorSm[] = {
 #endif
     /* other extensions go here */
     {
-        ITOK_TYPE_NONE,
+        ITOK_TYPE_ACCEPTOR_MIC,
         ITOK_TYPE_NONE,
         GSSEAP_STATE_ACCEPTOR_EXTS,
-        0,
-        eapGssSmInitCompleteAcceptorExts
+        SM_ITOK_FLAG_REQUIRED,
+        eapGssSmInitAcceptorMIC
     }
 };
 
-OM_uint32 KRB5_CALLCONV
-gss_init_sec_context(OM_uint32 *minor,
+OM_uint32
+gssEapInitSecContext(OM_uint32 *minor,
                      gss_cred_id_t cred,
-                     gss_ctx_id_t *context_handle,
+                     gss_ctx_id_t ctx,
                      gss_name_t target_name,
                      gss_OID mech_type,
                      OM_uint32 req_flags,
@@ -913,60 +959,26 @@ gss_init_sec_context(OM_uint32 *minor,
                      OM_uint32 *time_rec)
 {
     OM_uint32 major, tmpMinor;
-    gss_ctx_id_t ctx = *context_handle;
-    int initialContextToken = 0;
-
-    *minor = 0;
+    int initialContextToken = (ctx->mechanismUsed == GSS_C_NO_OID);
 
-    output_token->length = 0;
-    output_token->value = NULL;
-
-    if (ctx == GSS_C_NO_CONTEXT) {
-        if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
-            *minor = GSSEAP_WRONG_SIZE;
-            return GSS_S_DEFECTIVE_TOKEN;
-        }
+    if (cred != GSS_C_NO_CREDENTIAL)
+        GSSEAP_MUTEX_LOCK(&cred->mutex);
 
-        major = gssEapAllocContext(minor, &ctx);
+    if (ctx->cred == GSS_C_NO_CREDENTIAL) {
+        major = gssEapResolveInitiatorCred(minor, cred, target_name, &ctx->cred);
         if (GSS_ERROR(major))
-            return major;
-
-        ctx->flags |= CTX_FLAG_INITIATOR;
-        initialContextToken = 1;
-
-        *context_handle = ctx;
-    }
-
-    GSSEAP_MUTEX_LOCK(&ctx->mutex);
-
-    if (cred == GSS_C_NO_CREDENTIAL) {
-        if (ctx->defaultCred == GSS_C_NO_CREDENTIAL) {
-            major = gssEapAcquireCred(minor,
-                                      GSS_C_NO_NAME,
-                                      GSS_C_NO_BUFFER,
-                                      time_req,
-                                      GSS_C_NO_OID_SET,
-                                      GSS_C_INITIATE,
-                                      &ctx->defaultCred,
-                                      NULL,
-                                      NULL);
-            if (GSS_ERROR(major))
-                goto cleanup;
-        }
+            goto cleanup;
 
-        cred = ctx->defaultCred;
+        assert(ctx->cred != GSS_C_NO_CREDENTIAL);
     }
 
-    GSSEAP_MUTEX_LOCK(&cred->mutex);
+    GSSEAP_MUTEX_LOCK(&ctx->cred->mutex);
 
-    if ((cred->flags & CRED_FLAG_INITIATE) == 0) {
-        major = GSS_S_NO_CRED;
-        *minor = GSSEAP_CRED_USAGE_MISMATCH;
-        goto cleanup;
-    }
+    assert(ctx->cred->flags & CRED_FLAG_RESOLVED);
+    assert(ctx->cred->flags & CRED_FLAG_INITIATE);
 
     if (initialContextToken) {
-        major = initBegin(minor, cred, ctx, target_name, mech_type,
+        major = initBegin(minor, ctx, target_name, mech_type,
                           req_flags, time_req, input_chan_bindings);
         if (GSS_ERROR(major))
             goto cleanup;
@@ -1007,6 +1019,68 @@ gss_init_sec_context(OM_uint32 *minor,
 cleanup:
     if (cred != GSS_C_NO_CREDENTIAL)
         GSSEAP_MUTEX_UNLOCK(&cred->mutex);
+    if (ctx->cred != GSS_C_NO_CREDENTIAL)
+        GSSEAP_MUTEX_UNLOCK(&ctx->cred->mutex);
+
+    return major;
+}
+
+OM_uint32 GSSAPI_CALLCONV
+gss_init_sec_context(OM_uint32 *minor,
+                     gss_cred_id_t cred,
+                     gss_ctx_id_t *context_handle,
+                     gss_name_t target_name,
+                     gss_OID mech_type,
+                     OM_uint32 req_flags,
+                     OM_uint32 time_req,
+                     gss_channel_bindings_t input_chan_bindings,
+                     gss_buffer_t input_token,
+                     gss_OID *actual_mech_type,
+                     gss_buffer_t output_token,
+                     OM_uint32 *ret_flags,
+                     OM_uint32 *time_rec)
+{
+    OM_uint32 major, tmpMinor;
+    gss_ctx_id_t ctx = *context_handle;
+
+    *minor = 0;
+
+    output_token->length = 0;
+    output_token->value = NULL;
+
+    assert(ctx == GSS_C_NO_CONTEXT || ctx->mechanismUsed != GSS_C_NO_OID);
+
+    if (ctx == GSS_C_NO_CONTEXT) {
+        if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) {
+            *minor = GSSEAP_WRONG_SIZE;
+            return GSS_S_DEFECTIVE_TOKEN;
+        }
+
+        major = gssEapAllocContext(minor, &ctx);
+        if (GSS_ERROR(major))
+            return major;
+
+        ctx->flags |= CTX_FLAG_INITIATOR;
+
+        *context_handle = ctx;
+    }
+
+    GSSEAP_MUTEX_LOCK(&ctx->mutex);
+
+    major = gssEapInitSecContext(minor,
+                                 cred,
+                                 ctx,
+                                 target_name,
+                                 mech_type,
+                                 req_flags,
+                                 time_req,
+                                 input_chan_bindings,
+                                 input_token,
+                                 actual_mech_type,
+                                 output_token,
+                                 ret_flags,
+                                 time_rec);
+
     GSSEAP_MUTEX_UNLOCK(&ctx->mutex);
 
     if (GSS_ERROR(major))
index ec37491..a359f68 100644 (file)
@@ -45,8 +45,7 @@
 #define MA_SUPPORTED(ma)    MA_ADD((ma), mech_attrs)
 #define MA_KNOWN(ma)        MA_ADD((ma), known_mech_attrs)
 
-OM_uint32 KRB5_CALLCONV
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_attrs_for_mech(OM_uint32 *minor,
                            gss_const_OID mech_oid,
                            gss_OID_set *mech_attrs,
index 1c85662..d37818d 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_context(OM_uint32 *minor,
                     gss_ctx_id_t ctx,
                     gss_name_t *src_name,
index fc59e61..227ab16 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_cred(OM_uint32 *minor,
                  gss_cred_id_t cred,
                  gss_name_t *name,
index 24da201..191902d 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_cred_by_mech(OM_uint32 *minor,
                          gss_cred_id_t cred,
                          gss_OID mech_type,
index b8ff40e..2ad34ed 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-#ifdef HAVE_INQUIRECREDOPS /* Windows doesn't like zero-sized arrays; define this when we actually have any of these */
+#if 0
 static struct {
     gss_OID_desc oid;
     OM_uint32 (*inquire)(OM_uint32 *, const gss_cred_id_t,
@@ -45,15 +45,16 @@ static struct {
 };
 #endif
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_cred_by_oid(OM_uint32 *minor,
                         const gss_cred_id_t cred_handle,
-                        const gss_OID desired_object,
+                        const gss_OID desired_object GSSEAP_UNUSED,
                         gss_buffer_set_t *data_set)
 {
     OM_uint32 major;
+#if 0
     int i;
-
+#endif
     *data_set = GSS_C_NO_BUFFER_SET;
 
     if (cred_handle == GSS_C_NO_CREDENTIAL) {
@@ -66,7 +67,7 @@ gss_inquire_cred_by_oid(OM_uint32 *minor,
     major = GSS_S_UNAVAILABLE;
     *minor = GSSEAP_BAD_CRED_OPTION;
 
-#ifdef HAVE_INQUIRECREDOPS
+#if 0
     for (i = 0; i < sizeof(inquireCredOps) / sizeof(inquireCredOps[0]); i++) {
         if (oidEqual(&inquireCredOps[i].oid, desired_object)) {
             major = (*inquireCredOps[i].inquire)(minor, cred_handle,
@@ -74,9 +75,6 @@ gss_inquire_cred_by_oid(OM_uint32 *minor,
             break;
         }
     }
-#else
-    (void)i;
-    (void)desired_object;
 #endif
 
     GSSEAP_MUTEX_UNLOCK(&cred_handle->mutex);
index c6411b1..bd518c0 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_saslname_for_mech(OM_uint32 *minor,
                               const gss_OID mech,
                               gss_buffer_t sasl_mech_name,
index 863a810..89c869c 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_mechs_for_name(OM_uint32 *minor,
                            const gss_name_t input_name,
                            gss_OID_set *mech_types)
index f3eeadf..78b08a0 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_name(OM_uint32 *minor,
                  gss_name_t name,
                  int *name_is_MN,
@@ -64,11 +64,7 @@ gss_inquire_name(OM_uint32 *minor,
 
     GSSEAP_MUTEX_LOCK(&name->mutex);
 
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     major = gssEapInquireName(minor, name, name_is_MN, MN_mech, attrs);
-#else
-    major = GSS_S_UNAVAILABLE;
-#endif
 
     GSSEAP_MUTEX_UNLOCK(&name->mutex);
 
index 1f99eb7..0e60340 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_names_for_mech(OM_uint32 *minor,
                            gss_OID mechanism,
                            gss_OID_set *ret_name_types)
index 3564c1c..d6d7c14 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_mech_for_saslname(OM_uint32 *minor,
                               const gss_buffer_t sasl_mech_name,
                               gss_OID *mech_type)
index 537ff25..67b2ec8 100644 (file)
@@ -104,7 +104,7 @@ static struct {
     },
 };
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_inquire_sec_context_by_oid(OM_uint32 *minor,
                                const gss_ctx_id_t ctx,
                                const gss_OID desired_object,
index 7d9c871..2a8a96c 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_map_name_to_any(OM_uint32 *minor,
                     gss_name_t name,
                     int authenticated,
@@ -50,13 +50,7 @@ gss_map_name_to_any(OM_uint32 *minor,
 
     GSSEAP_MUTEX_LOCK(&name->mutex);
 
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     major = gssEapMapNameToAny(minor, name, authenticated, type_id, output);
-#else
-    (void)authenticated;
-    (void)type_id;
-    major = GSS_S_COMPLETE;
-#endif
 
     GSSEAP_MUTEX_UNLOCK(&name->mutex);
 
diff --git a/moonshot/mech_eap/mech_eap-noacceptor.exports b/moonshot/mech_eap/mech_eap-noacceptor.exports
new file mode 100644 (file)
index 0000000..4ecbc52
--- /dev/null
@@ -0,0 +1,52 @@
+gss_acquire_cred
+gss_add_cred
+gss_add_cred_with_password
+gss_canonicalize_name
+gss_compare_name
+gss_context_time
+gss_delete_sec_context
+gss_display_name
+gss_display_name_ext
+gss_display_status
+gss_duplicate_name
+gss_export_name
+gss_export_sec_context
+gss_get_mic
+gss_import_name
+gss_import_sec_context
+gss_indicate_mechs
+gss_init_sec_context
+gss_inquire_attrs_for_mech
+gss_inquire_context
+gss_inquire_cred
+gss_inquire_cred_by_mech
+gss_inquire_cred_by_oid
+gss_inquire_mechs_for_name
+gss_inquire_mech_for_saslname
+gss_inquire_names_for_mech
+gss_inquire_saslname_for_mech
+gss_inquire_sec_context_by_oid
+gss_process_context_token
+gss_pseudo_random
+gss_release_cred
+gss_release_name
+gss_internal_release_oid
+gss_set_sec_context_option
+gss_store_cred
+gss_unwrap
+gss_unwrap_iov
+gss_verify_mic
+gss_wrap
+gss_wrap_iov
+gss_wrap_iov_length
+gss_wrap_size_limit
+GSS_EAP_AES128_CTS_HMAC_SHA1_96_MECHANISM
+GSS_EAP_AES256_CTS_HMAC_SHA1_96_MECHANISM
+GSS_EAP_NT_EAP_NAME
+GSS_EAP_CRED_SET_CRED_FLAG
+GSS_EAP_CRED_SET_CRED_PASSWORD
+GSS_EAP_CRED_SET_RADIUS_CONFIG_FILE
+GSS_EAP_CRED_SET_RADIUS_CONFIG_STANZA
+gssspi_acquire_cred_with_password
+gssspi_authorize_localname
+gssspi_set_cred_option
index 12f7f54..10c7f81 100644 (file)
@@ -5,6 +5,7 @@ gss_add_cred_with_password
 gss_canonicalize_name
 gss_compare_name
 gss_context_time
+gss_delete_name_attribute
 gss_delete_sec_context
 gss_display_name
 gss_display_name_ext
@@ -50,6 +51,10 @@ gss_wrap_size_limit
 GSS_EAP_AES128_CTS_HMAC_SHA1_96_MECHANISM
 GSS_EAP_AES256_CTS_HMAC_SHA1_96_MECHANISM
 GSS_EAP_NT_EAP_NAME
+GSS_EAP_CRED_SET_CRED_FLAG
+GSS_EAP_CRED_SET_CRED_PASSWORD
+GSS_EAP_CRED_SET_RADIUS_CONFIG_FILE
+GSS_EAP_CRED_SET_RADIUS_CONFIG_STANZA
 gssspi_acquire_cred_with_password
 gssspi_authorize_localname
 gssspi_set_cred_option
index 2b7fb7e..bc9bba3 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
 gssspi_mech_invoke(OM_uint32 *minor,
                    const gss_OID desired_mech,
                    const gss_OID desired_object,
index 7f0310d..02a4b6d 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_process_context_token(OM_uint32 *minor,
                           gss_ctx_id_t ctx,
                           gss_buffer_t token_buffer)
index 684af94..476f1c5 100644 (file)
@@ -59,7 +59,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_pseudo_random(OM_uint32 *minor,
                   gss_ctx_id_t ctx,
                   int prf_key,
@@ -134,7 +134,7 @@ gss_pseudo_random(OM_uint32 *minor,
         goto cleanup;
     }
 
-    memcpy(ns.data + 4, prf_in->value, prf_in->length);
+    memcpy((unsigned char *)ns.data + 4, prf_in->value, prf_in->length);
     i = 0;
     p = (unsigned char *)prf_out->value;
     while (desired_output_len > 0) {
index 08e4e10..d68fb45 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_release_any_name_mapping(OM_uint32 *minor,
                              gss_name_t name,
                              gss_buffer_t type_id,
@@ -49,12 +49,7 @@ gss_release_any_name_mapping(OM_uint32 *minor,
 
     GSSEAP_MUTEX_LOCK(&name->mutex);
 
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     major = gssEapReleaseAnyNameMapping(minor, name, type_id, input);
-#else
-    (void)type_id;
-    major = GSS_S_COMPLETE;
-#endif
 
     *input = NULL;
 
index c7d3645..8bb7e54 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_release_cred(OM_uint32 *minor,
                  gss_cred_id_t *cred_handle)
 {
index 0bbf537..3d527ce 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_release_name(OM_uint32 *minor,
                  gss_name_t *name)
 {
index 4e0d4f0..291da40 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
 gss_internal_release_oid(OM_uint32 *minor,
                          gss_OID *oid)
 {
index bfffa1f..7bb9b7b 100644 (file)
@@ -42,7 +42,7 @@ setCredRadiusConfigFile(OM_uint32 *minor,
                         const gss_OID oid GSSEAP_UNUSED,
                         const gss_buffer_t buffer)
 {
-    OM_uint32 major;
+    OM_uint32 major, tmpMinor;
     gss_buffer_desc configFileBuffer = GSS_C_EMPTY_BUFFER;
 
     if (buffer != GSS_C_NO_BUFFER && buffer->length != 0) {
@@ -51,10 +51,8 @@ setCredRadiusConfigFile(OM_uint32 *minor,
             return major;
     }
 
-    if (cred->radiusConfigFile != NULL)
-        GSSEAP_FREE(cred->radiusConfigFile);
-
-    cred->radiusConfigFile = (char *)configFileBuffer.value;
+    gss_release_buffer(&tmpMinor, &cred->radiusConfigFile);
+    cred->radiusConfigFile = configFileBuffer;
 
     *minor = 0;
     return GSS_S_COMPLETE;
@@ -66,7 +64,7 @@ setCredRadiusConfigStanza(OM_uint32 *minor,
                           const gss_OID oid GSSEAP_UNUSED,
                           const gss_buffer_t buffer)
 {
-    OM_uint32 major;
+    OM_uint32 major, tmpMinor;
     gss_buffer_desc configStanzaBuffer = GSS_C_EMPTY_BUFFER;
 
     if (buffer != GSS_C_NO_BUFFER && buffer->length != 0) {
@@ -75,10 +73,8 @@ setCredRadiusConfigStanza(OM_uint32 *minor,
             return major;
     }
 
-    if (cred->radiusConfigStanza != NULL)
-        GSSEAP_FREE(cred->radiusConfigStanza);
-
-    cred->radiusConfigStanza = (char *)configStanzaBuffer.value;
+    gss_release_buffer(&tmpMinor, &cred->radiusConfigStanza);
+    cred->radiusConfigStanza = configStanzaBuffer;
 
     *minor = 0;
     return GSS_S_COMPLETE;
@@ -116,6 +112,15 @@ setCredFlag(OM_uint32 *minor,
     return GSS_S_COMPLETE;
 }
 
+static OM_uint32
+setCredPassword(OM_uint32 *minor,
+                gss_cred_id_t cred,
+                const gss_OID oid GSSEAP_UNUSED,
+                const gss_buffer_t buffer)
+{
+    return gssEapSetCredPassword(minor, cred, buffer);
+}
+
 static struct {
     gss_OID_desc oid;
     OM_uint32 (*setOption)(OM_uint32 *, gss_cred_id_t cred,
@@ -136,13 +141,19 @@ static struct {
         { 11, "\x2B\x06\x01\x04\x01\xA9\x4A\x16\x03\x03\x03" },
         setCredFlag,
     },
+    /* 1.3.6.1.4.1.5322.22.3.3.4 */
+    {
+        { 11, "\x2B\x06\x01\x04\x01\xA9\x4A\x16\x03\x03\x04" },
+        setCredPassword,
+    },
 };
 
 gss_OID GSS_EAP_CRED_SET_RADIUS_CONFIG_FILE     = &setCredOps[0].oid;
 gss_OID GSS_EAP_CRED_SET_RADIUS_CONFIG_STANZA   = &setCredOps[1].oid;
 gss_OID GSS_EAP_CRED_SET_CRED_FLAG              = &setCredOps[2].oid;
+gss_OID GSS_EAP_CRED_SET_CRED_PASSWORD          = &setCredOps[3].oid;
 
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
 gssspi_set_cred_option(OM_uint32 *minor,
                        gss_cred_id_t *pCred,
                        const gss_OID desired_object,
index 961bdef..2ccf5d7 100644 (file)
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_set_name_attribute(OM_uint32 *minor,
                        gss_name_t name,
                        int complete,
                        gss_buffer_t attr,
                        gss_buffer_t value)
 {
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     OM_uint32 major;
 
     if (name == GSS_C_NO_NAME) {
@@ -58,7 +57,4 @@ gss_set_name_attribute(OM_uint32 *minor,
     GSSEAP_MUTEX_UNLOCK(&name->mutex);
 
     return major;
-#else
-       return GSS_S_UNAVAILABLE;
-#endif
 }
index 14278dc..f9fa3a6 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-#ifdef HAVE_SETCTXOPS /* Windows doesn't like zero-sized arrays; define this when we actually have any of these */
+#if 0
 static struct {
     gss_OID_desc oid;
     OM_uint32 (*setOption)(OM_uint32 *, gss_ctx_id_t *pCtx,
@@ -45,15 +45,17 @@ static struct {
 };
 #endif
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_set_sec_context_option(OM_uint32 *minor,
                            gss_ctx_id_t *pCtx,
-                           const gss_OID desired_object,
-                           const gss_buffer_t value)
+                           const gss_OID desired_object GSSEAP_UNUSED,
+                           const gss_buffer_t value GSSEAP_UNUSED)
 {
     OM_uint32 major;
     gss_ctx_id_t ctx;
+#if 0
     int i;
+#endif
 
     major = GSS_S_UNAVAILABLE;
     *minor = GSSEAP_BAD_CONTEXT_OPTION;
@@ -66,7 +68,7 @@ gss_set_sec_context_option(OM_uint32 *minor,
     if (ctx != GSS_C_NO_CONTEXT)
         GSSEAP_MUTEX_LOCK(&ctx->mutex);
 
-#ifdef HAVE_SETCTXOPS
+#if 0
     for (i = 0; i < sizeof(setCtxOps) / sizeof(setCtxOps[0]); i++) {
         if (oidEqual(&setCtxOps[i].oid, desired_object)) {
             major = (*setCtxOps[i].setOption)(minor, &ctx,
@@ -74,10 +76,6 @@ gss_set_sec_context_option(OM_uint32 *minor,
             break;
         }
     }
-#else
-    (void)i;
-    (void)desired_object;
-    (void)value;
 #endif
 
     if (pCtx != NULL && *pCtx == NULL)
index 5beb730..d17a3ac 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_store_cred(OM_uint32 *minor,
                const gss_cred_id_t cred,
                gss_cred_usage_t input_usage,
index e3d5d6f..a185035 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_unwrap(OM_uint32 *minor,
            gss_ctx_id_t ctx,
            gss_buffer_t input_message_buffer,
index 30318c7..9e3ef19 100644 (file)
@@ -319,7 +319,7 @@ unwrapStream(OM_uint32 *minor,
     unsigned char *ptr;
     OM_uint32 code = 0, major = GSS_S_FAILURE;
     krb5_context krbContext;
-    int conf_req_flag, toktype2;
+    int conf_req_flag;
     int i = 0, j;
     gss_iov_buffer_desc *tiov = NULL;
     gss_iov_buffer_t stream, data = NULL;
@@ -346,8 +346,7 @@ unwrapStream(OM_uint32 *minor,
     }
 
     ptr = (unsigned char *)stream->buffer.value;
-    toktype2 = load_uint16_be(ptr);
-    ptr += 2;
+    ptr += 2; /* skip token type */
 
     tiov = (gss_iov_buffer_desc *)GSSEAP_CALLOC((size_t)iov_count + 2,
                                                 sizeof(gss_iov_buffer_desc));
@@ -529,7 +528,7 @@ gssEapUnwrapOrVerifyMIC(OM_uint32 *minor,
     return major;
 }
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_unwrap_iov(OM_uint32 *minor,
                gss_ctx_id_t ctx,
                int *conf_state,
index 6e35fd4..ae83923 100644 (file)
 #ifndef _UTIL_H_
 #define _UTIL_H_ 1
 
-#if defined(HAVE_SYS_PARAM_H)
+#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
-#if defined(HAVE_STDINT_H)
+#ifdef HAVE_STDINT_H
 #include <stdint.h>
 #endif
 #include <string.h>
@@ -72,8 +72,9 @@
 
 #include <krb5.h>
 
-#if defined(WIN32)
-#define inline  __inline
+#ifdef WIN32
+#define inline __inline
+#define snprintf _snprintf
 #endif
 
 #ifdef __cplusplus
@@ -85,43 +86,24 @@ extern "C" {
 #endif
 
 #if !defined(WIN32) && !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-#define GSSEAP_UNUSED __attribute__ ((__unused__)) 
+#define GSSEAP_UNUSED __attribute__ ((__unused__))
 #else
 #define GSSEAP_UNUSED
 #endif
 
-#if !defined(WIN32)
-#define GSSEAP_CONSTRUCTOR  __attribute__((constructor))
-#define GSSEAP_DESTRUCTOR   __attribute__((destructor))
-#else
-#define GSSEAP_CONSTRUCTOR
-#define GSSEAP_DESTRUCTOR
-#endif
-
-/* thread local storage */
-struct gss_eap_status_info;
-
-struct gss_eap_thread_local_data
-{
-       krb5_context context;
-       struct gss_eap_status_info* status_info;
-};
-
-struct gss_eap_thread_local_data* 
-gssEapGetThreadLocalData();
-
-void 
-gssEapDestroyStatusInfo(struct gss_eap_status_info* status);
-
-void 
-gssEapDestroyKrbContext(krb5_context context);
-
 /* util_buffer.c */
 OM_uint32
 makeStringBuffer(OM_uint32 *minor,
                  const char *string,
                  gss_buffer_t buffer);
 
+#define makeStringBufferOrCleanup(src, dst)             \
+    do {                                                \
+        major = makeStringBuffer((minor), (src), (dst));\
+        if (GSS_ERROR(major))                           \
+            goto cleanup;                               \
+    } while (0)
+
 OM_uint32
 bufferToString(OM_uint32 *minor,
                const gss_buffer_t buffer,
@@ -132,6 +114,13 @@ duplicateBuffer(OM_uint32 *minor,
                 const gss_buffer_t src,
                 gss_buffer_t dst);
 
+#define duplicateBufferOrCleanup(src, dst)              \
+    do {                                                \
+        major = duplicateBuffer((minor), (src), (dst)); \
+        if (GSS_ERROR(major))                           \
+            goto cleanup;                               \
+    } while (0)
+
 static inline int
 bufferEqual(const gss_buffer_t b1, const gss_buffer_t b2)
 {
@@ -212,12 +201,17 @@ enum gss_eap_token_type {
 #define ITOK_TYPE_REAUTH_RESP           0x00000009 /* optional */
 #define ITOK_TYPE_VERSION_INFO          0x0000000A /* optional */
 #define ITOK_TYPE_VENDOR_INFO           0x0000000B /* optional */
+#define ITOK_TYPE_GSS_FLAGS             0x0000000C /* optional */
+#define ITOK_TYPE_INITIATOR_MIC         0x0000000D /* critical, required, if not reauth */
+#define ITOK_TYPE_ACCEPTOR_MIC          0x0000000E /* TBD */
 
 #define ITOK_FLAG_CRITICAL              0x80000000  /* critical, wire flag */
 #define ITOK_FLAG_VERIFIED              0x40000000  /* verified, API flag */
 
 #define ITOK_TYPE_MASK                  (~(ITOK_FLAG_CRITICAL | ITOK_FLAG_VERIFIED))
 
+#define GSSEAP_WIRE_FLAGS_MASK          GSS_C_MUTUAL_FLAG
+
 OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
 OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
 
@@ -240,14 +234,26 @@ gssEapContextTime(OM_uint32 *minor,
                   gss_ctx_id_t context_handle,
                   OM_uint32 *time_rec);
 
+OM_uint32
+gssEapMakeTokenMIC(OM_uint32 *minor,
+                   gss_ctx_id_t ctx,
+                   gss_buffer_t tokenMIC);
+
+OM_uint32
+gssEapVerifyTokenMIC(OM_uint32 *minor,
+                     gss_ctx_id_t ctx,
+                     const gss_buffer_t tokenMIC);
+
 /* 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);
 
+gss_OID
+gssEapPrimaryMechForCred(gss_cred_id_t cred);
+
 OM_uint32
 gssEapAcquireCred(OM_uint32 *minor,
                   const gss_name_t desiredName,
-                  const gss_buffer_t password,
                   OM_uint32 timeReq,
                   const gss_OID_set desiredMechs,
                   int cred_usage,
@@ -255,6 +261,22 @@ gssEapAcquireCred(OM_uint32 *minor,
                   gss_OID_set *pActualMechs,
                   OM_uint32 *timeRec);
 
+OM_uint32
+gssEapSetCredPassword(OM_uint32 *minor,
+                      gss_cred_id_t cred,
+                      const gss_buffer_t password);
+
+OM_uint32
+gssEapSetCredService(OM_uint32 *minor,
+                     gss_cred_id_t cred,
+                     const gss_name_t target);
+
+OM_uint32
+gssEapResolveInitiatorCred(OM_uint32 *minor,
+                           const gss_cred_id_t cred,
+                           const gss_name_t target,
+                           gss_cred_id_t *resolvedCred);
+
 int gssEapCredAvailable(gss_cred_id_t cred, gss_OID mech);
 
 OM_uint32
@@ -492,6 +514,17 @@ gssEapOidToSaslName(const gss_OID oid);
 gss_OID
 gssEapSaslNameToOid(const gss_buffer_t name);
 
+/* util_moonshot.c */
+OM_uint32
+libMoonshotResolveDefaultIdentity(OM_uint32 *minor,
+                                  const gss_cred_id_t cred,
+                                  gss_name_t *pName);
+
+OM_uint32
+libMoonshotResolveInitiatorCred(OM_uint32 *minor,
+                                gss_cred_id_t cred,
+                                const gss_name_t targetName);
+
 /* util_name.c */
 #define EXPORT_NAME_FLAG_OID                    0x1
 #define EXPORT_NAME_FLAG_COMPOSITE              0x2
@@ -673,16 +706,29 @@ void
 gssEapSmTransition(gss_ctx_id_t ctx, enum gss_eap_state state);
 
 /* util_token.c */
+struct gss_eap_token_buffer_set {
+    gss_buffer_set_desc buffers; /* pointers only */
+    OM_uint32 *types;
+};
+
 OM_uint32
 gssEapEncodeInnerTokens(OM_uint32 *minor,
-                        gss_buffer_set_t extensions,
-                        OM_uint32 *types,
+                        struct gss_eap_token_buffer_set *tokens,
                         gss_buffer_t buffer);
 OM_uint32
 gssEapDecodeInnerTokens(OM_uint32 *minor,
                         const gss_buffer_t buffer,
-                        gss_buffer_set_t *pExtensions,
-                        OM_uint32 **pTypes);
+                        struct gss_eap_token_buffer_set *tokens);
+
+OM_uint32
+gssEapReleaseInnerTokens(OM_uint32 *minor,
+                         struct gss_eap_token_buffer_set *tokens,
+                         int freeBuffers);
+
+OM_uint32
+gssEapAllocInnerTokens(OM_uint32 *minor,
+                       size_t count,
+                       struct gss_eap_token_buffer_set *tokens);
 
 size_t
 tokenSize(const gss_OID_desc *mech, size_t body_size);
@@ -708,6 +754,18 @@ verifyTokenHeader(OM_uint32 *minor,
 #define GSSEAP_FREE                     free
 #define GSSEAP_REALLOC                  realloc
 
+#ifndef GSSAPI_CALLCONV
+#define GSSAPI_CALLCONV                 KRB5_CALLCONV
+#endif
+
+#ifdef WIN32
+#define GSSEAP_CONSTRUCTOR
+#define GSSEAP_DESTRUCTOR
+#else
+#define GSSEAP_CONSTRUCTOR              __attribute__((constructor))
+#define GSSEAP_DESTRUCTOR               __attribute__((destructor))
+#endif
+
 #define GSSEAP_NOT_IMPLEMENTED          do {            \
         assert(0 && "not implemented");                 \
         *minor = ENOSYS;                                \
@@ -715,26 +773,30 @@ verifyTokenHeader(OM_uint32 *minor,
     } while (0)
 
 #ifdef WIN32
+
 #include <winbase.h>
-#define GSSEAP_MUTEX                    CRITICAL_SECTION
-// wrapper for EnterCriticalSection() to provide return value
-inline int win32_mutex_init(CRITICAL_SECTION* m)
-{
-       EnterCriticalSection(m);
-       return 0;
-}
 
-#define GSSEAP_MUTEX_INIT(m)            win32_mutex_init((m))
+#define GSSEAP_GET_LAST_ERROR()                (GetLastError())
+
+#define GSSEAP_MUTEX                    CRITICAL_SECTION
+#define GSSEAP_MUTEX_INIT(m)            (InitializeCriticalSection((m)), 0)
 #define GSSEAP_MUTEX_DESTROY(m)         DeleteCriticalSection((m))
 #define GSSEAP_MUTEX_LOCK(m)            EnterCriticalSection((m))
 #define GSSEAP_MUTEX_UNLOCK(m)          LeaveCriticalSection((m))
 
+/* Thread-local is handled separately */
+
+#define GSSEAP_THREAD_ONCE              INIT_ONCE
+#define GSSEAP_ONCE(o, i)               InitOnceExecuteOnce((o), (i))
+#define GSSEAP_ONCE_INITIALIZER         INIT_ONCE_STATIC_INIT
+
 #else
+
 #include <pthread.h>
 
-#define GSSEAP_MUTEX                    pthread_mutex_t
-#define GSSEAP_MUTEX_INITIALIZER        PTHREAD_MUTEX_INITIALIZER
+#define GSSEAP_GET_LAST_ERROR()                (errno)
 
+#define GSSEAP_MUTEX                    pthread_mutex_t
 #define GSSEAP_MUTEX_INIT(m)            pthread_mutex_init((m), NULL)
 #define GSSEAP_MUTEX_DESTROY(m)         pthread_mutex_destroy((m))
 #define GSSEAP_MUTEX_LOCK(m)            pthread_mutex_lock((m))
@@ -748,7 +810,8 @@ inline int win32_mutex_init(CRITICAL_SECTION* m)
 #define GSSEAP_THREAD_ONCE              pthread_once_t
 #define GSSEAP_ONCE(o, i)               pthread_once((o), (i))
 #define GSSEAP_ONCE_INITIALIZER         PTHREAD_ONCE_INIT
-#endif
+
+#endif /* WIN32 */
 
 /* Helper functions */
 static inline void
@@ -899,6 +962,23 @@ gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data)
     data->length = buffer->length;
 }
 
+/* util_tld.c */
+struct gss_eap_status_info;
+
+struct gss_eap_thread_local_data {
+    krb5_context krbContext;
+    struct gss_eap_status_info *statusInfo;
+};
+
+struct gss_eap_thread_local_data *
+gssEapGetThreadLocalData(void);
+
+void
+gssEapDestroyStatusInfo(struct gss_eap_status_info *status);
+
+void
+gssEapDestroyKrbContext(krb5_context context);
+
 #ifdef __cplusplus
 }
 #endif
@@ -906,8 +986,8 @@ gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data)
 #ifdef GSSEAP_ENABLE_ACCEPTOR
 #include "util_json.h"
 #include "util_attr.h"
-#endif
 #include "util_base64.h"
+#endif /* GSSEAP_ENABLE_ACCEPTOR */
 #ifdef GSSEAP_ENABLE_REAUTH
 #include "util_reauth.h"
 #endif
index 01c3135..9496863 100644 (file)
@@ -57,12 +57,16 @@ gssEapAttrProvidersInitInternal(void)
     if (GSS_ERROR(major))
         goto cleanup;
 
+#ifdef HAVE_OPENSAML
     major = gssEapSamlAttrProvidersInit(&minor);
     if (GSS_ERROR(major))
         goto cleanup;
+#endif
 
+#ifdef HAVE_SHIBRESOLVER
     /* Allow Shibboleth initialization failure to be non-fatal */
     gssEapLocalAttrProviderInit(&minor);
+#endif
 
 cleanup:
 #ifdef GSSEAP_DEBUG
@@ -86,19 +90,19 @@ gssEapAttrProvidersInit(OM_uint32 *minor)
 OM_uint32
 gssEapAttrProvidersFinalize(OM_uint32 *minor)
 {
-    OM_uint32 major = GSS_S_COMPLETE;
-
     if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
-        major = gssEapLocalAttrProviderFinalize(minor);
-        if (major == GSS_S_COMPLETE)
-            major = gssEapSamlAttrProvidersFinalize(minor);
-        if (major == GSS_S_COMPLETE)
-            major = gssEapRadiusAttrProviderFinalize(minor);
+#ifdef HAVE_SHIBRESOLVER
+        gssEapLocalAttrProviderFinalize(minor);
+#endif
+#ifdef HAVE_OPENSAML
+        gssEapSamlAttrProvidersFinalize(minor);
+#endif
+        gssEapRadiusAttrProviderFinalize(minor);
 
         gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
     }
 
-    return major;
+    return GSS_S_COMPLETE;
 }
 
 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
index e3f3567..2af0850 100644 (file)
@@ -53,8 +53,10 @@ typedef bool
                                void *data);
 
 #define ATTR_TYPE_RADIUS            0U                  /* RADIUS AVPs */
+#ifdef HAVE_OPENSAML
 #define ATTR_TYPE_SAML_ASSERTION    1U                  /* SAML assertion */
 #define ATTR_TYPE_SAML              2U                  /* SAML attributes */
+#endif
 #define ATTR_TYPE_LOCAL             3U                  /* Local attributes */
 #define ATTR_TYPE_MIN               ATTR_TYPE_RADIUS
 #define ATTR_TYPE_MAX               ATTR_TYPE_LOCAL
index 8ff6c50..78c3636 100644 (file)
@@ -52,12 +52,13 @@ gssEapAllocContext(OM_uint32 *minor,
     }
 
     if (GSSEAP_MUTEX_INIT(&ctx->mutex) != 0) {
-        *minor = errno;
+        *minor = GSSEAP_GET_LAST_ERROR();
         gssEapReleaseContext(&tmpMinor, &ctx);
         return GSS_S_FAILURE;
     }
 
     ctx->state = GSSEAP_STATE_INITIAL;
+    ctx->mechanismUsed = GSS_C_NO_OID;
 
     /*
      * Integrity, confidentiality, sequencing and replay detection are
@@ -70,8 +71,7 @@ gssEapAllocContext(OM_uint32 *minor,
                     GSS_C_INTEG_FLAG    |   /* integrity */
                     GSS_C_CONF_FLAG     |   /* confidentiality */
                     GSS_C_SEQUENCE_FLAG |   /* sequencing */
-                    GSS_C_REPLAY_FLAG|      /* replay detection */
-      GSS_C_MUTUAL_FLAG; /*xxx big hack */
+                    GSS_C_REPLAY_FLAG;      /* replay detection */
 
     *pCtx = ctx;
 
@@ -120,21 +120,22 @@ gssEapReleaseContext(OM_uint32 *minor,
     if (ctx->flags & CTX_FLAG_KRB_REAUTH) {
         gssDeleteSecContext(&tmpMinor, &ctx->reauthCtx, GSS_C_NO_BUFFER);
     } else
-#endif
+#endif /* GSSEAP_ENABLE_REAUTH */
     if (CTX_IS_INITIATOR(ctx)) {
         releaseInitiatorContext(&ctx->initiatorCtx);
-    } else {
+    }
 #ifdef GSSEAP_ENABLE_ACCEPTOR
+    else {
         releaseAcceptorContext(&ctx->acceptorCtx);
-#endif
     }
+#endif /* GSSEAP_ENABLE_ACCEPTOR */
 
     krb5_free_keyblock_contents(krbContext, &ctx->rfc3961Key);
     gssEapReleaseName(&tmpMinor, &ctx->initiatorName);
     gssEapReleaseName(&tmpMinor, &ctx->acceptorName);
     gssEapReleaseOid(&tmpMinor, &ctx->mechanismUsed);
     sequenceFree(&tmpMinor, &ctx->seqState);
-    gssEapReleaseCred(&tmpMinor, &ctx->defaultCred);
+    gssEapReleaseCred(&tmpMinor, &ctx->cred);
 
     GSSEAP_MUTEX_DESTROY(&ctx->mutex);
 
@@ -155,6 +156,8 @@ gssEapMakeToken(OM_uint32 *minor,
 {
     unsigned char *p;
 
+    assert(ctx->mechanismUsed != GSS_C_NO_OID);
+
     outputToken->length = tokenSize(ctx->mechanismUsed, innerToken->length);
     outputToken->value = GSSEAP_MALLOC(outputToken->length);
     if (outputToken->value == NULL) {
@@ -232,3 +235,149 @@ gssEapContextTime(OM_uint32 *minor,
 
     return GSS_S_COMPLETE;
 }
+
+static OM_uint32
+gssEapMakeOrVerifyTokenMIC(OM_uint32 *minor,
+                           gss_ctx_id_t ctx,
+                           gss_buffer_t tokenMIC,
+                           int verifyMIC)
+{
+    OM_uint32 major;
+    gss_iov_buffer_desc *iov = NULL;
+    size_t i = 0, j;
+    enum gss_eap_token_type tokType;
+    OM_uint32 micTokType;
+    unsigned char wireTokType[2];
+    unsigned char *innerTokTypes = NULL, *innerTokLengths = NULL;
+    const struct gss_eap_token_buffer_set *tokens;
+
+    tokens = verifyMIC ? ctx->inputTokens : ctx->outputTokens;
+
+    assert(tokens != NULL);
+
+    iov = GSSEAP_CALLOC(2 + (3 * tokens->buffers.count) + 1, sizeof(*iov));
+    if (iov == NULL) {
+        major = GSS_S_FAILURE;
+        *minor = ENOMEM;
+        goto cleanup;
+    }
+
+    innerTokTypes = GSSEAP_MALLOC(4 * tokens->buffers.count);
+    if (innerTokTypes == NULL) {
+        *minor = ENOMEM;
+        major = GSS_S_FAILURE;
+        goto cleanup;
+    }
+
+    innerTokLengths = GSSEAP_MALLOC(4 * tokens->buffers.count);
+    if (innerTokLengths == NULL) {
+        major = GSS_S_FAILURE;
+        *minor = ENOMEM;
+        goto cleanup;
+    }
+
+    /* Mechanism OID */
+    assert(ctx->mechanismUsed != GSS_C_NO_OID);
+    iov[i].type = GSS_IOV_BUFFER_TYPE_DATA;
+    iov[i].buffer.length = ctx->mechanismUsed->length;
+    iov[i].buffer.value = ctx->mechanismUsed->elements;
+    i++;
+
+    /* Token type */
+    if (CTX_IS_INITIATOR(ctx) ^ verifyMIC) {
+        tokType = TOK_TYPE_INITIATOR_CONTEXT;
+        micTokType = ITOK_TYPE_INITIATOR_MIC;
+    } else {
+        tokType = TOK_TYPE_ACCEPTOR_CONTEXT;
+        micTokType = ITOK_TYPE_ACCEPTOR_MIC;
+    }
+    store_uint16_be(tokType, wireTokType);
+
+    iov[i].type = GSS_IOV_BUFFER_TYPE_DATA;
+    iov[i].buffer.length = sizeof(wireTokType);
+    iov[i].buffer.value = wireTokType;
+    i++;
+
+    for (j = 0; j < tokens->buffers.count; j++) {
+        if (verifyMIC &&
+            (tokens->types[j] & ITOK_TYPE_MASK) == micTokType)
+            continue; /* will use this slot for trailer */
+
+        iov[i].type = GSS_IOV_BUFFER_TYPE_DATA;
+        iov[i].buffer.length = 4;
+        iov[i].buffer.value = &innerTokTypes[j * 4];
+        store_uint32_be(tokens->types[j] & ~(ITOK_FLAG_VERIFIED),
+                        iov[i].buffer.value);
+        i++;
+
+        iov[i].type = GSS_IOV_BUFFER_TYPE_DATA;
+        iov[i].buffer.length = 4;
+        iov[i].buffer.value = &innerTokLengths[j * 4];
+        store_uint32_be(tokens->buffers.elements[j].length,
+                        iov[i].buffer.value);
+        i++;
+
+        iov[i].type = GSS_IOV_BUFFER_TYPE_DATA;
+        iov[i].buffer = tokens->buffers.elements[j];
+        i++;
+    }
+
+    if (verifyMIC) {
+        assert(tokenMIC->length >= 16);
+
+        assert(i < 2 + (3 * tokens->buffers.count));
+
+        iov[i].type = GSS_IOV_BUFFER_TYPE_HEADER;
+        iov[i].buffer.length = 16;
+        iov[i].buffer.value = tokenMIC->value;
+        i++;
+
+        iov[i].type = GSS_IOV_BUFFER_TYPE_TRAILER;
+        iov[i].buffer.length = tokenMIC->length - 16;
+        iov[i].buffer.value = (unsigned char *)tokenMIC->value + 16;
+        i++;
+
+        major = gssEapUnwrapOrVerifyMIC(minor, ctx, NULL, NULL,
+                                        iov, i, TOK_TYPE_MIC);
+    } else {
+        iov[i++].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
+        major = gssEapWrapOrGetMIC(minor, ctx, FALSE, NULL,
+                                   iov, i, TOK_TYPE_MIC);
+        if (!GSS_ERROR(major))
+            *tokenMIC = iov[i - 1].buffer;
+    }
+
+cleanup:
+    if (iov != NULL)
+        gssEapReleaseIov(iov, tokens->buffers.count);
+    if (innerTokTypes != NULL)
+        GSSEAP_FREE(innerTokTypes);
+    if (innerTokLengths != NULL)
+        GSSEAP_FREE(innerTokLengths);
+
+    return major;
+}
+
+OM_uint32
+gssEapMakeTokenMIC(OM_uint32 *minor,
+                   gss_ctx_id_t ctx,
+                   gss_buffer_t tokenMIC)
+{
+    tokenMIC->length = 0;
+    tokenMIC->value = NULL;
+
+    return gssEapMakeOrVerifyTokenMIC(minor, ctx, tokenMIC, FALSE);
+}
+
+OM_uint32
+gssEapVerifyTokenMIC(OM_uint32 *minor,
+                     gss_ctx_id_t ctx,
+                     const gss_buffer_t tokenMIC)
+{
+    if (tokenMIC->length < 16) {
+        *minor = GSSEAP_TOK_TRUNC;
+        return GSS_S_BAD_SIG;
+    }
+
+    return gssEapMakeOrVerifyTokenMIC(minor, ctx, tokenMIC, TRUE);
+}
index 40a8c11..bd5bf66 100644 (file)
 
 #include "gssapiP_eap.h"
 
-#if defined(WIN32)
-/*This didn't work for me(Alexey) when Visual Studio 2005 Express is used: */
-#include <Shlobj.h>
-/*This didn't work for me(Kevin) when Visual Studio 2010 Express is used: */
-/*#include <ShFolder.h>*/
-
-#if !defined(snprintf)
-#define snprintf  _snprintf
-#endif
-
+#ifdef WIN32
+# include <shlobj.h>     /* may need to use ShFolder.h instead */
+# include <stdio.h>
 #else
-#include <pwd.h>
+# include <pwd.h>
 #endif
-#include <stdio.h> /* for BUFSIZ */
 
 OM_uint32
 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred)
@@ -66,7 +58,7 @@ gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred)
     }
 
     if (GSSEAP_MUTEX_INIT(&cred->mutex) != 0) {
-        *minor = errno;
+        *minor = GSSEAP_GET_LAST_ERROR();
         gssEapReleaseCred(&tmpMinor, &cred);
         return GSS_S_FAILURE;
     }
@@ -77,6 +69,18 @@ gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred)
     return GSS_S_COMPLETE;
 }
 
+static void
+zeroAndReleasePassword(gss_buffer_t password)
+{
+    if (password->value != NULL) {
+        memset(password->value, 0, password->length);
+        GSSEAP_FREE(password->value);
+    }
+
+    password->value = NULL;
+    password->length = 0;
+}
+
 OM_uint32
 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred)
 {
@@ -91,16 +95,15 @@ gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred)
     GSSEAP_KRB_INIT(&krbContext);
 
     gssEapReleaseName(&tmpMinor, &cred->name);
+    gssEapReleaseName(&tmpMinor, &cred->target);
 
-    if (cred->password.value != NULL) {
-        memset(cred->password.value, 0, cred->password.length);
-        GSSEAP_FREE(cred->password.value);
-    }
+    zeroAndReleasePassword(&cred->password);
 
-    if (cred->radiusConfigFile != NULL)
-        GSSEAP_FREE(cred->radiusConfigFile);
-    if (cred->radiusConfigStanza != NULL)
-        GSSEAP_FREE(cred->radiusConfigStanza);
+    gss_release_buffer(&tmpMinor, &cred->radiusConfigFile);
+    gss_release_buffer(&tmpMinor, &cred->radiusConfigStanza);
+    gss_release_buffer(&tmpMinor, &cred->caCertificate);
+    gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
+    gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);
 
 #ifdef GSSEAP_ENABLE_REAUTH
     if (cred->krbCredCache != NULL) {
@@ -123,54 +126,55 @@ gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred)
 }
 
 static OM_uint32
-readDefaultIdentityAndCreds(OM_uint32 *minor,
-                            gss_buffer_t defaultIdentity,
-                            gss_buffer_t defaultCreds)
+readStaticIdentityFile(OM_uint32 *minor,
+                       gss_buffer_t defaultIdentity,
+                       gss_buffer_t defaultPassword)
 {
     OM_uint32 major, tmpMinor;
     FILE *fp = NULL;
     char buf[BUFSIZ];
     char *ccacheName;
-#if !defined(WIN32)
-    char pwbuf[BUFSIZ];
+    int i = 0;
+#ifndef WIN32
     struct passwd *pw = NULL, pwd;
+    char pwbuf[BUFSIZ];
 #endif
 
     defaultIdentity->length = 0;
     defaultIdentity->value = NULL;
 
-    defaultCreds->length = 0;
-    defaultCreds->value = NULL;
+    if (defaultPassword != GSS_C_NO_BUFFER) {
+        defaultPassword->length = 0;
+        defaultPassword->value = NULL;
+    }
 
     ccacheName = getenv("GSSEAP_IDENTITY");
     if (ccacheName == NULL) {
-#if !defined(WIN32)
-        if (getpwuid_r(getuid(), &pwd, pwbuf, sizeof(pwbuf), &pw) != 0 ||
-            pw == NULL || pw->pw_dir == NULL) {
+#ifdef WIN32
+        TCHAR szPath[MAX_PATH];
+
+        if (!SUCCEEDED(SHGetFolderPath(NULL,
+                                       CSIDL_APPDATA, /* |CSIDL_FLAG_CREATE */
+                                       NULL, /* User access token */
+                                       0,    /* SHGFP_TYPE_CURRENT */
+                                       szPath))) {
             major = GSS_S_CRED_UNAVAIL;
-            *minor = errno;
+            *minor = GSSEAP_GET_LAST_ERROR(); /* XXX */
             goto cleanup;
         }
 
-        snprintf(buf, sizeof(buf), "%s/.gss_eap_id", pw->pw_dir);
-        ccacheName = buf;
+        snprintf(buf, sizeof(buf), "%s/.gss_eap_id", szPath);
 #else
-       TCHAR szPath[MAX_PATH];
-
-       if(!SUCCEEDED(SHGetFolderPath(NULL,
-                                     CSIDL_APPDATA, /* |CSIDL_FLAG_CREATE */
-                                     NULL, /* User access token */
-                                     0,    /* == SHGFP_TYPE_CURRENT from ShlObj.h */
-                                     szPath))) {
+        if (getpwuid_r(getuid(), &pwd, pwbuf, sizeof(pwbuf), &pw) != 0 ||
+            pw == NULL || pw->pw_dir == NULL) {
             major = GSS_S_CRED_UNAVAIL;
-////Needs to be correctly converted from the GetLastError();
-            *minor = errno;
+            *minor = GSSEAP_GET_LAST_ERROR();
             goto cleanup;
-       }
+        }
 
-        snprintf(buf, sizeof(buf), "%s/.gss_eap_id", szPath);
+        snprintf(buf, sizeof(buf), "%s/.gss_eap_id", pw->pw_dir);
+#endif /* WIN32 */
         ccacheName = buf;
-#endif
     }
 
     fp = fopen(ccacheName, "r");
@@ -195,16 +199,20 @@ readDefaultIdentityAndCreds(OM_uint32 *minor,
                 break;
         }
 
-        if (defaultIdentity->value == NULL)
+        if (i == 0)
             dst = defaultIdentity;
-        else if (defaultCreds->value == NULL)
-            dst = defaultCreds;
+        else if (i == 1)
+            dst = defaultPassword;
         else
             break;
 
-        major = duplicateBuffer(minor, &src, dst);
-        if (GSS_ERROR(major))
-            goto cleanup;
+        if (dst != GSS_C_NO_BUFFER) {
+            major = duplicateBuffer(minor, &src, dst);
+            if (GSS_ERROR(major))
+                goto cleanup;
+        }
+
+        i++;
     }
 
     if (defaultIdentity->length == 0) {
@@ -222,16 +230,29 @@ cleanup:
 
     if (GSS_ERROR(major)) {
         gss_release_buffer(&tmpMinor, defaultIdentity);
-        gss_release_buffer(&tmpMinor, defaultCreds);
+        zeroAndReleasePassword(defaultPassword);
     }
 
+    memset(buf, 0, sizeof(buf));
+
     return major;
 }
 
+gss_OID
+gssEapPrimaryMechForCred(gss_cred_id_t cred)
+{
+    gss_OID nameMech = GSS_C_NO_OID;
+
+    if (cred->mechanisms != GSS_C_NO_OID_SET &&
+        cred->mechanisms->count == 1)
+        nameMech = &cred->mechanisms->elements[0];
+
+    return nameMech;
+}
+
 OM_uint32
 gssEapAcquireCred(OM_uint32 *minor,
                   const gss_name_t desiredName,
-                  const gss_buffer_t password,
                   OM_uint32 timeReq GSSEAP_UNUSED,
                   const gss_OID_set desiredMechs,
                   int credUsage,
@@ -241,10 +262,6 @@ gssEapAcquireCred(OM_uint32 *minor,
 {
     OM_uint32 major, tmpMinor;
     gss_cred_id_t cred;
-    gss_buffer_desc defaultIdentity = GSS_C_EMPTY_BUFFER;
-    gss_name_t defaultIdentityName = GSS_C_NO_NAME;
-    gss_buffer_desc defaultCreds = GSS_C_EMPTY_BUFFER;
-    gss_OID nameMech = GSS_C_NO_OID;
 
     /* XXX TODO validate with changed set_cred_option API */
     *pCred = GSS_C_NO_CREDENTIAL;
@@ -278,21 +295,6 @@ gssEapAcquireCred(OM_uint32 *minor,
     if (GSS_ERROR(major))
         goto cleanup;
 
-    if (cred->mechanisms != GSS_C_NO_OID_SET &&
-        cred->mechanisms->count == 1)
-        nameMech = &cred->mechanisms->elements[0];
-
-    if (cred->flags & CRED_FLAG_INITIATE) {
-        major = readDefaultIdentityAndCreds(minor, &defaultIdentity, &defaultCreds);
-        if (major == GSS_S_COMPLETE) {
-            major = gssEapImportName(minor, &defaultIdentity, GSS_C_NT_USER_NAME,
-                                     nameMech, &defaultIdentityName);
-            if (GSS_ERROR(major))
-                goto cleanup;
-        } else if (major != GSS_S_CRED_UNAVAIL)
-            goto cleanup;
-    }
-
     if (desiredName != GSS_C_NO_NAME) {
         GSSEAP_MUTEX_LOCK(&desiredName->mutex);
 
@@ -303,78 +305,6 @@ gssEapAcquireCred(OM_uint32 *minor,
         }
 
         GSSEAP_MUTEX_UNLOCK(&desiredName->mutex);
-
-        if (defaultIdentityName != GSS_C_NO_NAME) {
-            int nameEqual;
-
-            major = gssEapCompareName(minor, desiredName,
-                                      defaultIdentityName, &nameEqual);
-            if (GSS_ERROR(major))
-                goto cleanup;
-            else if (nameEqual)
-                cred->flags |= CRED_FLAG_DEFAULT_IDENTITY;
-        }
-    } else {
-        if (cred->flags & CRED_FLAG_ACCEPT) {
-            gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER;
-            char serviceName[5 + MAXHOSTNAMELEN];
-
-            /* default host-based service is host@localhost */
-            memcpy(serviceName, "host@", 5);
-            if (gethostname(&serviceName[5], MAXHOSTNAMELEN) != 0) {
-                major = GSS_S_FAILURE;
-                *minor = GSSEAP_NO_HOSTNAME;
-                goto cleanup;
-            }
-
-            nameBuf.value = serviceName;
-            nameBuf.length = strlen((char *)nameBuf.value);
-
-            major = gssEapImportName(minor, &nameBuf, GSS_C_NT_HOSTBASED_SERVICE,
-                                     nameMech, &cred->name);
-            if (GSS_ERROR(major))
-                goto cleanup;
-        } else if (cred->flags & CRED_FLAG_INITIATE) {
-            if (defaultIdentityName == GSS_C_NO_NAME) {
-                major = GSS_S_CRED_UNAVAIL;
-                *minor = GSSEAP_NO_DEFAULT_IDENTITY;
-                goto cleanup;
-            }
-
-            cred->name = defaultIdentityName;
-            defaultIdentityName = GSS_C_NO_NAME;
-        }
-        cred->flags |= CRED_FLAG_DEFAULT_IDENTITY;
-    }
-
-    assert(cred->name != GSS_C_NO_NAME);
-
-    if (password != GSS_C_NO_BUFFER) {
-        major = duplicateBuffer(minor, password, &cred->password);
-        if (GSS_ERROR(major))
-            goto cleanup;
-
-        cred->flags |= CRED_FLAG_PASSWORD;
-    } else if (defaultCreds.value != NULL &&
-        (cred->flags & CRED_FLAG_DEFAULT_IDENTITY)) {
-        cred->password = defaultCreds;
-
-        defaultCreds.length = 0;
-        defaultCreds.value = NULL;
-
-        cred->flags |= CRED_FLAG_PASSWORD;
-    } else if (cred->flags & CRED_FLAG_INITIATE) {
-        /*
-         * OK, here we need to ask the supplicant if we have creds or it
-         * will acquire them, so GS2 can know whether to prompt for a
-         * password or not.
-         */
-#if 0
-        && !gssEapCanReauthP(cred, GSS_C_NO_NAME, timeReq)
-#endif
-        major = GSS_S_CRED_UNAVAIL;
-        *minor = GSSEAP_NO_DEFAULT_CRED;
-        goto cleanup;
     }
 
     if (pActualMechs != NULL) {
@@ -394,12 +324,6 @@ gssEapAcquireCred(OM_uint32 *minor,
 cleanup:
     if (GSS_ERROR(major))
         gssEapReleaseCred(&tmpMinor, &cred);
-    gssEapReleaseName(&tmpMinor, &defaultIdentityName);
-    gss_release_buffer(&tmpMinor, &defaultIdentity);
-    if (defaultCreds.value != NULL) {
-        memset(defaultCreds.value, 0, defaultCreds.length);
-        gss_release_buffer(&tmpMinor, &defaultCreds);
-    }
 
     return major;
 }
@@ -424,6 +348,72 @@ gssEapCredAvailable(gss_cred_id_t cred, gss_OID mech)
     return present;
 }
 
+static OM_uint32
+staticIdentityFileResolveDefaultIdentity(OM_uint32 *minor,
+                                         const gss_cred_id_t cred,
+                                         gss_name_t *pName)
+{
+    OM_uint32 major, tmpMinor;
+    gss_OID nameMech = gssEapPrimaryMechForCred(cred);
+    gss_buffer_desc defaultIdentity = GSS_C_EMPTY_BUFFER;
+
+    *pName = GSS_C_NO_NAME;
+
+    major = readStaticIdentityFile(minor, &defaultIdentity, GSS_C_NO_BUFFER);
+    if (major == GSS_S_COMPLETE) {
+        major = gssEapImportName(minor, &defaultIdentity, GSS_C_NT_USER_NAME,
+                                 nameMech, pName);
+    }
+
+    gss_release_buffer(&tmpMinor, &defaultIdentity);
+
+    return major;
+}
+
+static OM_uint32
+gssEapResolveCredIdentity(OM_uint32 *minor,
+                          gss_cred_id_t cred)
+{
+    OM_uint32 major;
+    gss_OID nameMech = gssEapPrimaryMechForCred(cred);
+
+    if (cred->name != GSS_C_NO_NAME) {
+        *minor = 0;
+        return GSS_S_COMPLETE;
+    }
+
+    if (cred->flags & CRED_FLAG_ACCEPT) {
+        gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER;
+        char serviceName[5 + MAXHOSTNAMELEN];
+
+        /* default host-based service is host@localhost */
+        memcpy(serviceName, "host@", 5);
+        if (gethostname(&serviceName[5], MAXHOSTNAMELEN) != 0) {
+            *minor = GSSEAP_NO_HOSTNAME;
+            return GSS_S_FAILURE;
+        }
+
+        nameBuf.value = serviceName;
+        nameBuf.length = strlen((char *)nameBuf.value);
+
+        major = gssEapImportName(minor, &nameBuf, GSS_C_NT_HOSTBASED_SERVICE,
+                                 nameMech, &cred->name);
+        if (GSS_ERROR(major))
+            return major;
+    } else if (cred->flags & CRED_FLAG_INITIATE) {
+#ifdef HAVE_MOONSHOT_GET_IDENTITY
+        major = libMoonshotResolveDefaultIdentity(minor, cred, &cred->name);
+        if (major == GSS_S_CRED_UNAVAIL)
+#endif
+            major = staticIdentityFileResolveDefaultIdentity(minor, cred, &cred->name);
+        if (major != GSS_S_CRED_UNAVAIL)
+            return major;
+    }
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
+
 OM_uint32
 gssEapInquireCred(OM_uint32 *minor,
                   gss_cred_id_t cred,
@@ -436,9 +426,16 @@ gssEapInquireCred(OM_uint32 *minor,
     time_t now, lifetime;
 
     if (name != NULL) {
-        major = gssEapDuplicateName(minor, cred->name, name);
+        major = gssEapResolveCredIdentity(minor, cred);
         if (GSS_ERROR(major))
-            return major;
+            goto cleanup;
+
+        if (cred->name != GSS_C_NO_NAME) {
+            major = gssEapDuplicateName(minor, cred->name, name);
+            if (GSS_ERROR(major))
+                goto cleanup;
+        } else
+            *name = GSS_C_NO_NAME;
     }
 
     if (cred_usage != NULL) {
@@ -463,7 +460,7 @@ gssEapInquireCred(OM_uint32 *minor,
         else
             major = gssEapIndicateMechs(minor, mechanisms);
         if (GSS_ERROR(major))
-            return major;
+            goto cleanup;
     }
 
     if (cred->expiryTime == 0) {
@@ -480,12 +477,263 @@ gssEapInquireCred(OM_uint32 *minor,
     }
 
     if (lifetime == 0) {
+        major = GSS_S_CREDENTIALS_EXPIRED;
         *minor = GSSEAP_CRED_EXPIRED;
-        return GSS_S_CREDENTIALS_EXPIRED;
+        goto cleanup;
     }
 
     major = GSS_S_COMPLETE;
     *minor = 0;
 
+cleanup:
+    return major;
+}
+
+OM_uint32
+gssEapSetCredPassword(OM_uint32 *minor,
+                      gss_cred_id_t cred,
+                      const gss_buffer_t password)
+{
+    OM_uint32 major, tmpMinor;
+    gss_buffer_desc newPassword = GSS_C_EMPTY_BUFFER;
+
+    if (cred->flags & CRED_FLAG_RESOLVED) {
+        major = GSS_S_FAILURE;
+        *minor = GSSEAP_CRED_RESOLVED;
+        goto cleanup;
+    }
+
+    if (password != GSS_C_NO_BUFFER) {
+        major = duplicateBuffer(minor, password, &newPassword);
+        if (GSS_ERROR(major))
+            goto cleanup;
+
+        cred->flags |= CRED_FLAG_PASSWORD;
+    } else {
+        cred->flags &= ~(CRED_FLAG_PASSWORD);
+    }
+
+    gss_release_buffer(&tmpMinor, &cred->password);
+    cred->password = newPassword;
+
+    major = GSS_S_COMPLETE;
+    *minor = 0;
+
+cleanup:
+    return major;
+}
+
+OM_uint32
+gssEapSetCredService(OM_uint32 *minor,
+                     gss_cred_id_t cred,
+                     const gss_name_t target)
+{
+    OM_uint32 major, tmpMinor;
+    gss_name_t newTarget = GSS_C_NO_NAME;
+
+    if (cred->flags & CRED_FLAG_RESOLVED) {
+        major = GSS_S_FAILURE;
+        *minor = GSSEAP_CRED_RESOLVED;
+        goto cleanup;
+    }
+
+    if (target != GSS_C_NO_NAME) {
+        major = gssEapDuplicateName(minor, target, &newTarget);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+    gssEapReleaseName(&tmpMinor, &cred->target);
+    cred->target = newTarget;
+
+    major = GSS_S_COMPLETE;
+    *minor = 0;
+
+cleanup:
+    return major;
+}
+
+static OM_uint32
+gssEapDuplicateCred(OM_uint32 *minor,
+                    const gss_cred_id_t src,
+                    gss_cred_id_t *pDst)
+{
+    OM_uint32 major, tmpMinor;
+    gss_cred_id_t dst = GSS_C_NO_CREDENTIAL;
+
+    *pDst = GSS_C_NO_CREDENTIAL;
+
+    major = gssEapAllocCred(minor, &dst);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    dst->flags = src->flags;
+
+    if (src->name != GSS_C_NO_NAME) {
+        major = gssEapDuplicateName(minor, src->name, &dst->name);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+    if (src->target != GSS_C_NO_NAME) {
+        major = gssEapDuplicateName(minor, src->target, &dst->target);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+    if (src->password.value != NULL) {
+        major = duplicateBuffer(minor, &src->password, &dst->password);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+    major = duplicateOidSet(minor, src->mechanisms, &dst->mechanisms);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    dst->expiryTime = src->expiryTime;
+
+    if (src->radiusConfigFile.value != NULL)
+        duplicateBufferOrCleanup(&src->radiusConfigFile, &dst->radiusConfigFile);
+    if (src->radiusConfigStanza.value != NULL)
+        duplicateBufferOrCleanup(&src->radiusConfigStanza, &dst->radiusConfigStanza);
+    if (src->caCertificate.value != NULL)
+        duplicateBufferOrCleanup(&src->caCertificate, &dst->caCertificate);
+    if (src->subjectNameConstraint.value != NULL)
+        duplicateBufferOrCleanup(&src->subjectNameConstraint, &dst->subjectNameConstraint);
+    if (src->subjectAltNameConstraint.value != NULL)
+        duplicateBufferOrCleanup(&src->subjectAltNameConstraint, &dst->subjectAltNameConstraint);
+
+#ifdef GSSEAP_ENABLE_REAUTH
+    /* XXX krbCredCache, reauthCred */
+#endif
+
+    *pDst = dst;
+    dst = GSS_C_NO_CREDENTIAL;
+
+    major = GSS_S_COMPLETE;
+    *minor = 0;
+
+cleanup:
+    gssEapReleaseCred(&tmpMinor, &dst);
+
+    return major;
+}
+
+static OM_uint32
+staticIdentityFileResolveInitiatorCred(OM_uint32 *minor, gss_cred_id_t cred)
+{
+    OM_uint32 major, tmpMinor;
+    gss_buffer_desc defaultIdentity = GSS_C_EMPTY_BUFFER;
+    gss_name_t defaultIdentityName = GSS_C_NO_NAME;
+    gss_buffer_desc defaultPassword = GSS_C_EMPTY_BUFFER;
+    int isDefaultIdentity = FALSE;
+
+    major = readStaticIdentityFile(minor, &defaultIdentity, &defaultPassword);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    major = gssEapImportName(minor, &defaultIdentity, GSS_C_NT_USER_NAME,
+                             gssEapPrimaryMechForCred(cred), &defaultIdentityName);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    if (defaultIdentityName == GSS_C_NO_NAME) {
+        if (cred->name == GSS_C_NO_NAME) {
+            major = GSS_S_CRED_UNAVAIL;
+            *minor = GSSEAP_NO_DEFAULT_IDENTITY;
+            goto cleanup;
+        }
+    } else {
+        if (cred->name == GSS_C_NO_NAME) {
+            cred->name = defaultIdentityName;
+            defaultIdentityName = GSS_C_NO_NAME;
+            isDefaultIdentity = TRUE;
+        } else {
+            major = gssEapCompareName(minor, cred->name,
+                                      defaultIdentityName, &isDefaultIdentity);
+            if (GSS_ERROR(major))
+                goto cleanup;
+        }
+    }
+
+    if (isDefaultIdentity &&
+        (cred->flags & CRED_FLAG_PASSWORD) == 0) {
+        major = gssEapSetCredPassword(minor, cred, &defaultPassword);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+cleanup:
+    gssEapReleaseName(&tmpMinor, &defaultIdentityName);
+    zeroAndReleasePassword(&defaultPassword);
+    gss_release_buffer(&tmpMinor, &defaultIdentity);
+
+    return major;
+}
+
+OM_uint32
+gssEapResolveInitiatorCred(OM_uint32 *minor,
+                           const gss_cred_id_t cred,
+                           const gss_name_t targetName
+#ifndef HAVE_MOONSHOT_GET_IDENTITY
+                                                       GSSEAP_UNUSED
+#endif
+                           ,
+                           gss_cred_id_t *pResolvedCred)
+{
+    OM_uint32 major, tmpMinor;
+    gss_cred_id_t resolvedCred = GSS_C_NO_CREDENTIAL;
+
+    if (cred == GSS_C_NO_CREDENTIAL) {
+        major = gssEapAcquireCred(minor,
+                                  GSS_C_NO_NAME,
+                                  GSS_C_INDEFINITE,
+                                  GSS_C_NO_OID_SET,
+                                  GSS_C_INITIATE,
+                                  &resolvedCred,
+                                  NULL,
+                                  NULL);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    } else {
+        if ((cred->flags & CRED_FLAG_INITIATE) == 0) {
+            major = GSS_S_NO_CRED;
+            *minor = GSSEAP_CRED_USAGE_MISMATCH;
+            goto cleanup;
+        }
+
+        major = gssEapDuplicateCred(minor, cred, &resolvedCred);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+    if ((resolvedCred->flags & CRED_FLAG_RESOLVED) == 0) {
+#ifdef HAVE_MOONSHOT_GET_IDENTITY
+        major = libMoonshotResolveInitiatorCred(minor, resolvedCred, targetName);
+        if (major == GSS_S_CRED_UNAVAIL)
+#endif
+            major = staticIdentityFileResolveInitiatorCred(minor, resolvedCred);
+        if (GSS_ERROR(major))
+            goto cleanup;
+
+        if ((resolvedCred->flags & CRED_FLAG_PASSWORD) == 0) {
+            major = GSS_S_CRED_UNAVAIL;
+            *minor = GSSEAP_NO_DEFAULT_CRED;
+            goto cleanup;
+        }
+
+        resolvedCred->flags |= CRED_FLAG_RESOLVED;
+    }
+
+    *pResolvedCred = resolvedCred;
+    resolvedCred = GSS_C_NO_CREDENTIAL;
+
+    major = GSS_S_COMPLETE;
+    *minor = 0;
+
+cleanup:
+    gssEapReleaseCred(&tmpMinor, &resolvedCred);
+
     return major;
 }
index f230da2..8d7a9d3 100644 (file)
@@ -191,7 +191,7 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
      */
     kiov[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
     kiov[i].data.length = k5_trailerlen;
-    kiov[i].data.data = kiov[i - 1].data.data + ec + 16; /* E(Header) */
+    kiov[i].data.data = (char *)kiov[i - 1].data.data + ec + 16; /* E(Header) */
     i++;
 
     *pkiov = kiov;
index 0133772..97eb1ed 100644 (file)
@@ -322,6 +322,7 @@ JSONObject::number(void) const
     return json_number_value(m_obj);
 }
 
+#ifdef HAVE_SHIBRESOLVER
 JSONObject
 JSONObject::ddf(DDF &ddf)
 {
@@ -409,6 +410,7 @@ JSONObject::ddf(void) const
 
     return ddf;
 }
+#endif /* HAVE_SHIBRESOLVER */
 
 bool JSONObject::isObject(void) const
 {
index e2c5e29..4ffecc8 100644 (file)
 #include <new>
 
 #include <jansson.h>
-#include <shibsp/remoting/ddf.h>
 
+#ifdef HAVE_SHIBRESOLVER
+#include <shibsp/remoting/ddf.h>
 using namespace shibsp;
+#endif
 
 namespace gss_eap_util {
     class JSONObject;
@@ -88,7 +90,9 @@ namespace gss_eap_util {
         static JSONObject object(void);
         static JSONObject array(void);
         static JSONObject null(void);
+#ifdef HAVE_SHIBRESOLVER
         static JSONObject ddf(DDF &value);
+#endif
 
         char *dump(size_t flags = 0) const;
         void dump(FILE *fp, size_t flags = JSON_INDENT(4)) const;
@@ -123,7 +127,9 @@ namespace gss_eap_util {
         json_int_t integer(void) const;
         double real(void) const;
         double number(void) const;
+#ifdef HAVE_SHIBRESOLVER
         DDF ddf(void) const;
+#endif
 
         bool isObject(void) const;
         bool isArray(void) const;
index 73cf108..d56c7a8 100644 (file)
@@ -80,18 +80,17 @@ cleanup:
 OM_uint32
 gssEapKerberosInit(OM_uint32 *minor, krb5_context *context)
 {
-    struct gss_eap_thread_local_data* tld;
+    struct gss_eap_thread_local_data *tld;
+
     *minor = 0;
 
     tld = gssEapGetThreadLocalData();
-    if (tld)
-    {
-        *context = tld->context;
+    if (tld != NULL) {
+        *context = tld->krbContext;
         if (*context == NULL) {
             *minor = initKrbContext(context);
-            if (*minor == 0) {
-                tld->context = *context;
-            }
+            if (*minor == 0)
+                tld->krbContext = *context;
         }
     }
     return *minor == 0 ? GSS_S_COMPLETE : GSS_S_FAILURE;
@@ -280,7 +279,7 @@ rfc3961ChecksumTypeForKey(OM_uint32 *minor,
 #endif /* HAVE_KRB5INT_C_MANDATORY_CKSUMTYPE */
 
     if (!krb5_c_is_keyed_cksum(*cksumtype)) {
-        *minor = KRB5KRB_AP_ERR_INAPP_CKSUM;
+        *minor = (OM_uint32)KRB5KRB_AP_ERR_INAPP_CKSUM;
         return GSS_S_FAILURE;
     }
 
diff --git a/moonshot/mech_eap/util_moonshot.c b/moonshot/mech_eap/util_moonshot.c
new file mode 100644 (file)
index 0000000..75db452
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2011, 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"
+
+#ifdef HAVE_MOONSHOT_GET_IDENTITY
+#include <libmoonshot.h>
+
+static OM_uint32
+libMoonshotMapError(OM_uint32 *minor,
+                    MoonshotError **pError)
+{
+    MoonshotError *error = *pError;
+
+    assert(error != NULL);
+
+    switch (error->code) {
+    case MOONSHOT_ERROR_UNABLE_TO_START_SERVICE:
+        *minor = GSSEAP_UNABLE_TO_START_IDENTITY_SERVICE;
+        break;
+    case MOONSHOT_ERROR_NO_IDENTITY_SELECTED:
+        *minor = GSSEAP_NO_IDENTITY_SELECTED;
+        break;
+    case MOONSHOT_ERROR_INSTALLATION_ERROR:
+        *minor = GSSEAP_IDENTITY_SERVICE_INSTALL_ERROR;
+        break;
+    case MOONSHOT_ERROR_OS_ERROR:
+        *minor = GSSEAP_IDENTITY_SERVICE_OS_ERROR;
+        break;
+    case MOONSHOT_ERROR_IPC_ERROR:
+        *minor = GSSEAP_IDENTITY_SERVICE_IPC_ERROR;
+        break;
+    default:
+        *minor = GSSEAP_IDENTITY_SERVICE_UNKNOWN_ERROR;
+        break;
+    }
+
+    gssEapSaveStatusInfo(*minor, error->message);
+    moonshot_error_free(error);
+    *pError = NULL;
+
+    return GSS_S_CRED_UNAVAIL;
+}
+
+OM_uint32
+libMoonshotResolveDefaultIdentity(OM_uint32 *minor,
+                                  const gss_cred_id_t cred,
+                                  gss_name_t *pName)
+{
+    OM_uint32 major, tmpMinor;
+    gss_OID nameMech = gssEapPrimaryMechForCred(cred);
+    gss_name_t name = GSS_C_NO_NAME;
+    gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
+    char *nai = NULL;
+    char *password = NULL;
+    char *serverCertificateHash = NULL;
+    char *caCertificate = NULL;
+    char *subjectNameConstraint = NULL;
+    char *subjectAltNameConstraint = NULL;
+    MoonshotError *error = NULL;
+
+    *pName = GSS_C_NO_NAME;
+
+    if (!moonshot_get_default_identity(&nai,
+                                       &password,
+                                       &serverCertificateHash,
+                                       &caCertificate,
+                                       &subjectNameConstraint,
+                                       &subjectAltNameConstraint,
+                                       &error)) {
+        if (error->code == MOONSHOT_ERROR_NO_IDENTITY_SELECTED) {
+            major = GSS_S_CRED_UNAVAIL;
+            *minor = GSSEAP_NO_DEFAULT_IDENTITY;
+            moonshot_error_free(error);
+        } else
+            major = libMoonshotMapError(minor, &error);
+        goto cleanup;
+    }
+
+    tmpBuffer.value = nai;
+    tmpBuffer.length = strlen(nai);
+
+    major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME, nameMech, &name);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    *pName = name;
+    name = GSS_C_NO_NAME;
+
+cleanup:
+    moonshot_free(nai);
+    moonshot_free(password);
+    moonshot_free(serverCertificateHash);
+    moonshot_free(caCertificate);
+    moonshot_free(subjectNameConstraint);
+    moonshot_free(subjectAltNameConstraint);
+
+    gssEapReleaseName(&tmpMinor, &name);
+
+    return major;
+}
+
+OM_uint32
+libMoonshotResolveInitiatorCred(OM_uint32 *minor,
+                                gss_cred_id_t cred,
+                                const gss_name_t targetName)
+{
+    OM_uint32 major, tmpMinor;
+    gss_OID nameMech = gssEapPrimaryMechForCred(cred);
+    gss_buffer_desc initiator = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc target = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
+    char *nai = NULL;
+    char *password = NULL;
+    char *serverCertificateHash = NULL;
+    char *caCertificate = NULL;
+    char *subjectNameConstraint = NULL;
+    char *subjectAltNameConstraint = NULL;
+    MoonshotError *error = NULL;
+
+    if (cred->name != GSS_C_NO_NAME) {
+        major = gssEapExportName(minor, cred->name, &initiator);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+    if (targetName != GSS_C_NO_NAME) {
+        major = gssEapExportName(minor, targetName, &target);
+        if (GSS_ERROR(major))
+            goto cleanup;
+    }
+
+    if (!moonshot_get_identity((const char *)initiator.value,
+                               (const char *)cred->password.value,
+                               (const char *)target.value,
+                               &nai,
+                               &password,
+                               &serverCertificateHash,
+                               &caCertificate,
+                               &subjectNameConstraint,
+                               &subjectAltNameConstraint,
+                               &error)) {
+        major = libMoonshotMapError(minor, &error);
+        goto cleanup;
+    }
+
+    gssEapReleaseName(&tmpMinor, &cred->name);
+
+    tmpBuffer.value = nai;
+    tmpBuffer.length = strlen(nai);
+
+    major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME,
+                             nameMech, &cred->name);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    tmpBuffer.value = password;
+    tmpBuffer.length = strlen(password);
+
+    major = gssEapSetCredPassword(minor, cred, &tmpBuffer);
+    if (GSS_ERROR(major))
+        goto cleanup;
+
+    gss_release_buffer(&tmpMinor, &cred->caCertificate);
+    gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
+    gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);
+
+    if (serverCertificateHash != NULL) {
+        size_t len = strlen(serverCertificateHash);
+
+        #define HASH_PREFIX             "hash://server/sha256/"
+        #define HASH_PREFIX_LEN         (sizeof(HASH_PREFIX) - 1)
+
+        cred->caCertificate.value = GSSEAP_MALLOC(HASH_PREFIX_LEN + len + 1);
+        if (cred->caCertificate.value == NULL) {
+            major = GSS_S_FAILURE;
+            *minor = ENOMEM;
+            goto cleanup;
+        }
+
+        memcpy(cred->caCertificate.value, HASH_PREFIX, HASH_PREFIX_LEN);
+        memcpy((char *)cred->caCertificate.value + HASH_PREFIX_LEN, serverCertificateHash, len);
+
+        ((char *)cred->caCertificate.value)[HASH_PREFIX_LEN + len] = '\0';
+
+        cred->caCertificate.length = HASH_PREFIX_LEN + len;
+    } else if (caCertificate != NULL) {
+        makeStringBufferOrCleanup(caCertificate, &cred->caCertificate);
+    }
+
+    if (subjectNameConstraint != NULL)
+        makeStringBufferOrCleanup(subjectNameConstraint, &cred->subjectNameConstraint);
+    if (subjectAltNameConstraint != NULL)
+        makeStringBufferOrCleanup(subjectAltNameConstraint, &cred->subjectAltNameConstraint);
+
+cleanup:
+    moonshot_free(nai);
+    moonshot_free(password);
+    moonshot_free(serverCertificateHash);
+    moonshot_free(caCertificate);
+    moonshot_free(subjectNameConstraint);
+    moonshot_free(subjectAltNameConstraint);
+
+    gss_release_buffer(&tmpMinor, &initiator);
+    gss_release_buffer(&tmpMinor, &target);
+
+    return major;
+}
+#endif /* HAVE_MOONSHOT_GET_IDENTITY */
index 0e7d004..6f038ef 100644 (file)
@@ -81,7 +81,7 @@ gssEapAllocName(OM_uint32 *minor, gss_name_t *pName)
     }
 
     if (GSSEAP_MUTEX_INIT(&name->mutex) != 0) {
-        *minor = errno;
+        *minor = GSSEAP_GET_LAST_ERROR();
         gssEapReleaseName(&tmpMinor, &name);
         return GSS_S_FAILURE;
     }
@@ -427,19 +427,18 @@ gssEapImportNameInternal(OM_uint32 *minor,
     name->mechanismUsed = mechanismUsed;
     mechanismUsed = GSS_C_NO_OID;
 
+#ifdef GSSEAP_ENABLE_ACCEPTOR
     if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
         gss_buffer_desc buf;
 
         buf.length = remain;
         buf.value = p;
-#ifdef GSSEAP_ENABLE_ACCEPTOR
+
         major = gssEapImportAttrContext(minor, &buf, name);
-#else
-               major = GSS_S_UNAVAILABLE;
-#endif
         if (GSS_ERROR(major))
             goto cleanup;
     }
+#endif
 
     major = GSS_S_COMPLETE;
     *minor = 0;
@@ -569,16 +568,14 @@ gssEapExportNameInternal(OM_uint32 *minor,
         exportedNameLen += 6 + mech->length;
     }
     exportedNameLen += 4 + nameBuf.length;
-    if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
 #ifdef GSSEAP_ENABLE_ACCEPTOR
+    if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
         major = gssEapExportAttrContext(minor, name, &attrs);
-#else
-               major = GSS_S_UNAVAILABLE;
-#endif
         if (GSS_ERROR(major))
             goto cleanup;
         exportedNameLen += attrs.length;
     }
+#endif
 
     exportedName->value = GSSEAP_MALLOC(exportedNameLen);
     if (exportedName->value == NULL) {
@@ -678,15 +675,13 @@ gssEapCanonicalizeName(OM_uint32 *minor,
         goto cleanup;
     }
 
-    if (input_name->attrCtx != NULL) {
 #ifdef GSSEAP_ENABLE_ACCEPTOR
+    if (input_name->attrCtx != NULL) {
         major = gssEapDuplicateAttrContext(minor, input_name, name);
-#else
-               major = GSS_S_UNAVAILABLE;
-#endif
         if (GSS_ERROR(major))
             goto cleanup;
     }
+#endif
 
     *dest_name = name;
 
index 82d12cb..d209347 100644 (file)
@@ -154,7 +154,7 @@ OM_uint32
 gssEapRadiusMapError(OM_uint32 *minor,
                      struct rs_error *err);
 
-////This really need to be a function call on Windows
+/* This really needs to be a function call on Windows */
 #define RS_CONFIG_FILE      SYSCONFDIR "/radsec.conf"
 
 #define VENDORPEC_MS                        311 /* RFC 2548 */
@@ -171,9 +171,6 @@ gssEapRadiusMapError(OM_uint32 *minor,
 #define PW_SAML_AAA_ASSERTION               132
 #define PW_MS_WINDOWS_AUTH_DATA             133
 
-#define IS_RADIUS_ERROR(code)               ((code) >= ERROR_TABLE_BASE_rse && \
-                                             (code) <= ERROR_TABLE_BASE_rse + RSE_TIMEOUT_IO)
-
 #ifdef __cplusplus
 }
 #endif
index 41bedad..9a3862a 100644 (file)
@@ -46,6 +46,7 @@
 #include <xmltooling/util/DateTime.h>
 
 #include <saml/exceptions.h>
+#include <saml/SAMLConfig.h>
 #include <saml/saml1/core/Assertions.h>
 #include <saml/saml2/core/Assertions.h>
 #include <saml/saml2/metadata/Metadata.h>
@@ -322,8 +323,17 @@ gss_eap_saml_assertion_provider::prefix(void) const
 bool
 gss_eap_saml_assertion_provider::init(void)
 {
-    gss_eap_attr_ctx::registerProvider(ATTR_TYPE_SAML_ASSERTION, createAttrContext);
-    return true;
+    bool ret = false;
+
+    try {
+        ret = SAMLConfig::getConfig().init();
+    } catch (exception &e) {
+    }
+
+    if (ret)
+        gss_eap_attr_ctx::registerProvider(ATTR_TYPE_SAML_ASSERTION, createAttrContext);
+
+    return ret;
 }
 
 void
index 311de41..4c268ec 100644 (file)
  * Local attribute provider implementation.
  */
 
+#include "gssapiP_eap.h"
+
 #include <xmltooling/XMLObject.h>
+#ifndef HAVE_OPENSAML
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/ParserPool.h>
+#endif
 
 #include <saml/saml2/core/Assertions.h>
 
 
 #include <sstream>
 
-#include "gssapiP_eap.h"
-
 using namespace shibsp;
 using namespace shibresolver;
-using namespace opensaml::saml2md;
-using namespace opensaml;
 using namespace xmltooling;
 using namespace std;
+#ifdef HAVE_OPENSAML
+using namespace opensaml::saml2md;
+using namespace opensaml;
+#else
+using namespace xercesc;
+#endif
 
 gss_eap_shib_attr_provider::gss_eap_shib_attr_provider(void)
 {
@@ -143,12 +151,33 @@ gss_eap_shib_attr_provider::initWithGssContext(const gss_eap_attr_ctx *manager,
         gss_release_buffer(&minor, &mechName);
     }
 
+#ifdef HAVE_OPENSAML
     const gss_eap_saml_assertion_provider *saml;
     saml = static_cast<const gss_eap_saml_assertion_provider *>
         (m_manager->getProvider(ATTR_TYPE_SAML_ASSERTION));
     if (saml != NULL && saml->getAssertion() != NULL) {
         resolver->addToken(saml->getAssertion());
     }
+#else
+    /* If no OpenSAML, parse the XML assertion explicitly */
+    const gss_eap_radius_attr_provider *radius;
+    int authenticated, complete;
+    gss_buffer_desc value = GSS_C_EMPTY_BUFFER;
+
+    radius = static_cast<const gss_eap_radius_attr_provider *>
+        (m_manager->getProvider(ATTR_TYPE_RADIUS));
+    if (radius != NULL &&
+        radius->getFragmentedAttribute(PW_SAML_AAA_ASSERTION,
+                                       VENDORPEC_UKERNA,
+                                       &authenticated, &complete, &value)) {
+        string str((char *)value.value, value.length);
+        istringstream istream(str);
+        DOMDocument *doc = XMLToolingConfig::getConfig().getParser().parse(istream);
+        const XMLObjectBuilder *b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        resolver->addToken(b->buildFromDocument(doc));
+        gss_release_buffer(&minor, &value);
+    }
+#endif /* HAVE_OPENSAML */
 
     try {
         resolver->resolve();
@@ -436,8 +465,7 @@ gss_eap_shib_attr_provider::init(void)
     bool ret = false;
 
     try {
-        if (SPConfig::getConfig().getFeatures() == 0)
-            ret = ShibbolethResolver::init();
+        ret = ShibbolethResolver::init();
     } catch (exception &e) {
     }
 
index bf216dd..8d36085 100644 (file)
@@ -98,29 +98,22 @@ static OM_uint32
 makeErrorToken(OM_uint32 *minor,
                OM_uint32 majorStatus,
                OM_uint32 minorStatus,
-               gss_buffer_set_t *outputToken)
+               struct gss_eap_token_buffer_set *token)
 {
-    OM_uint32 major;
+    OM_uint32 major, tmpMinor;
     unsigned char errorData[8];
     gss_buffer_desc errorBuffer;
 
     assert(GSS_ERROR(majorStatus));
 
-    major = gss_create_empty_buffer_set(minor, outputToken);
-    if (GSS_ERROR(major))
-        return major;
-
     /*
      * Only return error codes that the initiator could have caused,
      * to avoid information leakage.
      */
-#ifdef GSSEAP_ENABLE_ACCEPTOR
     if (IS_RADIUS_ERROR(minorStatus)) {
         /* Squash RADIUS error codes */
         minorStatus = GSSEAP_RADIUS_PROT_FAILURE;
-    } else 
-#endif 
-       if (!IS_WIRE_ERROR(minorStatus)) {
+    } else if (!IS_WIRE_ERROR(minorStatus)) {
         /* Don't return non-wire error codes */
         return GSS_S_COMPLETE;
     }
@@ -130,64 +123,26 @@ makeErrorToken(OM_uint32 *minor,
     store_uint32_be(majorStatus, &errorData[0]);
     store_uint32_be(minorStatus, &errorData[4]);
 
-    errorBuffer.length = sizeof(errorData);
-    errorBuffer.value = errorData;
-
-    major = gss_add_buffer_set_member(minor, &errorBuffer, outputToken);
-    if (GSS_ERROR(major))
+    major = gssEapAllocInnerTokens(&tmpMinor, 1, token);
+    if (GSS_ERROR(major)) {
+        *minor = tmpMinor;
         return major;
-
-    return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-allocInnerTokens(OM_uint32 *minor,
-                 size_t count,
-                 gss_buffer_set_t *pTokens,
-                 OM_uint32 **pTokenTypes)
-{
-    OM_uint32 major, tmpMinor;
-    gss_buffer_set_t tokens = GSS_C_NO_BUFFER_SET;
-    OM_uint32 *tokenTypes = NULL;
-
-    major = gss_create_empty_buffer_set(minor, &tokens);
-    if (GSS_ERROR(major))
-        goto cleanup;
-
-    assert(tokens->count == 0);
-    assert(tokens->elements == NULL);
-
-    tokens->elements = (gss_buffer_desc *)GSSEAP_CALLOC(count, sizeof(gss_buffer_desc));
-    if (tokens->elements == NULL) {
-        major = GSS_S_FAILURE;
-        *minor = ENOMEM;
-        goto cleanup;
-    }
-
-    tokenTypes = (OM_uint32 *)GSSEAP_CALLOC(count, sizeof(OM_uint32));
-    if (tokenTypes == NULL) {
-        major = GSS_S_FAILURE;
-        *minor = ENOMEM;
-        goto cleanup;
     }
 
-    major = GSS_S_COMPLETE;
-    *minor = 0;
+    errorBuffer.length = sizeof(errorData);
+    errorBuffer.value = errorData;
 
-cleanup:
+    major = duplicateBuffer(&tmpMinor, &errorBuffer, &token->buffers.elements[0]);
     if (GSS_ERROR(major)) {
-        gss_release_buffer_set(&tmpMinor, &tokens);
-        tokens = GSS_C_NO_BUFFER_SET;
-        if (tokenTypes != NULL) {
-            GSSEAP_FREE(tokenTypes);
-            tokenTypes = NULL;
-        }
+        gssEapReleaseInnerTokens(&tmpMinor, token, 1);
+        *minor = tmpMinor;
+        return major;
     }
 
-    *pTokens = tokens;
-    *pTokenTypes = tokenTypes;
+    token->types[0] = ITOK_TYPE_CONTEXT_ERR | ITOK_FLAG_CRITICAL;
 
-    return major;
+    *minor = 0;
+    return GSS_S_COMPLETE;
 }
 
 OM_uint32
@@ -205,11 +160,10 @@ gssEapSmStep(OM_uint32 *minor,
              size_t smCount)
 {
     OM_uint32 major, tmpMajor, tmpMinor;
+    struct gss_eap_token_buffer_set inputTokens = { { 0, GSS_C_NO_BUFFER }, NULL };
+    struct gss_eap_token_buffer_set outputTokens = { { 0, GSS_C_NO_BUFFER }, NULL };
     gss_buffer_desc unwrappedInputToken = GSS_C_EMPTY_BUFFER;
     gss_buffer_desc unwrappedOutputToken = GSS_C_EMPTY_BUFFER;
-    gss_buffer_set_t innerInputTokens = GSS_C_NO_BUFFER_SET;
-    gss_buffer_set_t innerOutputTokens = GSS_C_NO_BUFFER_SET;
-    OM_uint32 *inputTokenTypes = NULL, *outputTokenTypes = NULL;
     unsigned int smFlags = 0;
     size_t i, j;
     int initialContextToken = 0;
@@ -250,17 +204,17 @@ gssEapSmStep(OM_uint32 *minor,
 
     assert(ctx->state < GSSEAP_STATE_ESTABLISHED);
 
-    major = gssEapDecodeInnerTokens(minor, &unwrappedInputToken,
-                                    &innerInputTokens, &inputTokenTypes);
+    major = gssEapDecodeInnerTokens(minor, &unwrappedInputToken, &inputTokens);
     if (GSS_ERROR(major))
         goto cleanup;
 
-    assert(innerInputTokens != GSS_C_NO_BUFFER_SET);
-
-    major = allocInnerTokens(minor, smCount, &innerOutputTokens, &outputTokenTypes);
+    major = gssEapAllocInnerTokens(minor, smCount, &outputTokens);
     if (GSS_ERROR(major))
         goto cleanup;
 
+    ctx->inputTokens = &inputTokens;
+    ctx->outputTokens = &outputTokens;
+
     /* Process all the tokens that are valid for the current state. */
     for (i = 0; i < smCount; i++) {
         struct gss_eap_sm *smp = &sm[i];
@@ -286,8 +240,8 @@ gssEapSmStep(OM_uint32 *minor,
             processToken = 1;
         } else if ((smFlags & SM_FLAG_TRANSITED) == 0) {
             /* Don't regurgitate a token which belonds to a previous state. */
-            for (j = 0; j < innerInputTokens->count; j++) {
-                if ((inputTokenTypes[j] & ITOK_TYPE_MASK) == smp->inputTokenType) {
+            for (j = 0; j < inputTokens.buffers.count; j++) {
+                if ((inputTokens.types[j] & ITOK_TYPE_MASK) == smp->inputTokenType) {
                     if (processToken) {
                         /* Check for duplicate inner tokens */
                         major = GSS_S_DEFECTIVE_TOKEN;
@@ -295,8 +249,8 @@ gssEapSmStep(OM_uint32 *minor,
                         break;
                     }
                     processToken = 1;
-                    innerInputToken = &innerInputTokens->elements[j];
-                    inputTokenType = &inputTokenTypes[j];
+                    innerInputToken = &inputTokens.buffers.elements[j];
+                    inputTokenType = &inputTokens.types[j];
                 }
             }
             if (GSS_ERROR(major))
@@ -324,18 +278,18 @@ gssEapSmStep(OM_uint32 *minor,
                 smFlags |= SM_FLAG_TRANSITED;
 
             if (innerOutputToken.value != NULL) {
-                innerOutputTokens->elements[innerOutputTokens->count] = innerOutputToken;
+                outputTokens.buffers.elements[outputTokens.buffers.count] = innerOutputToken;
                 assert(smp->outputTokenType != ITOK_TYPE_NONE);
-                outputTokenTypes[innerOutputTokens->count] = smp->outputTokenType;
+                outputTokens.types[outputTokens.buffers.count] = smp->outputTokenType;
                 if (smFlags & SM_FLAG_OUTPUT_TOKEN_CRITICAL)
-                    outputTokenTypes[innerOutputTokens->count] |= ITOK_FLAG_CRITICAL;
-                innerOutputTokens->count++;
+                    outputTokens.types[outputTokens.buffers.count] |= ITOK_FLAG_CRITICAL;
+                outputTokens.buffers.count++;
             }
             /*
              * Break out if we made a state transition and have some tokens to send.
              */
             if ((smFlags & SM_FLAG_TRANSITED) &&
-                 ((smFlags & SM_FLAG_FORCE_SEND_TOKEN) || innerOutputTokens->count != 0)) {
+                 ((smFlags & SM_FLAG_FORCE_SEND_TOKEN) || outputTokens.buffers.count != 0)) {
                 SM_ASSERT_VALID(ctx, major);
                 break;
             }
@@ -348,13 +302,13 @@ gssEapSmStep(OM_uint32 *minor,
         }
     }
 
-    assert(innerOutputTokens->count <= smCount);
+    assert(outputTokens.buffers.count <= smCount);
 
     /* Check we understood all critical tokens sent by peer */
     if (!GSS_ERROR(major)) {
-        for (j = 0; j < innerInputTokens->count; j++) {
-            if ((inputTokenTypes[j] & ITOK_FLAG_CRITICAL) &&
-                (inputTokenTypes[j] & ITOK_FLAG_VERIFIED) == 0) {
+        for (j = 0; j < inputTokens.buffers.count; j++) {
+            if ((inputTokens.types[j] & ITOK_FLAG_CRITICAL) &&
+                (inputTokens.types[j] & ITOK_FLAG_VERIFIED) == 0) {
                 major = GSS_S_UNAVAILABLE;
                 *minor = GSSEAP_CRIT_ITOK_UNAVAILABLE;
                 goto cleanup;
@@ -368,25 +322,21 @@ gssEapSmStep(OM_uint32 *minor,
             goto cleanup; /* return error directly to caller */
 
         /* replace any emitted tokens with error token */
-        gss_release_buffer_set(&tmpMinor, &innerOutputTokens);
+        gssEapReleaseInnerTokens(&tmpMinor, &outputTokens, 1);
 
-        tmpMajor = makeErrorToken(&tmpMinor, major, *minor, &innerOutputTokens);
+        tmpMajor = makeErrorToken(&tmpMinor, major, *minor, &outputTokens);
         if (GSS_ERROR(tmpMajor)) {
             major = tmpMajor;
             *minor = tmpMinor;
             goto cleanup;
         }
-
-        if (innerOutputTokens->count != 0)
-            outputTokenTypes[0] = ITOK_TYPE_CONTEXT_ERR | ITOK_FLAG_CRITICAL;
     }
 
     /* Format output token from inner tokens */
-    if (innerOutputTokens->count != 0 ||            /* inner tokens to send */
+    if (outputTokens.buffers.count != 0 ||            /* inner tokens to send */
         !CTX_IS_INITIATOR(ctx) ||                   /* any leg acceptor */
         !CTX_IS_ESTABLISHED(ctx)) {                 /* non-last leg initiator */
-        tmpMajor = gssEapEncodeInnerTokens(&tmpMinor, innerOutputTokens,
-                                           outputTokenTypes, &unwrappedOutputToken);
+        tmpMajor = gssEapEncodeInnerTokens(&tmpMinor, &outputTokens, &unwrappedOutputToken);
         if (tmpMajor == GSS_S_COMPLETE) {
             if (CTX_IS_INITIATOR(ctx))
                 tokType = TOK_TYPE_INITIATOR_CONTEXT;
@@ -409,13 +359,13 @@ gssEapSmStep(OM_uint32 *minor,
     SM_ASSERT_VALID(ctx, major);
 
 cleanup:
-    gss_release_buffer_set(&tmpMinor, &innerInputTokens);
-    gss_release_buffer_set(&tmpMinor, &innerOutputTokens);
-    if (inputTokenTypes != NULL)
-        GSSEAP_FREE(inputTokenTypes);
-    if (outputTokenTypes != NULL)
+    gssEapReleaseInnerTokens(&tmpMinor, &inputTokens, 0);
+    gssEapReleaseInnerTokens(&tmpMinor, &inputTokens, 1);
+
     gss_release_buffer(&tmpMinor, &unwrappedOutputToken);
-        GSSEAP_FREE(outputTokenTypes);
+
+    ctx->inputTokens = NULL;
+    ctx->outputTokens = NULL;
 
     return major;
 }
index 7679233..f6feeba 100644 (file)
  * SUCH DAMAGE.
  */
 
-/* Access all thread-local data through these methods which 
- * use pthreads to manage thread-local memory on Unix and TlsFoo() on Windows.
- * This would be more flexible, scalable, and extensible 
- * if implemented through a callback interface, but given that 
- * there are currently only two 'clients', hard-coding seems more 
- * straightforward
+/*
+ * Thread local data abstraction, using pthreads on Unix and the TlsXXX
+ * APIs on Windows.
  */
+
 #include "gssapiP_eap.h"
 
 /* Clean up thread-local data; called on thread detach */
 static void
-destroyThreadLocalData(struct gss_eap_thread_local_datatld)
+destroyThreadLocalData(struct gss_eap_thread_local_data *tld)
 {
-    if (tld->status_info)
-        gssEapDestroyStatusInfo(tld->status_info);
-    if (tld->context)
-        gssEapDestroyKrbContext(tld->context);
+    if (tld->statusInfo != NULL)
+        gssEapDestroyStatusInfo(tld->statusInfo);
+    if (tld->krbContext != NULL)
+        gssEapDestroyKrbContext(tld->krbContext);
     GSSEAP_FREE(tld);
 }
 
 #ifdef WIN32
 
-/* This is the tls index returned by TlsAlloc() on process init.  
- * Each thread, on thread attach in DllMain(), allocates its thread-local data and uses this index with TlsSetValue() to store it.
- * It can then subsequently be retrieved with TlsGetValue()
+/*
+ * This is the tls index returned by TlsAlloc() on process init.
+ * Each thread, on thread attach in DllMain(), allocates its thread-local
+ * data and uses this index with TlsSetValue() to store it.
+ * It can then subsequently be retrieved with TlsGetValue().
  */
 static DWORD tlsIndex;
 
 /* Access thread-local data */
 struct gss_eap_thread_local_data *
-gssEapGetThreadLocalData()
+gssEapGetThreadLocalData(void)
 {
     return TlsGetValue(tlsIndex);
 }
-/* DllMain() is the entry-point function for this DLL. */
-BOOL WINAPI DllMain(HINSTANCE hDLL, /* DLL module handle */
-    DWORD reason,                    /* reason called */
-    LPVOID reserved)                 /* reserved */
-{ 
+
+BOOL WINAPI
+DllMain(HINSTANCE hDLL,     /* DLL module handle */
+        DWORD reason,       /* reason called */
+        LPVOID reserved)    /* reserved */
+{
     struct gss_eap_thread_local_data *tlsData;
 
-    switch (reason) 
-    { 
-        // The DLL is loading due to process 
-        // initialization or a call to LoadLibrary. 
-        case DLL_PROCESS_ATTACH: 
+    switch (reason) {
+        case DLL_PROCESS_ATTACH:
             /* Allocate a TLS index. */
-            if ((tlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) 
-                return FALSE; 
+            gssEapInitiatorInit();
+            tlsIndex = TlsAlloc();
+            if (tlsIndex == TLS_OUT_OF_INDEXES)
+                return FALSE;
             /* No break: Initialize the index for first thread.*/
-        /* The attached process creates a new thread. */
-        case DLL_THREAD_ATTACH: 
+        case DLL_THREAD_ATTACH:
             /* Initialize the TLS index for this thread. */
             tlsData = GSSEAP_CALLOC(1, sizeof(*tlsData));
-            if (tlsData != NULL) 
-                TlsSetValue(tlsIndex, tlsData); 
-            break; 
-        /* The thread of the attached process terminates. */
-        case DLL_THREAD_DETACH: 
+            if (tlsData != NULL)
+                TlsSetValue(tlsIndex, tlsData);
+            break;
+        case DLL_THREAD_DETACH:
             /* Release the allocated memory for this thread. */
-            tlsData = TlsGetValue(tlsIndex); 
-            if (tlsData != NULL) 
-            {
-                destroyThreadLocalData(tlsData); 
+            tlsData = TlsGetValue(tlsIndex);
+            if (tlsData != NULL) {
+                destroyThreadLocalData(tlsData);
                 TlsSetValue(tlsIndex, NULL);
             }
-            break; 
-        /* DLL unload due to process termination or FreeLibrary. */
-        case DLL_PROCESS_DETACH: 
+            break;
+        case DLL_PROCESS_DETACH:
             /* Release the allocated memory for this thread. */
-            tlsData = TlsGetValue(tlsIndex); 
-            if (tlsData != NULL) 
-                destroyThreadLocalData(tlsData); 
+            tlsData = TlsGetValue(tlsIndex);
+            if (tlsData != NULL)
+                destroyThreadLocalData(tlsData);
             /* Release the TLS index. */
-            TlsFree(tlsIndex); 
-            break; 
-        default: 
-            break; 
-    } 
-    return TRUE; 
-    UNREFERENCED_PARAMETER(hDLL); 
-    UNREFERENCED_PARAMETER(reserved); 
+            TlsFree(tlsIndex);
+            gssEapFinalize();
+            break;
+        default:
+            break;
+    }
+
+    return TRUE;
+    UNREFERENCED_PARAMETER(hDLL);
+    UNREFERENCED_PARAMETER(reserved);
 }
 
 #else /* WIN32 */
 
-/* PTHREAD implementation */
+/* pthreads implementation */
+
 static GSSEAP_THREAD_ONCE tldKeyOnce = GSSEAP_ONCE_INITIALIZER;
 static GSSEAP_THREAD_KEY tldKey;
-static void 
-pthreadDestroyThreadLocalData(void* arg)
+
+static void
+pthreadDestroyThreadLocalData(void *arg)
 {
     struct gss_eap_thread_local_data* tld = arg;
-    if (tld)
-    {
+
+    if (tld != NULL)
         destroyThreadLocalData(tld);
-    }
 }
 
-static void 
+static void
 createThreadLocalDataKey(void)
 {
     GSSEAP_KEY_CREATE(&tldKey, pthreadDestroyThreadLocalData);
 }
 
-struct gss_eap_thread_local_data * 
+struct gss_eap_thread_local_data *
 gssEapGetThreadLocalData()
 {
     struct gss_eap_thread_local_data *tld;
+
     GSSEAP_ONCE(&tldKeyOnce, createThreadLocalDataKey);
+
     tld = GSSEAP_GETSPECIFIC(tldKey);
-    if (!tld)
-    {
+    if (tld == NULL) {
         tld = GSSEAP_CALLOC(1, sizeof(*tld));
+        if (tld == NULL)
+            return NULL;
+
         GSSEAP_SETSPECIFIC(tldKey, tld);
     }
+
     return tld;
 }
 
index a929198..9b05560 100644 (file)
@@ -59,8 +59,7 @@
 
 OM_uint32
 gssEapEncodeInnerTokens(OM_uint32 *minor,
-                        gss_buffer_set_t extensions,
-                        OM_uint32 *types,
+                        struct gss_eap_token_buffer_set *tokens,
                         gss_buffer_t buffer)
 {
     OM_uint32 major, tmpMinor;
@@ -70,10 +69,8 @@ gssEapEncodeInnerTokens(OM_uint32 *minor,
     buffer->value = NULL;
     buffer->length = 0;
 
-    if (extensions != GSS_C_NO_BUFFER_SET) {
-        for (i = 0; i < extensions->count; i++) {
-            required += 8 + extensions->elements[i].length;
-        }
+    for (i = 0; i < tokens->buffers.count; i++) {
+        required += 8 + tokens->buffers.elements[i].length;
     }
 
     /*
@@ -91,22 +88,20 @@ gssEapEncodeInnerTokens(OM_uint32 *minor,
     buffer->length = required;
     p = (unsigned char *)buffer->value;
 
-    if (extensions != GSS_C_NO_BUFFER_SET) {
-        for (i = 0; i < extensions->count; i++) {
-            gss_buffer_t extension = &extensions->elements[i];
+    for (i = 0; i < tokens->buffers.count; i++) {
+        gss_buffer_t tokenBuffer = &tokens->buffers.elements[i];
 
-            assert((types[i] & ITOK_FLAG_VERIFIED) == 0); /* private flag */
+        assert((tokens->types[i] & ITOK_FLAG_VERIFIED) == 0); /* private flag */
 
-             /*
-              * Extensions are encoded as type-length-value, where the upper
-              * bit of the type indicates criticality.
-              */
-            store_uint32_be(types[i], &p[0]);
-            store_uint32_be(extension->length, &p[4]);
-            memcpy(&p[8], extension->value, extension->length);
+         /*
+          * Extensions are encoded as type-length-value, where the upper
+          * bit of the type indicates criticality.
+          */
+        store_uint32_be(tokens->types[i], &p[0]);
+        store_uint32_be(tokenBuffer->length, &p[4]);
+        memcpy(&p[8], tokenBuffer->value, tokenBuffer->length);
 
-            p += 8 + extension->length;
-        }
+        p += 8 + tokenBuffer->length;
     }
 
     assert(p == (unsigned char *)buffer->value + required);
@@ -126,21 +121,16 @@ cleanup:
 OM_uint32
 gssEapDecodeInnerTokens(OM_uint32 *minor,
                         const gss_buffer_t buffer,
-                        gss_buffer_set_t *pExtensions,
-                        OM_uint32 **pTypes)
+                        struct gss_eap_token_buffer_set *tokens)
 {
     OM_uint32 major, tmpMinor;
-    gss_buffer_set_t extensions = GSS_C_NO_BUFFER_SET;
-    OM_uint32 *types = NULL;
     unsigned char *p;
+    size_t count = 0;
     size_t remain;
 
-    *pExtensions = GSS_C_NO_BUFFER_SET;
-    *pTypes = NULL;
-
-    major = gss_create_empty_buffer_set(minor, &extensions);
-    if (GSS_ERROR(major))
-        goto cleanup;
+    tokens->buffers.count = 0;
+    tokens->buffers.elements = NULL;
+    tokens->types = NULL;
 
     if (buffer->length == 0) {
         major = GSS_S_COMPLETE;
@@ -152,7 +142,7 @@ gssEapDecodeInnerTokens(OM_uint32 *minor,
 
     do {
         OM_uint32 *ntypes;
-        gss_buffer_desc extension;
+        gss_buffer_desc tokenBuffer, *newTokenBuffers;
 
         if (remain < 8) {
             major = GSS_S_DEFECTIVE_TOKEN;
@@ -160,42 +150,61 @@ gssEapDecodeInnerTokens(OM_uint32 *minor,
             goto cleanup;
         }
 
-        ntypes = GSSEAP_REALLOC(types,
-                                (extensions->count + 1) * sizeof(OM_uint32));
-        if (ntypes == NULL) {
-            major = GSS_S_FAILURE;
-            *minor = ENOMEM;
-            goto cleanup;
+        if (tokens->buffers.count <= count) {
+            if (count == 0)
+                count = 1;
+            else
+                count *= 2;
+
+            ntypes = GSSEAP_MALLOC(count * sizeof(OM_uint32));
+            if (ntypes == NULL) {
+                major = GSS_S_FAILURE;
+                *minor = ENOMEM;
+                goto cleanup;
+            }
+            if (tokens->types != NULL) {
+                memcpy(ntypes, tokens->types, tokens->buffers.count * sizeof(OM_uint32));
+                GSSEAP_FREE(tokens->types);
+            }
+            tokens->types = ntypes;
+
+            newTokenBuffers = GSSEAP_MALLOC(count * sizeof(gss_buffer_desc));
+            if (newTokenBuffers == NULL) {
+                major = GSS_S_FAILURE;
+                *minor = ENOMEM;
+                goto cleanup;
+            }
+            if (tokens->buffers.elements != NULL) {
+                memcpy(newTokenBuffers, tokens->buffers.elements,
+                       tokens->buffers.count * sizeof(gss_buffer_desc));
+                GSSEAP_FREE(tokens->buffers.elements);
+            }
+            tokens->buffers.elements = newTokenBuffers;
         }
-        types = ntypes;
 
-        types[extensions->count] = load_uint32_be(&p[0]);
-        extension.length = load_uint32_be(&p[4]);
+        tokens->types[tokens->buffers.count] = load_uint32_be(&p[0]);
+        tokenBuffer.length = load_uint32_be(&p[4]);
 
-        if (remain < 8 + extension.length) {
+        if (remain < 8 + tokenBuffer.length) {
             major = GSS_S_DEFECTIVE_TOKEN;
             *minor = GSSEAP_TOK_TRUNC;
             goto cleanup;
         }
-        extension.value = &p[8];
+        tokenBuffer.value = &p[8];
 
-        major = gss_add_buffer_set_member(minor, &extension, &extensions);
-        if (GSS_ERROR(major))
-            goto cleanup;
+        tokens->buffers.elements[tokens->buffers.count] = tokenBuffer;
+        tokens->buffers.count++;
 
-        p      += 8 + extension.length;
-        remain -= 8 + extension.length;
+        p      += 8 + tokenBuffer.length;
+        remain -= 8 + tokenBuffer.length;
     } while (remain != 0);
 
+    major = GSS_S_COMPLETE;
+    *minor = 0;
+
 cleanup:
-    if (GSS_ERROR(major)) {
-        gss_release_buffer_set(&tmpMinor, &extensions);
-        if (types != NULL)
-            GSSEAP_FREE(types);
-    } else {
-        *pExtensions = extensions;
-        *pTypes = types;
-    }
+    if (GSS_ERROR(major))
+        gssEapReleaseInnerTokens(&tmpMinor, tokens, 0);
 
     return major;
 }
@@ -415,3 +424,70 @@ verifyTokenHeader(OM_uint32 *minor,
     *minor = 0;
     return GSS_S_COMPLETE;
 }
+
+OM_uint32
+gssEapAllocInnerTokens(OM_uint32 *minor,
+                       size_t count,
+                       struct gss_eap_token_buffer_set *tokens)
+{
+    OM_uint32 major;
+
+    tokens->buffers.count = 0;
+    tokens->buffers.elements = (gss_buffer_desc *)GSSEAP_CALLOC(count, sizeof(gss_buffer_desc));
+    if (tokens->buffers.elements == NULL) {
+        major = GSS_S_FAILURE;
+        *minor = ENOMEM;
+        goto cleanup;
+    }
+
+    tokens->types = (OM_uint32 *)GSSEAP_CALLOC(count, sizeof(OM_uint32));
+    if (tokens->types == NULL) {
+        major = GSS_S_FAILURE;
+        *minor = ENOMEM;
+        goto cleanup;
+    }
+
+    major = GSS_S_COMPLETE;
+    *minor = 0;
+
+cleanup:
+    if (GSS_ERROR(major)) {
+        if (tokens->buffers.elements != NULL) {
+            GSSEAP_FREE(tokens->buffers.elements);
+            tokens->buffers.elements = NULL;
+        }
+        if (tokens->types != NULL) {
+            GSSEAP_FREE(tokens->types);
+            tokens->types = NULL;
+        }
+    }
+
+    return major;
+}
+
+OM_uint32
+gssEapReleaseInnerTokens(OM_uint32 *minor,
+                         struct gss_eap_token_buffer_set *tokens,
+                         int freeBuffers)
+{
+    OM_uint32 tmpMinor;
+    size_t i;
+
+    if (tokens->buffers.elements != NULL) {
+        if (freeBuffers) {
+            for (i = 0; i < tokens->buffers.count; i++)
+                gss_release_buffer(&tmpMinor, &tokens->buffers.elements[i]);
+        }
+        GSSEAP_FREE(tokens->buffers.elements);
+        tokens->buffers.elements = NULL;
+    }
+    tokens->buffers.count = 0;
+
+    if (tokens->types != NULL) {
+        GSSEAP_FREE(tokens->types);
+        tokens->types = NULL;
+    }
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
diff --git a/moonshot/mech_eap/vasprintf.c b/moonshot/mech_eap/vasprintf.c
deleted file mode 100644 (file)
index 85d4fb1..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * printf.c
- *
- * Copyright 2003, 2004, 2005, 2007, 2008 Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- *   require a specific license from the United States Government.
- *   It is the responsibility of any person or organization contemplating
- *   export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission.  Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- *
- *
- * Provide {,v}asprintf for platforms that don't have them.
- */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t)((size_t)0 - 1))
-#endif
-#if defined(HAS_VA_COPY) || defined(va_copy)
-/* Do nothing.  */
-#else
-#define va_copy(dest, src)      ((dest) = (src))
-#endif
-#if 0 /* Given that this used to specify 'memcmp' instead of 'memcpy', it is safe to say it has not really been tested and we should not use it */
-/* Assume array type, but still simply copyable.
-
-   There is, theoretically, the possibility that va_start will
-   allocate some storage pointed to by the va_list, and in that case
-   we'll just lose.  If anyone cares, we could try to devise a test
-   for that case.  */
-#define va_copy(dest, src)      memcpy(dest, src, sizeof(va_list)) /* was 'memcmp' which is almost certainly not right...*/
-#endif
-
-/* On error: BSD: Set *ret to NULL.  GNU: *ret is undefined.
-
-   Since we want to be able to use the GNU version directly, we need
-   provide only the weaker guarantee in this version.  */
-int
-vasprintf(char **ret, const char *format, va_list ap)
-{
-    va_list ap2;
-    char *str = NULL, *nstr;
-    size_t len = 80;
-    int len2;
-
-    while (1) {
-        if (len >= SIZE_MAX || len == 0)
-            goto fail;
-        nstr = realloc(str, len);
-        if (nstr == NULL)
-            goto fail;
-        str = nstr;
-
-        /* In theory, by c99 rules, vsnprintf() may destructively modify the passed in va_list.  Therefore, we va_copy it first.
-         * In practice, the va_list _isn't_ modified on windows and windows does not provide a native va_copy(), but the va_list 
-         * is just a pointer, which is why the va_copy() we defined above works.  If there were a platform where vsnprintf, etc,
-         * destructively modified the va_list _and_ it didn't define a va_copy() macro _and_ it didn't have a vasprintf(), 
-         * we could be in trouble.  But I don't think I'll be losing any sleep. */
-        va_copy(ap2, ap);
-        len2 = vsnprintf(str, len, format, ap2);
-        va_end(ap2);
-        /* ISO C vsnprintf returns the needed length.  Some old
-           vsnprintf implementations return -1 on truncation.  */
-        if (len2 < 0) {
-            /* Don't know how much space we need, just that we didn't
-               supply enough; get a bigger buffer and try again.  */
-            if (len <= SIZE_MAX/2)
-                len *= 2;
-            else if (len < SIZE_MAX)
-                len = SIZE_MAX;
-            else
-                goto fail;
-        } else if ((unsigned int) len2 >= SIZE_MAX) {
-            /* Need more space than we can request.  */
-            goto fail;
-        } else if ((size_t) len2 >= len) {
-            /* Need more space, but we know how much.  */
-            len = (size_t) len2 + 1;
-        } else {
-            /* Success!  */
-            break;
-        }
-    }
-    /* We might've allocated more than we need, if we're still using
-       the initial guess, or we got here by doubling.  */
-    if ((size_t) len2 < len - 1) {
-        nstr = realloc(str, (size_t) len2 + 1);
-        if (nstr)
-            str = nstr;
-    }
-    *ret = str;
-    return len2;
-
-fail:
-    free(str);
-    return -1;
-}
index 89bb081..d72c57e 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_verify_mic(OM_uint32 *minor,
                gss_ctx_id_t ctx,
                gss_buffer_t message_buffer,
index ef1b5fc..2e27fb3 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_wrap(OM_uint32 *minor,
          gss_ctx_id_t ctx,
          int conf_req_flag,
index 0162916..a40b980 100644 (file)
@@ -336,7 +336,7 @@ cleanup:
     return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
 }
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_wrap_iov(OM_uint32 *minor,
              gss_ctx_id_t ctx,
              int conf_req_flag,
index 9ee1364..65bb6ec 100644 (file)
@@ -196,7 +196,7 @@ gssEapWrapIovLength(OM_uint32 *minor,
     return GSS_S_COMPLETE;
 }
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_wrap_iov_length(OM_uint32 *minor,
                     gss_ctx_id_t ctx,
                     int conf_req_flag,
index b5f9cdf..d11fd63 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "gssapiP_eap.h"
 
-OM_uint32 KRB5_CALLCONV
+OM_uint32 GSSAPI_CALLCONV
 gss_wrap_size_limit(OM_uint32 *minor,
                     gss_ctx_id_t ctx,
                     int conf_req_flag,