Blame SOURCES/Return-UPN-SANs-as-strings.patch

d738b9
From 0f94f224f16f196d8d3fb56cfcf4a65bdd0f20c7 Mon Sep 17 00:00:00 2001
d738b9
From: Greg Hudson <ghudson@mit.edu>
d738b9
Date: Thu, 22 Mar 2018 20:07:17 -0400
d738b9
Subject: [PATCH] Return UPN SANs as strings
d738b9
d738b9
(cherry picked from commit fd3c824e3be56a1fa77d140fd7e93934bfd6e565)
d738b9
---
d738b9
 src/plugins/preauth/pkinit/pkinit_crypto.h    |  4 +--
d738b9
 .../preauth/pkinit/pkinit_crypto_openssl.c    | 28 +++++++------------
d738b9
 src/plugins/preauth/pkinit/pkinit_matching.c  | 16 ++---------
d738b9
 src/plugins/preauth/pkinit/pkinit_srv.c       | 21 +++++++++-----
d738b9
 4 files changed, 29 insertions(+), 40 deletions(-)
d738b9
d738b9
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
d738b9
index c14f4456a..b6e4e0ac3 100644
d738b9
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
d738b9
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
d738b9
@@ -101,7 +101,7 @@ typedef struct _pkinit_cert_matching_data {
d738b9
     unsigned int ku_bits;   /* key usage information */
d738b9
     unsigned int eku_bits;  /* extended key usage information */
d738b9
     krb5_principal *sans;   /* Null-terminated array of PKINIT SANs */
d738b9
-    krb5_principal *upns;   /* Null-terimnated array of UPN SANs */
d738b9
+    char **upns;	    /* Null-terimnated array of UPN SANs */
d738b9
 } pkinit_cert_matching_data;
d738b9
 
d738b9
 /*
d738b9
@@ -253,7 +253,7 @@ krb5_error_code crypto_retrieve_cert_sans
d738b9
 		    if non-NULL, a null-terminated array of
d738b9
 		    id-pkinit-san values found in the certificate
d738b9
 		    are returned */
d738b9
-	krb5_principal **upn_sans,			/* OUT
d738b9
+	char ***upn_sans,				/* OUT
d738b9
 		    if non-NULL, a null-terminated array of
d738b9
 		    id-ms-upn-san values found in the certificate
d738b9
 		    are returned */
d738b9
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
d738b9
index cf2f16294..3949eb9c2 100644
d738b9
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
d738b9
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
d738b9
@@ -29,6 +29,7 @@
d738b9
  * SUCH DAMAGES.
d738b9
  */
d738b9
 
d738b9
+#include "k5-int.h"
d738b9
 #include "pkinit_crypto_openssl.h"
d738b9
 #include "k5-buf.h"
d738b9
 #include <dlfcn.h>
d738b9
@@ -2095,15 +2096,14 @@ crypto_retrieve_X509_sans(krb5_context context,
d738b9
                           pkinit_plg_crypto_context plgctx,
d738b9
                           pkinit_req_crypto_context reqctx,
d738b9
                           X509 *cert,
d738b9
-                          krb5_principal **princs_ret,
d738b9
-                          krb5_principal **upn_ret,
d738b9
+                          krb5_principal **princs_ret, char ***upn_ret,
d738b9
                           unsigned char ***dns_ret)
d738b9
 {
d738b9
     krb5_error_code retval = EINVAL;
d738b9
     char buf[DN_BUF_LEN];
d738b9
     int p = 0, u = 0, d = 0, ret = 0, l;
d738b9
     krb5_principal *princs = NULL;
d738b9
-    krb5_principal *upns = NULL;
d738b9
+    char **upns = NULL;
d738b9
     unsigned char **dnss = NULL;
d738b9
     unsigned int i, num_found = 0, num_sans = 0;
d738b9
     X509_EXTENSION *ext = NULL;
d738b9
@@ -2153,7 +2153,7 @@ crypto_retrieve_X509_sans(krb5_context context,
d738b9
         }
d738b9
     }
