Fixes for Heimdal (macOS) builds from Stefan.
[mech_eap.git] / mech_eap / init_sec_context.c
index c4769d7..89faf49 100644 (file)
@@ -40,7 +40,9 @@
 #include "util_radius.h"
 #include "utils/radius_utils.h"
 #include "openssl/err.h"
+#ifdef HAVE_MOONSHOT_GET_IDENTITY
 #include "libmoonshot.h"
+#endif
 
 /* methods allowed for phase1 authentication*/
 static const struct eap_method_type allowed_eap_method_types[] = {
@@ -203,17 +205,6 @@ peerNotifyPending(void *ctx GSSEAP_UNUSED)
 {
 }
 
-static void peerNotifyCert(void *ctx GSSEAP_UNUSED,
-                          int depth ,
-                          const char *subject GSSEAP_UNUSED,
-                          const char *altsubject[] GSSEAP_UNUSED,
-                          int num_altsubject GSSEAP_UNUSED,
-                          const char *cert_hash GSSEAP_UNUSED,
-                          const struct wpabuf *cert  GSSEAP_UNUSED)
-{
-    printf("peerNotifyCert: depth=%d; hash=%s (%p)\n", depth, cert_hash, cert_hash);
-}
-
 
 static struct eapol_callbacks gssEapPolicyCallbacks = {
     peerGetConfig,
@@ -226,7 +217,7 @@ static struct eapol_callbacks gssEapPolicyCallbacks = {
     peerGetConfigBlob,
     peerNotifyPending,
     NULL,  /* eap_param_needed */
-    peerNotifyCert
+    NULL   /* eap_notify_cert */
 };
 
 
@@ -372,6 +363,7 @@ peerProcessChbindResponse(void *context, int code, int nsid,
     } /* else log failures? */
 }
 
+#ifdef HAVE_MOONSHOT_GET_IDENTITY
 static int cert_to_byte_array(X509 *cert, unsigned char **bytes)
 {
        unsigned char *buf;
@@ -418,10 +410,9 @@ static int sha256(unsigned char *bytes, int len, unsigned char *hash)
        return hash_len;
 }
 
-
-static int peerValidateCA(int ok_so_far, X509* cert, void *ca_ctx)
+static int peerValidateServerCert(int ok_so_far, X509* cert, void *ca_ctx)
 {
-    const char           *realm = NULL;
+    char                 *realm = NULL;
     unsigned char        *cert_bytes = NULL;
     int                   cert_len;
     unsigned char         hash[32];
@@ -430,9 +421,10 @@ static int peerValidateCA(int ok_so_far, X509* cert, void *ca_ctx)
     struct eap_peer_config *eap_config = (struct eap_peer_config *) ca_ctx;
     char *identity = strdup((const char *) eap_config->identity);
 
-    // Truncate the identity to just the username
+    // Truncate the identity to just the username; make a separate string for the realm.
     char* at = strchr(identity, '@');
     if (at != NULL) {
+        realm = strdup(at + 1);
         *at = '\0';
     }
     
@@ -441,22 +433,20 @@ static int peerValidateCA(int ok_so_far, X509* cert, void *ca_ctx)
     GSSEAP_FREE(cert_bytes);
     
     if (hash_len != 32) {
-        printf("peerValidateCA: Error: hash_len=%d, not 32!\n", hash_len);
+        fprintf(stderr, "peerValidateServerCert: Error: hash_len=%d, not 32!\n", hash_len);
         return FALSE;
     }
 
-    /* This is ugly, but it works -- anonymous_identity is '@' + realm
-     *  (see peerConfigInit)
-     */
-    realm = ((char *) eap_config->anonymous_identity) + 1;
-
     ok_so_far = moonshot_confirm_ca_certificate(identity, realm, hash, 32, &error);
     free(identity);
-
-    printf("peerValidateCA: Returning %d\n", ok_so_far);
+    if (realm != NULL) {
+        free(realm);
+    }
+    
+    wpa_printf(MSG_INFO, "peerValidateServerCert: Returning %d\n", ok_so_far);
     return ok_so_far;
 }
-
+#endif
 
 static OM_uint32
 peerConfigInit(OM_uint32 *minor, gss_ctx_id_t ctx)
@@ -566,7 +556,9 @@ peerConfigInit(OM_uint32 *minor, gss_ctx_id_t ctx)
         eapPeerConfig->private_key_passwd = (char *)cred->password.value;
     }
 
