2 * Copyright (c) 2000-2002 Damien Miller. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * This is a simple GNOME SSH passphrase grabber. To use it, set the
27 * environment variable SSH_ASKPASS to point to the location of
28 * gnome-ssh-askpass before calling "ssh-add < /dev/null".
30 * There is only two run-time options: if you set the environment variable
31 * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab
32 * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the
33 * pointer will be grabbed too. These may have some benefit to security if
34 * you don't trust your X server. We grab the keyboard always.
40 * cc `gnome-config --cflags gnome gnomeui` \
41 * gnome-ssh-askpass1.c -o gnome-ssh-askpass \
42 * `gnome-config --libs gnome gnomeui`
54 report_failed_grab (void)
58 err
= gnome_message_box_new("Could not grab keyboard or mouse.\n"
59 "A malicious client may be eavesdropping on your session.",
60 GNOME_MESSAGE_BOX_ERROR
, "EXIT", NULL
);
61 gtk_window_set_position(GTK_WINDOW(err
), GTK_WIN_POS_CENTER
);
62 gtk_object_set(GTK_OBJECT(err
), "type", GTK_WINDOW_POPUP
, NULL
);
64 gnome_dialog_run_and_close(GNOME_DIALOG(err
));
68 passphrase_dialog(char *message
)
72 int result
, i
, grab_server
, grab_pointer
;
73 GtkWidget
*dialog
, *entry
, *label
;
75 grab_server
= (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL
);
76 grab_pointer
= (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL
);
78 dialog
= gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK
,
79 GNOME_STOCK_BUTTON_CANCEL
, NULL
);
81 messages
= g_strsplit(message
, "\\n", 0);
83 for(i
= 0; messages
[i
]; i
++) {
84 label
= gtk_label_new(messages
[i
]);
85 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog
)->vbox
),
86 label
, FALSE
, FALSE
, 0);
89 entry
= gtk_entry_new();
90 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog
)->vbox
), entry
, FALSE
,
92 gtk_entry_set_visibility(GTK_ENTRY(entry
), FALSE
);
93 gtk_widget_grab_focus(entry
);
95 /* Center window and prepare for grab */
96 gtk_object_set(GTK_OBJECT(dialog
), "type", GTK_WINDOW_POPUP
, NULL
);
97 gnome_dialog_set_default(GNOME_DIALOG(dialog
), 0);
98 gtk_window_set_position (GTK_WINDOW(dialog
), GTK_WIN_POS_CENTER
);
99 gtk_window_set_policy(GTK_WINDOW(dialog
), FALSE
, FALSE
, TRUE
);
100 gnome_dialog_close_hides(GNOME_DIALOG(dialog
), TRUE
);
101 gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog
)->vbox
),
103 gtk_widget_show_all(dialog
);
107 XGrabServer(GDK_DISPLAY());
108 if (grab_pointer
&& gdk_pointer_grab(dialog
->window
, TRUE
, 0,
109 NULL
, NULL
, GDK_CURRENT_TIME
))
111 if (gdk_keyboard_grab(dialog
->window
, FALSE
, GDK_CURRENT_TIME
))
114 /* Make <enter> close dialog */
115 gnome_dialog_editable_enters(GNOME_DIALOG(dialog
), GTK_EDITABLE(entry
));
118 result
= gnome_dialog_run(GNOME_DIALOG(dialog
));
122 XUngrabServer(GDK_DISPLAY());
124 gdk_pointer_ungrab(GDK_CURRENT_TIME
);
125 gdk_keyboard_ungrab(GDK_CURRENT_TIME
);
128 /* Report passphrase if user selected OK */
129 passphrase
= gtk_entry_get_text(GTK_ENTRY(entry
));
133 /* Zero passphrase in memory */
134 memset(passphrase
, '\0', strlen(passphrase
));
135 gtk_entry_set_text(GTK_ENTRY(entry
), passphrase
);
137 gnome_dialog_close(GNOME_DIALOG(dialog
));
138 return (result
== 0 ? 0 : -1);
140 /* At least one grab failed - ungrab what we got, and report
141 the failure to the user. Note that XGrabServer() cannot
144 gdk_pointer_ungrab(GDK_CURRENT_TIME
);
147 XUngrabServer(GDK_DISPLAY());
148 gnome_dialog_close(GNOME_DIALOG(dialog
));
150 report_failed_grab();
155 main(int argc
, char **argv
)
160 gnome_init("GNOME ssh-askpass", "0.1", argc
, argv
);
165 message
= "Enter your OpenSSH passphrase:";
167 setvbuf(stdout
, 0, _IONBF
, 0);
168 result
= passphrase_dialog(message
);