1
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
3
* Dan Williams <dcbw@redhat.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
* (C) Copyright 2004 Red Hat, Inc.
27
#include <glade/glade.h>
29
#include <dbus/dbus.h>
30
#include <dbus/dbus-glib.h>
31
#include <glib/gi18n.h>
35
#include "vpn-password-dialog.h"
46
child_finished_cb (GPid pid, gint status, gpointer userdata)
48
int *child_status = (gboolean *) userdata;
50
*child_status = status;
54
child_stdout_data_cb (GIOChannel *source, GIOCondition condition, gpointer userdata)
57
IOUserData *io_user_data = (IOUserData *) userdata;
58
GSList **passwords = (GSList **) io_user_data->passwords;
60
if (! (condition & G_IO_IN))
63
if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) {
67
if (len == 1 && str[0] == '\n') {
69
/* on second line with a newline newline */
70
if (++io_user_data->num_newlines == 2) {
72
/* terminate the child */
73
if (write (io_user_data->child_stdin, buf, sizeof (buf)) == -1)
77
/* remove terminating newline */
79
*passwords = g_slist_append (*passwords, str);
91
nma_vpn_request_password (NMApplet *applet, const char *name, const char *service, gboolean retry)
93
const char *argv[] = {NULL /*"/usr/libexec/nm-vpnc-auth-dialog"*/,
94
"-n", NULL /*"davidznet42"*/,
95
"-s", NULL /*"org.freedesktop.vpnc"*/,
98
GSList *passwords = NULL;
103
GIOChannel *child_stdout_channel;
104
guint child_stdout_channel_eventid;
106
char *auth_dialog_binary;
107
IOUserData io_user_data;
109
auth_dialog_binary = NULL;
111
/* find the auth-dialog binary */
112
if ((dir = g_dir_open (VPN_NAME_FILES_DIR, 0, NULL)) != NULL) {
115
while (auth_dialog_binary == NULL && (f = g_dir_read_name (dir)) != NULL) {
119
if (!g_str_has_suffix (f, ".name"))
122
path = g_strdup_printf ("%s/%s", VPN_NAME_FILES_DIR, f);
124
keyfile = g_key_file_new ();
125
if (g_key_file_load_from_file (keyfile, path, 0, NULL)) {
128
if ((thisservice = g_key_file_get_string (keyfile,
130
"service", NULL)) != NULL &&
131
strcmp (thisservice, service) == 0) {
133
auth_dialog_binary = g_key_file_get_string (keyfile,
135
"auth-dialog", NULL);
138
g_free (thisservice);
140
g_key_file_free (keyfile);
146
if (auth_dialog_binary == NULL) {
147
/* could find auth-dialog */
150
dialog = gtk_message_dialog_new (NULL,
151
GTK_DIALOG_DESTROY_WITH_PARENT,
154
_("Cannot start VPN connection '%s'"),
156
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
157
_("Could not find the authentication dialog for VPN connection type '%s'. Contact your system administrator."),
159
gtk_window_present (GTK_WINDOW (dialog));
160
g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
164
/* Fix up parameters with what we got */
165
argv[0] = auth_dialog_binary;
173
if (!g_spawn_async_with_pipes (NULL, /* working_directory */
174
(gchar **) argv, /* argv */
176
G_SPAWN_DO_NOT_REAP_CHILD, /* flags */
177
NULL, /* child_setup */
178
NULL, /* user_data */
179
&child_pid, /* child_pid */
180
&child_stdin, /* standard_input */
181
&child_stdout, /* standard_output */
182
NULL, /* standard_error */
184
/* could not spawn */
187
dialog = gtk_message_dialog_new (NULL,
188
GTK_DIALOG_DESTROY_WITH_PARENT,
191
_("Cannot start VPN connection '%s'"),
193
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
194
_("There was a problem launching the authentication dialog for VPN connection type '%s'. Contact your system administrator."),
196
gtk_window_present (GTK_WINDOW (dialog));
197
g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
201
/* catch when child is reaped */
202
g_child_watch_add (child_pid, child_finished_cb, (gpointer) &child_status);
204
io_user_data.passwords = &passwords;
205
io_user_data.child_stdin = child_stdin;
206
io_user_data.num_newlines = 0;
208
/* listen to what child has to say */
209
child_stdout_channel = g_io_channel_unix_new (child_stdout);
210
child_stdout_channel_eventid = g_io_add_watch (child_stdout_channel, G_IO_IN, child_stdout_data_cb,
212
g_io_channel_set_encoding (child_stdout_channel, NULL, NULL);
214
/* recurse mainloop here until the child is finished (child_status is set in child_finished_cb) */
215
while (child_status == -1) {
216
g_main_context_iteration (NULL, TRUE);
219
g_spawn_close_pid (child_pid);
220
g_source_remove (child_stdout_channel_eventid);
221
g_io_channel_unref (child_stdout_channel);
223
if (child_status != 0) {
224
if (passwords != NULL) {
225
g_slist_foreach (passwords, (GFunc)g_free, NULL);
226
g_slist_free (passwords);
232
g_free (auth_dialog_binary);