[Use krb5 (in specified installation directory)]),
[check_krb5_dir="$withval"],
[check_krb5_dir=])
-for dir in $check_krb5_dir $prefix /usr /usr/local ; do
+for dir in $check_krb5_dir $prefix /usr/local /usr ; do
krb5dir="$dir"
if test -x "$dir/bin/krb5-config"; then
found_krb5="yes";
if test "x$target_windows" = "xyes"; then
KRB5_CFLAGS=-I"$check_krb5_dir/include";
- KRB5_LIBS="-L$check_krb5_dir/lib/ -lkrb5_32 -lgssapi32";
+ KRB5_LDFLAGS="-L$check_krb5_dir/lib/";
+ KRB5_LIBS="-lkrb5_32 -lgssapi32";
COMPILE_ET="$check_krb5_dir/bin/compile_et";
AC_MSG_RESULT([yes])
else
KRB5_CFLAGS=`$dir/bin/krb5-config gssapi --cflags`;
+ KRB5_LDFLAGS="-L$dir/lib";
KRB5_LIBS=`$dir/bin/krb5-config gssapi --libs`
AC_MSG_RESULT([yes])
AC_PATH_PROG(COMPILE_ET, [compile_et], [compile_et], [$dir/bin$PATH_SEPARATOr])
else
printf "Kerberos found in $krb5dir\n";
AC_SUBST(KRB5_CFLAGS)
+ AC_SUBST(KRB5_LDFLAGS)
AC_SUBST(KRB5_LIBS)
AC_SUBST(COMPILE_ET)
AC_CHECK_LIB(krb5, GSS_C_NT_COMPOSITE_EXPORT, [AC_DEFINE_UNQUOTED([HAVE_GSS_C_NT_COMPOSITE_EXPORT], 1, [Define if GSS-API library supports recent naming extensions draft])], [], "$KRB5_LIBS")
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
#endif /* CONFIG_NATIVE_WINDOWS */
#ifdef _MSC_VER
+#ifndef __cplusplus
#define inline __inline
+#endif
#undef vsnprintf
#define vsnprintf _vsnprintf
%global _moonshot_krb5 %{!?_moonshot_krb5:krb5-devel}%{?_moonshot_krb5}
Name: moonshot-gss-eap
Version: @VERSION@
-Release: 3%{?dist}
+Release: 4%{?dist}
Summary: Moonshot GSS-API Mechanism
Group: Security Tools
@TARGET_CFLAGS@ $(EAP_CFLAGS)
mech_eap_la_LDFLAGS = -avoid-version -module \
-export-symbols $(GSSEAP_EXPORTS) -no-undefined \
- @RADSEC_LDFLAGS@ @TARGET_LDFLAGS@
+ @KRB5_LDFLAGS@ @RADSEC_LDFLAGS@ @TARGET_LDFLAGS@
if TARGET_WINDOWS
mech_eap_la_LDFLAGS += -debug
endif
ATTRIBUTE GSS-Acceptor-Realm-Name 131 string
ATTRIBUTE SAML-AAA-Assertion 132 string
ATTRIBUTE MS-Windows-Auth-Data 133 octets
+ATTRIBUTE MS-Windows-Group-Sid 134 string
END-VENDOR UKERNA
key.length = KRB_KEY_LENGTH(&ctx->rfc3961Key);
key.value = KRB_KEY_DATA(&ctx->rfc3961Key);
+ /*
+ * As a shortcut, we omit the mechanism OID of the initiator name because
+ * we know it will match the context mechanism. The acceptor name mech OID
+ * is always included.
+ */
if (ctx->initiatorName != GSS_C_NO_NAME) {
major = gssEapExportNameInternal(minor, ctx->initiatorName,
&initiatorName,
if (ctx->acceptorName != GSS_C_NO_NAME) {
major = gssEapExportNameInternal(minor, ctx->acceptorName,
&acceptorName,
- EXPORT_NAME_FLAG_COMPOSITE);
+ EXPORT_NAME_FLAG_OID | EXPORT_NAME_FLAG_COMPOSITE);
if (GSS_ERROR(major))
goto cleanup;
}
gss_ctx_id_t ctx,
int prf_key,
const gss_buffer_t prf_in,
- ssize_t desired_output_len,
gss_buffer_t prf_out);
+/* query_mechanism_info.c */
+OM_uint32
+gssQueryMechanismInfo(OM_uint32 *minor,
+ gss_const_OID mech_oid,
+ unsigned char auth_scheme[16]);
+
/* query_meta_data.c */
OM_uint32
gssEapQueryMetaData(OM_uint32 *minor,
static OM_uint32
importName(OM_uint32 *minor,
+ gss_OID mech,
unsigned char **pBuf,
size_t *pRemain,
gss_name_t *pName)
{
- OM_uint32 major;
+ OM_uint32 major, tmpMinor, flags;
unsigned char *p = *pBuf;
size_t remain = *pRemain;
gss_buffer_desc tmp;
tmp.value = p + 4;
- major = gssEapImportNameInternal(minor, &tmp, pName,
- EXPORT_NAME_FLAG_COMPOSITE);
+ flags = EXPORT_NAME_FLAG_COMPOSITE;
+ if (mech == GSS_C_NO_OID)
+ flags |= EXPORT_NAME_FLAG_OID;
+
+ major = gssEapImportNameInternal(minor, &tmp, pName, flags);
if (GSS_ERROR(major))
return major;
+
+ if ((flags & EXPORT_NAME_FLAG_OID) == 0) {
+ major = gssEapCanonicalizeOid(minor, mech, 0, &(*pName)->mechanismUsed);
+ if (GSS_ERROR(major)) {
+ gssEapReleaseName(&tmpMinor, pName);
+ return major;
+ }
+ }
}
*pBuf += 4 + tmp.length;
if (GSS_ERROR(major))
return major;
- major = importName(minor, &p, &remain, &ctx->initiatorName);
+ /* Initiator name OID matches the context mechanism, so it's not encoded */
+ major = importName(minor, ctx->mechanismUsed, &p, &remain, &ctx->initiatorName);
if (GSS_ERROR(major))
return major;
- major = importName(minor, &p, &remain, &ctx->acceptorName);
+ major = importName(minor, GSS_C_NO_OID, &p, &remain, &ctx->acceptorName);
if (GSS_ERROR(major))
return major;
keySize = KRB_KEY_LENGTH(&ctx->rfc3961Key);
- major = gssEapPseudoRandom(minor, ctx, GSS_C_PRF_KEY_FULL, &salt,
- keySize, &key);
+ key.value = GSSEAP_MALLOC(keySize);
+ if (key.value == NULL) {
+ major = GSS_S_FAILURE;
+ *minor = ENOMEM;
+ goto cleanup;
+ }
+
+ key.length = keySize;
+
+ major = gssEapPseudoRandom(minor, ctx, GSS_C_PRF_KEY_FULL, &salt, &key);
if (GSS_ERROR(major))
goto cleanup;
gss_ctx_id_t ctx,
int prf_key,
const gss_buffer_t prf_in,
- ssize_t desired_output_len,
gss_buffer_t prf_out)
{
krb5_error_code code;
krb5_data t, ns;
unsigned char *p;
krb5_context krbContext;
-
- prf_out->length = 0;
- prf_out->value = NULL;
+ ssize_t desired_output_len = prf_out->length;
*minor = 0;
goto cleanup;
}
- prf_out->value = GSSEAP_MALLOC(desired_output_len);
- if (prf_out->value == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
- prf_out->length = desired_output_len;
-
code = krb5_c_prf_length(krbContext,
ctx->encryptionType,
&prflen);
GSSEAP_MUTEX_LOCK(&ctx->mutex);
- if (CTX_IS_ESTABLISHED(ctx)) {
- major = gssEapPseudoRandom(minor, ctx, prf_key,
- prf_in, desired_output_len, prf_out);
- } else {
+ if (!CTX_IS_ESTABLISHED(ctx)) {
major = GSS_S_NO_CONTEXT;
*minor = GSSEAP_CONTEXT_INCOMPLETE;
+ goto cleanup;
+ }
+
+ prf_out->value = GSSEAP_MALLOC(desired_output_len);
+ if (prf_out->value == NULL) {
+ major = GSS_S_FAILURE;
+ *minor = ENOMEM;
+ goto cleanup;
}
+ prf_out->length = desired_output_len;
+
+ major = gssEapPseudoRandom(minor, ctx, prf_key,
+ prf_in, prf_out);
+
+cleanup:
GSSEAP_MUTEX_UNLOCK(&ctx->mutex);
return major;
#include "gssapiP_eap.h"
-OM_uint32 GSSAPI_CALLCONV
-gss_query_mechanism_info(OM_uint32 *minor,
- gss_const_OID mech_oid,
- unsigned char auth_scheme[16])
+OM_uint32
+gssQueryMechanismInfo(OM_uint32 *minor,
+ gss_const_OID mech_oid,
+ unsigned char auth_scheme[16])
{
OM_uint32 major;
krb5_enctype enctype;
*minor = 0;
return GSS_S_COMPLETE;
}
+
+OM_uint32 GSSAPI_CALLCONV
+gss_query_mechanism_info(OM_uint32 *minor,
+ gss_const_OID mech_oid,
+ unsigned char auth_scheme[16])
+{
+ return gssQueryMechanismInfo(minor, mech_oid, auth_scheme);
+}
#include <krb5.h>
#ifdef WIN32
-#define inline __inline
+# ifndef __cplusplus
+# define inline __inline
+# endif
#define snprintf _snprintf
#endif
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
+#ifdef HAVE_OPENSAML
+ major = gssEapSamlAttrProvidersInit(&minor);
+ if (GSS_ERROR(major))
+ goto cleanup;
+#endif
cleanup:
#ifdef GSSEAP_DEBUG
gss_OID
gssEapPrimaryMechForCred(gss_cred_id_t cred)
{
- gss_OID nameMech = GSS_C_NO_OID;
+ gss_OID credMech = GSS_C_NO_OID;
- if (cred->mechanisms != GSS_C_NO_OID_SET &&
+ if (cred != GSS_C_NO_CREDENTIAL &&
+ cred->mechanisms != GSS_C_NO_OID_SET &&
cred->mechanisms->count == 1)
- nameMech = &cred->mechanisms->elements[0];
+ credMech = &cred->mechanisms->elements[0];
- return nameMech;
+ return credMech;
}
OM_uint32
GSSEAP_MUTEX_UNLOCK(&desiredName->mutex);
}
+#ifdef GSSEAP_ENABLE_ACCEPTOR
if (cred->flags & CRED_FLAG_ACCEPT) {
struct rs_context *radContext;
rs_context_destroy(radContext);
}
+#endif
if (pActualMechs != NULL) {
major = duplicateOidSet(minor, cred->mechanisms, pActualMechs);
lctx->version = 1;
lctx->initiate = CTX_IS_INITIATOR(ctx);
- lctx->endtime = ctx->expiryTime;
+ if (ctx->expiryTime == 0)
+ lctx->endtime = KRB_TIME_FOREVER;
+ else
+ lctx->endtime = ctx->expiryTime;
lctx->send_seq = ctx->sendSeq;
lctx->recv_seq = ctx->recvSeq;
lctx->protocol = 1;
lctx->cfx_kd.have_acceptor_subkey = haveAcceptorSubkey;
lkey = haveAcceptorSubkey
- ? &lctx->cfx_kd.ctx_key
- : &lctx->cfx_kd.acceptor_subkey;
+ ? &lctx->cfx_kd.acceptor_subkey
+ : &lctx->cfx_kd.ctx_key;
lkey->type = KRB_KEY_TYPE(&ctx->rfc3961Key);
lkey->data = GSSEAP_MALLOC(KRB_KEY_LENGTH(&ctx->rfc3961Key));
return major;
}
+static int stringEmpty(const char * s)
+{
+ if (s == NULL)
+ return 1;
+ if (strlen(s) > 0)
+ return 0;
+ return 1;
+}
+
OM_uint32
libMoonshotResolveInitiatorCred(OM_uint32 *minor,
gss_cred_id_t cred,
gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);
- if (serverCertificateHash != NULL) {
+ if (!stringEmpty(serverCertificateHash)) {
size_t len = strlen(serverCertificateHash);
#define HASH_PREFIX "hash://server/sha256/"
((char *)cred->caCertificate.value)[HASH_PREFIX_LEN + len] = '\0';
cred->caCertificate.length = HASH_PREFIX_LEN + len;
- } else if (caCertificate != NULL) {
+ } else if (!stringEmpty(caCertificate)) {
makeStringBufferOrCleanup(caCertificate, &cred->caCertificate);
}
- if (subjectNameConstraint != NULL)
+ if (!stringEmpty(subjectNameConstraint))
makeStringBufferOrCleanup(subjectNameConstraint, &cred->subjectNameConstraint);
- if (subjectAltNameConstraint != NULL)
+ if (!stringEmpty(subjectAltNameConstraint))
makeStringBufferOrCleanup(subjectAltNameConstraint, &cred->subjectAltNameConstraint);
cleanup:
*minor = GSSEAP_WRONG_SIZE;
return GSS_S_FAILURE;
}
- memcpy(*buf, vqueue, sizeof(queue));
+ if (vqueue != NULL)
+ memcpy(*buf, vqueue, sizeof(queue));
+ else
+ memset(*buf, 0, sizeof(queue));
*buf += sizeof(queue);
*lenremain -= sizeof(queue);