Skip to content

Add support for OpenSSL3+ URIs (via serf) #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: trunk
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -648,6 +648,10 @@ if (HAVE_UNISTD_H)
autocheck_symbol_exists("getpid" "unistd.h" HAVE_GETPID)
endif()

if (SVN_ENABLE_RA_SERF)
autocheck_symbol_exists("serf_ssl_cert_uri_set" "serf_bucket_types.h" HAVE_SERF_SSL_CERT_URI_SET)
endif()

include_directories("${CMAKE_CURRENT_BINARY_DIR}")

file(GLOB public_headers "subversion/include/*.h")
9 changes: 8 additions & 1 deletion build/ac-macros/serf.m4
Original file line number Diff line number Diff line change
@@ -89,6 +89,13 @@ AC_DEFUN(SVN_LIB_SERF,

svn_lib_serf=$serf_found

if test "$svn_lib_serf" = "yes"; then
save_ldflags="$LDFLAGS"
LDFLAGS="$LDFLAGS $SVN_SERF_LIBS"
AC_CHECK_FUNCS(serf_ssl_cert_uri_set)
LDFLAGS="$save_ldflags"
fi

SVN_DOT_CLANGD([$SVN_SERF_INCLUDES])
AC_SUBST(SVN_SERF_INCLUDES)
AC_SUBST(SVN_SERF_LIBS)
@@ -140,7 +147,7 @@ AC_DEFUN(SVN_SERF_PKG_CONFIG,
[
AC_MSG_NOTICE([serf library configuration via pkg-config])
if test -n "$PKG_CONFIG"; then
for serf_major in serf-2 serf-1; do
for serf_major in serf-2 serf-1 serf; do
AC_MSG_CHECKING([for $serf_major library])
if test -n "$serf_prefix" ; then
dnl User provided a prefix so we try to find the pc file under
14 changes: 14 additions & 0 deletions subversion/bindings/javahl/native/AuthnCallback.cpp
Original file line number Diff line number Diff line change
@@ -67,6 +67,11 @@ AuthnCallback::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
"(Ljava/lang/String;Z)"
JAVAHL_ARG("/callback/AuthnCallback")
"$SSLClientCertResult;")),
m_mid_ssl_client_cert_uri_prompt(
env.GetMethodID(cls, "sslClientCertUriPrompt",
"(Ljava/lang/String;Z)"
JAVAHL_ARG("/callback/AuthnCallback")
"$SSLClientCertUriResult;")),
m_mid_ssl_client_cert_passphrase_prompt(
env.GetMethodID(cls, "sslClientCertPassphrasePrompt",
"(Ljava/lang/String;Z)"
@@ -117,6 +122,15 @@ jobject AuthnCallback::ssl_client_cert_prompt(const ::Java::String&
realm.get(), jboolean(may_save));
}

jobject AuthnCallback::ssl_client_cert_uri_prompt(
const ::Java::String& realm,
bool may_save)
{
return m_env.CallObjectMethod(m_jthis,
impl().m_mid_ssl_client_cert_uri_prompt,
realm.get(), jboolean(may_save));
}

jobject AuthnCallback::ssl_client_cert_passphrase_prompt(
const ::Java::String& realm,
bool may_save)
7 changes: 7 additions & 0 deletions subversion/bindings/javahl/native/AuthnCallback.hpp
Original file line number Diff line number Diff line change
@@ -216,6 +216,12 @@ class AuthnCallback : public ::Java::Object
*/
jobject ssl_client_cert_prompt(const ::Java::String& realm, bool may_save);

/**
* Invokes the Java method AuthnCallback.sslClientCertUriPrompt().
*/
jobject ssl_client_cert_uri_prompt(const ::Java::String& realm,
bool may_save);

/**
* Invokes the Java method AuthnCallback.sslClientCertPassphrasePrompt().
*/
@@ -250,6 +256,7 @@ class AuthnCallback : public ::Java::Object
const ::Java::MethodID m_mid_user_password_prompt;
const ::Java::MethodID m_mid_ssl_server_trust_prompt;
const ::Java::MethodID m_mid_ssl_client_cert_prompt;
const ::Java::MethodID m_mid_ssl_client_cert_uri_prompt;
const ::Java::MethodID m_mid_ssl_client_cert_passphrase_prompt;
const ::Java::MethodID m_mid_allow_store_plaintext_password;
const ::Java::MethodID m_mid_allow_store_plaintext_passphrase;
2 changes: 2 additions & 0 deletions subversion/bindings/javahl/native/OperationContext.cpp
Original file line number Diff line number Diff line change
@@ -181,6 +181,8 @@ OperationContext::getAuthBaton(SVN::Pool &in_pool)
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
svn_auth_get_ssl_client_cert_file_provider(&provider, pool);
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
svn_auth_get_ssl_client_cert_uri_provider(&provider, pool);
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
svn_auth_get_ssl_client_cert_pw_file_provider2(
&provider,
plaintext_passphrase_prompt_func, plaintext_passphrase_prompt_baton,
56 changes: 56 additions & 0 deletions subversion/bindings/javahl/native/Prompter.cpp
Original file line number Diff line number Diff line change
@@ -126,6 +126,20 @@ get_provider_client_ssl(SVN::Pool &in_pool)
return provider;
}

svn_auth_provider_object_t *Prompter::
get_provider_client_ssl_uri(SVN::Pool &in_pool)
{
apr_pool_t *pool = in_pool.getPool();
svn_auth_provider_object_t *provider;
svn_auth_get_ssl_client_cert_uri_prompt_provider(&provider,
ssl_client_cert_uri_prompt,
this,
2 /* retry limit */,
pool);

return provider;
}

svn_auth_provider_object_t *
Prompter::get_provider_client_ssl_password(SVN::Pool &in_pool)
{
@@ -205,6 +219,22 @@ svn_error_t *Prompter::ssl_client_cert_prompt(
return err;
}

svn_error_t *Prompter::ssl_client_cert_uri_prompt(
svn_auth_cred_ssl_client_cert_uri_t **cred_p,
void *baton,
const char *realm,
svn_boolean_t may_save,
apr_pool_t *pool)
{
const ::Java::Env env;
svn_error_t *err;
SVN_JAVAHL_CATCH(
env, SVN_ERR_RA_NOT_AUTHORIZED,
err = static_cast<Prompter*>(baton)->dispatch_ssl_client_cert_uri_prompt(
env, cred_p, realm, may_save, pool));
return err;
}

svn_error_t *Prompter::ssl_client_cert_pw_prompt(
svn_auth_cred_ssl_client_cert_pw_t **cred_p,
void *baton,
@@ -373,6 +403,32 @@ svn_error_t *Prompter::dispatch_ssl_client_cert_prompt(

return SVN_NO_ERROR;
}
svn_error_t *Prompter::dispatch_ssl_client_cert_uri_prompt(
::Java::Env env,
svn_auth_cred_ssl_client_cert_uri_t **cred_p,
const char *realm,
svn_boolean_t may_save,
apr_pool_t *pool)
{
::JavaHL::AuthnCallback authn(env, m_prompter.get());

::JavaHL::AuthnCallback::AuthnResult result(
env,
authn.ssl_client_cert_uri_prompt(
::Java::String(env, realm), may_save));
if (!result.get())
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("User canceled dialog"));

::Java::String uri(env, result.identity());
svn_auth_cred_ssl_client_cert_uri_t *cred =
static_cast<svn_auth_cred_ssl_client_cert_uri_t*>(apr_pcalloc(pool, sizeof(*cred)));
cred->cert_uri = uri.strdup(pool);
cred->may_save = result.save();
*cred_p = cred;

return SVN_NO_ERROR;
}

svn_error_t *Prompter::dispatch_ssl_client_cert_pw_prompt(
::Java::Env env,
15 changes: 15 additions & 0 deletions subversion/bindings/javahl/native/Prompter.h
Original file line number Diff line number Diff line change
@@ -61,6 +61,7 @@ class Prompter
svn_auth_provider_object_t *get_provider_simple(SVN::Pool &in_pool);
svn_auth_provider_object_t *get_provider_server_ssl_trust(SVN::Pool &in_pool);
svn_auth_provider_object_t *get_provider_client_ssl(SVN::Pool &in_pool);
svn_auth_provider_object_t *get_provider_client_ssl_uri(SVN::Pool &in_pool);
svn_auth_provider_object_t *get_provider_client_ssl_password(SVN::Pool &in_pool);

protected:
@@ -147,6 +148,20 @@ class Prompter
svn_boolean_t may_save,
apr_pool_t *pool);

virtual svn_error_t *dispatch_ssl_client_cert_uri_prompt(
::Java::Env env,
svn_auth_cred_ssl_client_cert_uri_t **cred_p,
const char *realm,
svn_boolean_t may_save,
apr_pool_t *pool);

static svn_error_t *ssl_client_cert_uri_prompt(
svn_auth_cred_ssl_client_cert_uri_t **cred_p,
void *baton,
const char *realm,
svn_boolean_t may_save,
apr_pool_t *pool);

protected:
virtual svn_error_t *dispatch_plaintext_prompt(
::Java::Env env,
Original file line number Diff line number Diff line change
@@ -45,6 +45,7 @@ public interface ISVNConfig
public static final String KWALLET_WALLET = "kwallet-wallet";
public static final String KWALLET_SVN_APPLICATION_NAME_WITH_PID = "kwallet-svn-application-name-with-pid";
public static final String SSL_CLIENT_CERT_FILE_PROMPT = "ssl-client-cert-file-prompt";
public static final String SSL_CLIENT_CERT_URI_PROMPT = "ssl-client-cert-uri-prompt";

public static final String SECTION_HELPERS = "helpers";
public static final String EDITOR_CMD = "editor-cmd";
@@ -101,6 +102,7 @@ public interface ISVNConfig
public static final String SSL_TRUST_DEFAULT_CA = "ssl-trust-default-ca";
public static final String SSL_CLIENT_CERT_FILE = "ssl-client-cert-file";
public static final String SSL_CLIENT_CERT_PASSWORD = "ssl-client-cert-password";
public static final String SSL_CLIENT_CERT_URI = "ssl-client-cert-uri";
public static final String SSL_PKCS11_PROVIDER = "ssl-pkcs11-provider";
public static final String HTTP_LIBRARY = "http-library";
public static final String STORE_PASSWORDS = "store-passwords";
Original file line number Diff line number Diff line change
@@ -439,6 +439,53 @@ public SSLClientCertResult(String path, boolean maySave)
sslClientCertPrompt(String realm, boolean maySave);


/**
* The result type used by {@see #sslClientCertUriPrompt}.
*/
public static final class SSLClientCertUriResult
extends AuthnResult
implements java.io.Serializable
{
// Update the serialVersionUID when there is an incompatible change made to
// this class. See the Java documentation (following link or its counter-
// part in your specific Java release) for when a change is incompatible.
// https://docs.oracle.com/en/java/javase/11/docs/specs/serialization/version.html#type-changes-affecting-serialization
private static final long serialVersionUID = 1L;

/**
* Set the uri of the cerfiticate store in the result.
* Assumes the result may not be stored permanently.
* @param path The uri of the certificate store.
*/
public SSLClientCertUriResult(String uri)
{
identity = uri;
}

/**
* Set the uri of the cerfiticate store in the result.
* @param uri The uri of the certificate store.
* @param maySave Set if the result may be stored permanently.
*/
public SSLClientCertUriResult(String uri, boolean maySave)
{
save = maySave;
identity = uri;
}
}

/**
* Ask for the URI of a client SSL certificate.
* @param realm The realm from which the question originates.
* @param maySave Indicates whether saving credentials is allowed;
* if <code>false</code>, the <code>maySave</code> flag
* in the return value will be ignored.
* @return The result, or <code>null</code> if cancelled.
*/
public SSLClientCertUriResult
sslClientCertUriPrompt(String realm, boolean maySave);


/**
* The result type used by {@see #sslClientCertPassphrasePrompt}.
*/
Original file line number Diff line number Diff line change
@@ -374,6 +374,12 @@ private static class DefaultAuthnCallback
return null;
}

public SSLClientCertUriResult
sslClientCertUriPrompt(String realm, boolean maySave)
{
return null;
}

public SSLClientCertPassphraseResult
sslClientCertPassphrasePrompt(String realm, boolean maySave)
{
16 changes: 16 additions & 0 deletions subversion/bindings/swig/core.i
Original file line number Diff line number Diff line change
@@ -256,6 +256,7 @@
%ignore svn_cmdline_auth_plaintext_prompt;
%ignore svn_cmdline_auth_simple_prompt;
%ignore svn_cmdline_auth_ssl_client_cert_prompt;
%ignore svn_cmdline_auth_ssl_client_cert_uri_prompt;
%ignore svn_cmdline_auth_ssl_client_cert_pw_prompt;
%ignore svn_cmdline_auth_ssl_server_trust_prompt;
%ignore svn_cmdline_auth_username_prompt;
@@ -752,6 +753,7 @@ core_set_current_pool (apr_pool_t *pool)
%authprompt_callback_typemap(username)
%authprompt_callback_typemap(ssl_server_trust)
%authprompt_callback_typemap(ssl_client_cert)
%authprompt_callback_typemap(ssl_client_cert_uri)
%authprompt_callback_typemap(ssl_client_cert_pw)
%authprompt_callback_typemap(gnome_keyring_unlock)

@@ -1148,6 +1150,20 @@ svn_swig_rb_auth_get_ssl_client_cert_prompt_provider(
return rb_ary_new3(1, (VALUE)prompt_baton);
}

static VALUE
svn_swig_rb_auth_get_ssl_client_cert_uri_prompt_provider(
svn_auth_provider_object_t **provider,
svn_auth_ssl_client_cert_uri_prompt_func_t prompt_func,
void *prompt_baton,
int retry_limit,
apr_pool_t *pool)
{
svn_auth_get_ssl_client_cert_uri_prompt_provider(provider, prompt_func,
prompt_baton, retry_limit,
pool);
return rb_ary_new3(1, (VALUE)prompt_baton);
}

static VALUE
svn_swig_rb_auth_get_ssl_client_cert_pw_prompt_provider(
svn_auth_provider_object_t **provider,
22 changes: 22 additions & 0 deletions subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
Original file line number Diff line number Diff line change
@@ -1385,6 +1385,28 @@ svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt(
return SVN_NO_ERROR;
}

/* NOTE: calls back into Perl (by calling svn_swig_pl_callback_thunk) */
svn_error_t *svn_swig_pl_thunk_ssl_client_cert_uri_prompt(
svn_auth_cred_ssl_client_cert_uri_t **cred,
void *baton,
const char *realm,
svn_boolean_t may_save,
apr_pool_t *pool)
{
/* Be nice and allocate the memory for the cred structure before passing it
* off to the perl space */
*cred = apr_pcalloc(pool, sizeof(**cred));
if (!*cred) {
croak("Could not allocate memory for cred structure");
}
svn_swig_pl_callback_thunk(CALL_SV,
baton, NULL,
"SsbS", *cred, _SWIG_TYPE("svn_auth_cred_ssl_client_cert_uri_t *"),
realm, may_save, pool, POOLINFO);

return SVN_NO_ERROR;
}

/* Thunked version of svn_wc_notify_func_t callback type */
/* NOTE: calls back into Perl (by calling svn_swig_pl_callback_thunk) */
void svn_swig_pl_notify_func(void * baton,
8 changes: 8 additions & 0 deletions subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
Original file line number Diff line number Diff line change
@@ -209,6 +209,14 @@ svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt
svn_boolean_t may_save,
apr_pool_t *pool);

/* thunked ssl_client_cert_uri callback function */
svn_error_t *svn_swig_pl_thunk_ssl_client_cert_uri_prompt
(svn_auth_cred_ssl_client_cert_uri_t **cred,
void *baton,
const char *realm,
svn_boolean_t may_save,
apr_pool_t *pool);

/* Thunked version of svn_wc_notify_func_t callback type */
void svn_swig_pl_notify_func(void * baton,
const char *path,
Loading