Heimdal portability fixes (except for reauth)
authorLuke Howard <lukeh@padl.com>
Fri, 31 Dec 2010 08:45:03 +0000 (19:45 +1100)
committerLuke Howard <lukeh@padl.com>
Fri, 31 Dec 2010 08:45:03 +0000 (19:45 +1100)
17 files changed:
Makefile.am
accept_sec_context.c
acinclude.m4
gssapiP_eap.h
inquire_mech_for_saslname.c
inquire_names_for_mech.c
radsec_err.et
unwrap_iov.c
util.h
util_attr.h
util_cksum.c
util_crypt.c
util_krb.c
util_name.c
util_reauth.c
wrap_iov.c
wrap_iov_length.c

index f44d87b..fa81241 100644 (file)
@@ -8,14 +8,14 @@ gss_LTLIBRARIES = mech_eap.la
 
 mech_eap_la_CPPFLAGS = -DBUILD_GSSEAP_LIB -DSYSCONFDIR=\"${sysconfdir}\" -DDATAROOTDIR=\"${datarootdir}\"
 mech_eap_la_CFLAGS   = -g -Wall -fno-strict-aliasing \
-                       @EAP_CFLAGS@ @RADSEC_CFLAGS@ @KRB5_CFLAGS@ @TARGET_CFLAGS@
+                       @KRB5_CFLAGS@ @EAP_CFLAGS@ @RADSEC_CFLAGS@ @TARGET_CFLAGS@
 mech_eap_la_CXXFLAGS = -g -Wall \
-                       @EAP_CFLAGS@ @RADSEC_CFLAGS@ @KRB5_CFLAGS@ \
+                       @KRB5_CFLAGS@ @EAP_CFLAGS@ @RADSEC_CFLAGS@ \
                        @SHIBSP_CXXFLAGS@ @SHIBRESOLVER_CXXFLAGS@ @TARGET_CFLAGS@
 mech_eap_la_LDFLAGS  = -avoid-version -module \
                        -export-symbols mech_eap.exports -no-undefined \
                        @EAP_LDFLAGS@ @RADSEC_LDFLAGS@ @TARGET_LDFLAGS@
-mech_eap_la_LIBADD   = @EAP_LIBS@ @RADSEC_LIBS@ @KRB5_LIBS@ @SHIBSP_LIBS@ \
+mech_eap_la_LIBADD   = @KRB5_LIBS@ @EAP_LIBS@ @RADSEC_LIBS@ @SHIBSP_LIBS@ \
                       @SHIBRESOLVER_LIBS@
 
 mech_eap_la_SOURCES =                          \
@@ -106,12 +106,12 @@ radius_ad_la_SOURCES = util_adshim.c
 endif
 
 gsseap_err.h: gsseap_err.et
-       $(prefix)/bin/compile_et $<
+       $(COMPILE_ET) $<
 
 gsseap_err.c: gsseap_err.h
 
 radsec_err.h: radsec_err.et
-       $(prefix)/bin/compile_et $<
+       $(COMPILE_ET) $<
 
 radsec_err.c: radsec_err.h
 
