~ubuntu-branches/ubuntu/utopic/network-manager-openvpn/utopic

« back to all changes in this revision

Viewing changes to auth-dialog/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2009-02-25 10:43:09 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090225104309-v4b2scsl68protyn
Tags: 0.7.0.97-1
* New upstream release.
* debian/patches/01_dbus_policy.patch
  - Removed, merged upstream.
* debian/control
  - Drop libgnomeui-dev from Build-Depends, no longer required.

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>
13
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
15
 * GNU General Public License for more details.
15
16
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
17
 * You should have received a copy of the GNU General Public License along
 
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
 *
20
 
 * (C) Copyright 2004 Red Hat, Inc.
 
21
 * (C) Copyright 2004 - 2008 Red Hat, Inc.
21
22
 *               2005 Tim Niemueller [www.niemueller.de]
22
23
 */
23
24
 
26
27
#endif
27
28
 
28
29
#include <string.h>
 
30
#include <stdlib.h>
29
31
#include <glib/gi18n.h>
30
32
#include <gtk/gtk.h>
31
 
#include <libgnomeui/libgnomeui.h>
32
33
#include <gconf/gconf-client.h>
33
34
#include <gnome-keyring.h>
 
35
#include <nm-setting-vpn.h>
 
36
#include <nm-setting-connection.h>
34
37
 
 
38
#include "common-gnome/keyring-helpers.h"
 
39
#include "src/nm-openvpn-service.h"
35
40
#include "gnome-two-password-dialog.h"
36
41
 
37
 
#define VPN_SERVICE "org.freedesktop.NetworkManager.openvpn"
38
 
// MUST be the same as in gnome/applet/applet.h
39
 
// A real fix for this is needed by giving more information to auth apps
40
 
#define GCONF_PATH_VPN_CONNECTIONS "/system/networking/vpn_connections"
41
 
 
42
 
static GSList *
43
 
lookup_pass (const char *vpn_name, const char *vpn_service, gboolean *is_session)
44
 
{
45
 
  GSList *passwords;
46
 
  GList *keyring_result;
47
 
  GList *keyring_i;
48
 
 
49
 
  char *password = NULL;
50
 
  char *certpass = NULL;
51
 
 
52
 
  passwords = NULL;
53
 
 
54
 
  if (gnome_keyring_find_network_password_sync (g_get_user_name (),     /* user */
55
 
                                                NULL,                   /* domain */
56
 
                                                vpn_name,               /* server */
57
 
                                                NULL,                   /* object */
58
 
                                                vpn_service,            /* protocol */
59
 
                                                NULL,                   /* authtype */
60
 
                                                0,                      /* port */
61
 
                                                &keyring_result) != GNOME_KEYRING_RESULT_OK)
62
 
    return FALSE;
63
 
 
64
 
  *is_session = FALSE;
65
 
 
66
 
  // Go through all passwords and assign to appropriate variable
67
 
  for (keyring_i = keyring_result; keyring_i != NULL; keyring_i = g_list_next (keyring_i)) {
68
 
    
69
 
    GnomeKeyringNetworkPasswordData *data = keyring_i->data;
70
 
      
71
 
    if (strcmp (data->object, "password") == 0) {
72
 
      password = data->password;
73
 
    } else if (strcmp (data->object, "certpass") == 0) {
74
 
      certpass = data->password;
75
 
    }
76
 
 
77
 
    if (strcmp (data->keyring, "session") == 0)
78
 
      *is_session = TRUE;
79
 
    
80
 
  }
81
 
 
82
 
 
83
 
  if (password != NULL) {
84
 
    passwords = g_slist_append (passwords, g_strdup (password));
85
 
  } else {
86
 
    passwords = g_slist_append (passwords, g_strdup (""));
87
 
  }
88
 
 
89
 
  if (certpass != NULL) {
90
 
    passwords = g_slist_append (passwords, g_strdup (certpass));
91
 
  } else {
92
 
    passwords = g_slist_append (passwords, g_strdup (""));
93
 
  }
94
 
 
95
 
  gnome_keyring_network_password_list_free (keyring_result);
96
 
 
97
 
  return passwords;
98
 
}
99
 
 
100
 
static void save_vpn_password (const char *vpn_name, const char *vpn_service, const char *keyring, 
101
 
                               const char *password, const char *certpass)
102
 
