~network-manager/network-manager/ubuntu.hardy.07

« back to all changes in this revision

Viewing changes to vpn-daemons/vpnc/auth-dialog/main.c

* merge 0.7~~svn20080905t025540+eni0 snapshot to hardy branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
1
2
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
2
3
 *
3
4
 * Dan Williams <dcbw@redhat.com>
16
17
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
19
 *
19
 
 * (C) Copyright 2004 Red Hat, Inc.
 
20
 * (C) Copyright 2004 - 2008 Red Hat, Inc.
20
21
 */
21
22
 
22
23
#ifdef HAVE_CONFIG_H
26
27
#include <string.h>
27
28
#include <glib/gi18n.h>
28
29
#include <gtk/gtk.h>
29
 
#include <libgnomeui/libgnomeui.h>
30
30
#include <gnome-keyring.h>
 
31
#include <gnome-keyring-memory.h>
31
32
 
32
33
#include <nm-setting-vpn.h>
33
34
 
34
 
#include "../src/nm-vpnc-service.h"
 
35
#include "common-gnome/keyring-helpers.h"
 
36
#include "src/nm-vpnc-service.h"
35
37
#include "gnome-two-password-dialog.h"
36
38
 
37
 
#define KEYRING_CID_TAG "connection-id"
 
39
#define KEYRING_UUID_TAG "connection-uuid"
38
40
#define KEYRING_SN_TAG "setting-name"
39
41
#define KEYRING_SK_TAG "setting-key"
40
42
 
41
 
static char *
42
 
find_one_password (const char *vpn_id,
43
 
                   const char *vpn_name,
44
 
                   const char *vpn_service,
45
 
                   const char *secret_name,
46
 
                   gboolean *is_session)
47
 
{
48
 
        GList *found_list = NULL;
49
 
        GnomeKeyringResult ret;
50
 
        GnomeKeyringFound *found;
51
 
        char *secret;
52
 
 
53
 
        ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
54
 
                                              &found_list,
55
 
                                              KEYRING_CID_TAG,
56
 
                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
57
 
                                              vpn_id,
58
 
                                              KEYRING_SN_TAG,
59
 
                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
60
 
                                              NM_SETTING_VPN_SETTING_NAME,
61
 
                                              KEYRING_SK_TAG,
62
 
                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
63
 
                                              secret_name,
64
 
                                              NULL);
65
 
        if ((ret != GNOME_KEYRING_RESULT_OK) || (g_list_length (found_list) == 0))
66
 
                return NULL;
67
 
 
68
 
        found = (GnomeKeyringFound *) found_list->data;
69
 
 
70
 
        if (strcmp (found->keyring, "session") == 0)
71
 
                *is_session = TRUE;
72
 
        else
73
 
                *is_session = FALSE;
74
 
 
75
 
        secret = found->secret ? g_strdup (found->secret) : NULL;
76
 
        gnome_keyring_found_list_free (found_list);
77
 
 
78
 
        return secret;
79
 
}
80
 
 
81
 
static GSList *
82
 
lookup_pass (const char *vpn_id, const char *vpn_name, const char *vpn_service, gboolean *is_session)
83
 
{
84
 
        GSList *passwords = NULL;
85
 
        char *password;
86
 
        char *group_password;
87
 
 
88
 
        password = find_one_password (vpn_id, vpn_name, vpn_service, "password", is_session);
89
 
        if (!password)
90
 
                return NULL;
91
 
 
92
 
        group_password = find_one_password (vpn_id, vpn_name, vpn_service, "group-password", is_session);
93
 
        if (!group_password) {
94
 
                g_free (password);
95
 
                return NULL;
96
 
        }
97
 
 
98
 
        /* Group password first */
99
 
        passwords = g_slist_append (passwords, group_password);
100
 
        passwords = g_slist_append (passwords, password);
101
 
        return passwords;
102
 
}
103
 
 
104
 
static void
105
 
save_vpn_password (const char *vpn_id,
106
 
                   const char *vpn_name,
107
 
                   const char *vpn_service,
108
 
                   const char *keyring,
109
 
                   const char *secret_name,
110
 
                   const char *secret)
111
 
{
112
 
        char *display_name;
113
 
        GnomeKeyringResult ret;
114
 
        GnomeKeyringAttributeList *attrs = NULL;
115
 
        guint32 id = 0;
116
 
 
117
 
        display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_SETTING_NAME,
118
 
                                        secret_name,
119
 
                                        vpn_name,
120
 
                                        vpn_service);
121
 
 
122
 
        attrs = gnome_keyring_attribute_list_new ();
123
 
        gnome_keyring_attribute_list_append_string (attrs,
124
 
                                                    KEYRING_CID_TAG,
125
 
                                                    vpn_id);
