summaryrefslogtreecommitdiff
path: root/subversion/bindings/javahl/native/AuthnCallback.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/bindings/javahl/native/AuthnCallback.cpp')
-rw-r--r--subversion/bindings/javahl/native/AuthnCallback.cpp365
1 files changed, 365 insertions, 0 deletions
diff --git a/subversion/bindings/javahl/native/AuthnCallback.cpp b/subversion/bindings/javahl/native/AuthnCallback.cpp
new file mode 100644
index 0000000..3a25e04
--- /dev/null
+++ b/subversion/bindings/javahl/native/AuthnCallback.cpp
@@ -0,0 +1,365 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#include "svn_base64.h"
+#include "svn_x509.h"
+
+#include "jniwrapper/jni_stack.hpp"
+#include "jniwrapper/jni_exception.hpp"
+#include "jniwrapper/jni_string.hpp"
+#include "jniwrapper/jni_array.hpp"
+#include "jniwrapper/jni_list.hpp"
+
+#include "AuthnCallback.hpp"
+
+#include "svn_private_config.h"
+
+namespace JavaHL {
+
+// Class JavaHL::AuthnCallback
+const char* const AuthnCallback::m_class_name =
+ JAVAHL_CLASS("/callback/AuthnCallback");
+
+AuthnCallback::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
+ : ::Java::Object::ClassImpl(env, cls),
+ m_mid_username_prompt(
+ env.GetMethodID(cls, "usernamePrompt",
+ "(Ljava/lang/String;Z)"
+ JAVAHL_ARG("/callback/AuthnCallback")
+ "$UsernameResult;")),
+ m_mid_user_password_prompt(
+ env.GetMethodID(cls, "userPasswordPrompt",
+ "(Ljava/lang/String;Ljava/lang/String;Z)"
+ JAVAHL_ARG("/callback/AuthnCallback")
+ "$UserPasswordResult;")),
+ m_mid_ssl_server_trust_prompt(
+ env.GetMethodID(cls, "sslServerTrustPrompt",
+ "(Ljava/lang/String;"
+ JAVAHL_ARG("/callback/AuthnCallback")
+ "$SSLServerCertFailures;"
+ JAVAHL_ARG("/callback/AuthnCallback")
+ "$SSLServerCertInfo;"
+ "Z)"
+ JAVAHL_ARG("/callback/AuthnCallback")
+ "$SSLServerTrustResult;")),
+ m_mid_ssl_client_cert_prompt(
+ env.GetMethodID(cls, "sslClientCertPrompt",
+ "(Ljava/lang/String;Z)"
+ JAVAHL_ARG("/callback/AuthnCallback")
+ "$SSLClientCertResult;")),
+ m_mid_ssl_client_cert_passphrase_prompt(
+ env.GetMethodID(cls, "sslClientCertPassphrasePrompt",
+ "(Ljava/lang/String;Z)"
+ JAVAHL_ARG("/callback/AuthnCallback")
+ "$SSLClientCertPassphraseResult;")),
+ m_mid_allow_store_plaintext_password(
+ env.GetMethodID(cls, "allowStorePlaintextPassword",
+ "(Ljava/lang/String;)Z")),
+ m_mid_allow_store_plaintext_passphrase(
+ env.GetMethodID(cls, "allowStorePlaintextPassphrase",
+ "(Ljava/lang/String;)Z"))
+{}
+
+AuthnCallback::ClassImpl::~ClassImpl() {}
+
+jobject AuthnCallback::username_prompt(const ::Java::String& realm,
+ bool may_save)
+{
+ return m_env.CallObjectMethod(m_jthis, impl().m_mid_username_prompt,
+ realm.get(), jboolean(may_save));
+}
+
+
+jobject AuthnCallback::user_password_prompt(const ::Java::String& realm,
+ const ::Java::String& username,
+ bool may_save)
+{
+ return m_env.CallObjectMethod(m_jthis, impl().m_mid_user_password_prompt,
+ realm.get(), username.get(),
+ jboolean(may_save));
+}
+
+jobject AuthnCallback::ssl_server_trust_prompt(
+ const ::Java::String& realm,
+ const SSLServerCertFailures& failures,
+ const SSLServerCertInfo& info,
+ bool may_save)
+{
+ return m_env.CallObjectMethod(m_jthis, impl().m_mid_ssl_server_trust_prompt,
+ realm.get(), failures.get(), info.get(),
+ jboolean(may_save));
+}
+
+jobject AuthnCallback::ssl_client_cert_prompt(const ::Java::String&
+ realm, bool may_save)
+{
+ return m_env.CallObjectMethod(m_jthis, impl().m_mid_ssl_client_cert_prompt,
+ realm.get(), jboolean(may_save));
+}
+
+jobject AuthnCallback::ssl_client_cert_passphrase_prompt(
+ const ::Java::String& realm,
+ bool may_save)
+{
+ return m_env.CallObjectMethod(m_jthis,
+ impl().m_mid_ssl_client_cert_passphrase_prompt,
+ realm.get(), jboolean(may_save));
+}
+
+bool AuthnCallback::allow_store_plaintext_password(const ::Java::String& realm)
+{
+ return m_env.CallBooleanMethod(m_jthis,
+ impl().m_mid_allow_store_plaintext_password,
+ realm.get());
+}
+
+bool AuthnCallback::allow_store_plaintext_passphrase(const ::Java::String& realm)
+{
+ return m_env.CallBooleanMethod(m_jthis,
+ impl().m_mid_allow_store_plaintext_passphrase,
+ realm.get());
+}
+
+
+// Class JavaHL::AuthnCallback::AuthnResult
+const char* const AuthnCallback::AuthnResult::m_class_name =
+ JAVAHL_CLASS("/callback/AuthnCallback$AuthnResult");
+
+AuthnCallback::AuthnResult::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
+ : ::Java::Object::ClassImpl(env, cls),
+ m_fid_save(env.GetFieldID(cls, "save", "Z")),
+ m_fid_trust(env.GetFieldID(cls, "trust", "Z")),
+ m_fid_identity(env.GetFieldID(cls, "identity", "Ljava/lang/String;")),
+ m_fid_secret(env.GetFieldID(cls, "secret", "Ljava/lang/String;"))
+{}
+
+AuthnCallback::AuthnResult::ClassImpl::~ClassImpl() {}
+
+// Class JavaHL::AuthnCallback::SSLServerCertFailures
+const char* const AuthnCallback::SSLServerCertFailures::m_class_name =
+ JAVAHL_CLASS("/callback/AuthnCallback$SSLServerCertFailures");
+
+AuthnCallback::SSLServerCertFailures::ClassImpl::ClassImpl(
+ ::Java::Env env, jclass cls)
+ : ::Java::Object::ClassImpl(env, cls),
+ m_mid_ctor(env.GetMethodID(cls, "<init>", "(I)V"))
+{}
+
+AuthnCallback::SSLServerCertFailures::ClassImpl::~ClassImpl() {}
+
+AuthnCallback::SSLServerCertFailures::SSLServerCertFailures(
+ ::Java::Env env, jint failures)
+ : ::Java::Object(env,
+ ::Java::ClassCache::get_authn_ssl_server_cert_failures(env))
+{
+ set_this(env.NewObject(get_class(), impl().m_mid_ctor, failures));
+}
+
+
+// Class JavaHL::AuthnCallback::SSLServerCertInfo
+const char* const AuthnCallback::SSLServerCertInfo::m_class_name =
+ JAVAHL_CLASS("/callback/AuthnCallback$SSLServerCertInfo");
+
+AuthnCallback::SSLServerCertInfo::ClassImpl::ClassImpl(
+ ::Java::Env env, jclass cls)
+ : ::Java::Object::ClassImpl(env, cls),
+ m_mid_ctor(env.GetMethodID(cls, "<init>",
+ "(Ljava/lang/String;"
+ "Ljava/lang/String;JJ[B"
+ "Ljava/util/List;"
+ "Ljava/lang/String;)V"))
+{}
+
+AuthnCallback::SSLServerCertInfo::ClassImpl::~ClassImpl() {}
+
+AuthnCallback::SSLServerCertInfo::SSLServerCertInfo(
+ ::Java::Env env, const char* ascii_cert)
+ : ::Java::Object(env,
+ ::Java::ClassCache::get_authn_ssl_server_cert_info(env))
+{
+ SVN::Pool pool;
+
+ /* Convert header-less PEM to DER by undoing base64 encoding. */
+ const svn_string_t cert_string = { ascii_cert, strlen(ascii_cert) };
+ const svn_string_t* der = svn_base64_decode_string(&cert_string,
+ pool.getPool());
+
+ svn_x509_certinfo_t *certinfo;
+ SVN_JAVAHL_CHECK(env, svn_x509_parse_cert(&certinfo, der->data, der->len,
+ pool.getPool(), pool.getPool()));
+
+ const ::Java::String subject(
+ env, svn_x509_certinfo_get_subject(certinfo, pool.getPool()));
+ const ::Java::String issuer(
+ env, svn_x509_certinfo_get_issuer(certinfo, pool.getPool()));
+ const ::Java::String cert(env, ascii_cert);
+ const jlong valid_from =
+ (jlong(svn_x509_certinfo_get_valid_from(certinfo)) + 500) / 1000;
+ const jlong valid_to =
+ (jlong(svn_x509_certinfo_get_valid_to(certinfo)) + 500) / 1000;
+
+ const svn_checksum_t* digest = svn_x509_certinfo_get_digest(certinfo);
+ jsize digest_size;
+ switch (digest->kind)
+ {
+ case svn_checksum_sha1:
+ digest_size = 160 / 8;
+ break;
+
+ case svn_checksum_md5:
+ digest_size = 128 / 8;
+ break;
+
+ default:
+ digest_size = 0; // Initialize this to avoid compiler warnings
+ ::Java::IllegalArgumentException(env).raise(
+ _("Unknown certificate digest type"));
+ }
+ const ::Java::ByteArray fingerprint(env, digest->digest, digest_size);
+
+ jobject jhostnames = NULL;
+ const apr_array_header_t* hostnames =
+ svn_x509_certinfo_get_hostnames(certinfo);
+ if (hostnames)
+ {
+ ::Java::List< ::Java::String> hn(env, hostnames->nelts);
+ for (int i = 0; i < hostnames->nelts; ++i)
+ hn.add(::Java::String(env, APR_ARRAY_IDX(hostnames, i, const char*)));
+ jhostnames = hn.get();
+ }
+
+ set_this(env.NewObject(get_class(), impl().m_mid_ctor,
+ subject.get(), issuer.get(),
+ valid_from, valid_to,
+ fingerprint.get(),
+ jhostnames,
+ cert.get()));
+}
+
+
+// Class JavaHL::UserPasswordCallback
+const char* const UserPasswordCallback::m_class_name =
+ JAVAHL_CLASS("/callback/UserPasswordCallback");
+
+UserPasswordCallback::ClassImpl::ClassImpl(::Java::Env env, jclass cls)
+ : ::Java::Object::ClassImpl(env, cls),
+ m_mid_ask_trust_ssl_server(
+ env.GetMethodID(cls, "askTrustSSLServer",
+ "(Ljava/lang/String;Z)I")),
+ m_mid_prompt_2arg(
+ env.GetMethodID(cls, "prompt",
+ "(Ljava/lang/String;Ljava/lang/String;)Z")),
+ m_mid_ask_yes_no(
+ env.GetMethodID(cls, "askYesNo",
+ "(Ljava/lang/String;Ljava/lang/String;Z)Z")),
+ m_mid_ask_question_3arg(
+ env.GetMethodID(cls, "askQuestion",
+ "(Ljava/lang/String;Ljava/lang/String;Z)"
+ "Ljava/lang/String;")),
+ m_mid_get_username(
+ env.GetMethodID(cls, "getUsername",
+ "()Ljava/lang/String;")),
+ m_mid_get_password(
+ env.GetMethodID(cls, "getPassword",
+ "()Ljava/lang/String;")),
+ m_mid_prompt(
+ env.GetMethodID(cls, "prompt",
+ "(Ljava/lang/String;Ljava/lang/String;Z)Z")),
+ m_mid_ask_question(
+ env.GetMethodID(cls, "askQuestion",
+ "(Ljava/lang/String;Ljava/lang/String;ZZ)"
+ "Ljava/lang/String;")),
+ m_mid_user_allowed_save(
+ env.GetMethodID(cls, "userAllowedSave", "()Z"))
+{}
+
+UserPasswordCallback::ClassImpl::~ClassImpl() {}
+
+jint UserPasswordCallback::ask_trust_ssl_server(const ::Java::String& info,
+ bool allow_permanently)
+{
+ return m_env.CallIntMethod(m_jthis, impl().m_mid_ask_trust_ssl_server,
+ info.get(), jboolean(allow_permanently));
+}
+
+bool UserPasswordCallback::prompt(const ::Java::String& realm,
+ const ::Java::String& username)
+{
+ return m_env.CallBooleanMethod(m_jthis, impl().m_mid_prompt_2arg,
+ realm.get(), username.get());
+}
+
+bool UserPasswordCallback::ask_yes_no(const ::Java::String& realm,
+ const ::Java::String& question,
+ bool yes_is_default)
+{
+ return m_env.CallBooleanMethod(m_jthis, impl().m_mid_ask_yes_no,
+ realm.get(), question.get(),
+ jboolean(yes_is_default));
+}
+
+jstring UserPasswordCallback::ask_question(const ::Java::String& realm,
+ const ::Java::String& question,
+ bool show_answer)
+{
+ return jstring(m_env.CallObjectMethod(m_jthis,
+ impl().m_mid_ask_question_3arg,
+ realm.get(), question.get(),
+ jboolean(show_answer)));
+}
+
+jstring UserPasswordCallback::get_username()
+{
+ return jstring(m_env.CallObjectMethod(m_jthis, impl().m_mid_get_username));
+}
+
+jstring UserPasswordCallback::get_password()
+{
+ return jstring(m_env.CallObjectMethod(m_jthis, impl().m_mid_get_password));
+}
+
+bool UserPasswordCallback::prompt(const ::Java::String& realm,
+ const ::Java::String& username,
+ bool may_save)
+{
+ return m_env.CallBooleanMethod(m_jthis, impl().m_mid_prompt,
+ realm.get(), username.get(),
+ jboolean(may_save));
+}
+
+jstring UserPasswordCallback::ask_question(const ::Java::String& realm,
+ const ::Java::String& question,
+ bool show_answer, bool may_save)
+{
+ return jstring(m_env.CallObjectMethod(m_jthis, impl().m_mid_ask_question,
+ realm.get(), question.get(),
+ jboolean(show_answer),
+ jboolean(may_save)));
+}
+
+bool UserPasswordCallback::user_allowed_save()
+{
+ return m_env.CallBooleanMethod(m_jthis, impl().m_mid_user_allowed_save);
+}
+
+} // namespace JavaHL