blob: 3a25e0471765334627a9852e7f21e49ffc1ec1ab [file] [log] [blame]
/**
* @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