{
103
 
  guint32 item_id;
104
 
  GnomeKeyringResult keyring_result;
105
 
 
106
 
  if ( password != NULL) {
107
 
    keyring_result = gnome_keyring_set_network_password_sync (keyring,
108
 
                                                              g_get_user_name (),
109
 
                                                              NULL,
110
 
                                                              vpn_name,
111
 
                                                              "password",
112
 
                                                              vpn_service,
113
 
                                                              NULL,
114
 
                                                              0,
115
 
                                                              password,
116
 
                                                              &item_id);
117
 
    if (keyring_result != GNOME_KEYRING_RESULT_OK) {
118
 
      g_warning ("Couldn't store password in keyring, code %d", (int) keyring_result);
119
 
    }
120
 
  }
121
 
 
122
 
  if ( certpass != NULL) {
123
 
    keyring_result = gnome_keyring_set_network_password_sync (keyring,
124
 
                                                              g_get_user_name (),
125
 
                                                              NULL,
126
 
                                                              vpn_name,
127
 
                                                              "certpass",
128
 
                                                              vpn_service,
129
 
                                                              NULL,
130
 
                                                              0,
131
 
                                                              certpass,
132
 
                                                              &item_id);
133
 
    if (keyring_result != GNOME_KEYRING_RESULT_OK) {
134
 
      g_warning ("Couldn't store certpass in keyring, code %d", (int) keyring_result);
135
 
    }
136
 
  }
137
 
 
138
 
}
139
 
 
 
42
typedef struct {
 
43
        char *vpn_uuid;
 
44
        char *vpn_name;
 
45
 
 
46
        gboolean need_password;
 
47
        char *password;
 
48
 
 
49
        gboolean need_certpass;
 
50
        char *certpass;
 
51
} PasswordsInfo;
 
52
 
 
53
#define PROC_TYPE_TAG "Proc-Type: 4,ENCRYPTED"
140
54
 
141
55
/** Checks if a key is encrypted
142
56
 * The key file is read and it is checked if it contains a line reading
146
60
 * @return returns true if the key is encrypted, false otherwise
147
61
 */
148
62
static gboolean
149
 
pem_is_encrypted(const char *filename)
150
 
{
151
 
 
152
 
  GIOChannel *pem_chan;
153
 
  char       *str = NULL;
154
 
  gboolean encrypted = FALSE;
155
 
 
156
 
  pem_chan = g_io_channel_new_file (filename, "r", NULL);
157
 
 
158
 
  if ( pem_chan == NULL ) {
159
 
    // We don't know
160
 
    return FALSE;
161
 
  }
162
 
 
163
 
  while ( ! encrypted && (g_io_channel_read_line (pem_chan, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) ) {
164
 
    if ( strstr (str, "Proc-Type: 4,ENCRYPTED") == str ) {
165
 
      // encrypted!
166
 
      encrypted = TRUE;
167
 
    }
168
 
 
169
 
    g_free (str);
170
 
  }
171
 
 
172
 
  return encrypted;
173
 
}
174
 
 
175
 
 
176
 
static GSList *
177
 
get_passwords (const char *vpn_name,
178
 
               const char *vpn_service,
179
 
               gboolean retry,
180
 
               gboolean need_password,
181
 
               gboolean need_certpass)
182
 
{
183
 
  GSList          *result;
184
 
  char            *prompt;
185
 
  GtkWidget       *dialog;
186
 
  char            *keyring_password;
187
 
  char            *keyring_certpass;
188
 
  gboolean         keyring_is_session;
189
 
  GSList          *keyring_result;
190
 
  GnomeTwoPasswordDialogRemember remember;
191
 
  int              num_passwords = 0;
192
 
 
193
 
  result = NULL;
194
 
  keyring_password = NULL;
195
 
  keyring_certpass = NULL;
196
 
  keyring_result = NULL;
197
 
 
198
 
  g_return_val_if_fail (vpn_name != NULL, NULL);
199
 
 
200
 
  /* Use the system user name, since the VPN might have a different user name */
201
 
  if (!retry) {
202
 
    if ((result = lookup_pass (vpn_name, vpn_service, &keyring_is_session)) != NULL) {
203
 
      return result;
204
 
    }
205
 
  } else {
206
 
    if ((keyring_result = lookup_pass (vpn_name, vpn_service, &keyring_is_session)) != NULL) {
207
 
      keyring_password = g_strdup ((char *) keyring_result->data);
208
 
      keyring_certpass = g_strdup ((char *) (g_slist_next (keyring_result))->data);
209
 
    }
210
 
    g_slist_foreach (keyring_result, (GFunc)g_free, NULL);
211
 
    g_slist_free (keyring_result);
212
 
  }
213
 
 
214
 
  prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."), vpn_name);
215
 
  dialog = gnome_two_password_dialog_new (_("Authenticate VPN"), prompt, NULL, NULL, FALSE);
216
 
  g_free (prompt);
217
 
 
218
 
  gnome_two_password_dialog_set_show_username (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
219
 
  gnome_two_password_dialog_set_show_userpass_buttons (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
220
 
  gnome_two_password_dialog_set_show_domain (GNOME_TWO_PASSWORD_DIALOG (dialog), FALSE);
221
 
  gnome_two_password_dialog_set_show_remember (GNOME_TWO_PASSWORD_DIALOG (dialog), TRUE);
222
 
 
223
 
  if (need_password && need_certpass) {
224
 
    gnome_two_password_dialog_set_show_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog),
225
 
                                                           TRUE);
226
 
    gnome_two_password_dialog_set_password_secondary_label (GNOME_TWO_PASSWORD_DIALOG (dialog),
227
 
                                                            _("Certificate password:") );
228
 
 
229
 
    /* if retrying, put in the passwords from the keyring */
230
 
    if (keyring_password != NULL) {
231
 
      gnome_two_password_dialog_set_password (GNOME_TWO_PASSWORD_DIALOG (dialog),
232
 
                                              keyring_password);
233
 
    }
234
 
    if (keyring_certpass != NULL) {
235
 
      gnome_two_password_dialog_set_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog),
236
 
                                                        keyring_certpass);
237
 
    }
238
 
  } else {
239
 
    gnome_two_password_dialog_set_show_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog),
