[openssh-commits] [openssh] 01/01: Teach the GTK2/3 ssh-askpass the new prompt hints

git+noreply at mindrot.org git+noreply at mindrot.org
Mon Nov 18 15:22:43 AEDT 2019


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit b497e920b409250309c4abe64229237b8f2730ba
Author: Damien Miller <djm at mindrot.org>
Date:   Mon Nov 18 15:05:04 2019 +1100

    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.
---
 contrib/gnome-ssh-askpass2.c | 115 +++++++++++++++++++++++++++----------------
 1 file 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);

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list