126
 
        gnome_keyring_attribute_list_append_string (attrs,
127
 
                                                    KEYRING_SN_TAG,
128
 
                                                    NM_SETTING_VPN_SETTING_NAME);
129
 
        gnome_keyring_attribute_list_append_string (attrs,
130
 
                                                    KEYRING_SK_TAG,
131
 
                                                    secret_name);
132
 
 
133
 
        ret = gnome_keyring_item_create_sync (keyring,
134
 
                                              GNOME_KEYRING_ITEM_GENERIC_SECRET,
135
 
                                              display_name,
136
 
                                              attrs,
137
 
                                              secret,
138
 
                                              TRUE,
139
 
                                              &id);
140
 
        gnome_keyring_attribute_list_free (attrs);
141
 
        g_free (display_name);
142
 
}
143
 
 
144
 
static GSList *
145
 
get_passwords (const char *vpn_id,
146
 
               const char *vpn_name,
147
 
               const char *vpn_service,
148
 
               gboolean retry)
149
 
{
150
 
        GSList          *result;
151
 
        char            *prompt;
152
 
        GtkWidget       *dialog;
153
 
        char            *keyring_password;
154
 
        char            *keyring_group_password;
155
 
        gboolean         keyring_is_session;
156
 
        GSList          *keyring_result;
157
 
        GnomeTwoPasswordDialogRemember remember;
158
 
 
159
 
        result = NULL;
160
 
        keyring_password = NULL;
161
 
        keyring_group_password = NULL;
162
 
        keyring_result = NULL;
163
 
 
164
 
        g_return_val_if_fail (vpn_id != NULL, NULL);
165
 
        g_return_val_if_fail (vpn_name != NULL, NULL);
166
 
 
167
 
        /* Use the system user name, since the VPN might have a different user name */
168
 
        if (!retry) {
169
 
                if ((result = lookup_pass (vpn_id, vpn_name, vpn_service, &keyring_is_session)) != NULL) {
170
 
                        return result;
171
 
                }
172
 
        } else {
173
 
                if ((keyring_result = lookup_pass (vpn_id, vpn_name, vpn_service, &keyring_is_session)) != NULL) {
174
 
                        keyring_group_password = g_strdup ((char *) keyring_result->data);
175
 
                        keyring_password = g_strdup ((char *) (g_slist_next (keyring_result))->data);
176
 
                }
177
 
                g_slist_foreach (keyring_result, (GFunc)g_free, NULL);
178
 
                g_slist_free (keyring_result);
179
 
        }
 
43
static gboolean
 
44
get_secrets (const char *vpn_uuid,
 
45
             const char *vpn_name,
 
46
             const char *vpn_service,
 
47
             gboolean retry,
 
48
             char **password,
 
49
             char **group_password)
 
50
{
 
51
        GnomeTwoPasswordDialog *dialog;
 
52
        gboolean is_session = TRUE;
 
53
        gboolean found;
 
54
        char *prompt;
 
55
 
 
56
        g_return_val_if_fail (vpn_uuid != NULL, FALSE);
 
57
        g_return_val_if_fail (vpn_name != NULL, FALSE);
 
58
        g_return_val_if_fail (password != NULL, FALSE);
 
59
        g_return_val_if_fail (*password == NULL, FALSE);
 
60
        g_return_val_if_fail (group_password != NULL, FALSE);
 
61
        g_return_val_if_fail (*group_password == NULL, FALSE);
 
62
 
 
63
        found = keyring_helpers_lookup_secrets (vpn_uuid, password, group_password, &is_session);
 
64
        if (!retry && found && *password && *group_password)
 
65
                return TRUE;
180
66
 
181
67
        prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."), vpn_name);
182
 
        dialog = gnome_two_password_dialog_new (_("Authenticate VPN"), prompt, NULL, NULL, FALSE);
 
68
        dialog = GNOME_TWO_PASSWORD_DIALOG (gnome_two_password_dialog_new (_("Authenticate VPN"), prompt, NULL, NULL, FALSE));
183
69
        g_free (prompt);
184
70
 
185
 
        gnome_two_password_dialog_set_show_username (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
186
 
        gnome_two_password_dialog_set_show_userpass_buttons (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
187
 
        gnome_two_password_dialog_set_show_domain (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
188
 
        gnome_two_password_dialog_set_show_remember (GNOME_TWO_PASSWORD_DIALOG (dialog), TRUE);
189
 
        gnome_two_password_dialog_set_password_secondary_label (GNOME_TWO_PASSWORD_DIALOG (dialog), _("_Group Password:"));
190
 
        /* use the same keyring storage options as from the items we put in the entry boxes */
191
 
        remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING;
192
 
        if (keyring_result != NULL) {
193
 
                if (keyring_is_session)
194
 
                        remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION;
 
71
        gnome_two_password_dialog_set_show_username (dialog, FALSE);
 
72
        gnome_two_password_dialog_set_show_userpass_buttons (dialog, FALSE);
 
73
        gnome_two_password_dialog_set_show_domain (dialog, FALSE);
 
74
        gnome_two_password_dialog_set_show_remember (dialog, TRUE);
 
75
        gnome_two_password_dialog_set_password_secondary_label (dialog, _("_Group Password:"));
 
76
 
 
77
        /* If nothing was found in the keyring, default to not remembering any secrets */
 
78
        if (found) {
 
79
                /* Otherwise set default remember based on which keyring the secrets were found in */
 
80
                if (is_session)
 
81
                        gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION);
195
82
                else
196
 
                        remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER;                          
197
 
        }
198
 
        gnome_two_password_dialog_set_remember (GNOME_TWO_PASSWORD_DIALOG (dialog), remember);
199
 
 
200
 
        /* if retrying, put in the passwords from the keyring */
201
 
        if (keyring_password != NULL) {
202
 
                gnome_two_password_dialog_set_password (GNOME_TWO_PASSWORD_DIALOG (dialog), keyring_password);
203
 
        }
204
 
        if (keyring_group_password != NULL) {
205
 
                gnome_two_password_dialog_set_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog), keyring_group_password);
206
 
        }
207
 
 
208
 
        gtk_widget_show (dialog);
209
 
 
210
 
        if (gnome_two_password_dialog_run_and_block (GNOME_TWO_PASSWORD_DIALOG (dialog)))
211
 
        {
212
 
                char *password;
213
 
                char *group_password;
214
 
 
215
 
                password = gnome_two_password_dialog_get_password (GNOME_TWO_PASSWORD_DIALOG (dialog));
216
 
                group_password = gnome_two_password_dialog_get_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog));
217
 
                result = g_slist_append (result, group_password);
218
 
                result = g_slist_append (result, password);
219
 
 
220
 
                switch (gnome_two_password_dialog_get_remember (GNOME_TWO_PASSWORD_DIALOG (dialog)))
221
 
                {
222
 
                        case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION:
223
 
                                save_vpn_password (vpn_id, vpn_name, vpn_service, "session", "password", password);
224
 
                                save_vpn_password (vpn_id, vpn_name, vpn_service, "session", "group-password", group_password);
225
 
                                break;
226
 
                        case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER:
227
 
                                save_vpn_password (vpn_id, vpn_name, vpn_service, NULL, "password", password);
228
 
                                save_vpn_password (vpn_id, vpn_name, vpn_service, NULL, "group-password", group_password);
229
 
                                break;
230
 
                        default:
231
 
                                break;
 
83
                        gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER);
 
84
        } else
 
85
                gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING);
 