240
 
                                                           FALSE);
241
 
    if (need_password) {
242
 
      // defaults for label are ok
243
 
 
244
 
      /* if retrying, put in the passwords from the keyring */
245
 
      if (keyring_password != NULL) {
246
 
        gnome_two_password_dialog_set_password (GNOME_TWO_PASSWORD_DIALOG (dialog),
247
 
                                                keyring_password);
248
 
      }
249
 
 
250
 
    } else if (need_certpass) {
251
 
      gnome_two_password_dialog_set_password_primary_label (GNOME_TWO_PASSWORD_DIALOG (dialog),
252
 
                                                            _("Certificate password:") );
253
 
      /* if retrying, put in the passwords from the keyring */
254
 
      if (keyring_certpass != NULL) {
255
 
        gnome_two_password_dialog_set_password (GNOME_TWO_PASSWORD_DIALOG (dialog),
256
 
                                                keyring_certpass);
257
 
      }
258
 
    }
259
 
  }
260
 
 
261
 
  /* use the same keyring storage options as from the items we put in the entry boxes */
262
 
  remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING;
263
 
  if (keyring_result != NULL) {
264
 
    if (keyring_is_session)
265
 
      remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION;
266
 
    else
267
 
      remember = GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER;                            
268
 
  }
269
 
  gnome_two_password_dialog_set_remember (GNOME_TWO_PASSWORD_DIALOG (dialog), remember);
270
 
 
271
 
  gtk_widget_show (dialog);
272
 
 
273
 
  if (gnome_two_password_dialog_run_and_block (GNOME_TWO_PASSWORD_DIALOG (dialog))) {
274
 
    char *password = "unused";
275
 
    char *certpass = "unused";
276
 
 
277
 
    if (need_password && need_certpass) {
278
 
      password = gnome_two_password_dialog_get_password (GNOME_TWO_PASSWORD_DIALOG (dialog));
279
 
      certpass = gnome_two_password_dialog_get_password_secondary (GNOME_TWO_PASSWORD_DIALOG (dialog));
280
 
    } else {
281
 
      if (need_password) {
282
 
        password = gnome_two_password_dialog_get_password (GNOME_TWO_PASSWORD_DIALOG (dialog));
283
 
      } else if (need_certpass) {
284
 
        certpass = gnome_two_password_dialog_get_password (GNOME_TWO_PASSWORD_DIALOG (dialog));
285
 
      }
286
 
    }
287
 
 
288
 
    result = g_slist_append (result, g_strdup (password));
289
 
    result = g_slist_append (result, g_strdup (certpass));
290
 
 
291
 
    switch (gnome_two_password_dialog_get_remember (GNOME_TWO_PASSWORD_DIALOG (dialog))) {
292
 
    case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION:
293
 
      save_vpn_password (vpn_name, vpn_service, "session", password, certpass);
294
 
      break;
295
 
    case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER:
296
 
      save_vpn_password (vpn_name, vpn_service, NULL, password, certpass);
297
 
      break;
298
 
    default:
299
 
      break;
300
 
    }
301
 
  }
