2 * prompt.c -- ask the user for authentication information.
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
24 /* ==================================================================== */
32 #include <apr_portable.h>
34 #include "svn_cmdline.h"
35 #include "svn_ctype.h"
36 #include "svn_string.h"
38 #include "svn_error.h"
41 #include "private/svn_cmdline_private.h"
42 #include "svn_private_config.h"
46 #elif defined(HAVE_TERMIOS_H)
53 /* Descriptor of an open terminal */
54 typedef struct terminal_handle_t terminal_handle_t;
55 struct terminal_handle_t
57 apr_file_t *infd; /* input file handle */
58 apr_file_t *outfd; /* output file handle */
59 svn_boolean_t noecho; /* terminal echo was turned off */
60 svn_boolean_t close_handles; /* close handles when closing the terminal */
61 apr_pool_t *pool; /* pool associated with the file handles */
64 svn_boolean_t restore_state; /* terminal state was changed */
65 apr_os_file_t osinfd; /* OS-specific handle for infd */
66 struct termios attr; /* saved terminal attributes */
70 /* Initialize safe state of terminal_handle_t. */
72 terminal_handle_init(terminal_handle_t *terminal,
73 apr_file_t *infd, apr_file_t *outfd,
74 svn_boolean_t noecho, svn_boolean_t close_handles,
77 memset(terminal, 0, sizeof(*terminal));
78 terminal->infd = infd;
79 terminal->outfd = outfd;
80 terminal->noecho = noecho;
81 terminal->close_handles = close_handles;
82 terminal->pool = pool;
86 * Common pool cleanup handler for terminal_handle_t. Closes TERMINAL.
87 * If CLOSE_HANDLES is TRUE, close the terminal file handles.
88 * If RESTORE_STATE is TRUE, restores the TERMIOS flags of the terminal.
91 terminal_cleanup_handler(terminal_handle_t *terminal,
92 svn_boolean_t close_handles,
93 svn_boolean_t restore_state)
95 apr_status_t status = APR_SUCCESS;
98 /* Restore terminal state flags. */
99 if (restore_state && terminal->restore_state)
100 tcsetattr(terminal->osinfd, TCSANOW, &terminal->attr);
103 /* Close terminal handles. */
104 if (close_handles && terminal->close_handles)
106 apr_file_t *const infd = terminal->infd;
107 apr_file_t *const outfd = terminal->outfd;
111 terminal->infd = NULL;
112 status = apr_file_close(infd);
115 if (!status && outfd && outfd != infd)
117 terminal->outfd = NULL;
118 status = apr_file_close(terminal->outfd);
124 /* Normal pool cleanup for a terminal. */
125 static apr_status_t terminal_plain_cleanup(void *baton)
127 return terminal_cleanup_handler(baton, FALSE, TRUE);
130 /* Child pool cleanup for a terminal -- does not restore echo state. */
131 static apr_status_t terminal_child_cleanup(void *baton)
133 return terminal_cleanup_handler(baton, FALSE, FALSE);
136 /* Explicitly close the terminal, removing its cleanup handlers. */
138 terminal_close(terminal_handle_t *terminal)
142 /* apr_pool_cleanup_kill() removes both normal and child cleanup */
143 apr_pool_cleanup_kill(terminal->pool, terminal, terminal_plain_cleanup);
145 status = terminal_cleanup_handler(terminal, TRUE, TRUE);
147 return svn_error_create(status, NULL, _("Can't close terminal"));
151 /* Allocate and open *TERMINAL. If NOECHO is TRUE, try to turn off
152 terminal echo. Use POOL for all allocations.*/
154 terminal_open(terminal_handle_t **terminal, svn_boolean_t noecho,
160 /* On Windows, we'll use the console API directly if the process has
161 a console attached; otherwise we'll just use stdin and stderr. */
162 const HANDLE conin = CreateFileW(L"CONIN$", GENERIC_READ,
163 FILE_SHARE_READ | FILE_SHARE_WRITE,
165 FILE_ATTRIBUTE_NORMAL, NULL);
166 *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
167 if (conin != INVALID_HANDLE_VALUE)
169 /* The process has a console. */
171 terminal_handle_init(*terminal, NULL, NULL, noecho, FALSE, NULL);
175 /* Without evidence to the contrary, we'll assume this is *nix and
176 try to open /dev/tty. If that fails, we'll use stdin for input
177 and stderr for prompting. */
179 status = apr_file_open(&tmpfd, "/dev/tty",
180 APR_FOPEN_READ | APR_FOPEN_WRITE,
181 APR_OS_DEFAULT, pool);
182 *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
185 /* We have a terminal handle that we can use for input and output. */
186 terminal_handle_init(*terminal, tmpfd, tmpfd, FALSE, TRUE, pool);
191 /* There is no terminal. Sigh. */
195 status = apr_file_open_stdin(&infd, pool);
197 return svn_error_wrap_apr(status, _("Can't open stdin"));
198 status = apr_file_open_stderr(&outfd, pool);
200 return svn_error_wrap_apr(status, _("Can't open stderr"));
201 terminal_handle_init(*terminal, infd, outfd, FALSE, FALSE, pool);
204 #ifdef HAVE_TERMIOS_H
205 /* Set terminal state */
206 if (0 == apr_os_file_get(&(*terminal)->osinfd, (*terminal)->infd))
208 if (0 == tcgetattr((*terminal)->osinfd, &(*terminal)->attr))
210 struct termios attr = (*terminal)->attr;
211 /* Turn off signal handling and canonical input mode */
212 attr.c_lflag &= ~(ISIG | ICANON);
213 attr.c_cc[VMIN] = 1; /* Read one byte at a time */
214 attr.c_cc[VTIME] = 0; /* No timeout, wait indefinitely */
215 attr.c_lflag &= ~(ECHO); /* Turn off echo */
216 if (0 == tcsetattr((*terminal)->osinfd, TCSAFLUSH, &attr))
218 (*terminal)->noecho = noecho;
219 (*terminal)->restore_state = TRUE;
223 #endif /* HAVE_TERMIOS_H */
225 /* Register pool cleanup to close handles and restore echo state. */
226 apr_pool_cleanup_register((*terminal)->pool, *terminal,
227 terminal_plain_cleanup,
228 terminal_child_cleanup);
232 /* Write a null-terminated STRING to TERMINAL.
233 Use POOL for allocations related to converting STRING from UTF-8. */
235 terminal_puts(const char *string, terminal_handle_t *terminal,
239 const char *converted;
241 err = svn_cmdline_cstring_from_utf8(&converted, string, pool);
244 svn_error_clear(err);
245 converted = svn_cmdline_cstring_from_utf8_fuzzy(string, pool);
249 if (!terminal->outfd)
251 /* See terminal_open; we're using Console I/O. */
257 SVN_ERR(svn_io_file_write_full(terminal->outfd, converted,
258 strlen(converted), NULL, pool));
260 return svn_error_trace(svn_io_file_flush(terminal->outfd, pool));
263 /* These codes can be returned from terminal_getc instead of a character. */
264 #define TERMINAL_NONE 0x80000 /* no character read, retry */
265 #define TERMINAL_DEL (TERMINAL_NONE + 1) /* the input was a deleteion */
266 #define TERMINAL_EOL (TERMINAL_NONE + 2) /* end of input/end of line */
267 #define TERMINAL_EOF (TERMINAL_NONE + 3) /* end of file during input */
269 /* Helper for terminal_getc: writes CH to OUTFD as a control char. */
272 echo_control_char(char ch, apr_file_t *outfd)
274 if (svn_ctype_iscntrl(ch))
276 const char substitute = (ch < 32? '@' + ch : '?');
277 apr_file_putc('^', outfd);
278 apr_file_putc(substitute, outfd);
280 else if (svn_ctype_isprint(ch))
282 /* Pass printable characters unchanged. */
283 apr_file_putc(ch, outfd);
287 /* Everything else is strange. */
288 apr_file_putc('^', outfd);
289 apr_file_putc('!', outfd);
294 /* Read one character or control code from TERMINAL, returning it in CODE.
295 if CAN_ERASE and the input was a deletion, emit codes to erase the
296 last character displayed on the terminal.
297 Use POOL for all allocations. */
299 terminal_getc(int *code, terminal_handle_t *terminal,
300 svn_boolean_t can_erase, apr_pool_t *pool)
302 const svn_boolean_t echo = !terminal->noecho;
303 apr_status_t status = APR_SUCCESS;
309 /* See terminal_open; we're using Console I/O. */
311 /* The following was hoisted from APR's getpass for Windows. */
312 int concode = _getch();
315 case '\r': /* end-of-line */
316 *code = TERMINAL_EOL;
321 case EOF: /* end-of-file */
322 case 26: /* Ctrl+Z */
323 *code = TERMINAL_EOF;
325 _cputs((concode == EOF ? "[EOF]\r\n" : "^Z\r\n"));
328 case 3: /* Ctrl+C, Ctrl+Break */
329 /* _getch() bypasses Ctrl+C but not Ctrl+Break detection! */
332 return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
334 case 0: /* Function code prefix */
336 concode = (concode << 4) | _getch();
337 /* Catch {DELETE}, {<--}, Num{DEL} and Num{<--} */
338 if (concode == 0xE53 || concode == 0xE4B
339 || concode == 0x053 || concode == 0x04B)
341 *code = TERMINAL_DEL;
347 *code = TERMINAL_NONE;
354 *code = TERMINAL_DEL;
360 if (!apr_iscntrl(concode))
362 *code = (int)(unsigned char)concode;
363 _putch(echo ? concode : '*');
367 *code = TERMINAL_NONE;
373 #elif defined(HAVE_TERMIOS_H)
374 if (terminal->restore_state)
376 /* We're using a bytewise-immediate termios input */
377 const struct termios *const attr = &terminal->attr;
379 status = apr_file_getc(&ch, terminal->infd);
381 return svn_error_wrap_apr(status, _("Can't read from terminal"));
383 if (ch == attr->c_cc[VINTR] || ch == attr->c_cc[VQUIT])
386 echo_control_char(ch, terminal->outfd);
387 return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
389 else if (ch == '\r' || ch == '\n' || ch == attr->c_cc[VEOL])
392 *code = TERMINAL_EOL;
393 apr_file_putc('\n', terminal->outfd);
395 else if (ch == '\b' || ch == attr->c_cc[VERASE])
398 *code = TERMINAL_DEL;
401 apr_file_putc('\b', terminal->outfd);
402 apr_file_putc(' ', terminal->outfd);
403 apr_file_putc('\b', terminal->outfd);
406 else if (ch == attr->c_cc[VEOF])
409 *code = TERMINAL_EOF;
410 echo_control_char(ch, terminal->outfd);
412 else if (ch == attr->c_cc[VSUSP])
415 *code = TERMINAL_NONE;
418 else if (!apr_iscntrl(ch))
420 /* Normal character */
421 *code = (int)(unsigned char)ch;
422 apr_file_putc((echo ? ch : '*'), terminal->outfd);
426 /* Ignored character */
427 *code = TERMINAL_NONE;
428 apr_file_putc('\a', terminal->outfd);
432 #endif /* HAVE_TERMIOS_H */
434 /* Fall back to plain stream-based I/O. */
436 /* Wait for input on termin. This code is based on
437 apr_wait_for_io_or_timeout().
438 Note that this will return an EINTR on a signal. */
440 apr_pollfd_t pollset;
443 pollset.desc_type = APR_POLL_FILE;
444 pollset.desc.f = terminal->infd;
446 pollset.reqevents = APR_POLLIN;
448 status = apr_poll(&pollset, 1, &n, -1);
450 if (n == 1 && pollset.rtnevents & APR_POLLIN)
451 status = APR_SUCCESS;
456 status = apr_file_getc(&ch, terminal->infd);
457 if (APR_STATUS_IS_EINTR(status))
459 *code = TERMINAL_NONE;
462 else if (APR_STATUS_IS_EOF(status))
464 *code = TERMINAL_EOF;
468 return svn_error_wrap_apr(status, _("Can't read from terminal"));
470 *code = (int)(unsigned char)ch;
475 /* Set @a *result to the result of prompting the user with @a
476 * prompt_msg. Use @ *pb to get the cancel_func and cancel_baton.
477 * Do not call the cancel_func if @a *pb is NULL.
478 * Allocate @a *result in @a pool.
480 * If @a hide is true, then try to avoid displaying the user's input.
483 prompt(const char **result,
484 const char *prompt_msg,
486 svn_cmdline_prompt_baton2_t *pb,
489 /* XXX: If this functions ever starts using members of *pb
490 * which were not included in svn_cmdline_prompt_baton_t,
491 * we need to update svn_cmdline_prompt_user2 and its callers. */
493 svn_boolean_t saw_first_half_of_eol = FALSE;
494 svn_stringbuf_t *strbuf = svn_stringbuf_create_empty(pool);
495 terminal_handle_t *terminal;
499 SVN_ERR(terminal_open(&terminal, hide, pool));
500 SVN_ERR(terminal_puts(prompt_msg, terminal, pool));
504 SVN_ERR(terminal_getc(&code, terminal, (strbuf->len > 0), pool));
506 /* Check for cancellation after a character has been read, some
507 input processing modes may eat ^C and we'll only notice a
508 cancellation signal after characters have been read --
509 sometimes even after a newline. */
511 SVN_ERR(pb->cancel_func(pb->cancel_baton));
516 /* Nothing useful happened; retry. */
520 /* Delete the last input character. terminal_getc takes care
521 of erasing the feedback from the terminal, if applicable. */
522 svn_stringbuf_chop(strbuf, 1);
526 /* End-of-line means end of input. Trick the EOL-detection code
527 below to stop reading. */
528 saw_first_half_of_eol = TRUE;
529 c = APR_EOL_STR[1]; /* Could be \0 but still stops reading. */
533 return svn_error_create(
535 terminal_close(terminal),
536 _("End of file while reading from terminal"));
539 /* Convert the returned code back to the character. */
543 if (saw_first_half_of_eol)
545 if (c == APR_EOL_STR[1])
548 saw_first_half_of_eol = FALSE;
550 else if (c == APR_EOL_STR[0])
552 /* GCC might complain here: "warning: will never be executed"
553 * That's fine. This is a compile-time check for "\r\n\0" */
554 if (sizeof(APR_EOL_STR) == 3)
556 saw_first_half_of_eol = TRUE;
559 else if (sizeof(APR_EOL_STR) == 2)
562 /* ### APR_EOL_STR holds more than two chars? Who
563 ever heard of such a thing? */
564 SVN_ERR_MALFUNCTION();
567 svn_stringbuf_appendbyte(strbuf, c);
570 if (terminal->noecho)
572 /* If terminal echo was turned off, make sure future output
573 to the terminal starts on a new line, as expected. */
574 SVN_ERR(terminal_puts(APR_EOL_STR, terminal, pool));
576 SVN_ERR(terminal_close(terminal));
578 return svn_cmdline_cstring_to_utf8(result, strbuf->data, pool);
583 /** Prompt functions for auth providers. **/
585 /* Helper function for auth provider prompters: mention the
586 * authentication @a realm on stderr, in a manner appropriate for
587 * preceding a prompt; or if @a realm is null, then do nothing.
590 maybe_print_realm(const char *realm, apr_pool_t *pool)
594 terminal_handle_t *terminal;
595 SVN_ERR(terminal_open(&terminal, FALSE, pool));
596 SVN_ERR(terminal_puts(
598 _("Authentication realm: %s\n"), realm),
600 SVN_ERR(terminal_close(terminal));
607 /* This implements 'svn_auth_simple_prompt_func_t'. */
609 svn_cmdline_auth_simple_prompt(svn_auth_cred_simple_t **cred_p,
612 const char *username,
613 svn_boolean_t may_save,
616 svn_auth_cred_simple_t *ret = apr_pcalloc(pool, sizeof(*ret));
617 const char *pass_prompt;
618 svn_cmdline_prompt_baton2_t *pb = baton;
620 SVN_ERR(maybe_print_realm(realm, pool));
623 ret->username = apr_pstrdup(pool, username);
625 SVN_ERR(prompt(&(ret->username), _("Username: "), FALSE, pb, pool));
627 pass_prompt = apr_psprintf(pool, _("Password for '%s': "), ret->username);
628 SVN_ERR(prompt(&(ret->password), pass_prompt, TRUE, pb, pool));
629 ret->may_save = may_save;
635 /* This implements 'svn_auth_username_prompt_func_t'. */
637 svn_cmdline_auth_username_prompt(svn_auth_cred_username_t **cred_p,
640 svn_boolean_t may_save,
643 svn_auth_cred_username_t *ret = apr_pcalloc(pool, sizeof(*ret));
644 svn_cmdline_prompt_baton2_t *pb = baton;
646 SVN_ERR(maybe_print_realm(realm, pool));
648 SVN_ERR(prompt(&(ret->username), _("Username: "), FALSE, pb, pool));
649 ret->may_save = may_save;
655 /* This implements 'svn_auth_ssl_server_trust_prompt_func_t'. */
657 svn_cmdline_auth_ssl_server_trust_prompt
658 (svn_auth_cred_ssl_server_trust_t **cred_p,
661 apr_uint32_t failures,
662 const svn_auth_ssl_server_cert_info_t *cert_info,
663 svn_boolean_t may_save,
667 svn_stringbuf_t *msg;
668 svn_cmdline_prompt_baton2_t *pb = baton;
669 svn_stringbuf_t *buf = svn_stringbuf_createf
670 (pool, _("Error validating server certificate for '%s':\n"), realm);
672 if (failures & SVN_AUTH_SSL_UNKNOWNCA)
674 svn_stringbuf_appendcstr
676 _(" - The certificate is not issued by a trusted authority. Use the\n"
677 " fingerprint to validate the certificate manually!\n"));
680 if (failures & SVN_AUTH_SSL_CNMISMATCH)
682 svn_stringbuf_appendcstr
683 (buf, _(" - The certificate hostname does not match.\n"));
686 if (failures & SVN_AUTH_SSL_NOTYETVALID)
688 svn_stringbuf_appendcstr
689 (buf, _(" - The certificate is not yet valid.\n"));
692 if (failures & SVN_AUTH_SSL_EXPIRED)
694 svn_stringbuf_appendcstr
695 (buf, _(" - The certificate has expired.\n"));
698 if (failures & SVN_AUTH_SSL_OTHER)
700 svn_stringbuf_appendcstr
701 (buf, _(" - The certificate has an unknown error.\n"));
704 msg = svn_stringbuf_createf
706 _("Certificate information:\n"
708 " - Valid: from %s until %s\n"
710 " - Fingerprint: %s\n"),
712 cert_info->valid_from,
713 cert_info->valid_until,
714 cert_info->issuer_dname,
715 cert_info->fingerprint);
716 svn_stringbuf_appendstr(buf, msg);
720 svn_stringbuf_appendcstr
721 (buf, _("(R)eject, accept (t)emporarily or accept (p)ermanently? "));
725 svn_stringbuf_appendcstr(buf, _("(R)eject or accept (t)emporarily? "));
727 SVN_ERR(prompt(&choice, buf->data, FALSE, pb, pool));
729 if (choice[0] == 't' || choice[0] == 'T')
731 *cred_p = apr_pcalloc(pool, sizeof(**cred_p));
732 (*cred_p)->may_save = FALSE;
733 (*cred_p)->accepted_failures = failures;
735 else if (may_save && (choice[0] == 'p' || choice[0] == 'P'))
737 *cred_p = apr_pcalloc(pool, sizeof(**cred_p));
738 (*cred_p)->may_save = TRUE;
739 (*cred_p)->accepted_failures = failures;
750 /* This implements 'svn_auth_ssl_client_cert_prompt_func_t'. */
752 svn_cmdline_auth_ssl_client_cert_prompt
753 (svn_auth_cred_ssl_client_cert_t **cred_p,
756 svn_boolean_t may_save,
759 svn_auth_cred_ssl_client_cert_t *cred = NULL;
760 const char *cert_file = NULL;
761 const char *abs_cert_file = NULL;
762 svn_cmdline_prompt_baton2_t *pb = baton;
764 SVN_ERR(maybe_print_realm(realm, pool));
765 SVN_ERR(prompt(&cert_file, _("Client certificate filename: "),
767 SVN_ERR(svn_dirent_get_absolute(&abs_cert_file, cert_file, pool));
769 cred = apr_palloc(pool, sizeof(*cred));
770 cred->cert_file = abs_cert_file;
771 cred->may_save = may_save;
778 /* This implements 'svn_auth_ssl_client_cert_pw_prompt_func_t'. */
780 svn_cmdline_auth_ssl_client_cert_pw_prompt
781 (svn_auth_cred_ssl_client_cert_pw_t **cred_p,
784 svn_boolean_t may_save,
787 svn_auth_cred_ssl_client_cert_pw_t *cred = NULL;
789 const char *text = apr_psprintf(pool, _("Passphrase for '%s': "), realm);
790 svn_cmdline_prompt_baton2_t *pb = baton;
792 SVN_ERR(prompt(&result, text, TRUE, pb, pool));
794 cred = apr_pcalloc(pool, sizeof(*cred));
795 cred->password = result;
796 cred->may_save = may_save;
802 /* This is a helper for plaintext prompt functions. */
804 plaintext_prompt_helper(svn_boolean_t *may_save_plaintext,
805 const char *realmstring,
806 const char *prompt_string,
807 const char *prompt_text,
811 const char *answer = NULL;
812 svn_boolean_t answered = FALSE;
813 svn_cmdline_prompt_baton2_t *pb = baton;
814 const char *config_path = NULL;
815 terminal_handle_t *terminal;
818 SVN_ERR(svn_config_get_user_config_path(&config_path, pb->config_dir,
819 SVN_CONFIG_CATEGORY_SERVERS, pool));
821 SVN_ERR(terminal_open(&terminal, FALSE, pool));
822 SVN_ERR(terminal_puts(apr_psprintf(pool, prompt_text,
823 realmstring, config_path),
825 SVN_ERR(terminal_close(terminal));
829 svn_error_t *err = prompt(&answer, prompt_string, FALSE, pb, pool);
832 if (err->apr_err == SVN_ERR_CANCELLED)
834 *may_save_plaintext = FALSE;
840 if (apr_strnatcasecmp(answer, _("yes")) == 0 ||
841 apr_strnatcasecmp(answer, _("y")) == 0)
843 *may_save_plaintext = TRUE;
846 else if (apr_strnatcasecmp(answer, _("no")) == 0 ||
847 apr_strnatcasecmp(answer, _("n")) == 0)
849 *may_save_plaintext = FALSE;
853 prompt_string = _("Please type 'yes' or 'no': ");
860 /* This implements 'svn_auth_plaintext_prompt_func_t'. */
862 svn_cmdline_auth_plaintext_prompt(svn_boolean_t *may_save_plaintext,
863 const char *realmstring,
867 const char *prompt_string = _("Store password unencrypted (yes/no)? ");
868 const char *prompt_text =
869 _("\n-----------------------------------------------------------------------"
870 "\nATTENTION! Your password for authentication realm:\n"
874 "can only be stored to disk unencrypted! You are advised to configure\n"
875 "your system so that Subversion can store passwords encrypted, if\n"
876 "possible. See the documentation for details.\n"
878 "You can avoid future appearances of this warning by setting the value\n"
879 "of the 'store-plaintext-passwords' option to either 'yes' or 'no' in\n"
881 "-----------------------------------------------------------------------\n"
884 return plaintext_prompt_helper(may_save_plaintext, realmstring,
885 prompt_string, prompt_text, baton,
889 /* This implements 'svn_auth_plaintext_passphrase_prompt_func_t'. */
891 svn_cmdline_auth_plaintext_passphrase_prompt(svn_boolean_t *may_save_plaintext,
892 const char *realmstring,
896 const char *prompt_string = _("Store passphrase unencrypted (yes/no)? ");
897 const char *prompt_text =
898 _("\n-----------------------------------------------------------------------\n"
899 "ATTENTION! Your passphrase for client certificate:\n"
903 "can only be stored to disk unencrypted! You are advised to configure\n"
904 "your system so that Subversion can store passphrase encrypted, if\n"
905 "possible. See the documentation for details.\n"
907 "You can avoid future appearances of this warning by setting the value\n"
908 "of the 'store-ssl-client-cert-pp-plaintext' option to either 'yes' or\n"
910 "-----------------------------------------------------------------------\n"
913 return plaintext_prompt_helper(may_save_plaintext, realmstring,
914 prompt_string, prompt_text, baton,
919 /** Generic prompting. **/
922 svn_cmdline_prompt_user2(const char **result,
923 const char *prompt_str,
924 svn_cmdline_prompt_baton_t *baton,
927 /* XXX: We know prompt doesn't use the new members
928 * of svn_cmdline_prompt_baton2_t. */
929 return prompt(result, prompt_str, FALSE /* don't hide input */,
930 (svn_cmdline_prompt_baton2_t *)baton, pool);
933 /* This implements 'svn_auth_gnome_keyring_unlock_prompt_func_t'. */
935 svn_cmdline__auth_gnome_keyring_unlock_prompt(char **keyring_password,
936 const char *keyring_name,
940 const char *password;
941 const char *pass_prompt;
942 svn_cmdline_prompt_baton2_t *pb = baton;
944 pass_prompt = apr_psprintf(pool, _("Password for '%s' GNOME keyring: "),
946 SVN_ERR(prompt(&password, pass_prompt, TRUE, pb, pool));
947 *keyring_password = apr_pstrdup(pool, password);