diff options
Diffstat (limited to 'subversion/bindings/javahl/native/AuthnCallback.cpp')
-rw-r--r-- | subversion/bindings/javahl/native/AuthnCallback.cpp | 365 |
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 |