302
 
 
303
 
  g_free (keyring_password);
304
 
  g_free (keyring_certpass);
305
 
 
306
 
  gtk_widget_destroy (dialog);
307
 
 
308
 
  return result;
 
63
pem_is_encrypted (const char *filename)
 
64
{
 
65
        GIOChannel *pem_chan;
 
66
        char       *str = NULL;
 
67
        gboolean encrypted = FALSE;
 
68
 
 
69
        pem_chan = g_io_channel_new_file (filename, "r", NULL);
 
70
        if (!pem_chan)
 
71
                return FALSE;
 
72
 
 
73
        while (g_io_channel_read_line (pem_chan, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
 
74
                if (strncmp (str, PROC_TYPE_TAG, strlen (PROC_TYPE_TAG)) == 0) {
 
75
                        encrypted = TRUE;
 
76
                        break;
 
77
                }
 
78
                g_free (str);
 
79
        }
 
80
 
 
81
        g_io_channel_shutdown (pem_chan, FALSE, NULL);
 
82
        g_io_channel_unref (pem_chan);
 
83
        return encrypted;
 
84
}
 
85
 
 
86
 
 
87
static void
 
88
clear_secrets (PasswordsInfo *info)
 
89
{
 
90
        if (info->password) {
 
91
                memset (info->password, 0, strlen (info->password));
 
92
                g_free (info->password);
 
93
        }
 
94
        if (info->certpass) {
 
95
                memset (info->certpass, 0, strlen (info->certpass));
 
96
                g_free (info->certpass);
 
97
        }
 
98
}
 
99
 
 
100
static gboolean
 
101
get_secrets (PasswordsInfo *info, gboolean retry)
 
102
{
 
103
        GnomeTwoPasswordDialog *dialog;
 
104
        gboolean is_session = TRUE;
 
105
        char *prompt;
 
106
        gboolean success = FALSE, need_secret = FALSE;
 
107
 
 
108
        g_return_val_if_fail (info->vpn_uuid != NULL, FALSE);
 
109
        g_return_val_if_fail (info->vpn_name != NULL, FALSE);
 
110
 
 
111
        if (info->need_password) {
 
112
                info->password = keyring_helpers_lookup_secret (info->vpn_uuid, NM_OPENVPN_KEY_PASSWORD, &is_session);
 
113
                if (!info->password)
 
114
                        need_secret = TRUE;
 
115
        }
 
116
 
 
117
        if (info->need_certpass) {
 
118
                info->certpass = keyring_helpers_lookup_secret (info->vpn_uuid, NM_OPENVPN_KEY_CERTPASS, &is_session);
 
119
                if (!info->certpass)
 
120
                        need_secret = TRUE;
 
121
        }
 
122
 
 
123
        /* Have all passwords and we're not supposed to ask the user again */
 
124
        if (!need_secret && !retry)
 
125
                return TRUE;
 
126
 
 
127
        prompt = g_strdup_printf (_("You need to authenticate to access the Virtual Private Network '%s'."), info->vpn_name);
 
128
        dialog = GNOME_TWO_PASSWORD_DIALOG (gnome_two_password_dialog_new (_("Authenticate VPN"), prompt, NULL, NULL, FALSE));
 
129
        g_free (prompt);
 
130
 
 
131
        gnome_two_password_dialog_set_show_username (dialog, FALSE);
 
132
        gnome_two_password_dialog_set_show_userpass_buttons (dialog, FALSE);
 
133
        gnome_two_password_dialog_set_show_domain (dialog, FALSE);
 
134
        gnome_two_password_dialog_set_show_remember (dialog, TRUE);
 
135
 
 
136
        /* If nothing was found in the keyring, default to not remembering any secrets */
 
137
        if (info->password || info->certpass) {
 
138
                /* Otherwise set default remember based on which keyring the secrets were found in */
 
139
                if (is_session)
 
140
                        gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION);
 
141
                else
 
142
                        gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER);
 
143
        } else
 
