[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

svnauth ssl cert support -- please check windows build

From: Stefan Sperling <stsp_at_elego.de>
Date: Wed, 10 Jul 2013 03:33:59 +0200

Here's a rough patch that makes svnauth show SSL certs as a list
of fields, rather than a long base64 string.

I'm adding a dependency on OpenSSL for certificate parsing.
I hope this is fine. If OpenSSL is not available svnauth falls
back to printing the base64 encoded form of the certificate.

Since I'm tweaking the build system, it would be nice if someone
could check whether this breaks the Windows build, or the build on
other *nix platforms. And if it does, help me with fixing my patch.

Thanks!

Index: Makefile.in
===================================================================
--- Makefile.in (revision 1501587)
+++ Makefile.in (working copy)
@@ -48,6 +48,7 @@ SVN_GPG_AGENT_LIBS = @SVN_GPG_AGENT_LIBS@
 SVN_GNOME_KEYRING_LIBS = @SVN_GNOME_KEYRING_LIBS@
 SVN_KWALLET_LIBS = @SVN_KWALLET_LIBS@
 SVN_MAGIC_LIBS = @SVN_MAGIC_LIBS@
+SVN_OPENSSL_LIBS = @SVN_OPENSSL_LIBS@
 SVN_SASL_LIBS = @SVN_SASL_LIBS@
 SVN_SERF_LIBS = @SVN_SERF_LIBS@
 SVN_SQLITE_LIBS = @SVN_SQLITE_LIBS@
@@ -123,7 +124,7 @@ LT_CXX_LIBADD = @LT_CXX_LIBADD@
 INCLUDES = -I$(top_srcdir)/subversion/include -I$(top_builddir)/subversion \
            @SVN_APR_INCLUDES@ @SVN_APRUTIL_INCLUDES@ @SVN_APR_MEMCACHE_INCLUDES@ \
            @SVN_DB_INCLUDES@ @SVN_GNOME_KEYRING_INCLUDES@ \
- @SVN_KWALLET_INCLUDES@ @SVN_MAGIC_INCLUDES@ \
+ @SVN_KWALLET_INCLUDES@ @SVN_MAGIC_INCLUDES@ @SVN_OPENSSL_INCLUDES@ \
            @SVN_SASL_INCLUDES@ @SVN_SERF_INCLUDES@ @SVN_SQLITE_INCLUDES@ \
            @SVN_XML_INCLUDES@ @SVN_ZLIB_INCLUDES@
 
Index: aclocal.m4
===================================================================
--- aclocal.m4 (revision 1501587)
+++ aclocal.m4 (working copy)
@@ -39,6 +39,7 @@ sinclude(build/ac-macros/berkeley-db.m4)
 sinclude(build/ac-macros/compiler.m4)
 sinclude(build/ac-macros/ctypesgen.m4)
 sinclude(build/ac-macros/java.m4)
+sinclude(build/ac-macros/openssl.m4)
 sinclude(build/ac-macros/sasl.m4)
 sinclude(build/ac-macros/serf.m4)
 sinclude(build/ac-macros/sqlite.m4)
Index: build/ac-macros/openssl.m4
===================================================================
--- build/ac-macros/openssl.m4 (revision 0)
+++ build/ac-macros/openssl.m4 (working copy)
@@ -0,0 +1,106 @@
+dnl ===================================================================
+dnl Licensed to the Apache Software Foundation (ASF) under one
+dnl or more contributor license agreements. See the NOTICE file
+dnl distributed with this work for additional information
+dnl regarding copyright ownership. The ASF licenses this file
+dnl to you under the Apache License, Version 2.0 (the
+dnl "License"); you may not use this file except in compliance
+dnl with the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing,
+dnl software distributed under the License is distributed on an
+dnl "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+dnl KIND, either express or implied. See the License for the
+dnl specific language governing permissions and limitations
+dnl under the License.
+dnl ===================================================================
+dnl
+dnl SVN_LIB_OPENSSL
+dnl
+dnl Check configure options and assign variables related to
+dnl the OpenSSL library.
+dnl
+dnl If we find the library, set the shell variable
+dnl `svn_lib_openssl' to `yes'. Otherwise, set `svn_lib_openssl'
+dnl to `no'.
+
+AC_DEFUN(SVN_LIB_OPENSSL,
+[
+ AC_ARG_WITH(openssl, [AS_HELP_STRING([--with-openssl=PATH],
+ [Compile with OpenSSL in PATH])],
+ [
+ with_openssl="$withval"
+ required="yes"
+ ],
+ [
+ with_openssl="yes"
+ required="no"
+ ])
+
+ AC_MSG_CHECKING([whether to look for OpenSSL])
+
+ if test "${with_openssl}" = "no"; then
+ AC_MSG_RESULT([no])
+ svn_lib_openssl=no
+ else
+ AC_MSG_RESULT([yes])
+ saved_LDFLAGS="$LDFLAGS"
+ saved_CPPFLAGS="$CPPFLAGS"
+
+ if test "$with_openssl" = "yes"; then
+ AC_MSG_NOTICE([Looking in default locations])
+ AC_CHECK_HEADER(openssl/ssl.h,
+ [AC_CHECK_LIB(crypto, d2i_X509,
+ [AC_CHECK_LIB(ssl, SSL_library_init,
+ svn_lib_openssl=yes,
+ svn_lib_openssl=no,
+ -lcrypto)],
+ svn_lib_openssl=no)],
+ svn_lib_openssl=no)
+ if test "$svn_lib_openssl" = "no"; then
+ with_openssl="/usr/local"
+ fi
+ else
+ svn_lib_openssl=no
+ fi
+
+ if test "$svn_lib_openssl" = "no"; then
+ SVN_OPENSSL_INCLUDES="-I${with_openssl}/include"
+ CPPFLAGS="$CPPFLAGS $SVN_OPENSSL_INCLUDES"
+ LDFLAGS="$LDFLAGS `SVN_REMOVE_STANDARD_LIB_DIRS(-L${with_openssl}/lib)`"
+
+ AC_CHECK_HEADER(openssl/ssl.h,
+ [AC_CHECK_LIB(crypto, d2i_X509,
+ [AC_CHECK_LIB(ssl, SSL_library_init,
+ svn_lib_openssl=yes,
+ svn_lib_openssl=no,
+ -lcrypto)],
+ svn_lib_openssl=no)],
+ svn_lib_openssl=no)
+ fi
+
+ AC_MSG_CHECKING([for availability of OpenSSL])
+ if test "$svn_lib_openssl" = "yes"; then
+ SVN_OPENSSL_LIBS="-lcrypto -lssl"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+
+ if test "$required" = "yes"; then
+ dnl The user explicitly requested OpenSSL, but we couldn't find it.
+ dnl Exit with an error message.
+ AC_MSG_ERROR([Could not find OpenSSL])
+ fi
+
+ SVN_OPENSSL_INCLUDES=""
+ LDFLAGS="$saved_LDFLAGS"
+ fi
+
+ CPPFLAGS="$saved_CPPFLAGS"
+ fi
+
+ AC_SUBST(SVN_OPENSSL_INCLUDES)
+ AC_SUBST(SVN_OPENSSL_LIBS)
+])

Property changes on: build/ac-macros/openssl.m4
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: build.conf
===================================================================
--- build.conf (revision 1501587)
+++ build.conf (working copy)
@@ -202,7 +202,7 @@ manpages = subversion/svnmucc/svnmucc.1
 description = Subversion Authentication Credentials Management Tool
 type = exe
 path = subversion/svnauth
-libs = libsvn_subr apriconv apr
+libs = libsvn_subr apriconv apr openssl
 install = bin
 manpages = subversion/svnauth/svnauth.1
 
@@ -1193,6 +1193,10 @@ external-lib = $(SVN_KWALLET_LIBS)
 type = lib
 external-lib = $(SVN_MAGIC_LIBS)
 
+[openssl]
+type = lib
+external-lib = $(SVN_OPENSSL_LIBS)
+
 [sasl]
 type = lib
 external-lib = $(SVN_SASL_LIBS)
Index: configure.ac
===================================================================
--- configure.ac (revision 1501587)
+++ configure.ac (working copy)
@@ -482,6 +482,14 @@ if test "$svn_lib_sasl" = "yes"; then
             [Defined if Cyrus SASL v2 is present on the system])
 fi
 
+SVN_LIB_OPENSSL
+
+if test "$svn_lib_openssl" = "yes"; then
+ AC_DEFINE(SVN_HAVE_OPENSSL, 1,
+ [Defined if OpenSSL is present on the system])
+fi
+
+
 dnl Mac OS specific features -------------------
 
 SVN_LIB_MACHO_ITERATE
Index: subversion/svnauth/svnauth.c
===================================================================
--- subversion/svnauth/svnauth.c (revision 1501587)
+++ subversion/svnauth/svnauth.c (working copy)
@@ -27,6 +27,13 @@
 #include <apr_getopt.h>
 #include <apr_tables.h>
 
+#include "svn_private_config.h"
+
+#ifdef SVN_HAVE_OPENSSL
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#endif
+
 #include "svn_pools.h"
 #include "svn_error.h"
 #include "svn_opt.h"
@@ -39,7 +46,6 @@
 
 #include "private/svn_cmdline_private.h"
 
-#include "svn_private_config.h"
 
 /* Baton for passing option/argument state to a subcommand function. */
 struct svnauth_opt_state
@@ -157,6 +163,145 @@ subcommand_help(apr_getopt_t *os, void *baton, apr
 #define SEP_STRING \
   "------------------------------------------------------------------------\n"
 
+/* ### from libsvn_subr/ssl_server_trust_providers.c */
+#define AUTHN_ASCII_CERT_KEY "ascii_cert"
+
+#ifdef SVN_HAVE_OPENSSL
+static apr_hash_t *
+get_cert_info_from_x509_name(X509_NAME *name,
+ apr_pool_t *result_pool)
+{
+ char buf[1024];
+ apr_hash_t *cert_info = apr_hash_make(result_pool);
+
+ if (X509_NAME_get_text_by_NID(name, NID_commonName, buf, 1024) != -1)
+ apr_hash_set(cert_info, _("Common Name"), APR_HASH_KEY_STRING,
+ apr_pstrdup(result_pool, buf));
+
+ if (X509_NAME_get_text_by_NID(name, NID_pkcs9_emailAddress, buf, 1024) != -1)
+ apr_hash_set(cert_info, _("Email Address"), APR_HASH_KEY_STRING,
+ apr_pstrdup(result_pool, buf));
+
+ if (X509_NAME_get_text_by_NID(name, NID_organizationName, buf, 1024) != -1)
+ apr_hash_set(cert_info, _("Organization"), APR_HASH_KEY_STRING,
+ apr_pstrdup(result_pool, buf));
+
+ if (X509_NAME_get_text_by_NID(name, NID_localityName, buf, 1024) != -1)
+ apr_hash_set(cert_info, _("Locality"), APR_HASH_KEY_STRING,
+ apr_pstrdup(result_pool, buf));
+
+ if (X509_NAME_get_text_by_NID(name, NID_stateOrProvinceName, buf, 1024) != -1)
+ apr_hash_set(cert_info, _("State or Province"), APR_HASH_KEY_STRING,
+ apr_pstrdup(result_pool, buf));
+
+ if (X509_NAME_get_text_by_NID(name, NID_countryName, buf, 1024) != -1)
+ apr_hash_set(cert_info, _("Country"), APR_HASH_KEY_STRING,
+ apr_pstrdup(result_pool, buf));
+
+ return cert_info;
+}
+
+static svn_error_t *
+show_cert_info(apr_hash_t *cert_info,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *sorted_cert_info;
+ int i;
+
+ sorted_cert_info = svn_sort__hash(cert_info,
+ svn_sort_compare_items_lexically,
+ scratch_pool);
+ for (i = 0; i < sorted_cert_info->nelts; i++)
+ {
+ svn_sort__item_t item;
+ const char *key;
+ const char *value;
+
+ item = APR_ARRAY_IDX(sorted_cert_info, i, svn_sort__item_t);
+ key = item.key;
+ value = item.value;
+
+ SVN_ERR(svn_cmdline_printf(scratch_pool, " %s: %s\n", key, value));
+ }
+
+ return SVN_NO_ERROR;
+}
+#endif /* SVN_HAVE_OPENSSL */
+
+static svn_error_t *
+show_ascii_cert(const char *ascii_cert,
+ apr_pool_t *scratch_pool)
+{
+#ifdef SVN_HAVE_OPENSSL
+ BIO *bmem;
+ BIO *b64;
+ X509 *cert;
+ X509_NAME *name;
+ apr_hash_t *cert_info;
+ unsigned char checksum[EVP_MAX_MD_SIZE];
+ unsigned int checksum_len;
+ unsigned int i;
+
+ /* Construct a BIO chain to decode the base64-encoded ASCII_CERT. */
+ bmem = BIO_new_mem_buf((void*)ascii_cert, -1);
+ b64 = BIO_new(BIO_f_base64());
+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+ b64 = BIO_push(b64, bmem);
+
+ /* Parse the decoded X509 certificate. */
+ cert = d2i_X509_bio(b64, NULL);
+ if (cert == NULL)
+ {
+ BIO_free_all(b64);
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "%s: %s\n",
+ AUTHN_ASCII_CERT_KEY, ascii_cert));
+ return SVN_NO_ERROR;
+ }
+
+ /* Show issuer information. */
+ name = X509_get_issuer_name(cert);
+ if (name)
+ {
+ cert_info = get_cert_info_from_x509_name(name, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool, _("Certificate Issuer:\n")));
+ SVN_ERR(show_cert_info(cert_info, scratch_pool));
+ }
+ }
+
+ /* Show subject information. */
+ name = X509_get_subject_name(cert);
+ if (name)
+ {
+ cert_info = get_cert_info_from_x509_name(name, scratch_pool);
+ if (cert_info && apr_hash_count(cert_info) > 0)
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool,
+ _("Certificate Subject:\n")));
+ SVN_ERR(show_cert_info(cert_info, scratch_pool));
+ }
+ }
+
+ /* Display SHA1 checksum of certificate. */
+ if (X509_digest(cert, EVP_sha1(), checksum, &checksum_len))
+ {
+ SVN_ERR(svn_cmdline_printf(scratch_pool, _("SHA1 Checksum: ")));
+ for (i = 0; i < checksum_len; i++)
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "%02X%c", checksum[i],
+ i < (checksum_len - 1) ? ':' : '\n'));
+ }
+
+ X509_free(cert);
+ BIO_free_all(b64);
+#else
+ SVN_ERR(svn_cmdline_printf(scratch_pool, "%s: %s\n",
+ AUTHN_ASCII_CERT_KEY, ascii_cert));
+#endif /* SVN_HAVE_OPENSSL */
+
+ return SVN_NO_ERROR;
+}
+
 /* This implements `svn_config_auth_walk_func_t` */
 static svn_error_t *
 list_credentials(svn_boolean_t *delete_cred,
@@ -193,6 +338,8 @@ list_credentials(svn_boolean_t *delete_cred,
         SVN_ERR(svn_cmdline_printf(scratch_pool, _("%s: [not shown]\n"), key));
       else if (strcmp(value->data, realmstring) == 0)
         continue; /* realm string was already shown above */
+ else if (strcmp(key, AUTHN_ASCII_CERT_KEY) == 0)
+ SVN_ERR(show_ascii_cert(value->data, scratch_pool));
       else
         SVN_ERR(svn_cmdline_printf(scratch_pool, "%s: %s\n", key, value->data));
     }
Received on 2013-07-10 03:34:33 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.