View | Details | Raw Unified | Return to bug 1871 | Differences between
and this patch

Collapse All | Expand All

(-)contrib/gnome-ssh-askpass2.c (-33 / +49 lines)
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

Return to bug 1871