summaryrefslogtreecommitdiff
path: root/contrib/gnome-ssh-askpass2.c
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2020-08-21 00:00:13 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-08-21 00:00:13 +0000
commited358b3546c776c1c677fd88eb8f716cf6187510 (patch)
tree3c6134bcb2cda4b9dccc57b4a8b997a945aab62d /contrib/gnome-ssh-askpass2.c
parent22246b08952d746a7cc5a292570636cf4277598f (diff)
parent44a1065de8a58c51a021243a28bfa01e87822e4f (diff)
Merge changes I934c73d4,I28cdc9a0,I9e734da9,I3c079d86
* changes: UPSTREAM: depend UPSTREAM: upstream: avoid possible NULL deref; from Pedro Martelletto Revert "upstream: fix compilation with DEBUG_KEXDH; bz#3160 ok dtucker@" Merge upstream-master into master
Diffstat (limited to 'contrib/gnome-ssh-askpass2.c')
-rw-r--r--contrib/gnome-ssh-askpass2.c143
1 files changed, 87 insertions, 56 deletions
diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
index 9d97c30c..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:
*
@@ -57,19 +61,17 @@
#include <gdk/gdkx.h>
static void
-report_failed_grab (const char *what)
+report_failed_grab (GtkWidget *parent_window, const char *what)
{
GtkWidget *err;
- err = gtk_message_dialog_new(NULL, 0,
+ err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Could not grab %s. "
"A malicious client may be eavesdropping "
"on your session.", what);
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
- gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label),
- TRUE);
gtk_dialog_run(GTK_DIALOG(err));
@@ -84,51 +86,67 @@ 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;
- GtkWidget *dialog, *entry;
+ int buttons, default_response;
+ GtkWidget *parent_window, *dialog, *entry;
GdkGrabStatus status;
grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL);
grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL);
grab_tries = 0;
- dialog = gtk_message_dialog_new(NULL, 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_OK_CANCEL,
- "%s",
- message);
+ /* Create an invisible parent window so that GtkDialog doesn't
+ * 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;
+ }
- entry = gtk_entry_new();
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE,
- FALSE, 0);
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
- gtk_widget_grab_focus(entry);
- gtk_widget_show(entry);
+ dialog = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
+ 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);
- gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label),
- 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) {
for(;;) {
status = gdk_pointer_grab(
- (GTK_WIDGET(dialog))->window, TRUE, 0, NULL,
- NULL, GDK_CURRENT_TIME);
+ (gtk_widget_get_window(GTK_WIDGET(dialog))), TRUE,
+ 0, NULL, NULL, GDK_CURRENT_TIME);
if (status == GDK_GRAB_SUCCESS)
break;
usleep(GRAB_WAIT * 1000);
@@ -139,8 +157,9 @@ passphrase_dialog(char *message)
}
}
for(;;) {
- status = gdk_keyboard_grab((GTK_WIDGET(dialog))->window,
- FALSE, GDK_CURRENT_TIME);
+ status = gdk_keyboard_grab(
+ gtk_widget_get_window(GTK_WIDGET(dialog)), FALSE,
+ GDK_CURRENT_TIME);
if (status == GDK_GRAB_SUCCESS)
break;
usleep(GRAB_WAIT * 1000);
@@ -157,46 +176,51 @@ passphrase_dialog(char *message)
/* Ungrab */
if (grab_server)
- XUngrabServer(GDK_DISPLAY());
+ XUngrabServer(gdk_x11_get_default_xdisplay());
if (grab_pointer)
gdk_pointer_ungrab(GDK_CURRENT_TIME);
gdk_keyboard_ungrab(GDK_CURRENT_TIME);
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)
- XUngrabServer(GDK_DISPLAY());
+ XUngrabServer(gdk_x11_get_default_xdisplay());
gtk_widget_destroy(dialog);
- report_failed_grab(failed);
+ report_failed_grab(parent_window, failed);
return (-1);
}
@@ -204,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);
@@ -215,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);