86
 
 
87
        /* if retrying, pre-fill dialog with the password */
 
88
        if (*password) {
 
89
                gnome_two_password_dialog_set_password (dialog, *password);
 
90
                gnome_keyring_memory_free (*password);
 
91
                *password = NULL;
 
92
        }
 
93
        if (*group_password) {
 
94
                gnome_two_password_dialog_set_password_secondary (dialog, *group_password);
 
95
                gnome_keyring_memory_free (*group_password);
 
96
                *group_password = NULL;
 
97
        }
 
98
 
 
99
        gtk_widget_show (GTK_WIDGET (dialog));
 
100
 
 
101
        if (gnome_two_password_dialog_run_and_block (dialog)) {
 
102
                *password = gnome_two_password_dialog_get_password (dialog);
 
103
                *group_password = gnome_two_password_dialog_get_password_secondary (dialog);
 
104
 
 
105
                switch (gnome_two_password_dialog_get_remember (dialog)) {
 
106
                case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION:
 
107
                        keyring_helpers_save_secret (vpn_uuid, vpn_name, vpn_service, "session", "password", *password);
 
108
                        keyring_helpers_save_secret (vpn_uuid, vpn_name, vpn_service, "session", "group-password", *group_password);
 
109
                        break;
 
110
                case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER:
 
111
                        keyring_helpers_save_secret (vpn_uuid, vpn_name, vpn_service, NULL, "password", *password);
 
112
                        keyring_helpers_save_secret (vpn_uuid, vpn_name, vpn_service, NULL, "group-password", *group_password);
 
113
                        break;
 
114
                default:
 
115
                        break;
232
116
                }
233
117
 
234
118
        }
235
119
 
236
 
        g_free (keyring_password);
237
 
        g_free (keyring_group_password);
238
 
 
239
 
        gtk_widget_destroy (dialog);
240
 
 
241
 
        return result;
 
120
        gtk_widget_hide (GTK_WIDGET (dialog));
 
121
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
122
 
 
123
        return TRUE;
242
124
}
243
125
 
