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)));