1
/* NetworkManager -- Network link manager
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 2005 Red Hat, Inc.
23
#include <glib/gi18n.h>
24
#include <dbus/dbus.h>
25
#include <gconf/gconf-client.h>
26
#include <gnome-keyring.h>
30
#include "applet-compat.h"
31
#include "gconf-helpers.h"
34
#include "cipher-wep-hex.h"
35
#include "cipher-wep-ascii.h"
36
#include "cipher-wep-passphrase.h"
40
* Authentication modes
42
typedef enum NMDeviceAuthMethod
44
NM_DEVICE_AUTH_METHOD_UNKNOWN = 0,
45
NM_DEVICE_AUTH_METHOD_NONE,
46
NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM,
47
NM_DEVICE_AUTH_METHOD_SHARED_KEY
51
* Encryption key types
53
typedef enum NMEncKeyType
55
NM_ENC_TYPE_UNKNOWN = 0,
58
NM_ENC_TYPE_ASCII_KEY,
59
NM_ENC_TYPE_128_BIT_PASSPHRASE
60
/* FIXME: WPA and 802.1x support */
63
#define WEP_PREFIX "wep_"
67
unset_nm_gconf_key (GConfClient *client,
68
const char *escaped_network,
73
g_return_if_fail (client != NULL);
74
g_return_if_fail (escaped_network != NULL);
75
g_return_if_fail (key_name != NULL);
77
key = g_strdup_printf ("%s/%s/%s",
78
GCONF_PATH_WIRELESS_NETWORKS,
81
gconf_client_unset (client, key, NULL);
86
set_entry_cipher (GConfClient *client,
87
const char *escaped_network,
92
g_return_if_fail (client != NULL);
93
g_return_if_fail (escaped_network != NULL);
95
key = g_strdup_printf ("%s/%s/we_cipher", GCONF_PATH_WIRELESS_NETWORKS, escaped_network);
96
gconf_client_set_int (client, key, we_cipher, NULL);
101
convert_entry_auth_algorithm (GConfClient *client,
102
const char *escaped_network)
106
NMDeviceAuthMethod auth_method = NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM;
107
int we_auth_alg = IW_AUTH_ALG_OPEN_SYSTEM;
109
g_return_if_fail (client != NULL);
110
g_return_if_fail (escaped_network != NULL);
112
if (nm_gconf_get_int_helper (client,
113
GCONF_PATH_WIRELESS_NETWORKS,
117
auth_method = (NMDeviceAuthMethod) int_auth_method;
119
if (auth_method == NM_DEVICE_AUTH_METHOD_SHARED_KEY)
120
we_auth_alg = IW_AUTH_ALG_SHARED_KEY;
122
key = g_strdup_printf ("%s/%s/%sauth_algorithm",
123
GCONF_PATH_WIRELESS_NETWORKS,
126
gconf_client_set_int (client, key, we_auth_alg, NULL);
129
/* Remove the old auth_method key */
130
unset_nm_gconf_key (client, escaped_network, "auth_method");
134
get_key_from_keyring (const char *essid, int *item_id)
136
GnomeKeyringResult ret;
137
GList * found_list = NULL;
138
GnomeKeyringFound * found;
141
g_return_val_if_fail (essid != NULL, NULL);
143
ret = gnome_keyring_find_itemsv_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
146
GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
149
if (ret != GNOME_KEYRING_RESULT_OK)
152
found = (GnomeKeyringFound *) found_list->data;
153
key = g_strdup (found->secret);
155
*item_id = found->item_id;
156
gnome_keyring_found_list_free (found_list);
162
set_key_in_keyring (const char *essid,
165
GnomeKeyringAttributeList * attributes;
166
GnomeKeyringAttribute attr;
167
GnomeKeyringResult ret;
171
name = g_strdup_printf (_("Passphrase for wireless network %s"), essid);
173
attributes = gnome_keyring_attribute_list_new ();
174
attr.name = g_strdup ("essid");
175
attr.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
176
attr.value.string = g_strdup (essid);
177
g_array_append_val (attributes, attr);
179
ret = gnome_keyring_item_create_sync (NULL,
180
GNOME_KEYRING_ITEM_GENERIC_SECRET,
186
if (ret != GNOME_KEYRING_RESULT_OK)
188
nm_warning ("%s:%d (%s): Error converting encryption key for '%s'. Ret=%d",
189
__FILE__, __LINE__, __func__, essid, ret);
192
gnome_keyring_attribute_list_free (attributes);
196
convert_no_encryption (GConfClient *client,
197
const char *escaped_network)
199
g_return_if_fail (client != NULL);
200
g_return_if_fail (escaped_network != NULL);
202
set_entry_cipher (client, escaped_network, IW_AUTH_CIPHER_NONE);
204
/* Remove the old auth_method key if it's present */
205
unset_nm_gconf_key (client, escaped_network, "auth_method");
209
generic_convert_wep_entry (GConfClient *client,
210
const char *escaped_network,
212
IEEE_802_11_Cipher *first_cipher,
213
IEEE_802_11_Cipher *second_cipher)
216
int key_item_id = -1;
217
int real_we_cipher = IW_AUTH_CIPHER_WEP104;
218
IEEE_802_11_Cipher * real_cipher = NULL;
219
char * hashed_key = NULL;
221
g_return_if_fail (client != NULL);
222
g_return_if_fail (escaped_network != NULL);
223
g_return_if_fail (essid != NULL);
224
g_return_if_fail (first_cipher != NULL);
226
key = get_key_from_keyring (essid, &key_item_id);
228
/* Try to validate key with first cipher */
229
if (ieee_802_11_cipher_validate (first_cipher, essid, key) == 0)
231
if ((hashed_key = ieee_802_11_cipher_hash (first_cipher, essid, key)))
232
real_cipher = first_cipher;
235
if (second_cipher && !hashed_key)
237
/* Try second cipher then */
238
if (ieee_802_11_cipher_validate (second_cipher, essid, key) == 0)
239
if ((hashed_key = ieee_802_11_cipher_hash (second_cipher, essid, key)))
240
real_cipher = second_cipher;
243
if (real_cipher && hashed_key)
245
real_we_cipher = ieee_802_11_cipher_get_we_cipher (real_cipher);
246
/* Set the converted key in the keyring */
247
set_key_in_keyring (essid, hashed_key);
251
/* Couldn't convert the key, so remove it from
252
* the keyring and let the user enter it later.
254
nm_warning ("%s:%d (%s): Could not convert old WEP key for network '%s'.",
255
__FILE__, __LINE__, __func__, essid);
256
gnome_keyring_item_delete_sync (NULL, key_item_id);
260
/* Set new WE cipher */
261
set_entry_cipher (client, escaped_network, real_we_cipher);
263
/* Set the authentication algorithm */
264
convert_entry_auth_algorithm (client, escaped_network);
268
convert_one_entry (GConfClient *client,
272
GConfValue * addrs_value = NULL;
273
char * escaped_network;
276
NMEncKeyType key_type = NM_ENC_TYPE_NONE;
277
IEEE_802_11_Cipher * first_cipher = NULL;
278
IEEE_802_11_Cipher * second_cipher = NULL;
280
g_return_if_fail (client != NULL);
281
g_return_if_fail (essid != NULL);
283
if (!(escaped_network = gconf_escape_key (essid, strlen (essid))) || strlen (escaped_network) == 0)
285
nm_warning ("%s:%d (%s): couldn't unescape network name '%s'.",
286
__FILE__, __LINE__, __func__, essid);
290
/* Ignore any entry that looks like it doesn't need conversion */
291
if (nm_gconf_get_int_helper (client,
292
GCONF_PATH_WIRELESS_NETWORKS,
298
/* Grab the key type off this old entry so we know how to convert it */
299
if (nm_gconf_get_int_helper (client,
300
GCONF_PATH_WIRELESS_NETWORKS,
305
key_type = (NMEncKeyType) int_key_type;
308
/* Convert the list of stored access point BSSIDs */
309
key = g_strdup_printf ("%s/%s/addresses", GCONF_PATH_WIRELESS_NETWORKS, escaped_network);
310
if ((addrs_value = gconf_client_get (client, key, NULL)))
312
if ((addrs_value->type == GCONF_VALUE_LIST) && (gconf_value_get_list_type (addrs_value) == GCONF_VALUE_STRING))
317
list = gconf_client_get_list (client, key, GCONF_VALUE_STRING, NULL);
318
conv_key = g_strdup_printf ("%s/%s/bssids", GCONF_PATH_WIRELESS_NETWORKS, escaped_network);
319
gconf_client_set_list (client, conv_key, GCONF_VALUE_STRING, list, NULL);
321
g_slist_foreach (list, (GFunc) g_free, NULL);
324
gconf_value_free (addrs_value);
326
gconf_client_unset (client, key, NULL);
329
/* Convert security information, if any */
332
case NM_ENC_TYPE_UNKNOWN:
333
case NM_ENC_TYPE_NONE:
334
convert_no_encryption (client, escaped_network);
336
case NM_ENC_TYPE_HEX_KEY:
337
first_cipher = cipher_wep128_hex_new ();
338
second_cipher = cipher_wep64_hex_new ();
340
case NM_ENC_TYPE_ASCII_KEY:
341
first_cipher = cipher_wep128_ascii_new ();
342
second_cipher = cipher_wep64_ascii_new ();
344
case NM_ENC_TYPE_128_BIT_PASSPHRASE:
345
first_cipher = cipher_wep128_passphrase_new ();
346
second_cipher = cipher_wep64_passphrase_new ();
354
/* Do the actual key conversion */
355
generic_convert_wep_entry (client, escaped_network, essid, first_cipher, second_cipher);
356
ieee_802_11_cipher_unref (first_cipher);
358
ieee_802_11_cipher_unref (second_cipher);
360
unset_nm_gconf_key (client, escaped_network, "key_type");
363
g_free (escaped_network);
369
nma_compat_convert_oldformat_entries (GConfClient *client)
371
GSList * dir_list = NULL;
374
g_return_if_fail (client != NULL);
376
if (!(dir_list = gconf_client_all_dirs (client, GCONF_PATH_WIRELESS_NETWORKS, NULL)))
379
for (elt = dir_list; elt; elt = g_slist_next (elt))
383
char * dir = (char *) (elt->data);
385
g_snprintf (&key[0], 99, "%s/essid", dir);
386
if ((value = gconf_client_get (client, key, NULL)))
388
if (value->type == GCONF_VALUE_STRING)
390
const char *essid = gconf_value_get_string (value);
391
convert_one_entry (client, essid);
393
gconf_value_free (value);
397
g_slist_free (dir_list);