From 44d5b60336e2233813083e254a9ca751b7f3c172 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 5 Sep 2002 16:46:24 +1000 Subject: - (djm) Add gnome-ssh-askpass2.c (gtk2) by merge with patch from Nalin Dahyabhai --- contrib/gnome-ssh-askpass2.c | 201 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 contrib/gnome-ssh-askpass2.c (limited to 'contrib/gnome-ssh-askpass2.c') diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c new file mode 100644 index 000000000..8cccf9e60 --- /dev/null +++ b/contrib/gnome-ssh-askpass2.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2000-2002 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* GTK2 support by Nalin Dahyabhai */ + +/* + * This is a simple GNOME SSH passphrase grabber. To use it, set the + * environment variable SSH_ASKPASS to point to the location of + * gnome-ssh-askpass before calling "ssh-add < /dev/null". + * + * There is only two run-time options: if you set the environment variable + * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab + * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the + * pointer will be grabbed too. These may have some benefit to security if + * you don't trust your X server. We grab the keyboard always. + */ + +/* + * Compile with: + * + * cc `pkg-config --cflags gtk+-2.0` \ + * gnome-ssh-askpass.c -o gnome-ssh-askpass \ + * `pkg-config --libs gtk+-2.0` + * + */ + +#include +#include +#include +#include +#include +#include + +static void +report_failed_grab (const char *what) +{ + GtkWidget *err; + + err = gtk_message_dialog_new(NULL, 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)); + + gtk_widget_destroy(err); +} + +static void +ok_dialog(GtkWidget *entry, gpointer dialog) +{ + g_return_if_fail(GTK_IS_DIALOG(dialog)); + gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); +} + +static void +passphrase_dialog(char *message) +{ + const char *failed; + char *passphrase, *local; + char **messages; + int result, i, grab_server, grab_pointer; + GtkWidget *dialog, *entry, *label; + GdkGrabStatus status; + + grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); + grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); + + dialog = gtk_message_dialog_new(NULL, 0, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_OK_CANCEL, + "%s", + message); + + 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); + + gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label), + TRUE); + + /* Make 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); + + /* Grab focus */ + gtk_widget_show_now(dialog); + if (grab_server) { + gdk_x11_grab_server(); + } + if (grab_pointer) { + status = gdk_pointer_grab((GTK_WIDGET(dialog))->window, TRUE, + 0, NULL, NULL, GDK_CURRENT_TIME); + if (status != GDK_GRAB_SUCCESS) { + failed = "mouse"; + goto nograb; + } + } + status = gdk_keyboard_grab((GTK_WIDGET(dialog))->window, FALSE, + GDK_CURRENT_TIME); + if (status != GDK_GRAB_SUCCESS) { + failed = "keyboard"; + goto nograbkb; + } + result = gtk_dialog_run(GTK_DIALOG(dialog)); + + /* Ungrab */ + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + 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); + } + } + + /* 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; + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + gtk_widget_destroy(dialog); + + report_failed_grab(failed); +} + +int +main(int argc, char **argv) +{ + char *message; + + gtk_init(&argc, &argv); + + if (argc > 1) { + message = g_strjoinv(" ", argv + 1); + } else { + message = g_strdup("Enter your OpenSSH passphrase:"); + } + + setvbuf(stdout, 0, _IONBF, 0); + passphrase_dialog(message); + g_free(message); + + return 0; +} -- cgit v1.2.3