144
                gnome_two_password_dialog_set_remember (dialog, GNOME_TWO_PASSWORD_DIALOG_REMEMBER_NOTHING);
 
145
 
 
146
        /* pre-fill dialog with the password */
 
147
        if (info->need_password && info->need_certpass) {
 
148
                gnome_two_password_dialog_set_show_password_secondary (dialog, TRUE);
 
149
                gnome_two_password_dialog_set_password_secondary_label (dialog, _("Certificate pass_word:") );
 
150
 
 
151
                /* if retrying, put in the passwords from the keyring */
 
152
                if (info->password)
 
153
                        gnome_two_password_dialog_set_password (dialog, info->password);
 
154
                if (info->certpass)
 
155
                        gnome_two_password_dialog_set_password_secondary (dialog, info->certpass);
 
156
        } else {
 
157
                gnome_two_password_dialog_set_show_password_secondary (dialog, FALSE);
 
158
                if (info->need_password) {
 
159
                        /* if retrying, put in the passwords from the keyring */
 
160
                        if (info->password)
 
161
                                gnome_two_password_dialog_set_password (dialog, info->password);
 
162
                } else if (info->need_certpass) {
 
163
                        gnome_two_password_dialog_set_password_primary_label (dialog, _("Certificate password:"));
 
164
                        /* if retrying, put in the passwords from the keyring */
 
165
                        if (info->certpass)
 
166
                                gnome_two_password_dialog_set_password (dialog, info->certpass);
 
167
                }
 
168
        }
 
169
        clear_secrets (info);
 
170
 
 
171
        gtk_widget_show (GTK_WIDGET (dialog));
 
172
 
 
173
        if (gnome_two_password_dialog_run_and_block (dialog)) {
 
174
                gboolean save = FALSE;
 
175
                char *keyring = NULL;
 
176
 
 
177
                if (info->need_password)
 
178
                        info->password = g_strdup (gnome_two_password_dialog_get_password (dialog));
 
179
                if (info->need_certpass) {
 
180
                        info->certpass = g_strdup (info->need_password ? 
 
181
                                                                  gnome_two_password_dialog_get_password_secondary (dialog) :
 
182
                                                                  gnome_two_password_dialog_get_password (dialog));
 
183
                }
 
184
 
 
185
                switch (gnome_two_password_dialog_get_remember (dialog)) {
 
186
                case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_SESSION:
 
187
                        keyring = "session";
 
188
                        /* Fall through */
 
189
                case GNOME_TWO_PASSWORD_DIALOG_REMEMBER_FOREVER:
 
190
                        save = TRUE;
 
191
                        break;
 
192
                default:
 
193
                        break;
 
194
                }
 
195
 
 
196
                if (save) {
 
197
                        if (info->password) {
 
198
                                keyring_helpers_save_secret (info->vpn_uuid, info->vpn_name,
 
199
                                                                                         keyring, NM_OPENVPN_KEY_PASSWORD, info->password);
 
200
                        }
 
201
                        if (info->certpass) {
 
202
                                keyring_helpers_save_secret (info->vpn_uuid, info->vpn_name,
 
203
                                                                                         keyring, NM_OPENVPN_KEY_CERTPASS, info->certpass);
 
204
                        }
 
205
                }
 
206
 
 
207
                success = TRUE;
 
208
        }
 
209
 
 
210
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
211
 
 
212
        return success;
 
213
}
 
214
 
 
215
static gboolean
 
216
get_password_types (PasswordsInfo *info)
 
