Author: breser
Date: Sun Apr 12 19:23:49 2015
New Revision: 1673044

URL: http://svn.apache.org/r1673044
Log:
Allow the auth command to match on certificate subjects, issuers, digests
and hostnames.  We had this functionality and I unintentionally removed it
when converting to using the X.509 parser rather than storing the details
separately.

* subversion/svn/auth-cmd.c
  (parse_certificate, match_certificate): New functions.
  (match_credential): Call match_certificate() instead of
    ignoring the certificate.
  (show_cert): Use parse_certificate() which was factored out
    of this function.


Modified:
    subversion/trunk/subversion/svn/auth-cmd.c

Modified: subversion/trunk/subversion/svn/auth-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/auth-cmd.c?rev=1673044&r1=1673043&r2=1673044&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/auth-cmd.c (original)
+++ subversion/trunk/subversion/svn/auth-cmd.c Sun Apr 12 19:23:49 2015
@@ -96,6 +96,39 @@ show_cert_failures(const char *failure_s
   return SVN_NO_ERROR;
 }
 
+
+/* decodes from format we store certs in for auth creds and
+ * turns parsing errors into warnings if PRINT_WARNING is TRUE
+ * and ignores them otherwise. returns NULL if it couldn't
+ * parse a cert for any reason. */
+static svn_x509_certinfo_t *
+parse_certificate(const svn_string_t *ascii_cert,
+                  svn_boolean_t print_warning,
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
+{
+  svn_x509_certinfo_t *certinfo;
+  const svn_string_t *der_cert;
+  svn_error_t *err;
+
+  /* Convert header-less PEM to DER by undoing base64 encoding. */
+  der_cert = svn_base64_decode_string(ascii_cert, scratch_pool);
+
+  err = svn_x509_parse_cert(&certinfo, der_cert->data, der_cert->len,
+                            result_pool, scratch_pool);
+  if (err)
+    {
+      /* Just display X.509 parsing errors as warnings and continue */
+      if (print_warning)
+        svn_handle_warning2(stderr, err, "svn: ");
+      svn_error_clear(err);
+      return NULL;
+    }
+
+  return certinfo;
+}
+
+
 struct walk_credentials_baton_t
 {
   int matches;
@@ -115,6 +148,46 @@ match_pattern(const char *pattern, const
   return (apr_fnmatch(p, value, flags) == APR_SUCCESS);
 }
 
+static svn_boolean_t
+match_certificate(const char *pattern,
+                  const svn_string_t *ascii_cert,
+                  apr_pool_t *scratch_pool)
+{
+  svn_x509_certinfo_t *certinfo;
+  const char *value;
+  const svn_checksum_t *checksum;
+  const apr_array_header_t *hostnames;
+  int i;
+
+  certinfo = parse_certificate(ascii_cert, FALSE, scratch_pool, scratch_pool);
+  if (certinfo == NULL)
+    return FALSE;
+
+  value = svn_x509_certinfo_get_subject(certinfo, scratch_pool);
+  if (match_pattern(pattern, value, FALSE, scratch_pool))
+    return TRUE;
+
+  value = svn_x509_certinfo_get_issuer(certinfo, scratch_pool);
+  if (match_pattern(pattern, value, FALSE, scratch_pool))
+    return TRUE;
+
+  checksum = svn_x509_certinfo_get_digest(certinfo);
+  value = svn_checksum_to_cstring_display(checksum, scratch_pool);
+  if (match_pattern(pattern, value, TRUE, scratch_pool))
+    return TRUE;
+
+  hostnames = svn_x509_certinfo_get_hostnames(certinfo);
+  for (i = 0; i < hostnames->nelts; i++)
+    {
+      const char *hostname = APR_ARRAY_IDX(hostnames, i, const char *);
+      if (match_pattern(pattern, hostname, TRUE, scratch_pool))
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+
 static svn_error_t *
 match_credential(svn_boolean_t *match,
                  const char *cred_kind,
@@ -152,7 +225,7 @@ match_credential(svn_boolean_t *match,
                   strcmp(key, SVN_CONFIG_AUTHN_PASSPHRASE_KEY) == 0)
                 continue; /* don't match secrets */
               else if (strcmp(key, SVN_CONFIG_AUTHN_ASCII_CERT_KEY) == 0)
-                continue; /* don't match base64 data */
+                *match = match_certificate(pattern, value, iterpool);
               else
                 *match = match_pattern(pattern, value->data, FALSE, iterpool);
 
@@ -170,23 +243,13 @@ match_credential(svn_boolean_t *match,
 static svn_error_t *
 show_cert(const svn_string_t *pem_cert, apr_pool_t *scratch_pool)
 {
-  const svn_string_t *der_cert;
   svn_x509_certinfo_t *certinfo;
   const apr_array_header_t *hostnames;
-  svn_error_t *err;
 
-  /* Convert header-less PEM to DER by undoing base64 encoding. */
-  der_cert = svn_base64_decode_string(pem_cert, scratch_pool);
 
-  err = svn_x509_parse_cert(&certinfo, der_cert->data, der_cert->len,
-                            scratch_pool, scratch_pool);
-  if (err)
-    {
-      /* Just display X.509 parsing errors as warnings and continue */
-      svn_handle_warning2(stderr, err, "svn: ");
-      svn_error_clear(err);
-      return SVN_NO_ERROR;
-    }
+  certinfo = parse_certificate(pem_cert, TRUE, scratch_pool, scratch_pool);
+  if (certinfo == NULL)
+    return SVN_NO_ERROR;
 
   SVN_ERR(svn_cmdline_printf(scratch_pool, _("Subject: %s\n"),
                              svn_x509_certinfo_get_subject(certinfo, 
scratch_pool)));


Reply via email to