From: Luke Howard Date: Wed, 14 Sep 2011 06:11:37 +0000 (+1000) Subject: Merge branch 'windows' X-Git-Tag: 0.9.2~138 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=commitdiff_plain;h=5bf61a81066da96847e6317c00db9d4f96447db2;hp=-c Merge branch 'windows' 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 --- 5bf61a81066da96847e6317c00db9d4f96447db2 diff --combined acinclude.m4 index 8ecdd9c,336332a..ea542db --- a/acinclude.m4 +++ b/acinclude.m4 @@@ -1,5 -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,16 -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([ @@@ -129,7 -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). @@@ -137,12 -144,11 +151,12 @@@ ]) 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 @@@ -155,7 -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 @@@ -165,14 -170,11 +179,14 @@@ 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). @@@ -185,53 -187,17 +199,53 @@@ els 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) @@@ -308,43 -274,3 +322,43 @@@ els 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 + diff --combined configure.ac index b70e29e,5948d74..3d77b93 --- a/configure.ac +++ b/configure.ac @@@ -2,16 -2,19 +2,19 @@@ AC_PREREQ([2.61] AC_INIT([mech_eap], [0.1], [bugs@project-moonshot.org]) dnl AC_CONFIG_MACRO_DIR([m4]) dnl AM_INIT_AUTOMAKE([silent-rules]) + AC_USE_SYSTEM_EXTENSIONS + 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]) + LT_INIT([dlopen disable-static win32-dll]) - AC_PROG_CC + dnl AC_PROG_CC AC_PROG_CXX AC_CONFIG_HEADERS([config.h]) AC_CHECK_HEADERS(stdarg.h stdio.h stdint.h sys/param.h) AC_REPLACE_FUNCS(vasprintf) - AC_GNU_SOURCE dnl Check if we're on Solaris and set CFLAGS accordingly dnl AC_CANONICAL_TARGET @@@ -66,21 -69,15 +69,22 @@@ AM_CONDITIONAL(GSSEAP_ENABLE_ACCEPTOR, 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 diff --combined mech_eap/Makefile.am index c07f6ab,4ccdabe..ba6e8dd --- a/mech_eap/Makefile.am +++ b/mech_eap/Makefile.am @@@ -4,32 -4,33 +4,46 @@@ gssincludedir = $(includedir)/gssap 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 \ - -DEAP_TLS -DEAP_PEAP -DEAP_TTLS -DEAP_MD5 -DEAP_MSCHAPv2 -DEAP_GTC -DEAP_OTP -DEAP_LEAP -DEAP_PSK -DEAP_PAX -DEAP_SAKE -DEAP_GPSK -DEAP_GPSK_SHA256 -DEAP_SERVER_IDENTITY -DEAP_SERVER_TLS -DEAP_SERVER_PEAP -DEAP_SERVER_TTLS -DEAP_SERVER_MD5 -DEAP_SERVER_MSCHAPV2 -DEAP_SERVER_GTC -DEAP_SERVER_PSK -DEAP_SERVER_PAX -DEAP_SERVER_SAKE -DEAP_SERVER_GPSK -DEAP_SERVER_GPSK_SHA256 -DIEEE8021X_EAPOL + -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 + mech_eap_la_CFLAGS = -Zi + mech_eap_la_CXXFLAGS = -Zi + else + EAP_CFLAGS += -DEAP_TLS -DEAP_PEAP -DEAP_TTLS -DEAP_MD5 -DEAP_MSCHAPv2 -DEAP_GTC -DEAP_OTP -DEAP_LEAP -DEAP_PSK -DEAP_PAX -DEAP_SAKE -DEAP_GPSK -DEAP_GPSK_SHA256 -DEAP_SERVER_IDENTITY -DEAP_SERVER_TLS -DEAP_SERVER_PEAP -DEAP_SERVER_TTLS -DEAP_SERVER_MD5 -DEAP_SERVER_MSCHAPV2 -DEAP_SERVER_GTC -DEAP_SERVER_PSK -DEAP_SERVER_PAX -DEAP_SERVER_SAKE -DEAP_SERVER_GPSK -DEAP_SERVER_GPSK_SHA256 -DIEEE8021X_EAPOL + OS_LIBS = + mech_eap_la_CFLAGS = -Werror -Wall -Wunused-parameter + 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 \ @@@ -38,6 -39,7 +52,6 @@@ canonicalize_name.c \ compare_name.c \ context_time.c \ - delete_name_attribute.c \ delete_sec_context.c \ display_name.c \ display_name_ext.c \ @@@ -45,8 -47,10 +59,8 @@@ 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 \ @@@ -63,17 -67,21 +77,17 @@@ 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 \ @@@ -82,7 -90,6 +96,7 @@@ util_krb.c \ util_lucid.c \ util_mech.c \ + util_moonshot.c \ util_name.c \ util_oid.c \ util_ordering.c \ @@@ -95,33 -102,12 +109,33 @@@ 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 @@@ -138,6 -124,9 +152,6 @@@ radius_ad_la_SOURCES = util_adshim. endif endif -if TARGET_WINDOWS -mech_eap_la_LDFLAGS += -debug -else gsseap_err.h gsseap_err.c: gsseap_err.et $(COMPILE_ET) $< @@@ -148,4 -137,4 +162,3 @@@ radsec_err.c: radsec_err. clean-generic: rm -f gsseap_err.[ch] radsec_err.[ch] - -endif diff --combined mech_eap/delete_sec_context.c index ab3c54f,9619ead..7913e45 --- a/mech_eap/delete_sec_context.c +++ b/mech_eap/delete_sec_context.c @@@ -36,7 -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) @@@ -67,7 -67,7 +67,7 @@@ iov[1].buffer.value = NULL; iov[1].buffer.length = 0; - major = gssEapWrapOrGetMIC(minor, ctx, FALSE, FALSE, + major = gssEapWrapOrGetMIC(minor, ctx, FALSE, NULL, iov, 2, TOK_TYPE_DELETE_CONTEXT); if (GSS_ERROR(major)) { GSSEAP_MUTEX_UNLOCK(&ctx->mutex); diff --combined mech_eap/display_status.c index e5774d5,89d8628..6eac550 --- a/mech_eap/display_status.c +++ b/mech_eap/display_status.c @@@ -43,7 -43,7 +43,7 @@@ struct gss_eap_status_info }; void -gssEapDestroyStatusInfo(struct gss_eap_status_info* p) +gssEapDestroyStatusInfo(struct gss_eap_status_info *p) { struct gss_eap_status_info *next; @@@ -65,10 -65,10 +65,10 @@@ static voi 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 +78,9 @@@ } next = &p->next; } - p = GSSEAP_CALLOC(1, sizeof(*p)); } + if (p == NULL) { if (message != NULL) GSSEAP_FREE(message); @@@ -93,44 -93,28 +93,43 @@@ 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; } } - return NULL; } 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; @@@ -138,19 -122,19 +137,19 @@@ 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; @@@ -159,6 -143,18 +158,6 @@@ 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); @@@ -179,26 -175,3 +178,26 @@@ 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); +} diff --combined mech_eap/export_sec_context.c index 5f89903,98003d5..50f90f7 --- a/mech_eap/export_sec_context.c +++ b/mech_eap/export_sec_context.c @@@ -36,7 -36,6 +36,7 @@@ */ #include "gssapiP_eap.h" + #ifdef GSSEAP_ENABLE_ACCEPTOR static OM_uint32 gssEapExportPartialContext(OM_uint32 *minor, @@@ -47,7 -46,6 +47,6 @@@ size_t length, serverLen = 0; unsigned char *p; char serverBuf[MAXHOSTNAMELEN]; - if (ctx->acceptorCtx.radConn != NULL) { if (rs_conn_get_current_peer(ctx->acceptorCtx.radConn, serverBuf, sizeof(serverBuf)) != 0) { @@@ -60,7 -58,6 +59,6 @@@ } serverLen = strlen(serverBuf); } - length = 4 + serverLen + 4 + ctx->acceptorCtx.state.length; token->value = GSSEAP_MALLOC(length); @@@ -138,7 -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 @@@ -212,7 -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) diff --combined mech_eap/gssapiP_eap.h index c0fd894,a2ce5d6..cd5315d --- a/mech_eap/gssapiP_eap.h +++ b/mech_eap/gssapiP_eap.h @@@ -42,27 -42,16 +42,27 @@@ #include #include #include -#if defined(HAVE_UNISTD_H) +#ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_STDLIB_H #include +#endif +#ifdef HAVE_STDARG_H #include +#endif #include -#if defined(HAVE_SYS_PARAM_H) +#ifdef HAVE_SYS_PARAM_H #include #endif +#ifdef WIN32 +#ifndef MAXHOSTNAMELEN +# include +# define MAXHOSTNAMELEN NI_MAXHOST +#endif +#endif + /* GSS headers */ #include #include @@@ -89,21 -78,28 +89,25 @@@ typedef const gss_OID_desc *gss_const_O #include #include - /* FreeRADIUS headers */ #ifdef GSSEAP_ENABLE_ACCEPTOR + /* FreeRADIUS headers */ #ifdef __cplusplus extern "C" { #define operator fr_operator #endif #include #include + -////Because freeradius/autoconf.h is evil! -////#undef uint16_t -////#undef uint32_t -////#undef uint8_t + #undef pid_t + ++/* libradsec headers */ #include #include #ifdef __cplusplus #undef operator } #endif -#endif /*GSSEAP_ENABLE_ACCEPTOR*/ +#endif /* GSSEAP_ENABLE_ACCEPTOR */ #include "gsseap_err.h" #include "radsec_err.h" @@@ -131,16 -127,14 +135,16 @@@ struct gss_name_struc 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 @@@ -152,15 -146,11 +156,15 @@@ struct gss_cred_id_struc 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; @@@ -222,7 -212,7 +226,7 @@@ struct gss_ctx_id_struc 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 @@@ -235,8 -225,6 +239,8 @@@ #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 @@@ -248,36 -236,6 +252,36 @@@ #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, @@@ -321,18 -279,9 +325,18 @@@ rfc4121Flags(gss_ctx_id_t ctx, int rece 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, @@@ -340,13 -289,6 +344,13 @@@ gss_buffer_t token); +/* eap_mech.c */ +void +gssEapInitiatorInit(void); + +void +gssEapFinalize(void); + #ifdef __cplusplus } #endif diff --combined mech_eap/import_sec_context.c index 1b9c0ad,8854bf4..a2a712c --- a/mech_eap/import_sec_context.c +++ b/mech_eap/import_sec_context.c @@@ -114,7 -114,7 +114,7 @@@ gssEapImportPartialContext(OM_uint32 *m return GSS_S_COMPLETE; } - #endif + #endif /* GSSEAP_ENABLE_ACCEPTOR */ static OM_uint32 importMechanismOid(OM_uint32 *minor, @@@ -305,7 -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 @@@ -317,11 -316,11 +317,11 @@@ if (GSS_ERROR(major)) return major; } -#endif #ifdef GSSEAP_DEBUG assert(remain == 0); #endif - #endif ++#endif /* GSSEAP_ENABLE_ACCEPTOR */ major = GSS_S_COMPLETE; *minor = 0; @@@ -329,7 -328,7 +329,7 @@@ 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) diff --combined mech_eap/util.h index 5f0bc9d,6e35fd4..ae83923 --- a/mech_eap/util.h +++ b/mech_eap/util.h @@@ -61,10 -61,10 +61,10 @@@ #ifndef _UTIL_H_ #define _UTIL_H_ 1 -#if defined(HAVE_SYS_PARAM_H) +#ifdef HAVE_SYS_PARAM_H #include #endif -#if defined(HAVE_STDINT_H) +#ifdef HAVE_STDINT_H #include #endif #include @@@ -72,9 -72,8 +72,9 @@@ #include -#if defined(WIN32) -#define inline __inline +#ifdef WIN32 +#define inline __inline +#define snprintf _snprintf #endif #ifdef __cplusplus @@@ -85,25 -84,44 +85,25 @@@ extern "C" #define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) #endif - #if !defined(WIN32) && (!(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))) + #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, @@@ -114,13 -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) { @@@ -201,17 -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); @@@ -234,26 -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, @@@ -261,22 -255,6 +261,22 @@@ 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 @@@ -514,17 -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 @@@ -706,29 -673,16 +706,29 @@@ voi 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); @@@ -754,18 -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; \ @@@ -773,32 -715,26 +773,30 @@@ } while (0) #ifdef WIN32 + #include -#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)) - /* XXX yet to implement thread-local wrappers */ ++/* 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 -#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)) @@@ -812,8 -748,7 +810,8 @@@ #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 @@@ -964,23 -899,6 +962,23 @@@ gssBufferToKrbData(gss_buffer_t buffer 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 @@@ -988,8 -906,8 +986,8 @@@ #ifdef GSSEAP_ENABLE_ACCEPTOR #include "util_json.h" #include "util_attr.h" -#endif #include "util_base64.h" - #endif ++#endif /* GSSEAP_ENABLE_ACCEPTOR */ #ifdef GSSEAP_ENABLE_REAUTH #include "util_reauth.h" #endif diff --combined mech_eap/util_context.c index 61b9b23,8ff6c50..78c3636 --- a/mech_eap/util_context.c +++ b/mech_eap/util_context.c @@@ -52,13 -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 @@@ -71,7 -70,8 +71,7 @@@ 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; @@@ -100,7 -100,7 +100,7 @@@ releaseAcceptorContext(struct gss_eap_a if (ctx->vps != NULL) gssEapRadiusFreeAvps(&tmpMinor, &ctx->vps); } - #endif + #endif /* GSSEAP_ENABLE_ACCEPTOR */ OM_uint32 gssEapReleaseContext(OM_uint32 *minor, @@@ -120,22 -120,21 +120,22 @@@ 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 ++#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); @@@ -156,8 -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) { @@@ -235,149 -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); +} diff --combined mech_eap/util_cred.c index 856c0a5,40a8c11..bd5bf66 --- a/mech_eap/util_cred.c +++ b/mech_eap/util_cred.c @@@ -36,11 -36,20 +36,12 @@@ #include "gssapiP_eap.h" -#if defined(WIN32) -/*This didn't work for me(Alexey) when Visual Studio 2005 Express is used: */ -#include -/*This didn't work for me(Kevin) when Visual Studio 2010 Express is used: */ -/*#include */ - -#if !defined(snprintf) -#define snprintf _snprintf -#endif - +#ifdef WIN32 - #include ++# include /* may need to use ShFolder.h instead */ ++# include #else --#include ++# include #endif -#include /* for BUFSIZ */ OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred) @@@ -57,7 -66,7 +58,7 @@@ } if (GSSEAP_MUTEX_INIT(&cred->mutex) != 0) { - *minor = errno; + *minor = GSSEAP_GET_LAST_ERROR(); gssEapReleaseCred(&tmpMinor, &cred); return GSS_S_FAILURE; } @@@ -68,18 -77,6 +69,18 @@@ 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) { @@@ -94,15 -91,16 +95,15 @@@ 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) { @@@ -125,55 -123,54 +126,55 @@@ } 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, ++ 0, /* SHGFP_TYPE_CURRENT */ + szPath))) { major = GSS_S_CRED_UNAVAIL; - *minor = GetLastError(); - *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"); @@@ -198,20 -195,16 +199,20 @@@ 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) { @@@ -229,29 -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, @@@ -261,6 -241,10 +262,6 @@@ { 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; @@@ -294,6 -278,21 +295,6 @@@ 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); @@@ -304,6 -303,78 +305,6 @@@ } 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) { @@@ -323,6 -394,12 +324,6 @@@ 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; } @@@ -347,72 -424,6 +348,72 @@@ gssEapCredAvailable(gss_cred_id_t cred 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, @@@ -425,16 -436,9 +426,16 @@@ 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) { @@@ -459,7 -463,7 +460,7 @@@ else major = gssEapIndicateMechs(minor, mechanisms); if (GSS_ERROR(major)) - return major; + goto cleanup; } if (cred->expiryTime == 0) { @@@ -476,263 -480,12 +477,263 @@@ } 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; } diff --combined mech_eap/util_krb.c index 8589aa0,73cf108..d56c7a8 --- a/mech_eap/util_krb.c +++ b/mech_eap/util_krb.c @@@ -80,20 -80,20 +80,19 @@@ 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 -280,7 +279,7 @@@ rfc3961ChecksumTypeForKey(OM_uint32 *mi #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 --combined mech_eap/util_name.c index f14ca4c,0e7d004..6f038ef --- a/mech_eap/util_name.c +++ b/mech_eap/util_name.c @@@ -81,7 -81,7 +81,7 @@@ gssEapAllocName(OM_uint32 *minor, gss_n } if (GSSEAP_MUTEX_INIT(&name->mutex) != 0) { - *minor = errno; + *minor = GSSEAP_GET_LAST_ERROR(); gssEapReleaseName(&tmpMinor, &name); return GSS_S_FAILURE; } @@@ -112,7 -112,6 +112,6 @@@ gssEapReleaseName(OM_uint32 *minor, gss GSSEAP_KRB_INIT(&krbContext); krb5_free_principal(krbContext, name->krbPrincipal); gssEapReleaseOid(&tmpMinor, &name->mechanismUsed); - #ifdef GSSEAP_ENABLE_ACCEPTOR gssEapReleaseAttrContext(&tmpMinor, name); #endif @@@ -428,18 -427,19 +427,18 @@@ gssEapImportNameInternal(OM_uint32 *min 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,14 -569,16 +568,14 @@@ gssEapExportNameInternal(OM_uint32 *min 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) { @@@ -676,13 -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; diff --combined mech_eap/util_radius.h index da790ab,82d12cb..d209347 --- a/mech_eap/util_radius.h +++ b/mech_eap/util_radius.h @@@ -154,6 -154,7 +154,7 @@@ OM_uint3 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 */ @@@ -170,6 -171,9 +171,6 @@@ #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 diff --combined mech_eap/util_tld.c index 2e1ddfa,7679233..f6feeba --- a/mech_eap/util_tld.c +++ b/mech_eap/util_tld.c @@@ -30,125 -30,131 +30,127 @@@ * 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. ++ * 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_data* tld) +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; } + #endif /* WIN32 */