summaryrefslogtreecommitdiff
path: root/subversion/bindings/javahl/native/Prompter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/bindings/javahl/native/Prompter.cpp')
-rw-r--r--subversion/bindings/javahl/native/Prompter.cpp912
1 files changed, 496 insertions, 416 deletions
diff --git a/subversion/bindings/javahl/native/Prompter.cpp b/subversion/bindings/javahl/native/Prompter.cpp
index 14bd312..bad7467 100644
--- a/subversion/bindings/javahl/native/Prompter.cpp
+++ b/subversion/bindings/javahl/native/Prompter.cpp
@@ -25,468 +25,532 @@
*/
#include "Prompter.h"
-#include "Pool.h"
+#include "AuthnCallback.hpp"
+
#include "JNIUtil.h"
#include "JNIStringHolder.h"
#include "../include/org_apache_subversion_javahl_callback_UserPasswordCallback.h"
+
#include <apr_strings.h>
-#include "svn_auth.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_private_config.h"
-/**
- * Constructor
- * @param jprompter a global reference to the Java callback object
- */
-Prompter::Prompter(jobject jprompter)
-{
- m_prompter = jprompter;
-}
-Prompter::~Prompter()
+#include "jniwrapper/jni_stack.hpp"
+#include "jniwrapper/jni_string.hpp"
+
+// Class Prompter
+
+Prompter::UniquePtr Prompter::create(jobject jprompter)
{
- if (m_prompter!= NULL)
+ if (!jprompter)
+ return UniquePtr(NULL);
+
+ // Make sure no C++ exceptions are propagated from here.
+ const ::Java::Env jenv;
+ try
{
- // Since the reference to the Java object is a global one, it
- // has to be deleted.
- JNIEnv *env = JNIUtil::getEnv();
- env->DeleteGlobalRef(m_prompter);
+ const jclass cls = ::Java::ClassCache::get_authn_cb(jenv)->get_class();
+ if (!jenv.IsInstanceOf(jprompter, cls))
+ return UniquePtr(NULL);
+
+ return UniquePtr(new Prompter(jenv, jprompter));
}
+ SVN_JAVAHL_JNI_CATCH;
+ return UniquePtr(NULL);
}
-/**
- * Create a C++ peer object for the Java callback object
- *
- * @param jprompter Java callback object
- * @return C++ peer object
- */
-Prompter *Prompter::makeCPrompter(jobject jprompter)
+Prompter::UniquePtr Prompter::clone() const
{
- // If we have no Java object, we need no C++ object.
- if (jprompter == NULL)
- return NULL;
-
- JNIEnv *env = JNIUtil::getEnv();
-
- // Create a local frame for our references
- env->PushLocalFrame(LOCAL_FRAME_SIZE);
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
+ return create(m_prompter.get());
+}
- // Sanity check that the Java object implements UserPasswordCallback.
- jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
+Prompter::Prompter(::Java::Env env, jobject jprompter)
+ : m_prompter(env, jprompter)
+{}
- if (!env->IsInstanceOf(jprompter, clazz))
- POP_AND_RETURN_NULL;
+Prompter::~Prompter() {}
- // Create a new global ref for the Java object, because it is
- // longer used that this call.
- jobject myPrompt = env->NewGlobalRef(jprompter);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
- env->PopLocalFrame(NULL);
+svn_auth_provider_object_t *
+Prompter::get_provider_simple(SVN::Pool &in_pool)
+{
+ apr_pool_t *pool = in_pool.getPool();
+ svn_auth_provider_object_t *provider;
+ svn_auth_get_simple_prompt_provider(&provider,
+ simple_prompt,
+ this,
+ 2, /* retry limit */
+ pool);
- // Create the C++ peer.
- return new Prompter(myPrompt);
+ return provider;
}
-/**
- * Retrieve the username from the Java object
- * @return Java string for the username or NULL
- */
-jstring Prompter::username()
+svn_auth_provider_object_t *
+Prompter::get_provider_username(SVN::Pool &in_pool)
{
- JNIEnv *env = JNIUtil::getEnv();
-
- // Create a local frame for our references
- env->PushLocalFrame(LOCAL_FRAME_SIZE);
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
-
- // The method id will not change during the time this library is
- // loaded, so it can be cached.
- static jmethodID mid = 0;
-
- if (mid == 0)
- {
- jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
+ apr_pool_t *pool = in_pool.getPool();
+ svn_auth_provider_object_t *provider;
+ svn_auth_get_username_prompt_provider(&provider,
+ username_prompt,
+ this,
+ 2, /* retry limit */
+ pool);
- mid = env->GetMethodID(clazz, "getUsername", "()Ljava/lang/String;");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN_NULL;
- }
+ return provider;
+}
- jstring ret = static_cast<jstring>(env->CallObjectMethod(m_prompter, mid));
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
+svn_auth_provider_object_t *Prompter::
+get_provider_server_ssl_trust(SVN::Pool &in_pool)
+{
+ apr_pool_t *pool = in_pool.getPool();
+ svn_auth_provider_object_t *provider;
+ svn_auth_get_ssl_server_trust_prompt_provider
+ (&provider, ssl_server_trust_prompt, this, pool);
- return (jstring) env->PopLocalFrame(ret);
+ return provider;
}
-/**
- * Retrieve the password from the Java object
- * @return Java string for the password or NULL
- */
-jstring Prompter::password()
+svn_auth_provider_object_t *Prompter::
+get_provider_client_ssl(SVN::Pool &in_pool)
{
- JNIEnv *env = JNIUtil::getEnv();
+ apr_pool_t *pool = in_pool.getPool();
+ svn_auth_provider_object_t *provider;
+ svn_auth_get_ssl_client_cert_prompt_provider(&provider,
+ ssl_client_cert_prompt,
+ this,
+ 2 /* retry limit */,
+ pool);
- // Create a local frame for our references
- env->PushLocalFrame(LOCAL_FRAME_SIZE);
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
+ return provider;
+}
- // The method id will not change during the time this library is
- // loaded, so it can be cached.
- static jmethodID mid = 0;
+svn_auth_provider_object_t *
+Prompter::get_provider_client_ssl_password(SVN::Pool &in_pool)
+{
+ apr_pool_t *pool = in_pool.getPool();
+ svn_auth_provider_object_t *provider;
+ svn_auth_get_ssl_client_cert_pw_prompt_provider
+ (&provider, ssl_client_cert_pw_prompt, this, 2 /* retry limit */,
+ pool);
- if (mid == 0)
- {
- jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
+ return provider;
+}
- mid = env->GetMethodID(clazz, "getPassword", "()Ljava/lang/String;");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN_NULL;
- }
+svn_error_t *Prompter::simple_prompt(
+ svn_auth_cred_simple_t **cred_p,
+ void *baton,
+ const char *realm,
+ const char *username,
+ 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_simple_prompt(
+ env, cred_p, realm, username, may_save, pool));
+ return err;
+}
- jstring ret = static_cast<jstring>(env->CallObjectMethod(m_prompter, mid));
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
+svn_error_t *Prompter::username_prompt(
+ svn_auth_cred_username_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_username_prompt(
+ env, cred_p, realm, may_save, pool));
+ return err;
+}
- return (jstring) env->PopLocalFrame(ret);
+svn_error_t *Prompter::ssl_server_trust_prompt(
+ svn_auth_cred_ssl_server_trust_t **cred_p,
+ void *baton,
+ const char *realm,
+ apr_uint32_t failures,
+ const svn_auth_ssl_server_cert_info_t *cert_info,
+ 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_server_trust_prompt(
+ env, cred_p, realm, failures, cert_info, may_save, pool));
+ return err;
}
-/**
- * Ask the user a question, which can be answered by yes/no.
- * @param realm the server realm, for which this question is asked
- * @param question the question to ask the user
- * @param yesIsDefault flag if the yes-button should be the default button
- * @return flag who the user answered the question
- */
-bool Prompter::askYesNo(const char *realm, const char *question,
- bool yesIsDefault)
+
+svn_error_t *Prompter::ssl_client_cert_prompt(
+ svn_auth_cred_ssl_client_cert_t **cred_p,
+ void *baton,
+ const char *realm,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- JNIEnv *env = JNIUtil::getEnv();
+ 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_prompt(
+ env, cred_p, realm, may_save, pool));
+ return err;
+}
- // Create a local frame for our references
- env->PushLocalFrame(LOCAL_FRAME_SIZE);
- if (JNIUtil::isJavaExceptionThrown())
- return false;
+svn_error_t *Prompter::ssl_client_cert_pw_prompt(
+ svn_auth_cred_ssl_client_cert_pw_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_pw_prompt(
+ env, cred_p, realm, may_save, pool));
+ return err;
+}
- // The method id will not change during the time this library is
- // loaded, so it can be cached.
- static jmethodID mid = 0;
+svn_error_t *Prompter::plaintext_prompt(
+ svn_boolean_t *may_save_plaintext,
+ const char *realmstring,
+ void *baton,
+ 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_plaintext_prompt(
+ env, may_save_plaintext, realmstring, pool));
+ return err;
+}
- if (mid == 0)
- {
- jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
-
- mid = env->GetMethodID(clazz, "askYesNo",
- "(Ljava/lang/String;Ljava/lang/String;Z)Z");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN(false);
- }
+svn_error_t *Prompter::plaintext_passphrase_prompt(
+ svn_boolean_t *may_save_plaintext,
+ const char *realmstring,
+ void *baton,
+ 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_plaintext_passphrase_prompt(
+ env, may_save_plaintext, realmstring, pool));
+ return err;
+}
- // convert the texts to Java strings
- jstring jrealm = JNIUtil::makeJString(realm);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
- jstring jquestion = JNIUtil::makeJString(question);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
+svn_error_t *Prompter::dispatch_simple_prompt(
+ ::Java::Env env,
+ svn_auth_cred_simple_t **cred_p,
+ const char *realm,
+ const char *username,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
+{
+ ::JavaHL::AuthnCallback authn(env, m_prompter.get());
+
+ ::JavaHL::AuthnCallback::AuthnResult result(
+ env,
+ authn.user_password_prompt(::Java::String(env, realm),
+ ::Java::String(env, username),
+ may_save));
+ if (!result.get())
+ return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ _("User canceled dialog"));
- // execute the callback
- jboolean ret = env->CallBooleanMethod(m_prompter, mid, jrealm, jquestion,
- yesIsDefault ? JNI_TRUE : JNI_FALSE);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
+ ::Java::String user(env, result.identity());
+ ::Java::String pass(env, result.secret());
+ svn_auth_cred_simple_t *cred =
+ static_cast<svn_auth_cred_simple_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->username = user.strdup(pool);
+ cred->password = pass.strdup(pool);
+ cred->may_save = result.save();
+ *cred_p = cred;
- env->PopLocalFrame(NULL);
- return ret ? true:false;
+ return SVN_NO_ERROR;
}
-const char *Prompter::askQuestion(const char *realm, const char *question,
- bool showAnswer, bool maySave)
+svn_error_t *Prompter::dispatch_username_prompt(
+ ::Java::Env env,
+ svn_auth_cred_username_t **cred_p,
+ const char *realm,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- JNIEnv *env = JNIUtil::getEnv();
-
- // Create a local frame for our references
- env->PushLocalFrame(LOCAL_FRAME_SIZE);
- if (JNIUtil::isJavaExceptionThrown())
- return NULL;
+ ::JavaHL::AuthnCallback authn(env, m_prompter.get());
- static jmethodID mid = 0;
- static jmethodID mid2 = 0;
- if (mid == 0)
- {
- jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
-
- mid = env->GetMethodID(clazz, "askQuestion",
- "(Ljava/lang/String;Ljava/lang/String;"
- "ZZ)Ljava/lang/String;");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN_NULL;
-
- mid2 = env->GetMethodID(clazz, "userAllowedSave", "()Z");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN_NULL;
- }
+ ::JavaHL::AuthnCallback::AuthnResult result(
+ env,
+ authn.username_prompt(::Java::String(env, realm), may_save));
+ if (!result.get())
+ return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ _("User canceled dialog"));
- jstring jrealm = JNIUtil::makeJString(realm);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
+ ::Java::String user(env, result.identity());
+ svn_auth_cred_username_t *cred =
+ static_cast<svn_auth_cred_username_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->username = user.strdup(pool);
+ cred->may_save = result.save();
+ *cred_p = cred;
- jstring jquestion = JNIUtil::makeJString(question);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
+ return SVN_NO_ERROR;
+}
- jstring janswer = static_cast<jstring>(
- env->CallObjectMethod(m_prompter, mid, jrealm,
- jquestion,
- showAnswer ? JNI_TRUE : JNI_FALSE,
- maySave ? JNI_TRUE : JNI_FALSE));
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
+svn_error_t *Prompter::dispatch_ssl_server_trust_prompt(
+ ::Java::Env env,
+ svn_auth_cred_ssl_server_trust_t **cred_p,
+ const char *realm,
+ apr_uint32_t failures,
+ const svn_auth_ssl_server_cert_info_t *cert_info,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
+{
+ ::JavaHL::AuthnCallback authn(env, m_prompter.get());
+
+ ::JavaHL::AuthnCallback::AuthnResult result(
+ env,
+ authn.ssl_server_trust_prompt(
+ ::Java::String(env, realm),
+ ::JavaHL::AuthnCallback::SSLServerCertFailures(env, jint(failures)),
+ ::JavaHL::AuthnCallback::SSLServerCertInfo(env, cert_info->ascii_cert),
+ may_save));
+ if (!result.get())
+ return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ _("User canceled dialog"));
- JNIStringHolder answer(janswer);
- if (answer != NULL)
- {
- m_answer = answer;
- m_maySave = env->CallBooleanMethod(m_prompter, mid2) ? true: false;
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN_NULL;
- }
- else
+ const bool trust = result.trust();
+ if (!trust)
{
- m_answer = "";
- m_maySave = false;
+ *cred_p = NULL;
+ return SVN_NO_ERROR;
}
- env->PopLocalFrame(NULL);
- return m_answer.c_str();
-}
+ const bool save = result.save();
+ svn_auth_cred_ssl_server_trust_t *cred =
+ static_cast<svn_auth_cred_ssl_server_trust_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->may_save = save;
+ if (save)
+ cred->accepted_failures = failures;
+ *cred_p = cred;
-int Prompter::askTrust(const char *question, bool maySave)
-{
- static jmethodID mid = 0;
- JNIEnv *env = JNIUtil::getEnv();
-
- // Create a local frame for our references
- env->PushLocalFrame(LOCAL_FRAME_SIZE);
- if (JNIUtil::isJavaExceptionThrown())
- return -1;
-
- if (mid == 0)
- {
- jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(-1);
-
- mid = env->GetMethodID(clazz, "askTrustSSLServer",
- "(Ljava/lang/String;Z)I");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN(-1);
- }
- jstring jquestion = JNIUtil::makeJString(question);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(-1);
-
- jint ret = env->CallIntMethod(m_prompter, mid, jquestion,
- maySave ? JNI_TRUE : JNI_FALSE);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(-1);
-
- env->PopLocalFrame(NULL);
- return ret;
+ return SVN_NO_ERROR;
}
-bool Prompter::prompt(const char *realm, const char *pi_username, bool maySave)
+svn_error_t *Prompter::dispatch_ssl_client_cert_prompt(
+ ::Java::Env env,
+ svn_auth_cred_ssl_client_cert_t **cred_p,
+ const char *realm,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- JNIEnv *env = JNIUtil::getEnv();
- jboolean ret;
+ ::JavaHL::AuthnCallback authn(env, m_prompter.get());
- // Create a local frame for our references
- env->PushLocalFrame(LOCAL_FRAME_SIZE);
- if (JNIUtil::isJavaExceptionThrown())
- return false;
+ ::JavaHL::AuthnCallback::AuthnResult result(
+ env,
+ authn.ssl_client_cert_prompt(::Java::String(env, realm), may_save));
+ if (!result.get())
+ return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ _("User canceled dialog"));
- static jmethodID mid = 0;
- static jmethodID mid2 = 0;
- if (mid == 0)
- {
- jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
-
- mid = env->GetMethodID(clazz, "prompt",
- "(Ljava/lang/String;Ljava/lang/String;Z)Z");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN(false);
-
- mid2 = env->GetMethodID(clazz, "userAllowedSave", "()Z");
- if (JNIUtil::isJavaExceptionThrown() || mid == 0)
- POP_AND_RETURN(false);
- }
+ ::Java::String path(env, result.identity());
+ svn_auth_cred_ssl_client_cert_t *cred =
+ static_cast<svn_auth_cred_ssl_client_cert_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->cert_file = path.strdup(pool);
+ cred->may_save = result.save();
+ *cred_p = cred;
- jstring jrealm = JNIUtil::makeJString(realm);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
+ return SVN_NO_ERROR;
+}
- jstring jusername = JNIUtil::makeJString(pi_username);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
+svn_error_t *Prompter::dispatch_ssl_client_cert_pw_prompt(
+ ::Java::Env env,
+ svn_auth_cred_ssl_client_cert_pw_t **cred_p,
+ const char *realm,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
+{
+ ::JavaHL::AuthnCallback authn(env, m_prompter.get());
- ret = env->CallBooleanMethod(m_prompter, mid, jrealm, jusername,
- maySave ? JNI_TRUE: JNI_FALSE);
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
+ ::JavaHL::AuthnCallback::AuthnResult result(
+ env,
+ authn.ssl_client_cert_passphrase_prompt(
+ ::Java::String(env, realm), may_save));
+ if (!result.get())
+ return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+ _("User canceled dialog"));
- m_maySave = env->CallBooleanMethod(m_prompter, mid2) ? true : false;
- if (JNIUtil::isJavaExceptionThrown())
- POP_AND_RETURN(false);
+ ::Java::String passphrase(env, result.secret());
+ svn_auth_cred_ssl_client_cert_pw_t *cred =
+ static_cast<svn_auth_cred_ssl_client_cert_pw_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->password = passphrase.strdup(pool);
+ cred->may_save = result.save();
+ *cred_p = cred;
- env->PopLocalFrame(NULL);
- return ret ? true:false;
+ return SVN_NO_ERROR;
}
-svn_auth_provider_object_t *Prompter::getProviderSimple(SVN::Pool &in_pool)
+svn_error_t *Prompter::dispatch_plaintext_prompt(
+ ::Java::Env env,
+ svn_boolean_t *may_save_plaintext,
+ const char *realmstring,
+ apr_pool_t *pool)
{
- apr_pool_t *pool = in_pool.getPool();
- svn_auth_provider_object_t *provider;
- svn_auth_get_simple_prompt_provider(&provider,
- simple_prompt,
- this,
- 2, /* retry limit */
- pool);
-
- return provider;
+ ::JavaHL::AuthnCallback authn(env, m_prompter.get());
+ *may_save_plaintext =
+ authn.allow_store_plaintext_password(::Java::String(env, realmstring));
+ return SVN_NO_ERROR;
}
-svn_auth_provider_object_t *Prompter::getProviderUsername(SVN::Pool &in_pool)
+svn_error_t *Prompter::dispatch_plaintext_passphrase_prompt(
+ ::Java::Env env,
+ svn_boolean_t *may_save_plaintext,
+ const char *realmstring,
+ apr_pool_t *pool)
{
- apr_pool_t *pool = in_pool.getPool();
- svn_auth_provider_object_t *provider;
- svn_auth_get_username_prompt_provider(&provider,
- username_prompt,
- this,
- 2, /* retry limit */
- pool);
-
- return provider;
+ ::JavaHL::AuthnCallback authn(env, m_prompter.get());
+ *may_save_plaintext =
+ authn.allow_store_plaintext_passphrase(::Java::String(env, realmstring));
+ return SVN_NO_ERROR;
}
-svn_auth_provider_object_t *Prompter::getProviderServerSSLTrust(SVN::Pool &in_pool)
+
+// Class CompatPrompter
+
+Prompter::UniquePtr CompatPrompter::create(jobject jprompter)
{
- apr_pool_t *pool = in_pool.getPool();
- svn_auth_provider_object_t *provider;
- svn_auth_get_ssl_server_trust_prompt_provider
- (&provider, ssl_server_trust_prompt, this, pool);
+ if (!jprompter)
+ return UniquePtr(NULL);
- return provider;
+ // Make sure no C++ exceptions are propagated from here.
+ const ::Java::Env jenv;
+ try
+ {
+ const jclass cls =
+ ::Java::ClassCache::get_user_passwd_cb(jenv)->get_class();
+ if (!jenv.IsInstanceOf(jprompter, cls))
+ return UniquePtr(NULL);
+
+ return UniquePtr(new CompatPrompter(jenv, jprompter));
+ }
+ SVN_JAVAHL_JNI_CATCH;
+ return UniquePtr(NULL);
}
-svn_auth_provider_object_t *Prompter::getProviderClientSSL(SVN::Pool &in_pool)
+Prompter::UniquePtr CompatPrompter::clone() const
{
- apr_pool_t *pool = in_pool.getPool();
- svn_auth_provider_object_t *provider;
- svn_auth_get_ssl_client_cert_prompt_provider(&provider,
- ssl_client_cert_prompt,
- this,
- 2 /* retry limit */,
- pool);
-
- return provider;
+ return create(m_prompter.get());
}
-svn_auth_provider_object_t *Prompter::getProviderClientSSLPassword(SVN::Pool &in_pool)
+CompatPrompter::CompatPrompter(::Java::Env env, jobject jprompter)
+ : Prompter(env, jprompter)
+{}
+
+CompatPrompter::~CompatPrompter() {}
+
+namespace {
+jstring compat_ask_question(
+ bool& allowed_save,
+ ::Java::Env env,
+ ::JavaHL::UserPasswordCallback& authn,
+ const char *realm, const char *question,
+ bool show_answer, bool may_save)
{
- apr_pool_t *pool = in_pool.getPool();
- svn_auth_provider_object_t *provider;
- svn_auth_get_ssl_client_cert_pw_prompt_provider
- (&provider, ssl_client_cert_pw_prompt, this, 2 /* retry limit */,
- pool);
+ const jstring janswer =
+ authn.ask_question(::Java::String(env, realm),
+ ::Java::String(env, question),
+ show_answer, may_save);
- return provider;
-}
+ if (janswer)
+ allowed_save = authn.user_allowed_save();
+ else
+ allowed_save = false;
-svn_error_t *Prompter::simple_prompt(svn_auth_cred_simple_t **cred_p,
- void *baton,
- const char *realm, const char *username,
- svn_boolean_t may_save,
- apr_pool_t *pool)
+ return janswer;
+}
+} // anonymous namespace
+
+svn_error_t *CompatPrompter::dispatch_simple_prompt(
+ ::Java::Env env,
+ svn_auth_cred_simple_t **cred_p,
+ const char *realm, const char *username,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- Prompter *that = static_cast<Prompter *>(baton);
- svn_auth_cred_simple_t *ret =
- reinterpret_cast<svn_auth_cred_simple_t*>(apr_pcalloc(pool, sizeof(*ret)));
- if (!that->prompt(realm, username, may_save ? true : false))
- return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
- _("User canceled dialog"));
- jstring juser = that->username();
- JNIStringHolder user(juser);
- if (user == NULL)
+ ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
+
+ if (!authn.prompt(::Java::String(env, realm),
+ ::Java::String(env, username),
+ may_save))
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("User canceled dialog"));
- ret->username = apr_pstrdup(pool,user);
- jstring jpass = that->password();
- JNIStringHolder pass(jpass);
- if (pass == NULL)
+ const ::Java::String user(env, authn.get_username());
+ const ::Java::String pass(env, authn.get_password());
+
+ if (!user.get() || !pass.get())
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("User canceled dialog"));
- else
- {
- ret->password = apr_pstrdup(pool, pass);
- ret->may_save = that->m_maySave;
- }
- *cred_p = ret;
+
+ svn_auth_cred_simple_t *cred =
+ static_cast<svn_auth_cred_simple_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->username = user.strdup(pool);
+ cred->password = pass.strdup(pool);
+ cred->may_save = authn.user_allowed_save();
+ *cred_p = cred;
return SVN_NO_ERROR;
}
-svn_error_t *Prompter::username_prompt(svn_auth_cred_username_t **cred_p,
- void *baton,
- const char *realm,
- svn_boolean_t may_save,
- apr_pool_t *pool)
+svn_error_t *CompatPrompter::dispatch_username_prompt(
+ ::Java::Env env,
+ svn_auth_cred_username_t **cred_p,
+ const char *realm,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- Prompter *that = static_cast<Prompter *>(baton);
- svn_auth_cred_username_t *ret =
- reinterpret_cast<svn_auth_cred_username_t*>(apr_pcalloc(pool, sizeof(*ret)));
- const char *user = that->askQuestion(realm, _("Username: "), true,
- may_save ? true : false);
- if (user == NULL)
+ ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
+
+ bool allowed_save;
+ const ::Java::String user(
+ env,
+ compat_ask_question(allowed_save, env, authn,
+ realm, _("Username: "), true, may_save));
+ if (!user.get())
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("User canceled dialog"));
- ret->username = apr_pstrdup(pool,user);
- ret->may_save = that->m_maySave;
- *cred_p = ret;
+
+ svn_auth_cred_username_t *cred =
+ static_cast<svn_auth_cred_username_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->username = user.strdup(pool);
+ cred->may_save = allowed_save;
+ *cred_p = cred;
return SVN_NO_ERROR;
}
svn_error_t *
-Prompter::ssl_server_trust_prompt(svn_auth_cred_ssl_server_trust_t **cred_p,
- void *baton,
- const char *realm,
- apr_uint32_t failures,
- const svn_auth_ssl_server_cert_info_t *cert_info,
- svn_boolean_t may_save,
- apr_pool_t *pool)
+CompatPrompter::dispatch_ssl_server_trust_prompt(
+ ::Java::Env env,
+ svn_auth_cred_ssl_server_trust_t **cred_p,
+ const char *realm,
+ apr_uint32_t failures,
+ const svn_auth_ssl_server_cert_info_t *cert_info,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- Prompter *that = static_cast<Prompter *>(baton);
- svn_auth_cred_ssl_server_trust_t *ret =
- reinterpret_cast<svn_auth_cred_ssl_server_trust_t*>(apr_pcalloc(pool, sizeof(*ret)));
+ ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
std::string question = _("Error validating server certificate for ");
question += realm;
@@ -526,16 +590,20 @@ Prompter::ssl_server_trust_prompt(svn_auth_cred_ssl_server_trust_t **cred_p,
question += "\n";
}
- switch(that->askTrust(question.c_str(), may_save ? true : false))
+ svn_auth_cred_ssl_server_trust_t *cred =
+ static_cast<svn_auth_cred_ssl_server_trust_t*>(apr_pcalloc(pool, sizeof(*cred)));
+
+ switch (authn.ask_trust_ssl_server(::Java::String(env, question), may_save))
{
case org_apache_subversion_javahl_callback_UserPasswordCallback_AcceptTemporary:
- *cred_p = ret;
- ret->may_save = FALSE;
+ cred->may_save = FALSE;
+ cred->accepted_failures = failures;
+ *cred_p = cred;
break;
case org_apache_subversion_javahl_callback_UserPasswordCallback_AcceptPermanently:
- *cred_p = ret;
- ret->may_save = TRUE;
- ret->accepted_failures = failures;
+ cred->may_save = TRUE;
+ cred->accepted_failures = failures;
+ *cred_p = cred;
break;
default:
*cred_p = NULL;
@@ -544,79 +612,91 @@ Prompter::ssl_server_trust_prompt(svn_auth_cred_ssl_server_trust_t **cred_p,
}
svn_error_t *
-Prompter::ssl_client_cert_prompt(svn_auth_cred_ssl_client_cert_t **cred_p,
- void *baton,
- const char *realm,
- svn_boolean_t may_save,
- apr_pool_t *pool)
+CompatPrompter::dispatch_ssl_client_cert_prompt(
+ ::Java::Env env,
+ svn_auth_cred_ssl_client_cert_t **cred_p,
+ const char *realm,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- Prompter *that = static_cast<Prompter *>(baton);
- svn_auth_cred_ssl_client_cert_t *ret =
- reinterpret_cast<svn_auth_cred_ssl_client_cert_t*>(apr_pcalloc(pool, sizeof(*ret)));
- const char *cert_file =
- that->askQuestion(realm, _("client certificate filename: "), true,
- may_save ? true : false);
- if (cert_file == NULL)
+ ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
+
+ bool allowed_save;
+ const ::Java::String path(
+ env,
+ compat_ask_question(allowed_save, env, authn, realm,
+ _("Client certificate filename: "),
+ true, may_save));
+ if (!path.get())
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("User canceled dialog"));
- ret->cert_file = apr_pstrdup(pool, cert_file);
- ret->may_save = that->m_maySave;
- *cred_p = ret;
+
+ svn_auth_cred_ssl_client_cert_t *cred =
+ static_cast<svn_auth_cred_ssl_client_cert_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->cert_file = path.strdup(pool);
+ cred->may_save = allowed_save;
+ *cred_p = cred;
return SVN_NO_ERROR;
}
svn_error_t *
-Prompter::ssl_client_cert_pw_prompt(svn_auth_cred_ssl_client_cert_pw_t **cred_p,
- void *baton,
- const char *realm,
- svn_boolean_t may_save,
- apr_pool_t *pool)
+CompatPrompter::dispatch_ssl_client_cert_pw_prompt(
+ ::Java::Env env,
+ svn_auth_cred_ssl_client_cert_pw_t **cred_p,
+ const char *realm,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
{
- Prompter *that = static_cast<Prompter *>(baton);
- svn_auth_cred_ssl_client_cert_pw_t *ret =
- reinterpret_cast<svn_auth_cred_ssl_client_cert_pw_t*>(apr_pcalloc(pool, sizeof(*ret)));
- const char *info = that->askQuestion(realm,
- _("client certificate passphrase: "),
- false, may_save ? true : false);
- if (info == NULL)
+ ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
+
+ bool allowed_save;
+ const ::Java::String info(
+ env,
+ compat_ask_question(allowed_save, env, authn, realm,
+ _("Client certificate passphrase: "),
+ false, may_save));
+ if (!info.get())
return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
_("User canceled dialog"));
- ret->password = apr_pstrdup(pool, info);
- ret->may_save = that->m_maySave;
- *cred_p = ret;
+
+ svn_auth_cred_ssl_client_cert_pw_t *cred =
+ static_cast<svn_auth_cred_ssl_client_cert_pw_t*>(apr_pcalloc(pool, sizeof(*cred)));
+ cred->password = info.strdup(pool);
+ cred->may_save = allowed_save;
+ *cred_p = cred;
return SVN_NO_ERROR;
}
svn_error_t *
-Prompter::plaintext_prompt(svn_boolean_t *may_save_plaintext,
- const char *realmstring,
- void *baton,
- apr_pool_t *pool)
+CompatPrompter::dispatch_plaintext_prompt(
+ ::Java::Env env,
+ svn_boolean_t *may_save_plaintext,
+ const char *realmstring,
+ apr_pool_t *pool)
{
- Prompter *that = static_cast<Prompter *>(baton);
+ ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
- bool result = that->askYesNo(realmstring,
- _("Store password unencrypted?"),
- false);
-
- *may_save_plaintext = (result ? TRUE : FALSE);
+ *may_save_plaintext = authn.ask_yes_no(
+ ::Java::String(env, realmstring),
+ ::Java::String(env, _("Store password unencrypted?")),
+ false);
return SVN_NO_ERROR;
}
svn_error_t *
-Prompter::plaintext_passphrase_prompt(svn_boolean_t *may_save_plaintext,
- const char *realmstring,
- void *baton,
- apr_pool_t *pool)
+CompatPrompter::dispatch_plaintext_passphrase_prompt(
+ ::Java::Env env,
+ svn_boolean_t *may_save_plaintext,
+ const char *realmstring,
+ apr_pool_t *pool)
{
- Prompter *that = static_cast<Prompter *>(baton);
-
- bool result = that->askYesNo(realmstring,
- _("Store passphrase unencrypted?"),
- false);
+ ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
- *may_save_plaintext = (result ? TRUE : FALSE);
+ *may_save_plaintext = authn.ask_yes_no(
+ ::Java::String(env, realmstring),
+ ::Java::String(env, _("Store passphrase unencrypted?")),
+ false);
return SVN_NO_ERROR;
}