244
126
int 
245
127
main (int argc, char *argv[])
246
128
{
247
 
        GSList *passwords;
248
 
        static gboolean retry = FALSE;
249
 
        static gchar *vpn_name = NULL;
250
 
        static gchar *vpn_id = NULL;
251
 
        static gchar *vpn_service = NULL;
 
129
        gboolean retry = FALSE;
 
130
        gchar *vpn_name = NULL;
 
131
        gchar *vpn_uuid = NULL;
 
132
        gchar *vpn_service = NULL;
 
133
        char *password = NULL, *group_password = NULL;
252
134
        char buf[1];
253
135
        int ret;
 
136
        GError *error = NULL;
254
137
        GOptionContext *context;
255
 
        GnomeProgram *program;
256
 
        GOptionEntry entries[] =
257
 
                {
 
138
        GOptionEntry entries[] = {
258
139
                        { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
259
 
                        { "id", 'i', 0, G_OPTION_ARG_STRING, &vpn_id, "ID of VPN connection", NULL},
 
140
                        { "uuid", 'u', 0, G_OPTION_ARG_STRING, &vpn_uuid, "UUID of VPN connection", NULL},
260
141
                        { "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL},
261
142
                        { "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL},
262
143
                        { NULL }
264
145
 
265
146
        bindtextdomain (GETTEXT_PACKAGE, NULL);
266
147
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
148
        gtk_init (&argc, &argv);
267
149
        textdomain (GETTEXT_PACKAGE);
268
150
 
269
 
        passwords = NULL;
270
 
        
271
151
        context = g_option_context_new ("- vpnc auth dialog");
272
152
        g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
273
 
        
274
 
        program = gnome_program_init ("nm-vpnc-auth-dialog", VERSION,
275
 
                                      LIBGNOMEUI_MODULE,
276
 
                                      argc, argv,
277
 
                                      GNOME_PARAM_GOPTION_CONTEXT, context,
278
 
                                      GNOME_PARAM_NONE);
279
 
          
280
 
 
281
 
        if (vpn_id == NULL || vpn_name == NULL || vpn_service == NULL) {
282
 
                fprintf (stderr, "Have to supply ID, name, and service\n");
283
 
                goto out;
 
153
 
 
154
        if (!g_option_context_parse (context, &argc, &argv, &error)) {
 
155
                g_warning ("Error parsing options: %s\n", error->message);
 
156
                g_error_free (error);
 
157
                return 1;
 
158
        }
 
159
 
 
160
        g_option_context_free (context);
 
161
 
 
162
        if (vpn_uuid == NULL || vpn_name == NULL || vpn_service == NULL) {
 
163
                fprintf (stderr, "Have to supply UUID, name, and service\n");
 
164
                return 1;
284
165
        }
285
166
 
286
167
        if (strcmp (vpn_service, NM_DBUS_SERVICE_VPNC) != 0) {
287
168
                fprintf (stderr, "This dialog only works with the '%s' service\n", NM_DBUS_SERVICE_VPNC);
288
 
                goto out;               
 
169
                return 1;
289
170
        }
290
171
 
291
 
        passwords = get_passwords (vpn_id, vpn_name, vpn_service, retry);
292
 
        if (passwords == NULL)
293
 
                goto out;
 
172
        if (!get_secrets (vpn_uuid, vpn_name, vpn_service, retry, &password, &group_password))
 
173
                return 1;
294
174
 
295
175
        /* dump the passwords to stdout */
296
 
 
297
 
        printf ("%s\n%s\n", NM_VPNC_KEY_SECRET, (char *) passwords->data);
298
 
        printf ("%s\n%s\n", NM_VPNC_KEY_XAUTH_PASSWORD, (char *) passwords->next->data);
 
176
        printf ("%s\n%s\n", NM_VPNC_KEY_XAUTH_PASSWORD, password);
 
177
        printf ("%s\n%s\n", NM_VPNC_KEY_SECRET, group_password);
299
178
        printf ("\n\n");
300
179
 
 
180
        if (password) {
 
181
                memset (password, 0, strlen (password));
 
182
                gnome_keyring_memory_free (password);
 
183
        }
 
184
        if (group_password) {
 
185
                memset (group_password, 0, strlen (group_password));
 
186
                gnome_keyring_memory_free (group_password);
 
187
        }
 
188
 
301
189
        /* for good measure, flush stdout since Kansas is going Bye-Bye */
302
190
        fflush (stdout);
303
191
 
304
 
        g_slist_foreach (passwords, (GFunc)g_free, NULL);
305
 
        g_slist_free (passwords);
306
 
 
307
192
        /* wait for data on stdin  */
308
193
        ret = fread (buf, sizeof (char), sizeof (buf), stdin);
309
 
 
310
 
out:
311
 
        g_object_unref (program);
312
 
 
313
 
        return passwords != NULL ? 0 : 1;
 
194
        return 0;
314
195
}