d738b9
     if (upn_ret != NULL) {
d738b9
-        upns = calloc(num_sans + 1, sizeof(krb5_principal));
d738b9
+        upns = calloc(num_sans + 1, sizeof(*upns));
d738b9
         if (upns == NULL) {
d738b9
             retval = ENOMEM;
d738b9
             goto cleanup;
d738b9
@@ -2196,16 +2196,9 @@ crypto_retrieve_X509_sans(krb5_context context,
d738b9
                 /* Prevent abuse of embedded null characters. */
d738b9
                 if (memchr(name.data, '\0', name.length))
d738b9
                     break;
d738b9
-                ret = krb5_parse_name_flags(context, name.data,
d738b9
-                                            KRB5_PRINCIPAL_PARSE_ENTERPRISE,
d738b9
-                                            &upns[u]);
d738b9
-                if (ret) {
d738b9
-                    pkiDebug("%s: failed parsing ms-upn san value\n",
d738b9
-                             __FUNCTION__);
d738b9
-                } else {
d738b9
-                    u++;
d738b9
-                    num_found++;
d738b9
-                }
d738b9
+                upns[u] = k5memdup0(name.data, name.length, &ret;;
d738b9
+                if (upns[u] == NULL)
d738b9
+                    goto cleanup;
d738b9
             } else {
d738b9
                 pkiDebug("%s: unrecognized othername oid in SAN\n",
d738b9
                          __FUNCTION__);
d738b9
@@ -2257,7 +2250,7 @@ cleanup:
d738b9
         krb5_free_principal(context, princs[i]);
d738b9
     free(princs);
d738b9
     for (i = 0; upns != NULL && upns[i] != NULL; i++)
d738b9
-        krb5_free_principal(context, upns[i]);
d738b9
+        free(upns[i]);
d738b9
     free(upns);
d738b9
     for (i = 0; dnss != NULL && dnss[i] != NULL; i++)
d738b9
         free(dnss[i]);
d738b9
@@ -2281,8 +2274,7 @@ crypto_retrieve_cert_sans(krb5_context context,
d738b9
                           pkinit_plg_crypto_context plgctx,
d738b9
                           pkinit_req_crypto_context reqctx,
d738b9
                           pkinit_identity_crypto_context idctx,
d738b9
-                          krb5_principal **princs_ret,
d738b9
-                          krb5_principal **upn_ret,
d738b9
+                          krb5_principal **princs_ret, char ***upn_ret,
d738b9
                           unsigned char ***dns_ret)
d738b9
 {
d738b9
     krb5_error_code retval = EINVAL;
d738b9
@@ -5111,7 +5103,7 @@ crypto_cert_free_matching_data(krb5_context context,
d738b9
         krb5_free_principal(context, md->sans[i]);
d738b9
     free(md->sans);
d738b9
     for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++)
d738b9
-        krb5_free_principal(context, md->upns[i]);
d738b9
+        free(md->upns[i]);
d738b9
     free(md->upns);
d738b9
     free(md);
d738b9
 }
d738b9
diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c
d738b9
index fe1e0f386..d929fb3c0 100644
d738b9
--- a/src/plugins/preauth/pkinit/pkinit_matching.c
d738b9
+++ b/src/plugins/preauth/pkinit/pkinit_matching.c
d738b9
@@ -490,11 +490,7 @@ component_match(krb5_context context,
d738b9
                     break;
d738b9
             }
d738b9
             for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) {
d738b9
-                krb5_unparse_name_flags(context, md->upns[i],
d738b9
-                                        KRB5_PRINCIPAL_UNPARSE_NO_REALM,
d738b9
-                                        &princ_string);
d738b9
-                match = regexp_match(context, rc, princ_string);
d738b9
-                krb5_free_unparsed_name(context, princ_string);
d738b9
+                match = regexp_match(context, rc, md->upns[i]);
d738b9
                 if (match)
d738b9
                     break;
d738b9
             }
d738b9
@@ -584,14 +580,8 @@ check_all_certs(krb5_context context,
d738b9
             pkiDebug("%s: PKINIT san: '%s'\n", __FUNCTION__, san_string);
d738b9
             krb5_free_unparsed_name(context, san_string);
d738b9
         }
d738b9
-        for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++) {
d738b9
-            char *san_string;
d738b9
-            krb5_unparse_name_flags(context, md->upns[j],
d738b9
-                                    KRB5_PRINCIPAL_UNPARSE_NO_REALM,
d738b9
-                                    &san_string);
d738b9
-            pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, san_string);
d738b9
-            krb5_free_unparsed_name(context, san_string);
d738b9
-        }
d738b9
+        for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++)
d738b9
+            pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, md->upns[j]);
d738b9
 #endif
d738b9
         certs_checked++;
d738b9
         for (rc = rs->crs; rc != NULL; rc = rc->next) {
d738b9
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
d738b9
index 143d331a2..42ad45fe4 100644
d738b9
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
d738b9
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
d738b9
@@ -174,8 +174,9 @@ verify_client_san(krb5_context context,
d738b9
                   int *valid_san)
d738b9
 {
d738b9
     krb5_error_code retval;
d738b9
-    krb5_principal *princs = NULL;
d738b9
-    krb5_principal *upns = NULL;
d738b9
+    krb5_principal *princs = NULL, upn;
d738b9
+    krb5_boolean match;
d738b9
+    char **upns = NULL;
d738b9
     int i;
d738b9
 #ifdef DEBUG_SAN_INFO
d738b9
     char *client_string = NULL, *san_string;
d738b9
@@ -251,12 +252,18 @@ verify_client_san(krb5_context context,
d738b9
     pkiDebug("%s: Checking upn sans\n", __FUNCTION__);
d738b9
     for (i = 0; upns[i] != NULL; i++) {
d738b9
 #ifdef DEBUG_SAN_INFO
d738b9
-        krb5_unparse_name(context, upns[i], &san_string);
d738b9
         pkiDebug("%s: Comparing client '%s' to upn san value '%s'\n",
d738b9
-                 __FUNCTION__, client_string, san_string);
d738b9
-        krb5_free_unparsed_name(context, san_string);
d738b9
+                 __FUNCTION__, client_string, upns[i]);
d738b9
 #endif
d738b9
-        if (cb->match_client(context, rock, upns[i])) {
d738b9
+        retval = krb5_parse_name_flags(context, upns[i],
d738b9
+                                       KRB5_PRINCIPAL_PARSE_ENTERPRISE, &upn;;
d738b9
+        if (retval) {
d738b9
+            /* XXX trace */
d738b9
+            continue;
d738b9
+        }
d738b9
+        match = cb->match_client(context, rock, upn);
d738b9
+        krb5_free_principal(context, upn);
d738b9
+        if (match) {
d738b9
             TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(context);
d738b9
             *valid_san = 1;
d738b9
             retval = 0;
d738b9
@@ -282,7 +289,7 @@ out:
d738b9
     }
d738b9
     if (upns != NULL) {
d738b9
         for (i = 0; upns[i] != NULL; i++)
d738b9
-            krb5_free_principal(context, upns[i]);
d738b9
+            free(upns[i]);
d738b9
         free(upns);
d738b9
     }
d738b9
 #ifdef DEBUG_SAN_INFO