-    eapPeerConfig->server_cert_cb = peerValidateCA;
+#ifdef HAVE_MOONSHOT_GET_IDENTITY
+    eapPeerConfig->server_cert_cb = peerValidateServerCert;
+#endif
     eapPeerConfig->server_cert_ctx = eapPeerConfig;
 
     *minor = 0;
@@ -651,7 +643,7 @@ initReady(OM_uint32 *minor, gss_ctx_id_t ctx)
 static OM_uint32
 initBegin(OM_uint32 *minor,
           gss_ctx_id_t ctx,
-          gss_name_t target,
+          gss_const_name_t target,
           gss_OID mech,
           OM_uint32 reqFlags GSSEAP_UNUSED,
           OM_uint32 timeReq,
@@ -679,15 +671,15 @@ initBegin(OM_uint32 *minor,
         return major;
 
     if (target != GSS_C_NO_NAME) {
-        GSSEAP_MUTEX_LOCK(&target->mutex);
+        GSSEAP_MUTEX_LOCK(&((gss_name_t)target)->mutex);
 
         major = gssEapDuplicateName(minor, target, &ctx->acceptorName);
         if (GSS_ERROR(major)) {
-            GSSEAP_MUTEX_UNLOCK(&target->mutex);
+            GSSEAP_MUTEX_LOCK(&((gss_name_t)target)->mutex);
             return major;
         }
 
-        GSSEAP_MUTEX_UNLOCK(&target->mutex);
+        GSSEAP_MUTEX_UNLOCK(&((gss_name_t)target)->mutex);
     }
 
     major = gssEapCanonicalizeOid(minor,
@@ -711,7 +703,7 @@ static OM_uint32
 eapGssSmInitError(OM_uint32 *minor,
                   gss_cred_id_t cred GSSEAP_UNUSED,
                   gss_ctx_id_t ctx GSSEAP_UNUSED,
-                  gss_name_t target GSSEAP_UNUSED,
+                  gss_const_name_t target GSSEAP_UNUSED,
                   gss_OID mech GSSEAP_UNUSED,
                   OM_uint32 reqFlags GSSEAP_UNUSED,
                   OM_uint32 timeReq GSSEAP_UNUSED,
@@ -751,7 +743,7 @@ static OM_uint32
 eapGssSmInitGssReauth(OM_uint32 *minor,
                       gss_cred_id_t cred,
                       gss_ctx_id_t ctx,
-                      gss_name_t target,
+                      gss_const_name_t target,
                       gss_OID mech GSSEAP_UNUSED,
                       OM_uint32 reqFlags,
                       OM_uint32 timeReq,
@@ -770,7 +762,7 @@ eapGssSmInitGssReauth(OM_uint32 *minor,
      * context credential does not currently have the reauth creds.
      */
     if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_INITIAL) {
-        if (!gssEapCanReauthP(cred, target, timeReq))
+      if (!gssEapCanReauthP(cred, (gss_name_t) target, timeReq))
             return GSS_S_CONTINUE_NEEDED;
 
         ctx->flags |= CTX_FLAG_KRB_REAUTH;
@@ -782,7 +774,7 @@ eapGssSmInitGssReauth(OM_uint32 *minor,
 
     GSSEAP_ASSERT(cred != GSS_C_NO_CREDENTIAL);
 
-    major = gssEapMechToGlueName(minor, target, &mechTarget);
+    major = gssEapMechToGlueName(minor, (gss_name_t) target, &mechTarget);
     if (GSS_ERROR(major))
         goto cleanup;
 
@@ -827,7 +819,7 @@ static OM_uint32
 eapGssSmInitVendorInfo(OM_uint32 *minor,
                        gss_cred_id_t cred GSSEAP_UNUSED,
                        gss_ctx_id_t ctx GSSEAP_UNUSED,
-                       gss_name_t target GSSEAP_UNUSED,
+                       gss_const_name_t target GSSEAP_UNUSED,
                        gss_OID mech GSSEAP_UNUSED,
                        OM_uint32 reqFlags GSSEAP_UNUSED,
                        OM_uint32 timeReq GSSEAP_UNUSED,
@@ -850,7 +842,7 @@ static OM_uint32
 eapGssSmInitAcceptorName(OM_uint32 *minor,
                          gss_cred_id_t cred GSSEAP_UNUSED,
                          gss_ctx_id_t ctx,
-                         gss_name_t target GSSEAP_UNUSED,
+                         gss_const_name_t target GSSEAP_UNUSED,
                          gss_OID mech GSSEAP_UNUSED,
                          OM_uint32 reqFlags GSSEAP_UNUSED,
                          OM_uint32 timeReq GSSEAP_UNUSED,
@@ -933,7 +925,7 @@ static OM_uint32
 eapGssSmInitIdentity(OM_uint32 *minor,
                      gss_cred_id_t cred GSSEAP_UNUSED,
                      gss_ctx_id_t ctx,
-                     gss_name_t target GSSEAP_UNUSED,
+                     gss_const_name_t target GSSEAP_UNUSED,
                      gss_OID mech GSSEAP_UNUSED,
                      OM_uint32 reqFlags GSSEAP_UNUSED,
                      OM_uint32 timeReq GSSEAP_UNUSED,
@@ -989,7 +981,7 @@ static OM_uint32
 eapGssSmInitAuthenticate(OM_uint32 *minor,
                          gss_cred_id_t cred GSSEAP_UNUSED,
                          gss_ctx_id_t ctx,
-                         gss_name_t target GSSEAP_UNUSED,
+                         gss_const_name_t target GSSEAP_UNUSED,
                          gss_OID mech GSSEAP_UNUSED,
                          OM_uint32 reqFlags GSSEAP_UNUSED,
                          OM_uint32 timeReq GSSEAP_UNUSED,
@@ -1070,7 +1062,7 @@ static OM_uint32
 eapGssSmInitGssFlags(OM_uint32 *minor,
                      gss_cred_id_t cred GSSEAP_UNUSED,
                      gss_ctx_id_t ctx,
-                     gss_name_t target GSSEAP_UNUSED,
+                     gss_const_name_t target GSSEAP_UNUSED,
                      gss_OID mech GSSEAP_UNUSED,
                      OM_uint32 reqFlags GSSEAP_UNUSED,
                      OM_uint32 timeReq GSSEAP_UNUSED,
@@ -1099,7 +1091,7 @@ static OM_uint32
 eapGssSmInitGssChannelBindings(OM_uint32 *minor,
                                gss_cred_id_t cred GSSEAP_UNUSED,
                                gss_ctx_id_t ctx,
-                               gss_name_t target GSSEAP_UNUSED,
+                               gss_const_name_t target GSSEAP_UNUSED,
                                gss_OID mech GSSEAP_UNUSED,
                                OM_uint32 reqFlags GSSEAP_UNUSED,
                                OM_uint32 timeReq GSSEAP_UNUSED,
@@ -1114,6 +1106,9 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor,
     krb5_data data;
     krb5_checksum cksum;
     gss_buffer_desc cksumBuffer;
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_crypto krbCrypto;
+#endif
 
     if (chanBindings == GSS_C_NO_CHANNEL_BINDINGS ||
         chanBindings->application_data.length == 0)
@@ -1125,10 +1120,25 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor,
 
     gssBufferToKrbData(&chanBindings->application_data, &data);
 
+#ifdef HAVE_HEIMDAL_VERSION
+    code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, 0, &krbCrypto);
+    if (code != 0) {
+        *minor = code;
+        return GSS_S_FAILURE;
+    }
+
+    code = krb5_create_checksum(krbContext, krbCrypto,
+                                KEY_USAGE_GSSEAP_CHBIND_MIC,
+                                ctx->checksumType,
+                                data.data, data.length,
+                                &cksum);
+    krb5_crypto_destroy(krbContext, krbCrypto);
+#else
     code = krb5_c_make_checksum(krbContext, ctx->checksumType,
                                 &ctx->rfc3961Key,
                                 KEY_USAGE_GSSEAP_CHBIND_MIC,
                                 &data, &cksum);
+#endif /* HAVE_HEIMDAL_VERSION */
     if (code != 0) {
         *minor = code;
         return GSS_S_FAILURE;
@@ -1139,14 +1149,14 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor,
 
     major = duplicateBuffer(minor, &cksumBuffer, outputToken);
     if (GSS_ERROR(major)) {
-        krb5_free_checksum_contents(krbContext, &cksum);
+        KRB_CHECKSUM_FREE(krbContext, &cksum);
         return major;
     }
 
     *minor = 0;
     *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL;
 
-    krb5_free_checksum_contents(krbContext, &cksum);
+    KRB_CHECKSUM_FREE(krbContext, &cksum);
 
     return GSS_S_CONTINUE_NEEDED;
 }
@@ -1155,7 +1165,7 @@ static OM_uint32
 eapGssSmInitInitiatorMIC(OM_uint32 *minor,
                          gss_cred_id_t cred GSSEAP_UNUSED,
                          gss_ctx_id_t ctx,
-                         gss_name_t target GSSEAP_UNUSED,
+                         gss_const_name_t target GSSEAP_UNUSED,
                          gss_OID mech GSSEAP_UNUSED,
                          OM_uint32 reqFlags GSSEAP_UNUSED,
                          OM_uint32 timeReq GSSEAP_UNUSED,
@@ -1183,7 +1193,7 @@ static OM_uint32
 eapGssSmInitReauthCreds(OM_uint32 *minor,
                         gss_cred_id_t cred,
                         gss_ctx_id_t ctx,
-                        gss_name_t target GSSEAP_UNUSED,
+                        gss_const_name_t target GSSEAP_UNUSED,
                         gss_OID mech GSSEAP_UNUSED,
                         OM_uint32 reqFlags GSSEAP_UNUSED,
                         OM_uint32 timeReq GSSEAP_UNUSED,
@@ -1209,7 +1219,7 @@ static OM_uint32
 eapGssSmInitAcceptorMIC(OM_uint32 *minor,
                         gss_cred_id_t cred GSSEAP_UNUSED,
                         gss_ctx_id_t ctx,
-                        gss_name_t target GSSEAP_UNUSED,
+                        gss_const_name_t target GSSEAP_UNUSED,
                         gss_OID mech GSSEAP_UNUSED,
                         OM_uint32 reqFlags GSSEAP_UNUSED,
                         OM_uint32 timeReq GSSEAP_UNUSED,
@@ -1326,7 +1336,7 @@ OM_uint32
 gssEapInitSecContext(OM_uint32 *minor,
                      gss_cred_id_t cred,
                      gss_ctx_id_t ctx,
-                     gss_name_t target_name,
+                     gss_const_name_t target_name,
                      gss_OID mech_type,
                      OM_uint32 req_flags,
                      OM_uint32 time_req,
@@ -1413,9 +1423,17 @@ cleanup:
 
 OM_uint32 GSSAPI_CALLCONV
 gss_init_sec_context(OM_uint32 *minor,
+#ifdef HAVE_HEIMDAL_VERSION
+                     gss_const_cred_id_t cred,
+#else
                      gss_cred_id_t cred,
+#endif
                      gss_ctx_id_t *context_handle,
+#ifdef HAVE_HEIMDAL_VERSION
+                     gss_const_name_t target_name,
+#else
                      gss_name_t target_name,
+#endif
                      gss_OID mech_type,
                      OM_uint32 req_flags,
                      OM_uint32 time_req,
@@ -1452,7 +1470,7 @@ gss_init_sec_context(OM_uint32 *minor,
     GSSEAP_MUTEX_LOCK(&ctx->mutex);
 
     major = gssEapInitSecContext(minor,
-                                 cred,
+                                 (gss_cred_id_t)cred,
                                  ctx,
                                  target_name,
                                  mech_type,
@@ -1470,7 +1488,8 @@ gss_init_sec_context(OM_uint32 *minor,
     if (GSS_ERROR(major))
         gssEapReleaseContext(&tmpMinor, context_handle);
 
-    gssEapTraceStatus( "gss_init_sec_context", major, *minor);
+    gssEapTraceStatus("gss_init_sec_context", major, *minor);
+
     return major;
 }