217
{
 
218
        GConfClient *gconf_client = NULL;
 
219
        GSList *conf_list;
 
220
        GSList *iter;
 
221
        char *key;
 
222
        char *str;
 
223
        char *connection_path = NULL;
 
224
        gboolean success = FALSE;
 
225
        char *connection_type;
 
226
 
 
227
        /* FIXME: This whole thing sucks: we should not go around poking gconf
 
228
           directly, but there's nothing that does it for us right now */
 
229
 
 
230
        gconf_client = gconf_client_get_default ();
 
231
 
 
232
        conf_list = gconf_client_all_dirs (gconf_client, "/system/networking/connections", NULL);
 
233
        if (!conf_list)
 
234
                return FALSE;
 
235
 
 
236
        for (iter = conf_list; iter; iter = iter->next) {
 
237
                const char *path = (const char *) iter->data;
 
238
 
 
239
                key = g_strdup_printf ("%s/%s/%s", 
 
240
                                       path,
 
241
                                       NM_SETTING_CONNECTION_SETTING_NAME,
 
242
                                       NM_SETTING_CONNECTION_TYPE);
 
243
                str = gconf_client_get_string (gconf_client, key, NULL);
 
244
                g_free (key);
 
245
 
 
246
                if (!str || strcmp (str, "vpn")) {
 
247
                        g_free (str);
 
248
                        continue;
 
249
                }
 
250
                g_free (str);
 
251
 
 
252
                key = g_strdup_printf ("%s/%s/%s", 
 
253
                                       path,
 
254
                                       NM_SETTING_CONNECTION_SETTING_NAME,
 
255
                                       NM_SETTING_CONNECTION_UUID);
 
256
                str = gconf_client_get_string (gconf_client, key, NULL);
 
257
                g_free (key);
 
258
 
 
259
                if (!str || strcmp (str, info->vpn_uuid)) {
 
260
                        g_free (str);
 
261
                        continue;
 
262
                }
 
263
                g_free (str);
 
264
 
 
265
                /* Woo, found the connection */
 
266
                connection_path = g_strdup (path);
 
267
                break;
 
268
        }
 
269
 
 
270
        g_slist_foreach (conf_list, (GFunc) g_free, NULL);
 
271
        g_slist_free (conf_list);
 
272
 
 
273
        if (!connection_path)
 
274
                goto out;
 
275
 
 
276
        key = g_strdup_printf ("%s/%s/%s", connection_path,
 
277
                               NM_SETTING_VPN_SETTING_NAME,
 
278
                               NM_OPENVPN_KEY_CONNECTION_TYPE);
 
279
        connection_type = gconf_client_get_string (gconf_client, key, NULL);
 
280
        g_free (key);
 
281
        
 
282
        if (   !strcmp (connection_type, NM_OPENVPN_CONTYPE_TLS)
 
283
            || !strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
 
284
                success = TRUE;
 
285
 
 
286
                if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS))
 
287
                        info->need_password = TRUE;
 
288
 
 
289
                key = g_strdup_printf ("%s/%s/%s", connection_path, NM_SETTING_VPN_SETTING_NAME,
 
290
                                       NM_OPENVPN_KEY_KEY);
 
291
                str = gconf_client_get_string (gconf_client, key, NULL);
 
292
                if (str)
 
293
                        info->need_certpass = pem_is_encrypted (str);
 
294
                g_free (str);
 
295
                g_free (key);
 
296
        } else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_STATIC_KEY)) {
 
297
                success = TRUE;
 
298
        } else if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_PASSWORD)) {
 
299
                success = TRUE;
 
300
                info->need_password = TRUE;
 
301
        }
 
302
 
 
303
        g_free (connection_type);
 
304
        g_free (connection_path);
 
305
 
 
306
out:
 
307
        g_object_unref (gconf_client);
 
308
        return success;
309
309
}
310
310
 
