1 /**
2  * @copyright
3  * ====================================================================
4  *    Licensed to the Apache Software Foundation (ASF) under one
5  *    or more contributor license agreements.  See the NOTICE file
6  *    distributed with this work for additional information
7  *    regarding copyright ownership.  The ASF licenses this file
8  *    to you under the Apache License, Version 2.0 (the
9  *    "License"); you may not use this file except in compliance
10  *    with the License.  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *    Unless required by applicable law or agreed to in writing,
15  *    software distributed under the License is distributed on an
16  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  *    KIND, either express or implied.  See the License for the
18  *    specific language governing permissions and limitations
19  *    under the License.
20  * ====================================================================
21  * @endcopyright
22  *
23  * @file Prompter.cpp
24  * @brief Implementation of the class Prompter
25  */
26 
27 #include "Prompter.h"
28 #include "AuthnCallback.hpp"
29 
30 #include "JNIUtil.h"
31 #include "JNIStringHolder.h"
32 #include "../include/org_apache_subversion_javahl_callback_UserPasswordCallback.h"
33 
34 #include <apr_strings.h>
35 #include "svn_error.h"
36 #include "svn_error_codes.h"
37 #include "svn_private_config.h"
38 
39 
40 #include "jniwrapper/jni_stack.hpp"
41 #include "jniwrapper/jni_string.hpp"
42 
43 // Class Prompter
44 
create(jobject jprompter)45 Prompter::UniquePtr Prompter::create(jobject jprompter)
46 {
47   if (!jprompter)
48     return UniquePtr();
49 
50   // Make sure no C++ exceptions are propagated from here.
51   const ::Java::Env jenv;
52   try
53     {
54       const jclass cls = ::Java::ClassCache::get_authn_cb(jenv)->get_class();
55       if (!jenv.IsInstanceOf(jprompter, cls))
56         return UniquePtr();
57 
58       return UniquePtr(new Prompter(jenv, jprompter));
59     }
60   SVN_JAVAHL_JNI_CATCH;
61   return UniquePtr();
62 }
63 
clone() const64 Prompter::UniquePtr Prompter::clone() const
65 {
66   return create(m_prompter.get());
67 }
68 
Prompter(::Java::Env env,jobject jprompter)69 Prompter::Prompter(::Java::Env env, jobject jprompter)
70   : m_prompter(env, jprompter)
71 {}
72 
~Prompter()73 Prompter::~Prompter() {}
74 
75 
76 svn_auth_provider_object_t *
get_provider_simple(SVN::Pool & in_pool)77 Prompter::get_provider_simple(SVN::Pool &in_pool)
78 {
79   apr_pool_t *pool = in_pool.getPool();
80   svn_auth_provider_object_t *provider;
81   svn_auth_get_simple_prompt_provider(&provider,
82                                       simple_prompt,
83                                       this,
84                                       2, /* retry limit */
85                                       pool);
86 
87   return provider;
88 }
89 
90 svn_auth_provider_object_t *
get_provider_username(SVN::Pool & in_pool)91 Prompter::get_provider_username(SVN::Pool &in_pool)
92 {
93   apr_pool_t *pool = in_pool.getPool();
94   svn_auth_provider_object_t *provider;
95   svn_auth_get_username_prompt_provider(&provider,
96                                         username_prompt,
97                                         this,
98                                         2, /* retry limit */
99                                         pool);
100 
101   return provider;
102 }
103 
104 svn_auth_provider_object_t *Prompter::
get_provider_server_ssl_trust(SVN::Pool & in_pool)105 get_provider_server_ssl_trust(SVN::Pool &in_pool)
106 {
107   apr_pool_t *pool = in_pool.getPool();
108   svn_auth_provider_object_t *provider;
109   svn_auth_get_ssl_server_trust_prompt_provider
110     (&provider, ssl_server_trust_prompt, this, pool);
111 
112   return provider;
113 }
114 
115 svn_auth_provider_object_t *Prompter::
get_provider_client_ssl(SVN::Pool & in_pool)116 get_provider_client_ssl(SVN::Pool &in_pool)
117 {
118   apr_pool_t *pool = in_pool.getPool();
119   svn_auth_provider_object_t *provider;
120   svn_auth_get_ssl_client_cert_prompt_provider(&provider,
121                                                ssl_client_cert_prompt,
122                                                this,
123                                                2 /* retry limit */,
124                                                pool);
125 
126   return provider;
127 }
128 
129 svn_auth_provider_object_t *
get_provider_client_ssl_password(SVN::Pool & in_pool)130 Prompter::get_provider_client_ssl_password(SVN::Pool &in_pool)
131 {
132   apr_pool_t *pool = in_pool.getPool();
133   svn_auth_provider_object_t *provider;
134   svn_auth_get_ssl_client_cert_pw_prompt_provider
135     (&provider, ssl_client_cert_pw_prompt, this, 2 /* retry limit */,
136      pool);
137 
138   return provider;
139 }
140 
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)141 svn_error_t *Prompter::simple_prompt(
142     svn_auth_cred_simple_t **cred_p,
143     void *baton,
144     const char *realm,
145     const char *username,
146     svn_boolean_t may_save,
147     apr_pool_t *pool)
148 {
149   const ::Java::Env env;
150   svn_error_t *err;
151   SVN_JAVAHL_CATCH(
152       env, SVN_ERR_RA_NOT_AUTHORIZED,
153       err = static_cast<Prompter*>(baton)->dispatch_simple_prompt(
154           env, cred_p, realm, username, may_save, pool));
155   return err;
156 }
157 
username_prompt(svn_auth_cred_username_t ** cred_p,void * baton,const char * realm,svn_boolean_t may_save,apr_pool_t * pool)158 svn_error_t *Prompter::username_prompt(
159     svn_auth_cred_username_t **cred_p,
160     void *baton,
161     const char *realm,
162     svn_boolean_t may_save,
163     apr_pool_t *pool)
164 {
165   const ::Java::Env env;
166   svn_error_t *err;
167   SVN_JAVAHL_CATCH(
168       env, SVN_ERR_RA_NOT_AUTHORIZED,
169       err = static_cast<Prompter*>(baton)->dispatch_username_prompt(
170           env, cred_p, realm, may_save, pool));
171   return err;
172 }
173 
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)174 svn_error_t *Prompter::ssl_server_trust_prompt(
175     svn_auth_cred_ssl_server_trust_t **cred_p,
176     void *baton,
177     const char *realm,
178     apr_uint32_t failures,
179     const svn_auth_ssl_server_cert_info_t *cert_info,
180     svn_boolean_t may_save,
181     apr_pool_t *pool)
182 {
183   const ::Java::Env env;
184   svn_error_t *err;
185   SVN_JAVAHL_CATCH(
186       env, SVN_ERR_RA_NOT_AUTHORIZED,
187       err = static_cast<Prompter*>(baton)->dispatch_ssl_server_trust_prompt(
188           env, cred_p, realm, failures, cert_info, may_save, pool));
189   return err;
190 }
191 
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)192 svn_error_t *Prompter::ssl_client_cert_prompt(
193     svn_auth_cred_ssl_client_cert_t **cred_p,
194     void *baton,
195     const char *realm,
196     svn_boolean_t may_save,
197     apr_pool_t *pool)
198 {
199   const ::Java::Env env;
200   svn_error_t *err;
201   SVN_JAVAHL_CATCH(
202       env, SVN_ERR_RA_NOT_AUTHORIZED,
203       err = static_cast<Prompter*>(baton)->dispatch_ssl_client_cert_prompt(
204           env, cred_p, realm, may_save, pool));
205   return err;
206 }
207 
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)208 svn_error_t *Prompter::ssl_client_cert_pw_prompt(
209     svn_auth_cred_ssl_client_cert_pw_t **cred_p,
210     void *baton,
211     const char *realm,
212     svn_boolean_t may_save,
213     apr_pool_t *pool)
214 {
215   const ::Java::Env env;
216   svn_error_t *err;
217   SVN_JAVAHL_CATCH(
218       env, SVN_ERR_RA_NOT_AUTHORIZED,
219       err = static_cast<Prompter*>(baton)->dispatch_ssl_client_cert_pw_prompt(
220           env, cred_p, realm, may_save, pool));
221   return err;
222 }
223 
plaintext_prompt(svn_boolean_t * may_save_plaintext,const char * realmstring,void * baton,apr_pool_t * pool)224 svn_error_t *Prompter::plaintext_prompt(
225     svn_boolean_t *may_save_plaintext,
226     const char *realmstring,
227     void *baton,
228     apr_pool_t *pool)
229 {
230   const ::Java::Env env;
231   svn_error_t *err;
232   SVN_JAVAHL_CATCH(
233       env, SVN_ERR_RA_NOT_AUTHORIZED,
234       err = static_cast<Prompter*>(baton)->dispatch_plaintext_prompt(
235           env, may_save_plaintext, realmstring, pool));
236   return err;
237 }
238 
plaintext_passphrase_prompt(svn_boolean_t * may_save_plaintext,const char * realmstring,void * baton,apr_pool_t * pool)239 svn_error_t *Prompter::plaintext_passphrase_prompt(
240     svn_boolean_t *may_save_plaintext,
241     const char *realmstring,
242     void *baton,
243     apr_pool_t *pool)
244 {
245   const ::Java::Env env;
246   svn_error_t *err;
247   SVN_JAVAHL_CATCH(
248       env, SVN_ERR_RA_NOT_AUTHORIZED,
249       err = static_cast<Prompter*>(baton)->dispatch_plaintext_passphrase_prompt(
250           env, may_save_plaintext, realmstring, pool));
251   return err;
252 }
253 
254 
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)255 svn_error_t *Prompter::dispatch_simple_prompt(
256     ::Java::Env env,
257     svn_auth_cred_simple_t **cred_p,
258     const char *realm,
259     const char *username,
260     svn_boolean_t may_save,
261     apr_pool_t *pool)
262 {
263   ::JavaHL::AuthnCallback authn(env, m_prompter.get());
264 
265   ::JavaHL::AuthnCallback::AuthnResult result(
266       env,
267       authn.user_password_prompt(::Java::String(env, realm),
268                                  ::Java::String(env, username),
269                                  may_save));
270   if (!result.get())
271     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
272                             _("User canceled dialog"));
273 
274   ::Java::String user(env, result.identity());
275   ::Java::String pass(env, result.secret());
276   svn_auth_cred_simple_t *cred =
277     static_cast<svn_auth_cred_simple_t*>(apr_pcalloc(pool, sizeof(*cred)));
278   cred->username = user.strdup(pool);
279   cred->password  = pass.strdup(pool);
280   cred->may_save = result.save();
281   *cred_p = cred;
282 
283   return SVN_NO_ERROR;
284 }
285 
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)286 svn_error_t *Prompter::dispatch_username_prompt(
287     ::Java::Env env,
288     svn_auth_cred_username_t **cred_p,
289     const char *realm,
290     svn_boolean_t may_save,
291     apr_pool_t *pool)
292 {
293   ::JavaHL::AuthnCallback authn(env, m_prompter.get());
294 
295   ::JavaHL::AuthnCallback::AuthnResult result(
296       env,
297       authn.username_prompt(::Java::String(env, realm), may_save));
298   if (!result.get())
299     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
300                             _("User canceled dialog"));
301 
302   ::Java::String user(env, result.identity());
303   svn_auth_cred_username_t *cred =
304     static_cast<svn_auth_cred_username_t*>(apr_pcalloc(pool, sizeof(*cred)));
305   cred->username = user.strdup(pool);
306   cred->may_save = result.save();
307   *cred_p = cred;
308 
309   return SVN_NO_ERROR;
310 }
311 
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)312 svn_error_t *Prompter::dispatch_ssl_server_trust_prompt(
313     ::Java::Env env,
314     svn_auth_cred_ssl_server_trust_t **cred_p,
315     const char *realm,
316     apr_uint32_t failures,
317     const svn_auth_ssl_server_cert_info_t *cert_info,
318     svn_boolean_t may_save,
319     apr_pool_t *pool)
320 {
321   ::JavaHL::AuthnCallback authn(env, m_prompter.get());
322 
323   ::JavaHL::AuthnCallback::AuthnResult result(
324       env,
325       authn.ssl_server_trust_prompt(
326           ::Java::String(env, realm),
327           ::JavaHL::AuthnCallback::SSLServerCertFailures(env, jint(failures)),
328           ::JavaHL::AuthnCallback::SSLServerCertInfo(env, cert_info->ascii_cert),
329           may_save));
330   if (!result.get())
331     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
332                             _("User canceled dialog"));
333 
334   const bool trust = result.trust();
335   if (!trust)
336     {
337       *cred_p = NULL;
338       return SVN_NO_ERROR;
339     }
340 
341   const bool save = result.save();
342   svn_auth_cred_ssl_server_trust_t *cred =
343     static_cast<svn_auth_cred_ssl_server_trust_t*>(apr_pcalloc(pool, sizeof(*cred)));
344   cred->may_save = save;
345   cred->accepted_failures = failures;
346   *cred_p = cred;
347 
348   return SVN_NO_ERROR;
349 }
350 
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)351 svn_error_t *Prompter::dispatch_ssl_client_cert_prompt(
352     ::Java::Env env,
353     svn_auth_cred_ssl_client_cert_t **cred_p,
354     const char *realm,
355     svn_boolean_t may_save,
356     apr_pool_t *pool)
357 {
358   ::JavaHL::AuthnCallback authn(env, m_prompter.get());
359 
360   ::JavaHL::AuthnCallback::AuthnResult result(
361       env,
362       authn.ssl_client_cert_prompt(::Java::String(env, realm), may_save));
363   if (!result.get())
364     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
365                             _("User canceled dialog"));
366 
367   ::Java::String path(env, result.identity());
368   svn_auth_cred_ssl_client_cert_t *cred =
369     static_cast<svn_auth_cred_ssl_client_cert_t*>(apr_pcalloc(pool, sizeof(*cred)));
370   cred->cert_file = path.strdup(pool);
371   cred->may_save = result.save();
372   *cred_p = cred;
373 
374   return SVN_NO_ERROR;
375 }
376 
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)377 svn_error_t *Prompter::dispatch_ssl_client_cert_pw_prompt(
378     ::Java::Env env,
379     svn_auth_cred_ssl_client_cert_pw_t **cred_p,
380     const char *realm,
381     svn_boolean_t may_save,
382     apr_pool_t *pool)
383 {
384   ::JavaHL::AuthnCallback authn(env, m_prompter.get());
385 
386   ::JavaHL::AuthnCallback::AuthnResult result(
387       env,
388       authn.ssl_client_cert_passphrase_prompt(
389           ::Java::String(env, realm), may_save));
390   if (!result.get())
391     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
392                             _("User canceled dialog"));
393 
394   ::Java::String passphrase(env, result.secret());
395   svn_auth_cred_ssl_client_cert_pw_t *cred =
396     static_cast<svn_auth_cred_ssl_client_cert_pw_t*>(apr_pcalloc(pool, sizeof(*cred)));
397   cred->password = passphrase.strdup(pool);
398   cred->may_save = result.save();
399   *cred_p = cred;
400 
401   return SVN_NO_ERROR;
402 }
403 
dispatch_plaintext_prompt(::Java::Env env,svn_boolean_t * may_save_plaintext,const char * realmstring,apr_pool_t * pool)404 svn_error_t *Prompter::dispatch_plaintext_prompt(
405     ::Java::Env env,
406     svn_boolean_t *may_save_plaintext,
407     const char *realmstring,
408     apr_pool_t *pool)
409 {
410   ::JavaHL::AuthnCallback authn(env, m_prompter.get());
411   *may_save_plaintext =
412     authn.allow_store_plaintext_password(::Java::String(env, realmstring));
413   return SVN_NO_ERROR;
414 }
415 
dispatch_plaintext_passphrase_prompt(::Java::Env env,svn_boolean_t * may_save_plaintext,const char * realmstring,apr_pool_t * pool)416 svn_error_t *Prompter::dispatch_plaintext_passphrase_prompt(
417     ::Java::Env env,
418     svn_boolean_t *may_save_plaintext,
419     const char *realmstring,
420     apr_pool_t *pool)
421 {
422   ::JavaHL::AuthnCallback authn(env, m_prompter.get());
423   *may_save_plaintext =
424     authn.allow_store_plaintext_passphrase(::Java::String(env, realmstring));
425   return SVN_NO_ERROR;
426 }
427 
428 
429 // Class CompatPrompter
430 
create(jobject jprompter)431 Prompter::UniquePtr CompatPrompter::create(jobject jprompter)
432 {
433   if (!jprompter)
434     return UniquePtr();
435 
436   // Make sure no C++ exceptions are propagated from here.
437   const ::Java::Env jenv;
438   try
439     {
440       const jclass cls =
441         ::Java::ClassCache::get_user_passwd_cb(jenv)->get_class();
442       if (!jenv.IsInstanceOf(jprompter, cls))
443         return UniquePtr();
444 
445       return UniquePtr(new CompatPrompter(jenv, jprompter));
446     }
447   SVN_JAVAHL_JNI_CATCH;
448   return UniquePtr();
449 }
450 
clone() const451 Prompter::UniquePtr CompatPrompter::clone() const
452 {
453   return create(m_prompter.get());
454 }
455 
CompatPrompter(::Java::Env env,jobject jprompter)456 CompatPrompter::CompatPrompter(::Java::Env env, jobject jprompter)
457   : Prompter(env, jprompter)
458 {}
459 
~CompatPrompter()460 CompatPrompter::~CompatPrompter() {}
461 
462 namespace {
compat_ask_question(bool & allowed_save,::Java::Env env,::JavaHL::UserPasswordCallback & authn,const char * realm,const char * question,bool show_answer,bool may_save)463 jstring compat_ask_question(
464     bool& allowed_save,
465     ::Java::Env env,
466     ::JavaHL::UserPasswordCallback& authn,
467     const char *realm, const char *question,
468     bool show_answer, bool may_save)
469 {
470   const jstring janswer =
471     authn.ask_question(::Java::String(env, realm),
472                        ::Java::String(env, question),
473                        show_answer, may_save);
474 
475   if (janswer)
476     allowed_save = authn.user_allowed_save();
477   else
478     allowed_save = false;
479 
480   return janswer;
481 }
482 } // anonymous namespace
483 
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)484 svn_error_t *CompatPrompter::dispatch_simple_prompt(
485     ::Java::Env env,
486     svn_auth_cred_simple_t **cred_p,
487     const char *realm, const char *username,
488     svn_boolean_t may_save,
489     apr_pool_t *pool)
490 {
491   ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
492 
493   if (!authn.prompt(::Java::String(env, realm),
494                     ::Java::String(env, username),
495                     may_save))
496     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
497                             _("User canceled dialog"));
498   const ::Java::String user(env, authn.get_username());
499   const ::Java::String pass(env, authn.get_password());
500 
501   if (!user.get() || !pass.get())
502     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
503                             _("User canceled dialog"));
504 
505   svn_auth_cred_simple_t *cred =
506     static_cast<svn_auth_cred_simple_t*>(apr_pcalloc(pool, sizeof(*cred)));
507   cred->username = user.strdup(pool);
508   cred->password  = pass.strdup(pool);
509   cred->may_save = authn.user_allowed_save();
510   *cred_p = cred;
511 
512   return SVN_NO_ERROR;
513 }
514 
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)515 svn_error_t *CompatPrompter::dispatch_username_prompt(
516     ::Java::Env env,
517     svn_auth_cred_username_t **cred_p,
518     const char *realm,
519     svn_boolean_t may_save,
520     apr_pool_t *pool)
521 {
522   ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
523 
524   bool allowed_save;
525   const ::Java::String user(
526       env,
527       compat_ask_question(allowed_save, env, authn,
528                           realm, _("Username: "), true, may_save));
529   if (!user.get())
530     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
531                             _("User canceled dialog"));
532 
533   svn_auth_cred_username_t *cred =
534     static_cast<svn_auth_cred_username_t*>(apr_pcalloc(pool, sizeof(*cred)));
535   cred->username = user.strdup(pool);
536   cred->may_save = allowed_save;
537   *cred_p = cred;
538 
539   return SVN_NO_ERROR;
540 }
541 
542 svn_error_t *
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)543 CompatPrompter::dispatch_ssl_server_trust_prompt(
544     ::Java::Env env,
545     svn_auth_cred_ssl_server_trust_t **cred_p,
546     const char *realm,
547     apr_uint32_t failures,
548     const svn_auth_ssl_server_cert_info_t *cert_info,
549     svn_boolean_t may_save,
550     apr_pool_t *pool)
551 {
552   ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
553 
554   std::string question = _("Error validating server certificate for ");
555   question += realm;
556   question += ":\n";
557 
558   if (failures & SVN_AUTH_SSL_UNKNOWNCA)
559     {
560       question += _(" - Unknown certificate issuer\n");
561       question += _("   Fingerprint: ");
562       question += cert_info->fingerprint;
563       question += "\n";
564       question += _("   Distinguished name: ");
565       question += cert_info->issuer_dname;
566       question += "\n";
567     }
568 
569   if (failures & SVN_AUTH_SSL_CNMISMATCH)
570     {
571       question += _(" - Hostname mismatch (");
572       question += cert_info->hostname;
573       question += _(")\n");
574     }
575 
576   if (failures & SVN_AUTH_SSL_NOTYETVALID)
577     {
578       question += _(" - Certificate is not yet valid\n");
579       question += _("   Valid from ");
580       question += cert_info->valid_from;
581       question += "\n";
582     }
583 
584   if (failures & SVN_AUTH_SSL_EXPIRED)
585     {
586       question += _(" - Certificate is expired\n");
587       question += _("   Valid until ");
588       question += cert_info->valid_until;
589       question += "\n";
590     }
591 
592   svn_auth_cred_ssl_server_trust_t *cred =
593     static_cast<svn_auth_cred_ssl_server_trust_t*>(apr_pcalloc(pool, sizeof(*cred)));
594 
595   switch (authn.ask_trust_ssl_server(::Java::String(env, question), may_save))
596     {
597     case org_apache_subversion_javahl_callback_UserPasswordCallback_AcceptTemporary:
598       cred->may_save = FALSE;
599       cred->accepted_failures = failures;
600       *cred_p = cred;
601       break;
602     case org_apache_subversion_javahl_callback_UserPasswordCallback_AcceptPermanently:
603       cred->may_save = TRUE;
604       cred->accepted_failures = failures;
605       *cred_p = cred;
606       break;
607     default:
608       *cred_p = NULL;
609     }
610   return SVN_NO_ERROR;
611 }
612 
613 svn_error_t *
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)614 CompatPrompter::dispatch_ssl_client_cert_prompt(
615     ::Java::Env env,
616     svn_auth_cred_ssl_client_cert_t **cred_p,
617     const char *realm,
618     svn_boolean_t may_save,
619     apr_pool_t *pool)
620 {
621   ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
622 
623   bool allowed_save;
624   const ::Java::String path(
625       env,
626       compat_ask_question(allowed_save, env, authn, realm,
627                           _("Client certificate filename: "),
628                           true, may_save));
629   if (!path.get())
630     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
631                             _("User canceled dialog"));
632 
633   svn_auth_cred_ssl_client_cert_t *cred =
634     static_cast<svn_auth_cred_ssl_client_cert_t*>(apr_pcalloc(pool, sizeof(*cred)));
635   cred->cert_file = path.strdup(pool);
636   cred->may_save = allowed_save;
637   *cred_p = cred;
638   return SVN_NO_ERROR;
639 }
640 
641 svn_error_t *
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)642 CompatPrompter::dispatch_ssl_client_cert_pw_prompt(
643     ::Java::Env env,
644     svn_auth_cred_ssl_client_cert_pw_t **cred_p,
645     const char *realm,
646     svn_boolean_t may_save,
647     apr_pool_t *pool)
648 {
649   ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
650 
651   bool allowed_save;
652   const ::Java::String info(
653       env,
654       compat_ask_question(allowed_save, env, authn, realm,
655                           _("Client certificate passphrase: "),
656                           false, may_save));
657   if (!info.get())
658     return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
659                             _("User canceled dialog"));
660 
661   svn_auth_cred_ssl_client_cert_pw_t *cred =
662     static_cast<svn_auth_cred_ssl_client_cert_pw_t*>(apr_pcalloc(pool, sizeof(*cred)));
663   cred->password = info.strdup(pool);
664   cred->may_save = allowed_save;
665   *cred_p = cred;
666   return SVN_NO_ERROR;
667 }
668 
669 svn_error_t *
dispatch_plaintext_prompt(::Java::Env env,svn_boolean_t * may_save_plaintext,const char * realmstring,apr_pool_t * pool)670 CompatPrompter::dispatch_plaintext_prompt(
671     ::Java::Env env,
672     svn_boolean_t *may_save_plaintext,
673     const char *realmstring,
674     apr_pool_t *pool)
675 {
676   ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
677 
678   *may_save_plaintext = authn.ask_yes_no(
679       ::Java::String(env, realmstring),
680       ::Java::String(env, _("Store password unencrypted?")),
681       false);
682 
683   return SVN_NO_ERROR;
684 }
685 
686 svn_error_t *
dispatch_plaintext_passphrase_prompt(::Java::Env env,svn_boolean_t * may_save_plaintext,const char * realmstring,apr_pool_t * pool)687 CompatPrompter::dispatch_plaintext_passphrase_prompt(
688     ::Java::Env env,
689     svn_boolean_t *may_save_plaintext,
690     const char *realmstring,
691     apr_pool_t *pool)
692 {
693   ::JavaHL::UserPasswordCallback authn(env, m_prompter.get());
694 
695   *may_save_plaintext = authn.ask_yes_no(
696       ::Java::String(env, realmstring),
697       ::Java::String(env, _("Store passphrase unencrypted?")),
698       false);
699 
700   return SVN_NO_ERROR;
701 }
702