mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Unix Pageant: option to behave like ssh-askpass.
Since Pageant contains its own passphrase prompt system rather than delegating it to another process, it's not trivial to use it in other contexts. But having gone to the effort of coming up with my own askpass system that (I think) does a better job at not revealing the length of the password, I _want_ to use it in other contexts where a GUI passphrase or password prompt is needed. Solution: an --askpass option.
This commit is contained in:
parent
e6b06c900f
commit
4467fa4d2a
@ -129,6 +129,7 @@ static void usage(void)
|
||||
printf(" -s -c force POSIX or C shell syntax (in agent mode)\n");
|
||||
printf(" --tty-prompt force tty-based passphrase prompt (in -a mode)\n");
|
||||
printf(" --gui-prompt force GUI-based passphrase prompt (in -a mode)\n");
|
||||
printf(" --askpass <prompt> behave like a standalone askpass program\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -343,15 +344,13 @@ enum {
|
||||
PROMPT_UNSPEC, PROMPT_TTY, PROMPT_GUI
|
||||
} prompt_type = PROMPT_UNSPEC;
|
||||
|
||||
static char *askpass_tty(const char *comment)
|
||||
static char *askpass_tty(const char *prompt)
|
||||
{
|
||||
int ret;
|
||||
prompts_t *p = new_prompts(NULL);
|
||||
p->to_server = FALSE;
|
||||
p->name = dupstr("Pageant passphrase prompt");
|
||||
add_prompt(p,
|
||||
dupprintf("Enter passphrase to load key '%s': ", comment),
|
||||
FALSE);
|
||||
add_prompt(p, dupcat(prompt, ": ", (const char *)NULL), FALSE);
|
||||
ret = console_get_userpass_input(p, NULL, 0);
|
||||
assert(ret >= 0);
|
||||
|
||||
@ -366,20 +365,17 @@ static char *askpass_tty(const char *comment)
|
||||
}
|
||||
}
|
||||
|
||||
static char *askpass_gui(const char *comment)
|
||||
static char *askpass_gui(const char *prompt)
|
||||
{
|
||||
char *prompt, *passphrase;
|
||||
char *passphrase;
|
||||
int success;
|
||||
|
||||
/* in gtkask.c */
|
||||
char *gtk_askpass_main(const char *display, const char *wintitle,
|
||||
const char *prompt, int *success);
|
||||
|
||||
prompt = dupprintf("Enter passphrase to load key '%s': ", comment);
|
||||
passphrase = gtk_askpass_main(display,
|
||||
"Pageant passphrase prompt",
|
||||
prompt, &success);
|
||||
sfree(prompt);
|
||||
passphrase = gtk_askpass_main(
|
||||
display, "Pageant passphrase prompt", prompt, &success);
|
||||
if (!success) {
|
||||
/* return value is error message */
|
||||
fprintf(stderr, "%s\n", passphrase);
|
||||
@ -389,7 +385,7 @@ static char *askpass_gui(const char *comment)
|
||||
return passphrase;
|
||||
}
|
||||
|
||||
static char *askpass(const char *comment)
|
||||
static char *askpass(const char *prompt)
|
||||
{
|
||||
if (prompt_type == PROMPT_TTY) {
|
||||
if (!have_controlling_tty()) {
|
||||
@ -397,7 +393,7 @@ static char *askpass(const char *comment)
|
||||
"for passphrase prompt\n");
|
||||
return NULL;
|
||||
}
|
||||
return askpass_tty(comment);
|
||||
return askpass_tty(prompt);
|
||||
}
|
||||
|
||||
if (prompt_type == PROMPT_GUI) {
|
||||
@ -406,13 +402,13 @@ static char *askpass(const char *comment)
|
||||
"for passphrase prompt\n");
|
||||
return NULL;
|
||||
}
|
||||
return askpass_gui(comment);
|
||||
return askpass_gui(prompt);
|
||||
}
|
||||
|
||||
if (have_controlling_tty()) {
|
||||
return askpass_tty(comment);
|
||||
return askpass_tty(prompt);
|
||||
} else if (display) {
|
||||
return askpass_gui(comment);
|
||||
return askpass_gui(prompt);
|
||||
} else {
|
||||
fprintf(stderr, "no way to read a passphrase without tty or "
|
||||
"X display\n");
|
||||
@ -444,8 +440,11 @@ static int unix_add_keyfile(const char *filename_str)
|
||||
* And now try prompting for a passphrase.
|
||||
*/
|
||||
while (1) {
|
||||
char *passphrase = askpass(err);
|
||||
char *prompt = dupprintf(
|
||||
"Enter passphrase to load key '%s'", err);
|
||||
char *passphrase = askpass(prompt);
|
||||
sfree(err);
|
||||
sfree(prompt);
|
||||
err = NULL;
|
||||
if (!passphrase)
|
||||
break;
|
||||
@ -1010,6 +1009,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int doing_opts = TRUE;
|
||||
keyact curr_keyact = KEYACT_AGENT_LOAD;
|
||||
const char *standalone_askpass_prompt = NULL;
|
||||
|
||||
/*
|
||||
* Process the command line.
|
||||
@ -1063,6 +1063,14 @@ int main(int argc, char **argv)
|
||||
prompt_type = PROMPT_TTY;
|
||||
} else if (!strcmp(p, "--gui-prompt")) {
|
||||
prompt_type = PROMPT_GUI;
|
||||
} else if (!strcmp(p, "--askpass")) {
|
||||
if (--argc > 0) {
|
||||
standalone_askpass_prompt = *++argv;
|
||||
} else {
|
||||
fprintf(stderr, "pageant: expected a prompt message "
|
||||
"after --askpass\n");
|
||||
exit(1);
|
||||
}
|
||||
} else if (!strcmp(p, "--")) {
|
||||
doing_opts = FALSE;
|
||||
}
|
||||
@ -1082,6 +1090,27 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!display) {
|
||||
display = getenv("DISPLAY");
|
||||
if (display && !*display)
|
||||
display = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deal with standalone-askpass mode.
|
||||
*/
|
||||
if (standalone_askpass_prompt) {
|
||||
char *passphrase = askpass(standalone_askpass_prompt);
|
||||
|
||||
if (!passphrase)
|
||||
return 1;
|
||||
|
||||
puts(passphrase);
|
||||
smemclr(passphrase, strlen(passphrase));
|
||||
sfree(passphrase);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block SIGPIPE, so that we'll get EPIPE individually on
|
||||
* particular network connections that go wrong.
|
||||
@ -1091,12 +1120,6 @@ int main(int argc, char **argv)
|
||||
sk_init();
|
||||
uxsel_init();
|
||||
|
||||
if (!display) {
|
||||
display = getenv("DISPLAY");
|
||||
if (display && !*display)
|
||||
display = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now distinguish our two main running modes. Either we're
|
||||
* actually starting up an agent, in which case we should have a
|
||||
|
Loading…
Reference in New Issue
Block a user