311
311
int 
312
312
main (int argc, char *argv[])
313
313
{
314
 
  GConfClient *gconf_client = NULL;
315
 
  GConfValue  *gconf_val = NULL;
316
 
  gchar       *gconf_key = NULL;
317
 
  char        *escaped_name;
318
 
  gboolean     needs_password = FALSE;
319
 
  gboolean     needs_certpass = FALSE;
320
 
  gboolean     valid_conn = FALSE;
321
 
  GSList      *i;
322
 
  GSList      *passwords;
323
 
  gchar       *key = NULL;
324
 
  gchar       *connection_type = NULL;
325
 
  static gboolean  retry = FALSE;
326
 
  static gchar    *vpn_name = NULL;
327
 
  static gchar    *vpn_service = NULL;
328
 
  GError          *error = NULL;
329
 
  GOptionContext  *context;
330
 
  int          bytes_read;
331
 
  static GOptionEntry entries[] = 
332
 
    {
333
 
      { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
334
 
      { "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL},
335
 
      { "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL},
336
 
      { NULL }
337
 
    };
338
 
  char buf[1];
339
 
 
340
 
  bindtextdomain (GETTEXT_PACKAGE, NULL);
341
 
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
342
 
  textdomain (GETTEXT_PACKAGE);
343
 
 
344
 
  passwords = NULL;
345
 
 
346
 
  context = g_option_context_new ("- openvpn auth dialog");
347
 
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
348
 
  g_option_context_add_group (context, gtk_get_option_group (TRUE));
349
 
  g_option_context_parse (context, &argc, &argv, &error);
350
 
 
351
 
  if (vpn_name == NULL || vpn_service == NULL) {
352
 
    fprintf (stderr, "Have to supply both name and service\n");
353
 
    goto out;
354
 
  }
355
 
 
356
 
  if (strcmp (vpn_service, VPN_SERVICE) != 0) {
357
 
    fprintf (stderr, "This dialog only works with the '%s' service\n", VPN_SERVICE);
358
 
    goto out;           
359
 
  }
360
 
 
361
 
  gnome_program_init ("nm-openvpn-auth-dialog", VERSION, LIBGNOMEUI_MODULE,
362
 
                      argc, argv, 
363
 
                      GNOME_PARAM_NONE, GNOME_PARAM_NONE);
364
 
 
365
 
 
366
 
  gconf_client = gconf_client_get_default();
367
 
  escaped_name = gconf_escape_key (vpn_name, strlen (vpn_name));
368
 
  gconf_key    = g_strdup_printf ("%s/%s/vpn_data", GCONF_PATH_VPN_CONNECTIONS, escaped_name);
369
 
  if ( !(gconf_val = gconf_client_get (gconf_client, gconf_key, NULL)) ||
370
 
       !(gconf_val->type == GCONF_VALUE_LIST) ||
371
 
       !(gconf_value_get_list_type (gconf_val) == GCONF_VALUE_STRING)) {
372
 
 
373
 
    if (gconf_val)
374
 
      gconf_value_free (gconf_val);
375
 
    g_free (gconf_key);
376
 
    goto out;
377
 
  }
378
 
  g_free (gconf_key);
379
 
 
380
 
  valid_conn = TRUE;
381
 
    
382
 
  for (i = gconf_value_get_list (gconf_val); i != NULL; i = g_slist_next (i)) {
383
 
    const char *gkey = gconf_value_get_string ((GConfValue *)i->data);
384
 
    const char *gval = NULL;
385
 
 
386
 
    i = g_slist_next (i);
387
 
    if (i != NULL) {
388
 
      gval = gconf_value_get_string ((GConfValue *)i->data);
389
 
    }
390
 
 
391
 
    if ( gkey != NULL ) {
392
 
      if ( strcmp (gkey, "connection-type") == 0 ) {
393
 
        connection_type = g_strdup (gval);
394
 
        if ( (strcmp (gval, "password") == 0) ||
395
 
             (strcmp (gval, "x509userpass") == 0) ) {
396
 
          needs_password = TRUE;
397
 
        }
398
 
      } else if ( strcmp (gkey, "key") == 0 ) {
399
 
        key = g_strdup (gval);
400
 
      }
401
 
    }
402
 
  }
403
 
  gconf_value_free (gconf_val);
404
 
 
405
 
  if ( (connection_type != NULL) && (key != NULL) ) {
406
 
    if ( (strcmp (connection_type, "x509") == 0) ||
407
 
         (strcmp (connection_type, "x509userpass") == 0) ) {
408
 
      needs_certpass = pem_is_encrypted (key);
409
 
    }
410
 
  }
411
 
 
412
 
  if ( needs_password || needs_certpass ) {
413
 
    passwords = get_passwords (vpn_name, vpn_service, retry, needs_password, needs_certpass);
414
 
    if (passwords == NULL)
415
 
      goto out;
416
 
 
417
 
    /* dump the passwords to stdout */
418
 
    for (i = passwords; i != NULL; i = g_slist_next (i)) {
419
 
      char *password = (char *) i->data;
420
 
      printf ("%s\n", password);
421
 
    }
422
 
 
423
 
    g_slist_foreach (passwords, (GFunc)g_free, NULL);
424
 
    g_slist_free (passwords);
425
 
 
426
 
  } else {
427
 
    printf ("No password needed\nNo certpass needed\n");
428
 
  }
429
 
 
430
 
  printf ("\n\n");
431
 
  /* for good measure, flush stdout since Kansas is going Bye-Bye */
432
 
  fflush (stdout);
433
 
 
434
 
  /* wait for data on stdin  */
435
 
  bytes_read = fread (buf, sizeof (char), sizeof (buf), stdin);
436
 
 
437
 
 out:
438
 
  g_object_unref (gconf_client);
439
 
  g_option_context_free (context);
440
 
 
441
 
  g_free (connection_type);
442
 
  g_free (key);
443
 
 
444
 
  if ( ! valid_conn ) {
445
 
    return 1;
446
 
  } else if ( needs_password ) {
447
 
    return (passwords != NULL) ? 0 : 1;
448
 
  } else {
449
 
    return 0;
450
 
  }
 
314
        PasswordsInfo info;
 
315
        gboolean retry = FALSE;
 
316
        gchar *vpn_name = NULL;
 
317
        gchar *vpn_uuid = NULL;
 
318
        gchar *vpn_service = NULL;
 
319
        char buf[1];
 
320
        int ret;
 
321
        GOptionContext *context;
 
322
        GOptionEntry entries[] = {
 
323
                        { "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
 
324
                        { "uuid", 'u', 0, G_OPTION_ARG_STRING, &vpn_uuid, "UUID of VPN connection", NULL},
 
325
                        { "name", 'n', 0, G_OPTION_ARG_STRING, &vpn_name, "Name of VPN connection", NULL},
 
326
                        { "service", 's', 0, G_OPTION_ARG_STRING, &vpn_service, "VPN service type", NULL},
 
327
                        { NULL }
 
328
                };
 
329
 
 
330
        bindtextdomain (GETTEXT_PACKAGE, NULL);
 
331
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
332
        textdomain (GETTEXT_PACKAGE);
 
333
 
 
334
        gtk_init (&argc, &argv);
 
335
 
 
336
        context = g_option_context_new ("- openvpn auth dialog");
 
337
        g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
 
338
        g_option_context_parse (context, &argc, &argv, NULL);
 
339
        g_option_context_free (context);
 
340
 
 
341
        if (vpn_uuid == NULL || vpn_name == NULL || vpn_service == NULL) {
 
342
                fprintf (stderr, "Have to supply ID, name, and service\n");
 
343
                return EXIT_FAILURE;
 
344
        }
 
345
 
 
346
        if (strcmp (vpn_service, NM_DBUS_SERVICE_OPENVPN) != 0) {
 
347
                fprintf (stderr, "This dialog only works with the '%s' service\n", NM_DBUS_SERVICE_OPENVPN);
 
348
                return EXIT_FAILURE;
 
349
        }
 
350
 
 
351
        memset (&info, 0, sizeof (PasswordsInfo));
 
352
        info.vpn_uuid = vpn_uuid;
 
353
        info.vpn_name = vpn_name;
 
354
 
 
355
        if (!get_password_types (&info)) {
 
356
                fprintf (stderr, "Invalid connection");
 
357
                return EXIT_FAILURE;
 
358
        }
 
359
 
 
360
        if (!info.need_password && !info.need_certpass) {
 
361
                printf ("%s\n%s\n\n\n", NM_OPENVPN_KEY_NOSECRET, "true");
 
362
                return EXIT_SUCCESS;
 
363
        }
 
364
 
 
365
        if (get_secrets (&info, retry)) {
 
366
                if (info.need_password)
 
367
                        printf ("%s\n%s\n", NM_OPENVPN_KEY_PASSWORD, info.password);
 
368
                if (info.need_certpass)
 
369
                        printf ("%s\n%s\n", NM_OPENVPN_KEY_CERTPASS, info.certpass);
 
370
        }
 
371
        printf ("\n\n");
 
372
 
 
373
        clear_secrets (&info);
 
374
 
 
375
        /* for good measure, flush stdout since Kansas is going Bye-Bye */
 
376
        fflush (stdout);
 
377
 
 
378
        /* wait for data on stdin  */
 
379
        ret = fread (buf, sizeof (char), sizeof (buf), stdin);
 
380
 
 
381
 
 
382
        return EXIT_SUCCESS;
451
383
}