|
Lines 23-39
Link Here
|
| 23 |
*/ |
23 |
*/ |
| 24 |
|
24 |
|
| 25 |
/* GTK2 support by Nalin Dahyabhai <nalin@redhat.com> */ |
25 |
/* GTK2 support by Nalin Dahyabhai <nalin@redhat.com> */ |
|
|
26 |
/* SSH_ASKPASS_CONFIRMATION_ONLY support by |
| 27 |
Daniel Kahn Gillmor <dkg@fifthhorseman.net> */ |
| 26 |
|
28 |
|
| 27 |
/* |
29 |
/* |
| 28 |
* This is a simple GNOME SSH passphrase grabber. To use it, set the |
30 |
* This is a simple GNOME SSH passphrase grabber. To use it, set the |
| 29 |
* environment variable SSH_ASKPASS to point to the location of |
31 |
* environment variable SSH_ASKPASS to point to the location of |
| 30 |
* gnome-ssh-askpass before calling "ssh-add < /dev/null". |
32 |
* gnome-ssh-askpass before calling "ssh-add < /dev/null". |
| 31 |
* |
33 |
* |
| 32 |
* There is only two run-time options: if you set the environment variable |
34 |
* if SSH_ASKPASS_CONFIRMATION_ONLY is set, then no text input will be |
|
|
35 |
* displayed, and the keyboard, mouse, and X server will not be "grabbed". |
| 36 |
* |
| 37 |
* There are two more run-time options: if you set the environment variable |
| 33 |
* "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab |
38 |
* "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab |
| 34 |
* the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the |
39 |
* the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the |
| 35 |
* pointer will be grabbed too. These may have some benefit to security if |
40 |
* pointer will be grabbed too. These may have some benefit to security if |
| 36 |
* you don't trust your X server. We grab the keyboard always. |
41 |
* you don't trust your X server. We always grab the keyboard unless this |
|
|
42 |
* is just a confirmation prompt. |
| 37 |
*/ |
43 |
*/ |
| 38 |
|
44 |
|
| 39 |
#define GRAB_TRIES 16 |
45 |
#define GRAB_TRIES 16 |
|
Lines 88-103
Link Here
|
| 88 |
{ |
94 |
{ |
| 89 |
const char *failed; |
95 |
const char *failed; |
| 90 |
char *passphrase, *local; |
96 |
char *passphrase, *local; |
| 91 |
int result, grab_tries, grab_server, grab_pointer; |
97 |
int result, grab_tries, grab_server, grab_pointer, confirmation_only; |
| 92 |
GtkWidget *dialog, *entry; |
98 |
GtkWidget *dialog, *entry; |
| 93 |
GdkGrabStatus status; |
99 |
GdkGrabStatus status; |
| 94 |
|
100 |
|
| 95 |
grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); |
101 |
grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); |
| 96 |
grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); |
102 |
grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); |
|
|
103 |
confirmation_only = (getenv("SSH_ASKPASS_CONFIRMATION_ONLY") != NULL); |
| 97 |
grab_tries = 0; |
104 |
grab_tries = 0; |
| 98 |
|
105 |
|
| 99 |
dialog = gtk_message_dialog_new(NULL, 0, |
106 |
dialog = gtk_message_dialog_new(NULL, 0, |
| 100 |
GTK_MESSAGE_QUESTION, |
107 |
GTK_MESSAGE_QUESTION, |
|
|
108 |
confirmation_only ? |
| 109 |
GTK_BUTTONS_YES_NO : |
| 101 |
GTK_BUTTONS_OK_CANCEL, |
110 |
GTK_BUTTONS_OK_CANCEL, |
| 102 |
"%s", |
111 |
"%s", |
| 103 |
message); |
112 |
message); |
|
Lines 105-113
Link Here
|
| 105 |
entry = gtk_entry_new(); |
114 |
entry = gtk_entry_new(); |
| 106 |
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, |
115 |
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, |
| 107 |
FALSE, 0); |
116 |
FALSE, 0); |
| 108 |
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); |
117 |
if (!confirmation_only) { |
| 109 |
gtk_widget_grab_focus(entry); |
118 |
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); |
| 110 |
gtk_widget_show(entry); |
119 |
gtk_widget_grab_focus(entry); |
|
|
120 |
gtk_widget_show(entry); |
| 121 |
} |
| 111 |
|
122 |
|
| 112 |
gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); |
123 |
gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); |
| 113 |
gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); |
124 |
gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); |
|
Lines 116-122
Link Here
|
| 116 |
TRUE); |
127 |
TRUE); |
| 117 |
|
128 |
|
| 118 |
/* Make <enter> close dialog */ |
129 |
/* Make <enter> close dialog */ |
| 119 |
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); |
130 |
gtk_dialog_set_default_response(GTK_DIALOG(dialog), confirmation_only ? GTK_RESPONSE_YES : GTK_RESPONSE_OK); |
| 120 |
g_signal_connect(G_OBJECT(entry), "activate", |
131 |
g_signal_connect(G_OBJECT(entry), "activate", |
| 121 |
G_CALLBACK(ok_dialog), dialog); |
132 |
G_CALLBACK(ok_dialog), dialog); |
| 122 |
|
133 |
|
|
Lines 124-171
Link Here
|
| 124 |
|
135 |
|
| 125 |
/* Grab focus */ |
136 |
/* Grab focus */ |
| 126 |
gtk_widget_show_now(dialog); |
137 |
gtk_widget_show_now(dialog); |
| 127 |
if (grab_pointer) { |
138 |
/* no need to grab focus for a confirmation prompt */ |
|
|
139 |
if (!confirmation_only) { |
| 140 |
if (grab_pointer) { |
| 141 |
for(;;) { |
| 142 |
status = gdk_pointer_grab( |
| 143 |
(GTK_WIDGET(dialog))->window, TRUE, 0, NULL, |
| 144 |
NULL, GDK_CURRENT_TIME); |
| 145 |
if (status == GDK_GRAB_SUCCESS) |
| 146 |
break; |
| 147 |
usleep(GRAB_WAIT * 1000); |
| 148 |
if (++grab_tries > GRAB_TRIES) { |
| 149 |
failed = "mouse"; |
| 150 |
goto nograb; |
| 151 |
} |
| 152 |
} |
| 153 |
} |
| 128 |
for(;;) { |
154 |
for(;;) { |
| 129 |
status = gdk_pointer_grab( |
155 |
status = gdk_keyboard_grab((GTK_WIDGET(dialog))->window, |
| 130 |
(GTK_WIDGET(dialog))->window, TRUE, 0, NULL, |
156 |
FALSE, GDK_CURRENT_TIME); |
| 131 |
NULL, GDK_CURRENT_TIME); |
|
|
| 132 |
if (status == GDK_GRAB_SUCCESS) |
157 |
if (status == GDK_GRAB_SUCCESS) |
| 133 |
break; |
158 |
break; |
| 134 |
usleep(GRAB_WAIT * 1000); |
159 |
usleep(GRAB_WAIT * 1000); |
| 135 |
if (++grab_tries > GRAB_TRIES) { |
160 |
if (++grab_tries > GRAB_TRIES) { |
| 136 |
failed = "mouse"; |
161 |
failed = "keyboard"; |
| 137 |
goto nograb; |
162 |
goto nograbkb; |
| 138 |
} |
163 |
} |
| 139 |
} |
164 |
} |
| 140 |
} |
165 |
if (grab_server) { |
| 141 |
for(;;) { |
166 |
gdk_x11_grab_server(); |
| 142 |
status = gdk_keyboard_grab((GTK_WIDGET(dialog))->window, |
|
|
| 143 |
FALSE, GDK_CURRENT_TIME); |
| 144 |
if (status == GDK_GRAB_SUCCESS) |
| 145 |
break; |
| 146 |
usleep(GRAB_WAIT * 1000); |
| 147 |
if (++grab_tries > GRAB_TRIES) { |
| 148 |
failed = "keyboard"; |
| 149 |
goto nograbkb; |
| 150 |
} |
167 |
} |
| 151 |
} |
168 |
} |
| 152 |
if (grab_server) { |
|
|
| 153 |
gdk_x11_grab_server(); |
| 154 |
} |
| 155 |
|
169 |
|
| 156 |
result = gtk_dialog_run(GTK_DIALOG(dialog)); |
170 |
result = gtk_dialog_run(GTK_DIALOG(dialog)); |
| 157 |
|
171 |
|
| 158 |
/* Ungrab */ |
172 |
/* Ungrab */ |
| 159 |
if (grab_server) |
173 |
if (!confirmation_only) { |
| 160 |
XUngrabServer(GDK_DISPLAY()); |
174 |
if (grab_server) |
| 161 |
if (grab_pointer) |
175 |
XUngrabServer(GDK_DISPLAY()); |
| 162 |
gdk_pointer_ungrab(GDK_CURRENT_TIME); |
176 |
if (grab_pointer) |
| 163 |
gdk_keyboard_ungrab(GDK_CURRENT_TIME); |
177 |
gdk_pointer_ungrab(GDK_CURRENT_TIME); |
|
|
178 |
gdk_keyboard_ungrab(GDK_CURRENT_TIME); |
| 179 |
} |
| 164 |
gdk_flush(); |
180 |
gdk_flush(); |
| 165 |
|
181 |
|
| 166 |
/* Report passphrase if user selected OK */ |
182 |
/* Report passphrase if user selected OK */ |
| 167 |
passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); |
183 |
passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); |
| 168 |
if (result == GTK_RESPONSE_OK) { |
184 |
if (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_YES) { |
| 169 |
local = g_locale_from_utf8(passphrase, strlen(passphrase), |
185 |
local = g_locale_from_utf8(passphrase, strlen(passphrase), |
| 170 |
NULL, NULL, NULL); |
186 |
NULL, NULL, NULL); |
| 171 |
if (local != NULL) { |
187 |
if (local != NULL) { |
|
Lines 184-190
Link Here
|
| 184 |
g_free(passphrase); |
200 |
g_free(passphrase); |
| 185 |
|
201 |
|
| 186 |
gtk_widget_destroy(dialog); |
202 |
gtk_widget_destroy(dialog); |
| 187 |
return (result == GTK_RESPONSE_OK ? 0 : -1); |
203 |
return (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_YES ? 0 : -1); |
| 188 |
|
204 |
|
| 189 |
/* At least one grab failed - ungrab what we got, and report |
205 |
/* At least one grab failed - ungrab what we got, and report |
| 190 |
the failure to the user. Note that XGrabServer() cannot |
206 |
the failure to the user. Note that XGrabServer() cannot |