index 7fa39ef..d7a4708 100644 (file)
@@ -197,10 +197,10 @@ setAcceptorIdentity(OM_uint32 *minor,
 
     krbPrinc = ctx->acceptorName->krbPrincipal;
     assert(krbPrinc != NULL);
-    assert(krb5_princ_size(krbContext, krbPrinc) >= 2);
+    assert(KRB_PRINC_LENGTH(krbPrinc) >= 2);
 
     /* Acceptor-Service-Name */
-    krbDataToGssBuffer(krb5_princ_component(krbContext, krbPrinc, 0), &nameBuf);
+    krbPrincComponentToGssBuffer(krbPrinc, 0, &nameBuf);
 
     major = gssEapRadiusAddAvp(minor, vps,
                                PW_GSS_ACCEPTOR_SERVICE_NAME,
@@ -210,7 +210,7 @@ setAcceptorIdentity(OM_uint32 *minor,
         return major;
 
     /* Acceptor-Host-Name */
-    krbDataToGssBuffer(krb5_princ_component(krbContext, krbPrinc, 1), &nameBuf);
+    krbPrincComponentToGssBuffer(krbPrinc, 1, &nameBuf);
 
     major = gssEapRadiusAddAvp(minor, vps,
                                PW_GSS_ACCEPTOR_HOST_NAME,
@@ -219,13 +219,13 @@ setAcceptorIdentity(OM_uint32 *minor,
     if (GSS_ERROR(major))
         return major;
 
-    if (krb5_princ_size(krbContext, krbPrinc) > 2) {
+    if (KRB_PRINC_LENGTH(krbPrinc) > 2) {
         /* Acceptor-Service-Specific */
         krb5_principal_data ssiPrinc = *krbPrinc;
         char *ssi;
 
-        krb5_princ_size(krbContext, &ssiPrinc) -= 2;
-        krb5_princ_name(krbContext, &ssiPrinc) += 2;
+        KRB_PRINC_LENGTH(&ssiPrinc) -= 2;
+        KRB_PRINC_NAME(&ssiPrinc) += 2;
 
         *minor = krb5_unparse_name_flags(krbContext, &ssiPrinc,
                                          KRB5_PRINCIPAL_UNPARSE_NO_REALM, &ssi);
@@ -247,7 +247,7 @@ setAcceptorIdentity(OM_uint32 *minor,
         krb5_free_unparsed_name(krbContext, ssi);
     }
 
-    krbDataToGssBuffer(krb5_princ_realm(krbContext, krbPrinc), &nameBuf);
+    krbPrincRealmToGssBuffer(krbPrinc, &nameBuf);
     if (nameBuf.length != 0) {
         /* Acceptor-Realm-Name */
         major = gssEapRadiusAddAvp(minor, vps,
index 2cff774..242a1f0 100644 (file)
@@ -15,6 +15,7 @@ for dir in $check_krb5_dir /usr /usr/local ; do
      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";
      break;
    fi
 done
@@ -32,9 +33,11 @@ else
        printf "Kerberos found in $krb5dir\n";
        AC_SUBST(KRB5_CFLAGS)
        AC_SUBST(KRB5_LIBS)
+       AC_SUBST(COMPILE_ET)
        AC_CHECK_LIB(gssapi_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")
        AC_CHECK_LIB(gssapi_krb5, gss_inquire_attrs_for_mech, [AC_DEFINE_UNQUOTED([HAVE_GSS_INQUIRE_ATTRS_FOR_MECH], 1, [Define if GSS-API library supports RFC 5587])], [], "$KRB5_LIBS")
        AC_CHECK_LIB(gssapi_krb5, gss_krb5_import_cred, [AC_DEFINE_UNQUOTED([HAVE_GSS_KRB5_IMPORT_CRED], 1, [Define if GSS-API library supports gss_krb5_import_cred])], [], "$KRB5_LIBS")
+       AC_CHECK_LIB(krb5, heimdal_version, [AC_DEFINE_UNQUOTED([HAVE_HEIMDAL_VERSION], 1, [Define if building against Heimdal Kerberos implementation])], [], "$KRB5_LIBS")
 fi
 ])dnl
 
index 274d694..b53e131 100644 (file)
@@ -46,7 +46,9 @@
 /* GSS headers */
 #include <gssapi/gssapi.h>
 #include <gssapi/gssapi_krb5.h>
+#ifndef HAVE_HEIMDAL_VERSION
 #include <gssapi/gssapi_ext.h>
+#endif
 #include "gssapi_eap.h"
 
 /* Kerberos headers */
@@ -89,7 +91,12 @@ extern "C" {
 struct gss_eap_saml_attr_ctx;
 struct gss_eap_attr_ctx;
 
-struct gss_name_struct {
+#ifdef HAVE_HEIMDAL_VERSION
+struct gss_name_t_desc_struct
+#else
+struct gss_name_struct
+#endif
+{
     GSSEAP_MUTEX mutex; /* mutex protects attrCtx */
     OM_uint32 flags;
     krb5_principal krbPrincipal; /* this is immutable */
@@ -103,7 +110,12 @@ struct gss_name_struct {
 #define CRED_FLAG_DEFAULT_CCACHE            0x00100000
 #define CRED_FLAG_PUBLIC_MASK               0x0000FFFF
 
-struct gss_cred_id_struct {
+#ifdef HAVE_HEIMDAL_VERSION
+struct gss_cred_id_t_desc_struct
+#else
+struct gss_cred_id_struct
+#endif
+{
     GSSEAP_MUTEX mutex;
     OM_uint32 flags;
     gss_name_t name;
@@ -167,7 +179,12 @@ struct gss_eap_acceptor_ctx {
     VALUE_PAIR *vps;
 };
 
-struct gss_ctx_id_struct {
+#ifdef HAVE_HEIMDAL_VERSION
+struct gss_ctx_id_t_desc_struct
+#else
+struct gss_ctx_id_struct
+#endif
+{
     GSSEAP_MUTEX mutex;
     enum gss_eap_state state;
     OM_uint32 flags;
index 536f3c7..6de0399 100644 (file)
@@ -46,18 +46,20 @@ gss_inquire_saslname_for_mech(OM_uint32 *minor,
     OM_uint32 major;
     gss_buffer_t name;
     krb5_enctype etype = ENCTYPE_NULL;
-    char krbBuf[128] = "eap-";
 
     /* Dynamically construct mechanism name from Kerberos string enctype */
     major = gssEapOidToEnctype(minor, mech, &etype);
     if (GSS_ERROR(major))
         return major;
 
-    if (mech_name != GSS_C_NO_BUFFER &&
-        krb5_enctype_to_name(etype, 0, &krbBuf[4], sizeof(krbBuf) - 4) == 0) {
-        major = makeStringBuffer(minor, krbBuf, mech_name);
-        if (GSS_ERROR(major))
-            return major;
+    if (mech_name != GSS_C_NO_BUFFER) {
+        krb5_context krbContext;
+
+        GSSEAP_KRB_INIT(&krbContext);
+
+        *minor = krbEnctypeToString(krbContext, etype, "eap-", mech_name);
+        if (*minor != 0)
+            return GSS_S_FAILURE;
     }
 
     if (mech_description != GSS_C_NO_BUFFER) {
index 7217e33..3f53217 100644 (file)
@@ -50,6 +50,7 @@ gss_inquire_names_for_mech(OM_uint32 *minor,
         GSS_C_NT_COMPOSITE_EXPORT,
 #endif
         GSS_EAP_NT_PRINCIPAL_NAME,
+        GSS_C_NT_ANONYMOUS,
     };
     size_t i;
 
index 07aa549..887ef0a 100644 (file)
@@ -33,4 +33,6 @@
 # Placeholders only
 error_table rse
 
+error_code GSSEAP_RSE_OK,                       ""
+
 end
index 8af08ef..e76f3d4 100644 (file)
 OM_uint32
 unwrapToken(OM_uint32 *minor,
             gss_ctx_id_t ctx,
+#ifdef HAVE_HEIMDAL_VERSION
+            krb5_crypto krbCrypto,
+#else
+            krb5_keyblock *unused __attribute__((__unused__)),
+#endif
             int *conf_state,
             gss_qop_t *qop_state,
             gss_iov_buffer_desc *iov,
             int iov_count,
             enum gss_eap_token_type toktype)
 {
-    OM_uint32 code;
+    OM_uint32 major = GSS_S_FAILURE, code;
     gss_iov_buffer_t header;
     gss_iov_buffer_t padding;
     gss_iov_buffer_t trailer;
@@ -86,6 +91,9 @@ unwrapToken(OM_uint32 *minor,
     int valid = 0;
     int conf_flag = 0;
     krb5_context krbContext;
+#ifdef HAVE_HEIMDAL_VERSION
+    int freeCrypto = (krbCrypto == NULL);
+#endif
 
     GSSEAP_KRB_INIT(&krbContext);
 
@@ -99,8 +107,9 @@ unwrapToken(OM_uint32 *minor,
 
     padding = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
     if (padding != NULL && padding->buffer.length != 0) {
-        *minor = GSSEAP_BAD_PADDING_IOV;
-        return GSS_S_DEFECTIVE_TOKEN;
+        code = GSSEAP_BAD_PADDING_IOV;
+        major = GSS_S_DEFECTIVE_TOKEN;
+        goto cleanup;
     }
 
     trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
@@ -122,17 +131,28 @@ unwrapToken(OM_uint32 *minor,
     ptr = (unsigned char *)header->buffer.value;
 
     if (header->buffer.length < 16) {
-        *minor = GSSEAP_TOK_TRUNC;
-        return GSS_S_DEFECTIVE_TOKEN;
+        code = GSSEAP_TOK_TRUNC;
+        major = GSS_S_DEFECTIVE_TOKEN;
+        goto cleanup;
     }
 
     if ((ptr[2] & flags) != flags) {
-        *minor = GSSEAP_BAD_DIRECTION;
-        return GSS_S_BAD_SIG;
+        code = GSSEAP_BAD_DIRECTION;
+        major = GSS_S_BAD_SIG;
+        goto cleanup;
     }
 
+#ifdef HAVE_HEIMDAL_VERSION
+    if (krbCrypto == NULL) {
+        code = krb5_crypto_init(krbContext, &ctx->rfc3961Key,
+                                ETYPE_NULL, &krbCrypto);
+        if (code != 0)
+            goto cleanup;
+    }
+#endif
+
     if (toktype == TOK_TYPE_WRAP) {
-        unsigned int krbTrailerLen;
+        size_t krbTrailerLen;
 
         if (load_uint16_be(ptr) != TOK_TYPE_WRAP)
             goto defective;
@@ -143,15 +163,12 @@ unwrapToken(OM_uint32 *minor,
         rrc = load_uint16_be(ptr + 6);
         seqnum = load_uint64_be(ptr + 8);
 
-        code = krb5_c_crypto_length(krbContext,
-                                    ctx->encryptionType,
-                                    conf_flag ? KRB5_CRYPTO_TYPE_TRAILER :
-                                    KRB5_CRYPTO_TYPE_CHECKSUM,
-                                    &krbTrailerLen);
-        if (code != 0) {
-            *minor = code;
-            return GSS_S_FAILURE;
-        }
+        code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                               conf_flag ? KRB5_CRYPTO_TYPE_TRAILER :
+                                           KRB5_CRYPTO_TYPE_CHECKSUM,
+                               &krbTrailerLen);
+        if (code != 0)
+            goto cleanup;
 
         /* Deal with RRC */
         if (trailer == NULL) {
@@ -177,11 +194,11 @@ unwrapToken(OM_uint32 *minor,
             /* Decrypt */
             code = gssEapDecrypt(krbContext,
                                  ((ctx->gssFlags & GSS_C_DCE_STYLE) != 0),
-                                 ec, rrc, &ctx->rfc3961Key,
-                                 keyUsage, 0, iov, iov_count);
+                                 ec, rrc, KRB_CRYPTO_CONTEXT(ctx), keyUsage,
+                                 iov, iov_count);
             if (code != 0) {
-                *minor = code;
-                return GSS_S_BAD_SIG;
+                major = GSS_S_BAD_SIG;
+                goto cleanup;
             }
 
             /* Validate header integrity */
@@ -194,8 +211,9 @@ unwrapToken(OM_uint32 *minor,
                 || althdr[2] != ptr[2]
                 || althdr[3] != ptr[3]
                 || memcmp(althdr + 8, ptr + 8, 8) != 0) {
-                *minor = GSSEAP_BAD_WRAP_TOKEN;
-                return GSS_S_BAD_SIG;
+                code = GSSEAP_BAD_WRAP_TOKEN;
+                major = GSS_S_BAD_SIG;
+                goto cleanup;
             }
         } else {
             /* Verify checksum: note EC is checksum size here, not padding */
@@ -207,11 +225,11 @@ unwrapToken(OM_uint32 *minor,
             store_uint16_be(0, ptr + 6);
 
             code = gssEapVerify(krbContext, ctx->checksumType, rrc,
-                                &ctx->rfc3961Key, keyUsage,
+                                KRB_CRYPTO_CONTEXT(ctx), keyUsage,
                                 iov, iov_count, &valid);
             if (code != 0 || valid == FALSE) {
-                *minor = code;
-                return GSS_S_BAD_SIG;
+                major = GSS_S_BAD_SIG;
+                goto cleanup;
             }
         }
 
@@ -226,11 +244,11 @@ unwrapToken(OM_uint32 *minor,
         seqnum = load_uint64_be(ptr + 8);
 
         code = gssEapVerify(krbContext, ctx->checksumType, 0,
-                            &ctx->rfc3961Key, keyUsage,
+                            KRB_CRYPTO_CONTEXT(ctx), keyUsage,
                             iov, iov_count, &valid);
         if (code != 0 || valid == FALSE) {
-            *minor = code;
-            return GSS_S_BAD_SIG;
+            major = GSS_S_BAD_SIG;
+            goto cleanup;
         }
         code = sequenceCheck(minor, &ctx->seqState, seqnum);
     } else if (toktype == TOK_TYPE_DELETE_CONTEXT) {
@@ -241,17 +259,25 @@ unwrapToken(OM_uint32 *minor,
         goto defective;
     }
 
-    *minor = 0;
-
     if (conf_state != NULL)
         *conf_state = conf_flag;
 
-    return code;
+    code = 0;
+    major = GSS_S_COMPLETE;
+    goto cleanup;
 
 defective:
-    *minor = GSSEAP_BAD_WRAP_TOKEN;
+    code = GSSEAP_BAD_WRAP_TOKEN;
+    major = GSS_S_DEFECTIVE_TOKEN;
 
-    return GSS_S_DEFECTIVE_TOKEN;
+cleanup:
+    *minor = code;
+#ifdef HAVE_HEIMDAL_VERSION
+    if (freeCrypto && krbCrypto != NULL)
+        krb5_crypto_destroy(krbContext, krbCrypto);
+#endif
+
+    return major;
 }
 
 int
@@ -298,6 +324,9 @@ unwrapStream(OM_uint32 *minor,
     gss_iov_buffer_desc *tiov = NULL;
     gss_iov_buffer_t stream, data = NULL;
     gss_iov_buffer_t theader, tdata = NULL, tpadding, ttrailer;
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_crypto krbCrypto = NULL;
+#endif
 
     GSSEAP_KRB_INIT(&krbContext);
 
@@ -367,10 +396,16 @@ unwrapStream(OM_uint32 *minor,
     ttrailer = &tiov[i++];
     ttrailer->type = GSS_IOV_BUFFER_TYPE_TRAILER;
 
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, ETYPE_NULL, &krbCrypto);
+    if (code != 0)
+        goto cleanup;
+#endif
+
     {
         size_t ec, rrc;
-        unsigned int krbHeaderLen = 0;
-        unsigned int krbTrailerLen = 0;
+        size_t krbHeaderLen = 0;
+        size_t krbTrailerLen = 0;
 
         conf_req_flag = ((ptr[0] & TOK_FLAG_WRAP_CONFIDENTIAL) != 0);
         ec = conf_req_flag ? load_uint16_be(ptr + 2) : 0;
@@ -385,19 +420,19 @@ unwrapStream(OM_uint32 *minor,
         }
 
         if (conf_req_flag) {
-            code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
-                                        KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
+            code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                                    KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
             if (code != 0)
                 goto cleanup;
             theader->buffer.length += krbHeaderLen; /* length validated later */
         }
 
         /* no PADDING for CFX, EC is used instead */
-        code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
-                                    conf_req_flag
-                                      ? KRB5_CRYPTO_TYPE_TRAILER
-                                      : KRB5_CRYPTO_TYPE_CHECKSUM,
-                                    &krbTrailerLen);
+        code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                               conf_req_flag
+                                  ? KRB5_CRYPTO_TYPE_TRAILER
+                                  : KRB5_CRYPTO_TYPE_CHECKSUM,
+                               &krbTrailerLen);
         if (code != 0)
             goto cleanup;
 
@@ -441,8 +476,8 @@ unwrapStream(OM_uint32 *minor,
 
     assert(i <= iov_count + 2);
 
-    major = unwrapToken(&code, ctx, conf_state, qop_state,
-                        tiov, i, toktype);
+    major = unwrapToken(&code, ctx, KRB_CRYPTO_CONTEXT(ctx),
+                        conf_state, qop_state, tiov, i, toktype);
     if (major == GSS_S_COMPLETE) {
         *data = *tdata;
     } else if (tdata->type & GSS_IOV_BUFFER_FLAG_ALLOCATED) {
@@ -455,6 +490,10 @@ unwrapStream(OM_uint32 *minor,
 cleanup:
     if (tiov != NULL)
         GSSEAP_FREE(tiov);
+#ifdef HAVE_HEIMDAL_VERSION
+    if (krbCrypto != NULL)
+        krb5_crypto_destroy(krbContext, krbCrypto);
+#endif
 
     *minor = code;
 
@@ -481,7 +520,9 @@ gssEapUnwrapOrVerifyMIC(OM_uint32 *minor,
         major = unwrapStream(minor, ctx, conf_state, qop_state,
                              iov, iov_count, toktype);
     } else {
-        major = unwrapToken(minor, ctx, conf_state, qop_state,
+        major = unwrapToken(minor, ctx,
+                            NULL, /* krbCrypto */
+                            conf_state, qop_state,
                             iov, iov_count, toktype);
     }
 
diff --git a/util.h b/util.h
index de8dcb8..16af15e 100644 (file)
--- a/util.h
+++ b/util.h
@@ -114,7 +114,11 @@ int
 gssEapSign(krb5_context context,
            krb5_cksumtype type,
            size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+           krb5_crypto crypto,
+#else
            krb5_keyblock *key,
+#endif
            krb5_keyusage sign_usage,
            gss_iov_buffer_desc *iov,
            int iov_count);
@@ -123,7 +127,11 @@ int
 gssEapVerify(krb5_context context,
              krb5_cksumtype type,
              size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+             krb5_crypto crypto,
+#else
              krb5_keyblock *key,
+#endif
              krb5_keyusage sign_usage,
              gss_iov_buffer_desc *iov,
              int iov_count,
@@ -202,15 +210,27 @@ int gssEapCredAvailable(gss_cred_id_t cred, gss_OID mech);
 /* util_crypt.c */
 int
 gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
-              size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
+              size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+              krb5_crypto crypto,
+#else
+              krb5_keyblock *key,
+#endif
+              int usage,
               gss_iov_buffer_desc *iov, int iov_count);
 
 int
 gssEapDecrypt(krb5_context context, int dce_style, size_t ec,
-              size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
+              size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+              krb5_crypto crypto,
+#else
+              krb5_keyblock *key,
+#endif
+              int usage,
               gss_iov_buffer_desc *iov, int iov_count);
 
-krb5_cryptotype
+int
 gssEapMapCryptoFlag(OM_uint32 type);
 
 gss_iov_buffer_t
@@ -279,15 +299,41 @@ gssEapVerifyExtensions(OM_uint32 *minor,
                        const gss_buffer_t buffer);
 
 /* util_krb.c */
+#ifdef HAVE_HEIMDAL_VERSION
+#define KRB_KEY_TYPE(key)       ((key)->keytype)
+#define KRB_KEY_DATA(key)       ((key)->keyvalue.data)
+#define KRB_KEY_LENGTH(key)     ((key)->keyvalue.length)
+#else
 #define KRB_KEY_TYPE(key)       ((key)->enctype)
 #define KRB_KEY_DATA(key)       ((key)->contents)
 #define KRB_KEY_LENGTH(key)     ((key)->length)
+#endif /* HAVE_HEIMDAL_VERSION */
+
 #define KRB_KEY_INIT(key)       do {        \
         KRB_KEY_TYPE(key) = ENCTYPE_NULL;   \
         KRB_KEY_DATA(key) = NULL;           \
         KRB_KEY_LENGTH(key) = 0;            \
     } while (0)
 
+#ifdef HAVE_HEIMDAL_VERSION
+#define KRB_PRINC_LENGTH(princ) ((princ)->name.name_string.len)
+#define KRB_PRINC_TYPE(princ)   ((princ)->name.name_type)
+#define KRB_PRINC_NAME(princ)   ((princ)->name.name_string.val)
+#define KRB_CRYPTO_CONTEXT(ctx) (krbCrypto)
+#else
+#define KRB_PRINC_LENGTH(princ) (krb5_princ_size(NULL, (princ)))
+#define KRB_PRINC_TYPE(princ)   (krb5_princ_type(NULL, (princ)))
+#define KRB_PRINC_NAME(princ)   (krb5_princ_name(NULL, (princ)))
+#define KRB_CRYPTO_CONTEXT(ctx) (&(ctx)->rfc3961Key)
+#endif /* HAVE_HEIMDAL_VERSION */
+
+#ifdef HAVE_HEIMDAL_VERSION
+#define GSS_IOV_BUFFER_FLAG_ALLOCATE    GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE
+#define GSS_IOV_BUFFER_FLAG_ALLOCATED   GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED
+
+#define GSS_S_CRED_UNAVAIL              GSS_S_FAILURE
+#endif
+
 #define GSSEAP_KRB_INIT(ctx) do {                   \
         OM_uint32 tmpMajor;                         \
                                                     \
@@ -305,6 +351,44 @@ rfc3961ChecksumTypeForKey(OM_uint32 *minor,
                           krb5_keyblock *key,
                           krb5_cksumtype *cksumtype);
 
+krb5_const_principal
+krbAnonymousPrincipal(void);
+
+krb5_error_code
+krbCryptoLength(krb5_context krbContext,
+#ifdef HAVE_HEIMDAL_VERSION
+                krb5_crypto krbCrypto,
+#else
+                krb5_keyblock *key,
+#endif
+                int type,
+                size_t *length);
+
+krb5_error_code
+krbPaddingLength(krb5_context krbContext,
+#ifdef HAVE_HEIMDAL_VERSION
+                 krb5_crypto krbCrypto,
+#else
+                 krb5_keyblock *key,
+#endif
+                 size_t dataLength,
+                 size_t *padLength);
+
+krb5_error_code
+krbBlockSize(krb5_context krbContext,
+#ifdef HAVE_HEIMDAL_VERSION
+                 krb5_crypto krbCrypto,
+#else
+                 krb5_keyblock *key,
+#endif
+                 size_t *blockSize);
+
+krb5_error_code
+krbEnctypeToString(krb5_context krbContext,
+                   krb5_enctype enctype,
+                   const char *prefix,
+                   gss_buffer_t string);
+
 /* util_lucid.c */
 OM_uint32
 gssEapExportLucidSecContext(OM_uint32 *minor,
@@ -611,6 +695,30 @@ krbDataToGssBuffer(krb5_data *data, gss_buffer_t buffer)
 }
 
 static inline void
+krbPrincComponentToGssBuffer(krb5_principal krbPrinc,
+                             int index, gss_buffer_t buffer)
+{
+#ifdef HAVE_HEIMDAL_VERSION
+    buffer->value = (void *)krbPrinc->name.name_string.val[index];
+    buffer->length = strlen((char *)buffer->value);
+#else
+    buffer->value = (void *)krb5_princ_component(NULL, krbPrinc, index)->data;
+    buffer->length = krb5_princ_component(NULL, krbPrinc, index)->length;
+#endif /* HAVE_HEIMDAL_VERSION */
+}
+
+static inline void
+krbPrincRealmToGssBuffer(krb5_principal krbPrinc, gss_buffer_t buffer)
+{
+#ifdef HAVE_HEIMDAL_VERSION
+    buffer->value = (void *)krbPrinc->realm;
+    buffer->length = strlen(krbPrinc->realm);
+#else
+    krbDataToGssBuffer(krb5_princ_realm(NULL, krbPrinc), buffer);
+#endif
+}
+
+static inline void
 gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data)
 {
     data->data = (char *)buffer->value;
index e55e9a9..01f8e2f 100644 (file)
 #ifndef _UTIL_ATTR_H_
 #define _UTIL_ATTR_H_ 1
 
+#ifdef HAVE_HEIMDAL_VERSION
+/* Removed in draft-ietf-kitten-gssapi-naming-exts-08 */
+typedef struct gss_any *gss_any_t;
+#endif
+
 #ifdef __cplusplus
 #include <string>
 #include <new>
index 9616e9c..cbd531d 100644 (file)
@@ -61,7 +61,11 @@ static int
 gssEapChecksum(krb5_context context,
                krb5_cksumtype type,
                size_t rrc,
-               krb5_keyblock *key,
+#ifdef HAVE_HEIMDAL_VERSION
+               krb5_crypto crypto,
+#else
+               krb5_keyblock *crypto,
+#endif
                krb5_keyusage sign_usage,
                gss_iov_buffer_desc *iov,
                int iov_count,
@@ -74,13 +78,15 @@ gssEapChecksum(krb5_context context,
     krb5_crypto_iov *kiov;
     size_t kiov_count;
     int i = 0, j;
-    unsigned int k5_checksumlen;
+    size_t k5_checksumlen;
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_cksumtype cksumtype;
+#endif
 
     if (verify)
         *valid = FALSE;
 
-    code = krb5_c_crypto_length(context, KRB_KEY_TYPE(key),
-                                KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen);
+    code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5_checksumlen);
     if (code != 0)
         return code;
 
@@ -130,17 +136,28 @@ gssEapChecksum(krb5_context context,
     }
     i++;
 
+#ifdef HAVE_HEIMDAL_VERSION
+    if (verify) {
+        code = krb5_verify_checksum_iov(context, crypto, sign_usage,
+                                        kiov, kiov_count, &cksumtype);
+        *valid = (code == 0);
+    } else {
+        code = krb5_create_checksum_iov(context, crypto, sign_usage,
+                                        kiov, kiov_count, &cksumtype);
+    }
+#else
     if (verify) {
         krb5_boolean kvalid = FALSE;
 
-        code = krb5_c_verify_checksum_iov(context, type, key,
+        code = krb5_c_verify_checksum_iov(context, type, crypto,
                                           sign_usage, kiov, kiov_count, &kvalid);
 
         *valid = kvalid;
     } else {
-        code = krb5_c_make_checksum_iov(context, type, key,
+        code = krb5_c_make_checksum_iov(context, type, crypto,
                                         sign_usage, kiov, kiov_count);
     }
+#endif /* HAVE_HEIMDAL_VERSION */
 
     GSSEAP_FREE(kiov);
 
@@ -151,12 +168,16 @@ int
 gssEapSign(krb5_context context,
            krb5_cksumtype type,
            size_t rrc,
-           krb5_keyblock *key,
+#ifdef HAVE_HEIMDAL_VERSION
+           krb5_crypto crypto,
+#else
+           krb5_keyblock *crypto,
+#endif
            krb5_keyusage sign_usage,
            gss_iov_buffer_desc *iov,
            int iov_count)
 {
-    return gssEapChecksum(context, type, rrc, key,
+    return gssEapChecksum(context, type, rrc, crypto,
                           sign_usage, iov, iov_count, 0, NULL);
 }
 
@@ -164,13 +185,17 @@ int
 gssEapVerify(krb5_context context,
              krb5_cksumtype type,
              size_t rrc,
-             krb5_keyblock *key,
+#ifdef HAVE_HEIMDAL_VERSION
+             krb5_crypto crypto,
+#else
+             krb5_keyblock *crypto,
+#endif
              krb5_keyusage sign_usage,
              gss_iov_buffer_desc *iov,
              int iov_count,
              int *valid)
 {
-    return gssEapChecksum(context, type, rrc, key,
+    return gssEapChecksum(context, type, rrc, crypto,
                           sign_usage, iov, iov_count, 1, valid);
 }
 
index 62e880e..9841c9d 100644 (file)
  */
 static krb5_error_code
 mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
-       krb5_enctype enctype, gss_iov_buffer_desc *iov,
+#ifdef HAVE_HEIMDAL_VERSION
+       krb5_crypto crypto,
+#else
+       krb5_keyblock *crypto,
+#endif
+       gss_iov_buffer_desc *iov,
        int iov_count, krb5_crypto_iov **pkiov,
        size_t *pkiov_count)
 {
@@ -99,7 +104,7 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
     int i = 0, j;
     size_t kiov_count;
     krb5_crypto_iov *kiov;
-    unsigned int k5_headerlen = 0, k5_trailerlen = 0;
+    size_t k5_headerlen = 0, k5_trailerlen = 0;
     size_t gss_headerlen, gss_trailerlen;
     krb5_error_code code;
 
@@ -112,13 +117,11 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
     trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
     assert(trailer == NULL || rrc == 0);
 
-    code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_HEADER,
-                                &k5_headerlen);
+    code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_HEADER, &k5_headerlen);
     if (code != 0)
         return code;
 
-    code = krb5_c_crypto_length(context, enctype, KRB5_CRYPTO_TYPE_TRAILER,
-                                &k5_trailerlen);
+    code = krbCryptoLength(context, crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5_trailerlen);
     if (code != 0)
         return code;
 
@@ -198,89 +201,83 @@ mapIov(krb5_context context, int dce_style, size_t ec, size_t rrc,
 }
 
 int
-gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
-              size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
-              gss_iov_buffer_desc *iov, int iov_count)
+gssEapEncrypt(krb5_context context,
+              int dce_style,
+              size_t ec,
+              size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+              krb5_crypto crypto,
+#else
+              krb5_keyblock *crypto,
+#endif
+              int usage,
+              gss_iov_buffer_desc *iov,
+              int iov_count)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd;
     size_t kiov_count;
-    krb5_crypto_iov *kiov;
+    krb5_crypto_iov *kiov = NULL;
 
-    if (iv) {
-        code = krb5_c_block_size(context, KRB_KEY_TYPE(key), &blocksize);
-        if (code)
-            return(code);
-
-        ivd.length = blocksize;
-        ivd.data = GSSEAP_MALLOC(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
+    code = mapIov(context, dce_style, ec, rrc, crypto,
+                  iov, iov_count, &kiov, &kiov_count);
+    if (code != 0)
+        goto cleanup;
 
-    code = mapIov(context, dce_style, ec, rrc,
-                  KRB_KEY_TYPE(key), iov, iov_count,
-                  &kiov, &kiov_count);
-    if (code == 0) {
-        code = krb5_c_encrypt_iov(context, key, usage, pivd, kiov, kiov_count);
-        GSSEAP_FREE(kiov);
-    }
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_encrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL);
+#else
+    code = krb5_c_encrypt_iov(context, crypto, usage, NULL, kiov, kiov_count);
+#endif
+    if (code != 0)
+        goto cleanup;
 
-    if (pivd != NULL)
-        GSSEAP_FREE(pivd->data);
+cleanup:
+    if (kiov != NULL)
+        GSSEAP_FREE(kiov);
 
     return code;
 }
 
 int
-gssEapDecrypt(krb5_context context, int dce_style, size_t ec,
-              size_t rrc, krb5_keyblock *key, int usage, krb5_pointer iv,
-              gss_iov_buffer_desc *iov, int iov_count)
+gssEapDecrypt(krb5_context context,
+              int dce_style,
+              size_t ec,
+              size_t rrc,
+#ifdef HAVE_HEIMDAL_VERSION
+              krb5_crypto crypto,
+#else
+              krb5_keyblock *crypto,
+#endif
+              int usage,
+              gss_iov_buffer_desc *iov,
+              int iov_count)
 {
     krb5_error_code code;
-    size_t blocksize;
-    krb5_data ivd, *pivd;
     size_t kiov_count;
     krb5_crypto_iov *kiov;
 
-    if (iv) {
-        code = krb5_c_block_size(context, KRB_KEY_TYPE(key), &blocksize);
-        if (code)
-            return(code);
-
-        ivd.length = blocksize;
-        ivd.data = GSSEAP_MALLOC(ivd.length);
-        if (ivd.data == NULL)
-            return ENOMEM;
-        memcpy(ivd.data, iv, ivd.length);
-        pivd = &ivd;
-    } else {
-        pivd = NULL;
-    }
+    code = mapIov(context, dce_style, ec, rrc, crypto,
+                  iov, iov_count, &kiov, &kiov_count);
+    if (code != 0)
+        goto cleanup;
 
-    code = mapIov(context, dce_style, ec, rrc,
-                  KRB_KEY_TYPE(key), iov, iov_count,
-                  &kiov, &kiov_count);
-    if (code == 0) {
-        code = krb5_c_decrypt_iov(context, key, usage, pivd, kiov, kiov_count);
-        GSSEAP_FREE(kiov);
-    }
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_decrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL);
+#else
+    code = krb5_c_decrypt_iov(context, crypto, usage, NULL, kiov, kiov_count);
+#endif
 
-    if (pivd != NULL)
-        GSSEAP_FREE(pivd->data);
+cleanup:
+    if (kiov != NULL)
+        GSSEAP_FREE(kiov);
 
     return code;
 }
 
-krb5_cryptotype
+int
 gssEapMapCryptoFlag(OM_uint32 type)
 {
-    krb5_cryptotype ktype;
+    int ktype;
 
     switch (GSS_IOV_BUFFER_TYPE(type)) {
     case GSS_IOV_BUFFER_TYPE_DATA:
index 4cc4b14..82d6c50 100644 (file)
@@ -93,7 +93,10 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor,
                        krb5_keyblock *pKey)
 {
     krb5_context krbContext;
-    krb5_data data, ns, t, prfOut;
+#ifndef HAVE_HEIMDAL_VERSION
+    krb5_data data;
+#endif
+    krb5_data ns, t, prfOut;
     krb5_keyblock kd;
     krb5_error_code code;
     size_t randomLength, keyLength, prfLength;
@@ -120,9 +123,6 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor,
     if (code != 0)
         goto cleanup;
 
-    data.length = MIN(inputKeyLength, randomLength);
-    data.data = (char *)inputKey;
-
     KRB_KEY_DATA(&kd) = GSSEAP_MALLOC(keyLength);
     if (KRB_KEY_DATA(&kd) == NULL) {
         code = ENOMEM;
@@ -131,7 +131,15 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor,
     KRB_KEY_LENGTH(&kd) = keyLength;
 
     /* Convert MSK into a Kerberos key */
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_random_to_key(krbContext, encryptionType, inputKey,
+                              MIN(inputKeyLength, randomLength), &kd);
+#else
+    data.length = MIN(inputKeyLength, randomLength);
+    data.data = (char *)inputKey;
+
     code = krb5_c_random_to_key(krbContext, encryptionType, &data, &kd);
+#endif
     if (code != 0)
         goto cleanup;
 
@@ -174,7 +182,12 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor,
      }
 
     /* Finally, convert PRF output into a new key which we will return */
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_random_to_key(krbContext, encryptionType,
+                              prfOut.data, prfOut.length, &kd);
+#else
     code = krb5_c_random_to_key(krbContext, encryptionType, &prfOut, &kd);
+#endif
     if (code != 0)
         goto cleanup;
 
@@ -236,7 +249,11 @@ rfc3961ChecksumTypeForKey(OM_uint32 *minor,
     if (*minor != 0)
         return GSS_S_FAILURE;
 
+#ifdef HAVE_HEIMDAL_VERSION
+    *cksumtype = cksum.cksumtype;
+#else
     *cksumtype = cksum.checksum_type;
+#endif
 
     krb5_free_checksum_contents(krbContext, &cksum);
 #endif /* HAVE_KRB5INT_C_MANDATORY_CKSUMTYPE */
@@ -248,3 +265,153 @@ rfc3961ChecksumTypeForKey(OM_uint32 *minor,
 
     return GSS_S_COMPLETE;
 }
+
+#ifdef HAVE_HEIMDAL_VERSION
+static heim_general_string krbAnonymousPrincipalComponents[] =
+    { KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME };
+
+static const Principal krbAnonymousPrincipalData = {
+    { KRB5_NT_WELLKNOWN, { 2, krbAnonymousPrincipalComponents } },
+    "WELLKNOWN:ANONYMOUS"
+};
+#endif
+
+krb5_const_principal
+krbAnonymousPrincipal(void)
+{
+#ifdef HAVE_HEIMDAL_VERSION
+    return &krbAnonymousPrincipalData;
+#else
+    return krb5_anonymous_principal();
+#endif
+}
+
+krb5_error_code
+krbCryptoLength(krb5_context krbContext,
+#ifdef HAVE_HEIMDAL_VERSION
+                krb5_crypto krbCrypto,
+#else
+                krb5_keyblock *key,
+#endif
+                int type,
+                size_t *length)
+{
+#ifdef HAVE_HEIMDAL_VERSION
+    return krb5_crypto_length(krbContext, krbCrypto, type, length);
+#else
+    unsigned int len;
+    krb5_error_code code;
+
+    code = krb5_c_crypto_length(krbContext, KRB_KEY_TYPE(key), type, &len);
+    if (code == 0)
+        *length = (size_t)len;
+
+    return code;
+#endif
+}
+
+krb5_error_code
+krbPaddingLength(krb5_context krbContext,
+#ifdef HAVE_HEIMDAL_VERSION
+                 krb5_crypto krbCrypto,
+#else
+                 krb5_keyblock *key,
+#endif
+                 size_t dataLength,
+                 size_t *padLength)
+{
+    krb5_error_code code;
+#ifdef HAVE_HEIMDAL_VERSION
+    size_t headerLength, paddingLength;
+
+    code = krbCryptoLength(krbContext, krbCrypto,
+                           KRB5_CRYPTO_TYPE_HEADER, &headerLength);
+    if (code != 0)
+        return code;
+
+    dataLength += headerLength;
+
+    code = krb5_crypto_length(krbContext, krbCrypto,
+                              KRB5_CRYPTO_TYPE_PADDING, &paddingLength);
+    if (code != 0)
+        return code;
+
+    if (paddingLength != 0 && (dataLength % paddingLength) != 0)
+        *padLength = paddingLength - (dataLength % paddingLength);
+    else
+        *padLength = 0;
+
+    return 0;
+#else
+    unsigned int pad;
+
+    code = krb5_c_padding_length(krbContext, KRB_KEY_TYPE(key), dataLength, &pad);
+    if (code == 0)
+        *padLength = (size_t)pad;
+
+    return code;
+#endif /* HAVE_HEIMDAL_VERSION */
+}
+
+krb5_error_code
+krbBlockSize(krb5_context krbContext,
+#ifdef HAVE_HEIMDAL_VERSION
+                 krb5_crypto krbCrypto,
+#else
+                 krb5_keyblock *key,
+#endif
+                 size_t *blockSize)
+{
+#ifdef HAVE_HEIMDAL_VERSION
+    return krb5_crypto_getblocksize(krbContext, krbCrypto, blockSize);
+#else
+    return krb5_c_block_size(krbContext, KRB_KEY_TYPE(key), blockSize);
+#endif
+}
+
+krb5_error_code
+krbEnctypeToString(krb5_context krbContext,
+                   krb5_enctype enctype,
+                   const char *prefix,
+                   gss_buffer_t string)
+{
+    krb5_error_code code;
+#ifdef HAVE_HEIMDAL_VERSION
+    char *enctypeBuf = NULL;
+#else
+    char enctypeBuf[128];
+#endif
+    size_t prefixLength, enctypeLength;
+
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_enctype_to_string(krbContext, enctype, &enctypeBuf);
+#else
+    code = krb5_enctype_to_name(enctype, 0, enctypeBuf, sizeof(enctypeBuf));
+#endif
+    if (code != 0)
+        return code;
+
+    prefixLength = (prefix != NULL) ? strlen(prefix) : 0;
+    enctypeLength = strlen(enctypeBuf);
+
+    string->value = GSSEAP_MALLOC(prefixLength + enctypeLength + 1);
+    if (string->value == NULL) {
+#ifdef HAVE_HEIMDAL_VERSION
+        krb5_xfree(enctypeBuf);
+#endif
+        return ENOMEM;
+    }
+
+    if (prefixLength != 0)
+        memcpy(string->value, prefix, prefixLength);
+    memcpy((char *)string->value + prefixLength, enctypeBuf, enctypeLength);
+
+    string->length = prefixLength + enctypeLength;
+    ((char *)string->value)[string->length] = '\0';
+
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_xfree(enctypeBuf);
+#endif
+
+    return 0;
+}
index 9bceb3b..b1475f8 100644 (file)
@@ -136,7 +136,7 @@ krbPrincipalToName(OM_uint32 *minor,
     name->krbPrincipal = *principal;
     *principal = NULL;
 
-    if (name->krbPrincipal->length > 1) {
+    if (KRB_PRINC_LENGTH(name->krbPrincipal) > 1) {
         name->flags |= NAME_FLAG_SERVICE;
     } else {
         name->flags |= NAME_FLAG_NAI;
@@ -201,7 +201,7 @@ importUserName(OM_uint32 *minor,
 
     if (nameBuffer == GSS_C_NO_BUFFER) {
         *minor = krb5_copy_principal(krbContext,
-                                     krb5_anonymous_principal(), &krbPrinc);
+                                     krbAnonymousPrincipal(), &krbPrinc);
         if (*minor != 0)
             return GSS_S_FAILURE;
     } else {
@@ -225,6 +225,30 @@ importUserName(OM_uint32 *minor,
     return major;
 }
 
+static OM_uint32
+importAnonymousName(OM_uint32 *minor,
+                    const gss_buffer_t nameBuffer,
+                    gss_name_t *pName)
+{
+    OM_uint32 major;
+    krb5_context krbContext;
+    krb5_principal krbPrinc;
+
+    GSSEAP_KRB_INIT(&krbContext);
+
+    *minor = krb5_copy_principal(krbContext, krbAnonymousPrincipal(),
+                                 &krbPrinc);
+    if (*minor != 0)
+        return GSS_S_FAILURE;
+
+    major = krbPrincipalToName(minor, &krbPrinc, pName);
+    if (GSS_ERROR(major)) {
+        krb5_free_principal(krbContext, krbPrinc);
+    }
+
+    return major;
+}
+
 #define UPDATE_REMAIN(n)    do {            \
         p += (n);                           \
         remain -= (n);                      \
@@ -361,6 +385,7 @@ gssEapImportName(OM_uint32 *minor,
         { GSS_EAP_NT_PRINCIPAL_NAME,        importUserName              },
         { GSS_C_NT_HOSTBASED_SERVICE,       importServiceName           },
         { GSS_C_NT_HOSTBASED_SERVICE_X,     importServiceName           },
+        { GSS_C_NT_ANONYMOUS,               importAnonymousName         },
         { GSS_C_NT_EXPORT_NAME,             importExportName            },
 #ifdef HAVE_GSS_C_NT_COMPOSITE_EXPORT
         { GSS_C_NT_COMPOSITE_EXPORT,        importCompositeExportName   },
@@ -536,6 +561,7 @@ gssEapDisplayName(OM_uint32 *minor,
     OM_uint32 major;
     krb5_context krbContext;
     char *krbName;
+    gss_OID name_type;
 
     GSSEAP_KRB_INIT(&krbContext);
 
@@ -560,8 +586,16 @@ gssEapDisplayName(OM_uint32 *minor,
 
     krb5_free_unparsed_name(krbContext, krbName);
 
+    if (KRB_PRINC_TYPE(name->krbPrincipal) == KRB5_NT_WELLKNOWN &&
+        krb5_principal_compare(krbContext,
+                               name->krbPrincipal, krbAnonymousPrincipal())) {
+        name_type = GSS_C_NT_ANONYMOUS;
+    } else {
+        name_type = GSS_EAP_NT_PRINCIPAL_NAME;
+    }
+
     if (output_name_type != NULL)
-        *output_name_type = GSS_EAP_NT_PRINCIPAL_NAME;
+        *output_name_type = name_type;
 
     return GSS_S_COMPLETE;
 }
index 7806671..47be2a3 100644 (file)
@@ -275,7 +275,7 @@ static int
 isTicketGrantingServiceP(krb5_context krbContext,
                          krb5_const_principal principal)
 {
-    if (krb5_princ_size(krbContext, principal) == 2 &&
+    if (KRB_PRINC_LENGTH(principal) == 2 &&
         krb5_princ_component(krbContext, principal, 0)->length == 6 &&
         memcmp(krb5_princ_component(krbContext,
                                     principal, 0)->data, "krbtgt", 6) == 0)
index ed9be57..19f263c 100644 (file)
@@ -98,9 +98,12 @@ gssEapWrapOrGetMIC(OM_uint32 *minor,
     unsigned char *tbuf = NULL;
     int keyUsage;
     size_t rrc = 0;
-    unsigned int gssHeaderLen, gssTrailerLen;
+    size_t gssHeaderLen, gssTrailerLen;
     size_t dataLen, assocDataLen;
     krb5_context krbContext;
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_crypto krbCrypto = NULL;
+#endif
 
     if (ctx->encryptionType == ENCTYPE_NULL) {
         *minor = GSSEAP_KEY_UNAVAILABLE;
@@ -135,32 +138,37 @@ gssEapWrapOrGetMIC(OM_uint32 *minor,
 
     trailer = gssEapLocateIov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
 
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, ETYPE_NULL, &krbCrypto);
+    if (code != 0)
+        goto cleanup;
+#endif
+
     if (toktype == TOK_TYPE_WRAP && conf_req_flag) {
-        unsigned int krbHeaderLen, krbTrailerLen, krbPadLen;
-        size_t ec = 0;
-        size_t confDataLen = dataLen - assocDataLen;
+        size_t krbHeaderLen, krbTrailerLen, krbPadLen;
+        size_t ec = 0, confDataLen = dataLen - assocDataLen;
 
-        code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
-                                    KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
+        code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                               KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
         if (code != 0)
             goto cleanup;
 
-        code = krb5_c_padding_length(krbContext, ctx->encryptionType,
-                                     confDataLen + 16 /* E(Header) */,
-                                     &krbPadLen);
+        code = krbPaddingLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                                confDataLen + 16 /* E(Header) */,
+                                &krbPadLen);
         if (code != 0)
             goto cleanup;
 
         if (krbPadLen == 0 && (ctx->gssFlags & GSS_C_DCE_STYLE)) {
             /* Windows rejects AEAD tokens with non-zero EC */
-            code = krb5_c_block_size(krbContext, ctx->encryptionType, &ec);
+            code = krbBlockSize(krbContext, KRB_CRYPTO_CONTEXT(ctx), &ec);
             if (code != 0)
                 goto cleanup;
         } else
             ec = krbPadLen;
 
-        code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
-                                    KRB5_CRYPTO_TYPE_TRAILER, &krbTrailerLen);
+        code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                               KRB5_CRYPTO_TYPE_TRAILER, &krbTrailerLen);
         if (code != 0)
             goto cleanup;
 
@@ -221,8 +229,8 @@ gssEapWrapOrGetMIC(OM_uint32 *minor,
 
         code = gssEapEncrypt(krbContext,
                              ((ctx->gssFlags & GSS_C_DCE_STYLE) != 0),
-                             ec, rrc, &ctx->rfc3961Key,
-                             keyUsage, 0, iov, iov_count);
+                             ec, rrc, KRB_CRYPTO_CONTEXT(ctx),
+                             keyUsage, iov, iov_count);
         if (code != 0)
             goto cleanup;
 
@@ -235,9 +243,8 @@ gssEapWrapOrGetMIC(OM_uint32 *minor,
 
         gssHeaderLen = 16;
 
-        code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
-                                    KRB5_CRYPTO_TYPE_CHECKSUM,
-                                    &gssTrailerLen);
+        code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                               KRB5_CRYPTO_TYPE_CHECKSUM, &gssTrailerLen);
         if (code != 0)
             goto cleanup;
 
@@ -288,8 +295,8 @@ gssEapWrapOrGetMIC(OM_uint32 *minor,
         }
         store_uint64_be(ctx->sendSeq, outbuf + 8);
 
-        code = gssEapSign(krbContext, ctx->checksumType,
-                          rrc, &ctx->rfc3961Key, keyUsage,
+        code = gssEapSign(krbContext, ctx->checksumType, rrc,
+                          KRB_CRYPTO_CONTEXT(ctx), keyUsage,
                           iov, iov_count);
         if (code != 0)
             goto cleanup;
@@ -319,6 +326,10 @@ gssEapWrapOrGetMIC(OM_uint32 *minor,
 cleanup:
     if (code != 0)
         gssEapReleaseIov(iov, iov_count);
+#ifdef HAVE_HEIMDAL_VERSION
+    if (krbCrypto != NULL)
+        krb5_crypto_destroy(krbContext, krbCrypto);
+#endif
 
     *minor = code;
 
index c3372e9..134ecc8 100644 (file)
@@ -75,11 +75,14 @@ gssEapWrapIovLength(OM_uint32 *minor,
     gss_iov_buffer_t header, trailer, padding;
     size_t dataLength, assocDataLength;
     size_t gssHeaderLen, gssPadLen, gssTrailerLen;
-    unsigned int krbHeaderLen = 0, krbTrailerLen = 0, krbPadLen = 0;
+    size_t krbHeaderLen = 0, krbTrailerLen = 0, krbPadLen = 0;
     krb5_error_code code;
     krb5_context krbContext;
     int dce_style;
     size_t ec;
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_crypto krbCrypto = NULL;
+#endif
 
     if (qop_req != GSS_C_QOP_DEFAULT) {
         *minor = GSSEAP_UNKNOWN_QOP;
@@ -120,18 +123,24 @@ gssEapWrapIovLength(OM_uint32 *minor,
 
     gssHeaderLen = gssPadLen = gssTrailerLen = 0;
 
-    code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
-                                conf_req_flag ?
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, ETYPE_NULL, &krbCrypto);
+    if (code != 0)
+        return code;
+#endif
+
+    code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                           conf_req_flag ?
                                 KRB5_CRYPTO_TYPE_TRAILER : KRB5_CRYPTO_TYPE_CHECKSUM,
-                                &krbTrailerLen);
+                           &krbTrailerLen);
     if (code != 0) {
         *minor = code;
         return GSS_S_FAILURE;
     }
 
     if (conf_req_flag) {
-        code = krb5_c_crypto_length(krbContext, ctx->encryptionType,
-                                    KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
+        code = krbCryptoLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                               KRB5_CRYPTO_TYPE_HEADER, &krbHeaderLen);
         if (code != 0) {
             *minor = code;
             return GSS_S_FAILURE;
@@ -143,9 +152,9 @@ gssEapWrapIovLength(OM_uint32 *minor,
         gssHeaderLen += krbHeaderLen; /* Kerb-Header */
         gssTrailerLen = 16 /* E(Header) */ + krbTrailerLen; /* Kerb-Trailer */
 
-        code = krb5_c_padding_length(krbContext, ctx->encryptionType,
-                                     dataLength - assocDataLength + 16 /* E(Header) */,
-                                     &krbPadLen);
+        code = krbPaddingLength(krbContext, KRB_CRYPTO_CONTEXT(ctx),
+                                dataLength - assocDataLength + 16 /* E(Header) */,
+                                &krbPadLen);
         if (code != 0) {
             *minor = code;
             return GSS_S_FAILURE;
@@ -153,7 +162,7 @@ gssEapWrapIovLength(OM_uint32 *minor,
 
         if (krbPadLen == 0 && dce_style) {
             /* Windows rejects AEAD tokens with non-zero EC */
-            code = krb5_c_block_size(krbContext, ctx->encryptionType, &ec);
+            code = krbBlockSize(krbContext, KRB_CRYPTO_CONTEXT(ctx), &ec);
             if (code != 0) {
                 *minor = code;
                 return GSS_S_FAILURE;