summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2019-11-18 15:05:04 +1100
committerDamien Miller <djm@mindrot.org>2019-11-18 15:22:40 +1100
commitb497e920b409250309c4abe64229237b8f2730ba (patch)
treead8f12463b4743c0ef9e0db1e132a57ee0a9b1bf /contrib
parent857f49e91eeae6feb781ef5f5e26c38ca3d953ec (diff)
downloadopenssh-git-b497e920b409250309c4abe64229237b8f2730ba.tar.gz
Teach the GTK2/3 ssh-askpass the new prompt hints
ssh/ssh-agent now sets a hint environment variable $SSH_ASKPASS_PROMPT when running the askpass program. This is intended to allow the askpass to vary its UI across the three cases it supports: asking for a passphrase, confirming the use of a key and (recently) reminding a user to touch their security key. This adapts the gnome-ssh-askpass[23] to use these hints. Specifically, for SSH_ASKPASS_PROMPT=confirm it will skip the text input box and show only "yes"/"no" buttons. For SSH_ASKPASS_PROMPT=none (used to remind users to tap their security key), it shows only a "close" button. Help wanted: adapt the other askpass programs in active use, including x11-ssh-askpass, lxqt-openssh-askpass, etc.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/gnome-ssh-askpass2.c115
1 files changed, 72 insertions, 43 deletions
diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
index 535a6927..bc83a2d6 100644
--- a/contrib/gnome-ssh-askpass2.c
+++ b/contrib/gnome-ssh-askpass2.c
@@ -39,6 +39,10 @@
#define GRAB_TRIES 16
#define GRAB_WAIT 250 /* milliseconds */
+#define PROMPT_ENTRY 0
+#define PROMPT_CONFIRM 1
+#define PROMPT_NONE 2
+
/*
* Compile with:
*
@@ -82,11 +86,12 @@ ok_dialog(GtkWidget *entry, gpointer dialog)
}
static int
-passphrase_dialog(char *message)
+passphrase_dialog(char *message, int prompt_type)
{
const char *failed;
char *passphrase, *local;
int result, grab_tries, grab_server, grab_pointer;
+ int buttons, default_response;
GtkWidget *parent_window, *dialog, *entry;
GdkGrabStatus status;
@@ -98,31 +103,43 @@ passphrase_dialog(char *message)
* complain. */
parent_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ switch (prompt_type) {
+ case PROMPT_CONFIRM:
+ buttons = GTK_BUTTONS_YES_NO;
+ default_response = GTK_RESPONSE_YES;
+ break;
+ case PROMPT_NONE:
+ buttons = GTK_BUTTONS_CLOSE;
+ default_response = GTK_RESPONSE_CLOSE;
+ break;
+ default:
+ buttons = GTK_BUTTONS_OK_CANCEL;
+ default_response = GTK_RESPONSE_OK;
+ break;
+ }
+
dialog = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_OK_CANCEL,
- "%s",
- message);
-
- entry = gtk_entry_new();
- gtk_box_pack_start(
- GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry,
- FALSE, FALSE, 0);
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
- gtk_widget_grab_focus(entry);
- gtk_widget_show(entry);
+ GTK_MESSAGE_QUESTION, buttons, "%s", message);
gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH");
gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
-
- /* Make <enter> close dialog */
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
- g_signal_connect(G_OBJECT(entry), "activate",
- G_CALLBACK(ok_dialog), dialog);
-
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_response);
gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+ if (prompt_type == PROMPT_ENTRY) {
+ entry = gtk_entry_new();
+ gtk_box_pack_start(
+ GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
+ entry, FALSE, FALSE, 0);
+ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+ gtk_widget_grab_focus(entry);
+ gtk_widget_show(entry);
+ /* Make <enter> close dialog */
+ g_signal_connect(G_OBJECT(entry), "activate",
+ G_CALLBACK(ok_dialog), dialog);
+ }
+
/* Grab focus */
gtk_widget_show_now(dialog);
if (grab_pointer) {
@@ -166,32 +183,37 @@ passphrase_dialog(char *message)
gdk_flush();
/* Report passphrase if user selected OK */
- passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
- if (result == GTK_RESPONSE_OK) {
- local = g_locale_from_utf8(passphrase, strlen(passphrase),
- NULL, NULL, NULL);
- if (local != NULL) {
- puts(local);
- memset(local, '\0', strlen(local));
- g_free(local);
- } else {
- puts(passphrase);
+ if (prompt_type == PROMPT_ENTRY) {
+ passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
+ if (result == GTK_RESPONSE_OK) {
+ local = g_locale_from_utf8(passphrase,
+ strlen(passphrase), NULL, NULL, NULL);
+ if (local != NULL) {
+ puts(local);
+ memset(local, '\0', strlen(local));
+ g_free(local);
+ } else {
+ puts(passphrase);
+ }
}
+ /* Zero passphrase in memory */
+ memset(passphrase, '\b', strlen(passphrase));
+ gtk_entry_set_text(GTK_ENTRY(entry), passphrase);
+ memset(passphrase, '\0', strlen(passphrase));
+ g_free(passphrase);
}
-
- /* Zero passphrase in memory */
- memset(passphrase, '\b', strlen(passphrase));
- gtk_entry_set_text(GTK_ENTRY(entry), passphrase);
- memset(passphrase, '\0', strlen(passphrase));
- g_free(passphrase);
-
+
gtk_widget_destroy(dialog);
- return (result == GTK_RESPONSE_OK ? 0 : -1);
+ if (result != GTK_RESPONSE_OK && result != GTK_RESPONSE_YES)
+ return -1;
+ return 0;
- /* At least one grab failed - ungrab what we got, and report
- the failure to the user. Note that XGrabServer() cannot
- fail. */
nograbkb:
+ /*
+ * At least one grab failed - ungrab what we got, and report
+ * the failure to the user. Note that XGrabServer() cannot
+ * fail.
+ */
gdk_pointer_ungrab(GDK_CURRENT_TIME);
nograb:
if (grab_server)
@@ -206,8 +228,8 @@ passphrase_dialog(char *message)
int
main(int argc, char **argv)
{
- char *message;
- int result;
+ char *message, *prompt_mode;
+ int result, prompt_type = PROMPT_ENTRY;
gtk_init(&argc, &argv);
@@ -217,8 +239,15 @@ main(int argc, char **argv)
message = g_strdup("Enter your OpenSSH passphrase:");
}
+ if ((prompt_mode = getenv("SSH_ASKPASS_PROMPT")) != NULL) {
+ if (strcasecmp(prompt_mode, "confirm") == 0)
+ prompt_type = PROMPT_CONFIRM;
+ else if (strcasecmp(prompt_mode, "none") == 0)
+ prompt_type = PROMPT_NONE;
+ }
+
setvbuf(stdout, 0, _IONBF, 0);
- result = passphrase_dialog(message);
+ result = passphrase_dialog(message, prompt_type);
g_free(message);
return (result);