You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/10/21 15:37:15 UTC
svn commit: r1534149 - in /subversion/trunk/subversion:
include/private/svn_auth_private.h libsvn_ra_serf/util.c libsvn_subr/auth.c
libsvn_subr/cmdline.c libsvn_subr/win32_crypto.c
Author: rhuijben
Date: Mon Oct 21 13:37:14 2013
New Revision: 1534149
URL: http://svn.apache.org/r1534149
Log:
Extend the Windows CRYPTOAPI based ssl certificate verification to properly
handle intermediate authorities, like how webbrowsers handle this.
When I originally implemented the ssl server certificate verification, most
certificates were directly signed by the root authority while since then
most certificates moved to using short lived intermediate authorities.
This re-enables common cases like
$ svn info https://svn.apache.org/repos/asf/
to work directly on Windows, without an initial prompt for accepting a
certificate from an unknown authority, just like it worked a few years ago.
* subversion/include/private/svn_auth_private.h
(SVN_AUTH_CRED_SSL_SERVER_AUTHORITY): Declare new credential type.
(svn_auth__get_windows_ssl_server_authority_provider): New function.
* subversion/libsvn_ra_serf/util.c
(includes): Add svn_auth_private.h.
(ssl_server_cert): Instead of just recording authority failures call a
new (optional) provider to allow
* subversion/libsvn_subr/auth.c
(includes): Add svn_auth_private.h.
(svn_auth_get_platform_specific_provider): Allow loading new provider.
* subversion/libsvn_subr/cmdline.c
(svn_cmdline_create_auth_baton): Hook new provider in the same place as
where we hook the server certificate provider.
* subversion/libsvn_subr/win32_crypto.c
(windows_ssl_server_trust_first_credentials): Fix an old bug, where instead
of properly accepting a failure, we removed the failure where it was
originally stored. (This happened to work in serf an neon for years)
(windows_server_authority_provider): New variable.
(svn_auth__get_windows_ssl_server_authority_provider): New function.
Modified:
subversion/trunk/subversion/include/private/svn_auth_private.h
subversion/trunk/subversion/libsvn_ra_serf/util.c
subversion/trunk/subversion/libsvn_subr/auth.c
subversion/trunk/subversion/libsvn_subr/cmdline.c
subversion/trunk/subversion/libsvn_subr/win32_crypto.c
Modified: subversion/trunk/subversion/include/private/svn_auth_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_auth_private.h?rev=1534149&r1=1534148&r2=1534149&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_auth_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_auth_private.h Mon Oct 21 13:37:14 2013
@@ -37,6 +37,24 @@
extern "C" {
#endif /* __cplusplus */
+/** SSL server authority verification credential type.
+ *
+ * The followin auth parameters are available to the providers:
+ *
+ * - @c SVN_AUTH_PARAM_SSL_SERVER_FAILURES (@c apr_uint32_t*)
+ * - @c SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO
+ * (@c svn_auth_ssl_server_cert_info_t*)
+ *
+ * The following optional auth parameters are relevant to the providers:
+ *
+ * - @c SVN_AUTH_PARAM_NO_AUTH_CACHE (@c void*)
+ *
+ * @since New in 1.9.
+ */
+#define SVN_AUTH_CRED_SSL_SERVER_AUTHORITY "svn.ssl.server.authority"
+
+
+
/* If you add a password type for a provider which stores
* passwords on disk in encrypted form, remember to update
* svn_auth__simple_save_creds_helper. Otherwise it will be
@@ -213,6 +231,25 @@ svn_auth__ssl_client_cert_pw_set(svn_boo
svn_boolean_t non_interactive,
apr_pool_t *pool);
+#if (defined(WIN32) && !defined(__MINGW32__)) || defined(DOXYGEN)
+/**
+ * Set @a *provider to an authentication provider that implements
+ * ssl authority verification via the Windows CryptoApi.
+ *
+ * This provider automatically validates authority certificates with
+ * the CryptoApi, like Internet Explorer and the Windows network API do.
+ * This allows the rollout of root certificates via Windows Domain
+ * policies, instead of Subversion specific configuration.
+ *
+ * @note This function is only available on Windows.
+ */
+void
+svn_auth__get_windows_ssl_server_authority_provider(
+ svn_auth_provider_object_t **provider,
+ apr_pool_t *pool);
+#endif
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=1534149&r1=1534148&r2=1534149&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Mon Oct 21 13:37:14 2013
@@ -48,6 +48,7 @@
#include "private/svn_dep_compat.h"
#include "private/svn_fspath.h"
#include "private/svn_subr_private.h"
+#include "private/svn_auth_private.h"
#include "ra_serf.h"
@@ -275,13 +276,8 @@ ssl_server_cert(void *baton, int failure
void *creds;
int found_matching_hostname = 0;
- /* Implicitly approve any non-server certs. */
- if (serf_ssl_cert_depth(cert) > 0)
- {
- if (failures)
- conn->server_cert_failures |= ssl_convert_serf_failures(failures);
- return APR_SUCCESS;
- }
+ if (!failures && ! conn->server_cert_failures)
+ return SVN_NO_ERROR;
/* Extract the info from the certificate */
subject = serf_ssl_cert_subject(cert, scratch_pool);
@@ -305,6 +301,58 @@ ssl_server_cert(void *baton, int failure
svn_failures = (ssl_convert_serf_failures(failures)
| conn->server_cert_failures);
+ /* Handle any non-server certs. */
+ if (serf_ssl_cert_depth(cert) > 0)
+ {
+ svn_error_t *err;
+
+ svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+ SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO,
+ &cert_info);
+
+ svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+ SVN_AUTH_PARAM_SSL_SERVER_FAILURES,
+ &svn_failures);
+
+ realmstring = apr_psprintf(scratch_pool, "AUTHORITY:%s",
+ cert_info.fingerprint);
+
+ err = svn_auth_first_credentials(&creds, &state,
+ SVN_AUTH_CRED_SSL_SERVER_AUTHORITY,
+ realmstring,
+ conn->session->wc_callbacks->auth_baton,
+ scratch_pool);
+
+ svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+ SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO, NULL);
+
+ svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
+ SVN_AUTH_PARAM_SSL_SERVER_FAILURES, NULL);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_AUTHN_NO_PROVIDER)
+ return svn_error_trace(err);
+
+ /* No provider registered that handles server authorities */
+ svn_error_clear(err);
+ creds = NULL;
+ }
+
+ if (creds)
+ {
+ server_creds = creds;
+ SVN_ERR(svn_auth_save_credentials(state, scratch_pool));
+
+ svn_failures &= ~server_creds->accepted_failures;
+ }
+
+ if (svn_failures)
+ conn->server_cert_failures |= svn_failures;
+
+ return APR_SUCCESS;
+ }
+
/* Try to find matching server name via subjectAltName first... */
if (san) {
int i;
Modified: subversion/trunk/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/auth.c?rev=1534149&r1=1534148&r2=1534149&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/auth.c (original)
+++ subversion/trunk/subversion/libsvn_subr/auth.c Mon Oct 21 13:37:14 2013
@@ -35,6 +35,7 @@
#include "svn_config.h"
#include "svn_dso.h"
#include "svn_version.h"
+#include "private/svn_auth_private.h"
#include "private/svn_dep_compat.h"
#include "auth.h"
@@ -542,6 +543,11 @@ svn_auth_get_platform_specific_provider(
{
svn_auth_get_windows_ssl_server_trust_provider(provider, pool);
}
+ else if (strcmp(provider_name, "windows") == 0 &&
+ strcmp(provider_type, "ssl_server_authority") == 0)
+ {
+ svn_auth__get_windows_ssl_server_authority_provider(provider, pool);
+ }
#endif
}
Modified: subversion/trunk/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cmdline.c?rev=1534149&r1=1534148&r2=1534149&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cmdline.c Mon Oct 21 13:37:14 2013
@@ -591,7 +591,7 @@ svn_cmdline_create_auth_baton(svn_auth_b
svn_auth_get_username_provider(&provider, pool);
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
- /* The server-cert, client-cert, and client-cert-password providers. */
+ /* The windows ssl server certificate CRYPTOAPI provider. */
SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
"windows",
"ssl_server_trust",
@@ -600,6 +600,15 @@ svn_cmdline_create_auth_baton(svn_auth_b
if (provider)
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
+ /* The windows ssl authority certificate CRYPTOAPI provider. */
+ SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
+ "windows",
+ "ssl_server_authority",
+ pool));
+
+ if (provider)
+ APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
+
svn_auth_get_ssl_server_trust_file_provider(&provider, pool);
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
svn_auth_get_ssl_client_cert_file_provider(&provider, pool);
Modified: subversion/trunk/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/win32_crypto.c?rev=1534149&r1=1534148&r2=1534149&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/trunk/subversion/libsvn_subr/win32_crypto.c Mon Oct 21 13:37:14 2013
@@ -436,8 +436,9 @@ windows_ssl_server_trust_first_credentia
const char *realmstring,
apr_pool_t *pool)
{
- apr_uint32_t *failures = svn_hash_gets(parameters,
- SVN_AUTH_PARAM_SSL_SERVER_FAILURES);
+ apr_uint32_t *failure_ptr = svn_hash_gets(parameters,
+ SVN_AUTH_PARAM_SSL_SERVER_FAILURES);
+ apr_uint32_t failures = *failure_ptr;
const svn_auth_ssl_server_cert_info_t *cert_info =
svn_hash_gets(parameters, SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO);
@@ -445,7 +446,7 @@ windows_ssl_server_trust_first_credentia
*iter_baton = NULL;
/* We can accept only unknown certificate authority. */
- if (*failures & SVN_AUTH_SSL_UNKNOWNCA)
+ if (failures & SVN_AUTH_SSL_UNKNOWNCA)
{
svn_boolean_t ok;
@@ -455,15 +456,16 @@ windows_ssl_server_trust_first_credentia
if (ok)
{
/* Clear failure flag. */
- *failures &= ~SVN_AUTH_SSL_UNKNOWNCA;
+ failures &= ~SVN_AUTH_SSL_UNKNOWNCA;
}
}
/* If all failures are cleared now, we return the creds */
- if (! *failures)
+ if (! failures)
{
svn_auth_cred_ssl_server_trust_t *creds =
apr_pcalloc(pool, sizeof(*creds));
+ creds->accepted_failures = *failure_ptr & ~failures;
creds->may_save = FALSE; /* No need to save it. */
*credentials = creds;
}
@@ -489,4 +491,24 @@ svn_auth_get_windows_ssl_server_trust_pr
*provider = po;
}
+static const svn_auth_provider_t windows_server_authority_provider = {
+ SVN_AUTH_CRED_SSL_SERVER_AUTHORITY,
+ windows_ssl_server_trust_first_credentials,
+ NULL,
+ NULL,
+};
+
+/* Public API */
+void
+svn_auth__get_windows_ssl_server_authority_provider(
+ svn_auth_provider_object_t **provider,
+ apr_pool_t *pool)
+{
+ svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
+
+ po->vtable = &windows_server_authority_provider;
+ *provider = po;
+}
+
+
#endif /* WIN32 */