2004-08-24 Dan Williams <dcbw@redhat.com>

* src/NetworkManagerAP.[ch]
		- Add a "enc_method_good" member and accessors to an Access Point
			to signal when we've found the correct encryption method
			for an access point
		- Add a "timestamp" member and accessors, remove "priority" member
			and accessors (use timestamps instead)
		- Rename "wep_key"->"enc_key"
		- (nm_ap_get_enc_key_hashed): new, return the correct mangled key
			for a specified encryption method using the access points
			source encryption key/passphrase

	* src/NetworkManagerAPList.c
		- When updating a network with dbus, grab timestamp now instead of
			priority

	* src/NetworkManagerDBus.[ch]
		- Add signal for "DeviceActivating"
		- Switch priority->timestamp

	* src/NetworkManagerDevice.c
		- Change references of "wep_key" -> "enc_key" or "key"
		- Signal DeviceActivating when starting activation
		- When activating a wireless device, if the access point we are connecting
			to is encrypted, and we have a source key, try to generate a mangled
			key and use that (ie, generate real WEP key from a passphrase)
		- Rework device activation to fallback to other encryption methods if
			a previous one didn't work (ie, try mangling a key as a 104-bit passphrase
			first, then if that doesn't work fall back to direct hex key).
		- (nm_device_update_best_ap): fix a deadlock, and use timestamps instead of
			priority.  We now prefer the latest access point used, rather than using
			a priority scheme
		- (nm_device_do_normal_scan): make the encryption method "unknown" on access
			points we've just discovered, and merge in correct info from the global
			access point lists


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@68 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2004-08-25 22:41:12 +00:00
parent b034d4d1ab
commit 846b78966b
8 changed files with 240 additions and 99 deletions

View file

@ -21,6 +21,7 @@
#include "NetworkManagerAP.h"
#include "NetworkManagerUtils.h"
#include "NetworkManagerWireless.h"
extern gboolean debug;
@ -39,11 +40,12 @@ struct NMAccessPoint
gboolean encrypted;
gboolean invalid;
NMAPEncMethod enc_method;
gboolean enc_method_good;
gboolean matched; // used in ap list diffing
/* Things from user prefs */
gchar *wep_key;
guint priority;
gchar *enc_key;
time_t timestamp;
};
@ -61,7 +63,7 @@ NMAccessPoint * nm_ap_new (void)
if (!ap)
syslog( LOG_ERR, "nm_ap_new() could not allocate a new user access point info structure. Not enough memory?" );
ap->priority = NM_AP_PRIORITY_WORST;
ap->timestamp = 0;
ap->refcount = 1;
return (ap);
@ -102,9 +104,9 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap)
new_ap->rate = src_ap->rate;
new_ap->encrypted = src_ap->encrypted;
if (src_ap->wep_key && (strlen (src_ap->wep_key) > 0))
new_ap->wep_key = g_strdup (src_ap->wep_key);
new_ap->priority = src_ap->priority;
if (src_ap->enc_key && (strlen (src_ap->enc_key) > 0))
new_ap->enc_key = g_strdup (src_ap->enc_key);
new_ap->timestamp = 0;
return (new_ap);
}
@ -129,10 +131,10 @@ void nm_ap_unref (NMAccessPoint *ap)
{
g_free (ap->essid);
g_free (ap->address);
g_free (ap->wep_key);
g_free (ap->enc_key);
ap->essid = NULL;
ap->wep_key = NULL;
ap->enc_key = NULL;
g_free (ap);
}
@ -140,21 +142,21 @@ void nm_ap_unref (NMAccessPoint *ap)
/*
* Get/set functions for priority
* Get/set functions for timestamp
*
*/
guint nm_ap_get_priority (NMAccessPoint *ap)
time_t nm_ap_get_timestamp (NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, 0);
return (ap->priority);
return (ap->timestamp);
}
void nm_ap_set_priority (NMAccessPoint *ap, guint priority)
void nm_ap_set_timestamp (NMAccessPoint *ap, time_t timestamp)
{
g_return_if_fail (ap != NULL);
ap->priority = priority;
ap->timestamp = timestamp;
}
@ -181,24 +183,54 @@ void nm_ap_set_essid (NMAccessPoint *ap, gchar * essid)
/*
* Get/set functions for WEP key
* Get/set functions for encryption key
*
*/
gchar * nm_ap_get_wep_key (NMAccessPoint *ap)
gchar * nm_ap_get_enc_key_source (NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, NULL);
return (ap->wep_key);
return (ap->enc_key);
}
void nm_ap_set_wep_key (NMAccessPoint *ap, gchar * wep_key)
void nm_ap_set_enc_key_source (NMAccessPoint *ap, gchar * key)
{
g_return_if_fail (ap != NULL);
if (ap->wep_key)
g_free (ap->wep_key);
if (ap->enc_key)
g_free (ap->enc_key);
ap->wep_key = g_strdup (wep_key);
ap->enc_key = g_strdup (key);
}
gchar *nm_ap_get_enc_key_hashed (NMAccessPoint *ap, NMAPEncMethod method)
{
gchar *hashed = NULL;
char *source_key;
g_return_val_if_fail (ap != NULL, NULL);
source_key = nm_ap_get_enc_key_source (ap);
switch (method)
{
case (NM_AP_ENC_METHOD_104_BIT_PASSPHRASE):
if (source_key)
hashed = nm_wireless_128bit_key_from_passphrase (source_key);
break;
case (NM_AP_ENC_METHOD_40_BIT_PASSPHRASE):
case (NM_AP_ENC_METHOD_HEX_KEY):
case (NM_AP_ENC_METHOD_UNKNOWN):
if (source_key)
hashed = g_strdup (source_key);
break;
default:
hashed = NULL;
break;
}
return (hashed);
}
@ -367,4 +399,24 @@ void nm_ap_set_enc_method (NMAccessPoint *ap, NMAPEncMethod enc_method)
g_return_if_fail (ap != NULL);
ap->enc_method = enc_method;
/* By definition, if the encryption method is "unknown", it cannot be
* "firm" (that is, we know what method we need to use to talk to an ap)
*/
if (enc_method == NM_AP_ENC_METHOD_UNKNOWN)
ap->enc_method_good = FALSE;
}
gboolean nm_ap_get_enc_method_good (NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, FALSE);
return (ap->enc_method_good);
}
void nm_ap_set_enc_method_good (NMAccessPoint *ap, gboolean good)
{
g_return_if_fail (ap != NULL);
ap->enc_method_good = good;
}

View file

@ -27,11 +27,10 @@
typedef struct NMAccessPoint NMAccessPoint;
#define NM_AP_PRIORITY_WORST 1000
typedef enum NMAPEncMethod
{
NM_AP_ENC_METHOD_NONE = 0,
NM_AP_ENC_METHOD_UNKNOWN = 0,
NM_AP_ENC_METHOD_NONE,
NM_AP_ENC_METHOD_HEX_KEY,
NM_AP_ENC_METHOD_40_BIT_PASSPHRASE,
NM_AP_ENC_METHOD_104_BIT_PASSPHRASE
@ -44,14 +43,15 @@ NMAccessPoint *nm_ap_new_from_ap (NMAccessPoint *ap);
void nm_ap_unref (NMAccessPoint *ap);
void nm_ap_ref (NMAccessPoint *ap);
guint nm_ap_get_priority (NMAccessPoint *ap);
void nm_ap_set_priority (NMAccessPoint *ap, guint priority);
time_t nm_ap_get_timestamp (NMAccessPoint *ap);
void nm_ap_set_timestamp (NMAccessPoint *ap, time_t timestamp);
gchar * nm_ap_get_essid (NMAccessPoint *ap);
void nm_ap_set_essid (NMAccessPoint *ap, gchar * essid);
void nm_ap_set_essid (NMAccessPoint *ap, gchar *essid);
gchar * nm_ap_get_wep_key (NMAccessPoint *ap);
void nm_ap_set_wep_key (NMAccessPoint *ap, gchar * wep_key);
gchar * nm_ap_get_enc_key_source (NMAccessPoint *ap);
gchar * nm_ap_get_enc_key_hashed (NMAccessPoint *ap, NMAPEncMethod method);
void nm_ap_set_enc_key_source (NMAccessPoint *ap, gchar *key);
gboolean nm_ap_get_encrypted (NMAccessPoint *ap);
void nm_ap_set_encrypted (NMAccessPoint *ap, gboolean encrypted);
@ -77,4 +77,7 @@ void nm_ap_set_matched (NMAccessPoint *ap, gboolean matched);
NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap);
void nm_ap_set_enc_method (NMAccessPoint *ap, NMAPEncMethod enc_method);
gboolean nm_ap_get_enc_method_good (NMAccessPoint *ap);
void nm_ap_set_enc_method_good (NMAccessPoint *ap, gboolean good);
#endif

View file

@ -233,17 +233,17 @@ void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NM
if ((essid = nm_dbus_get_network_essid (data->dbus_connection, list->type, network)))
{
char *key = nm_dbus_get_network_key (data->dbus_connection, list->type, network);
gint priority = nm_dbus_get_network_priority (data->dbus_connection, list->type, network);
time_t timestamp = nm_dbus_get_network_timestamp (data->dbus_connection, list->type, network);
if (priority >= 0)
if (timestamp >= 0)
{
/* Find access point in list, if not found create a new AP and add it to the list */
if (!(ap = nm_ap_list_get_ap_by_essid (list, network)))
nm_ap_list_append_ap (list, (ap = nm_ap_new ()));
nm_ap_set_essid (ap, essid);
nm_ap_set_wep_key (ap, key);
nm_ap_set_priority (ap, priority);
nm_ap_set_enc_key_source (ap, key);
nm_ap_set_timestamp (ap, timestamp);
}
g_free (essid);
@ -466,8 +466,8 @@ void nm_ap_list_print_members (NMAccessPointList *list, const char *name)
syslog (LOG_DEBUG, "AP_LIST_PRINT: printing members of '%s'", name);
while ((ap = nm_ap_list_iter_next (iter)))
{
syslog (LOG_DEBUG, "\t%d)\tessid='%s', prio=%d, key='%s', enc=%d, addr=0x%X, qual=%d, freq=%f, rate=%d, inval=%d",
i, nm_ap_get_essid (ap), nm_ap_get_priority (ap), nm_ap_get_wep_key (ap), nm_ap_get_encrypted (ap),
syslog (LOG_DEBUG, "\t%d)\tessid='%s', timestamp=%d, key='%s', enc=%d, addr=0x%X, qual=%d, freq=%f, rate=%d, inval=%d",
i, nm_ap_get_essid (ap), nm_ap_get_timestamp (ap), nm_ap_get_enc_key_source (ap), nm_ap_get_encrypted (ap),
nm_ap_get_address (ap), nm_ap_get_quality (ap), nm_ap_get_freq (ap), nm_ap_get_rate (ap),
nm_ap_get_invalid (ap));
i++;

View file

@ -34,7 +34,6 @@ extern gboolean debug;
#include "NetworkManagerDbus.h"
#include "NetworkManagerAP.h"
#include "NetworkManagerAPList.h"
#include "NetworkManagerWireless.h"
/*
@ -336,6 +335,41 @@ void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev
}
/*
* nm_dbus_signal_device_now_active
*
* Notifies the bus that a particular device is newly active.
*
*/
void nm_dbus_signal_device_activating (DBusConnection *connection, NMDevice *dev)
{
DBusMessage *message;
unsigned char *dev_path;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL);
if (!(dev_path = nm_dbus_get_object_path_from_device (dev)))
return;
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceActivating");
if (!message)
{
syslog (LOG_ERR, "nm_dbus_signal_device_activating(): Not enough memory for new dbus message!");
g_free (dev_path);
return;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, dev_path, DBUS_TYPE_INVALID);
g_free (dev_path);
if (!dbus_connection_send (connection, message, NULL))
syslog (LOG_WARNING, "nm_dbus_signal_device_activating(): Could not raise the DeviceActivating signal!");
dbus_message_unref (message);
}
/*
* nm_dbus_signal_device_ip4_address_change
*
@ -593,9 +627,6 @@ static void nm_dbus_set_user_key_for_network (DBusConnection *connection, DBusMe
if ((dev = nm_get_device_by_iface (data, device)))
nm_device_set_user_key_for_network (dev, data->invalid_ap_list, network, passphrase);
char *key = nm_wireless_128bit_key_from_passphrase (passphrase);
g_free (key);
dbus_free (device);
dbus_free (network);
dbus_free (passphrase);
@ -746,30 +777,30 @@ char * nm_dbus_get_network_key (DBusConnection *connection, NMNetworkType type,
/*
* nm_dbus_get_network_priority
* nm_dbus_get_network_timestamp
*
* Get a network's priority from NetworkManagerInfo
* Get a network's timestamp from NetworkManagerInfo
*
* Returns: -1 on error
* AP Priority if no error
* timestamp if no error
*
*/
gint nm_dbus_get_network_priority (DBusConnection *connection, NMNetworkType type, const char *network)
time_t nm_dbus_get_network_timestamp (DBusConnection *connection, NMNetworkType type, const char *network)
{
DBusMessage *message;
DBusError error;
DBusMessage *reply;
guint priority = -1;
time_t timestamp = -1;
g_return_val_if_fail (connection != NULL, -1);
g_return_val_if_fail (network != NULL, -1);
g_return_val_if_fail (type != NETWORK_TYPE_UNKNOWN, -1);
message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH,
NMI_DBUS_INTERFACE, "getNetworkPriority");
NMI_DBUS_INTERFACE, "getNetworkTimestamp");
if (!message)
{
syslog (LOG_ERR, "nm_dbus_get_network_priority(): Couldn't allocate the dbus message");
syslog (LOG_ERR, "nm_dbus_get_network_timestamp(): Couldn't allocate the dbus message");
return (-1);
}
@ -781,21 +812,21 @@ gint nm_dbus_get_network_priority (DBusConnection *connection, NMNetworkType typ
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
if (dbus_error_is_set (&error))
syslog (LOG_ERR, "nm_dbus_get_network_priority(): %s raised %s", error.name, error.message);
syslog (LOG_ERR, "nm_dbus_get_network_timestamp(): %s raised %s", error.name, error.message);
else if (!reply)
syslog (LOG_NOTICE, "nm_dbus_get_network_priority(): reply was NULL.");
syslog (LOG_NOTICE, "nm_dbus_get_network_timestamp(): reply was NULL.");
else
{
dbus_error_init (&error);
if (!dbus_message_get_args (reply, &error, DBUS_TYPE_UINT32, &priority, DBUS_TYPE_INVALID))
priority = -1;
if (!dbus_message_get_args (reply, &error, DBUS_TYPE_INT32, &timestamp, DBUS_TYPE_INVALID))
timestamp = -1;
}
dbus_message_unref (message);
if (reply)
dbus_message_unref (reply);
return (priority);
return (timestamp);
}
@ -1125,8 +1156,8 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection,
if (!success)
{
dbus_message_unref (reply_message);
return (nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoActiveNetwork",
"The device is not associated with any networks at this time."));
return (nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoNetworks",
"The device cannot see any wireless networks."));
}
}
else

View file

@ -47,6 +47,8 @@ void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDev
void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev);
void nm_dbus_signal_device_activating (DBusConnection *connection, NMDevice *dev);
void nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap);
@ -61,7 +63,7 @@ char * nm_dbus_get_network_essid (DBusConnection *connection, NMNetworkType t
char * nm_dbus_get_network_key (DBusConnection *connection, NMNetworkType type, const char *network);
gint nm_dbus_get_network_priority (DBusConnection *connection, NMNetworkType type, const char *network);
time_t nm_dbus_get_network_timestamp (DBusConnection *connection, NMNetworkType type, const char *network);
char ** nm_dbus_get_networks (DBusConnection *connection, NMNetworkType type, int *num_networks);

View file

@ -591,13 +591,15 @@ void nm_device_get_ap_address (NMDevice *dev, struct ether_addr *addr)
/*
* nm_device_set_wep_key
* nm_device_set_enc_key
*
* If a device is wireless, set the WEP key that it should use.
* If a device is wireless, set the encryption key that it should use.
*
* wep_key: WEP key to use, or NULL or "" to disable WEP
* key: encryption key to use, or NULL or "" to disable encryption.
* NOTE that at this time, the key must be the raw HEX key, not
* a passphrase.
*/
void nm_device_set_wep_key (NMDevice *dev, const char *wep_key)
void nm_device_set_enc_key (NMDevice *dev, const char *key)
{
int iwlib_socket;
int err;
@ -610,11 +612,11 @@ void nm_device_set_wep_key (NMDevice *dev, const char *wep_key)
g_return_if_fail (nm_device_is_wireless (dev));
/* Make sure the essid we get passed is a valid size */
if (!wep_key)
if (!key)
safe_key[0] = '\0';
else
{
strncpy (safe_key, wep_key, IW_ENCODING_TOKEN_MAX);
strncpy (safe_key, key, IW_ENCODING_TOKEN_MAX);
safe_key[IW_ENCODING_TOKEN_MAX] = '\0';
}
@ -647,11 +649,11 @@ void nm_device_set_wep_key (NMDevice *dev, const char *wep_key)
{
err = iw_set_ext (iwlib_socket, nm_device_get_iface (dev), SIOCSIWENCODE, &wreq);
if (err == -1)
syslog (LOG_ERR, "nm_device_set_wep_key(): error setting key for device %s. errno = %d", nm_device_get_iface (dev), errno);
syslog (LOG_ERR, "nm_device_set_enc_key(): error setting key for device %s. errno = %d", nm_device_get_iface (dev), errno);
}
close (iwlib_socket);
} else syslog (LOG_ERR, "nm_device_set_wep_key(): could not get wireless control socket.");
} else syslog (LOG_ERR, "nm_device_set_enc_key(): could not get wireless control socket.");
}
@ -811,9 +813,11 @@ gboolean nm_device_is_up (NMDevice *dev)
gboolean nm_device_activation_begin (NMDevice *dev)
{
GError *error = NULL;
NMData *data = (NMData *)dev->app_data;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (!dev->activating, TRUE); // Return if activation has already begun
g_return_val_if_fail (data != NULL, FALSE);
/* Ref the device so it doesn't go away while worker function is active */
nm_device_ref (dev);
@ -831,6 +835,8 @@ gboolean nm_device_activation_begin (NMDevice *dev)
return (FALSE);
}
nm_dbus_signal_device_activating (data->dbus_connection, dev);
return (TRUE);
}
@ -862,12 +868,19 @@ static gboolean nm_device_activate_wireless (NMDevice *dev)
/* If there is a desired AP to connect to, use that essid and possible WEP key */
if (best_ap && nm_ap_get_essid (best_ap))
{
/* Disable WEP */
nm_device_set_wep_key (dev, NULL);
if (nm_ap_get_encrypted (best_ap) && nm_ap_get_wep_key (best_ap))
nm_device_set_wep_key (dev, nm_ap_get_wep_key (best_ap));
nm_device_bring_down (dev);
/* Disable encryption, then re-enable and set correct key on the card
* if we are going to encrypt traffic.
*/
nm_device_set_enc_key (dev, NULL);
if (nm_ap_get_encrypted (best_ap) && nm_ap_get_enc_key_source (best_ap))
{
char *hashed_key = nm_ap_get_enc_key_hashed (best_ap, nm_ap_get_enc_method (best_ap));
nm_device_set_enc_key (dev, hashed_key);
g_free (hashed_key);
}
nm_device_set_essid (dev, nm_ap_get_essid (best_ap));
syslog (LOG_INFO, "nm_device_wireless_activate(%s) using essid '%s'", nm_device_get_iface (dev), nm_ap_get_essid (best_ap));
@ -920,15 +933,47 @@ static gpointer nm_device_activation_worker (gpointer user_data)
if ((best_ap = nm_device_get_best_ap (dev)))
{
/* WEP key we have is wrong, ask user for one */
if ( (!nm_device_need_ap_switch (dev) || !nm_ap_get_wep_key (best_ap))
if ( (!nm_device_need_ap_switch (dev) || !nm_ap_get_enc_key_source (best_ap))
&& nm_ap_get_encrypted (best_ap))
{
dev->options.wireless.user_key_received = FALSE;
nm_dbus_get_user_key_for_network (dev->app_data->dbus_connection, dev, best_ap);
gboolean ask_for_key = TRUE;
/* Wait for the key to come back */
while (!dev->options.wireless.user_key_received && !dev->quit_activation)
g_usleep (G_USEC_PER_SEC / 4);
/* If we have a key, try all the key/passphrase generation methods
* before asking the user for a key.
*/
if (nm_ap_get_enc_key_source (best_ap) && !nm_ap_get_enc_method_good (best_ap))
{
/* Try another method, since the one set before obviously didn't work */
switch (nm_ap_get_enc_method (best_ap))
{
case (NM_AP_ENC_METHOD_UNKNOWN):
nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_104_BIT_PASSPHRASE);
ask_for_key = FALSE;
break;
case (NM_AP_ENC_METHOD_104_BIT_PASSPHRASE):
nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_40_BIT_PASSPHRASE);
ask_for_key = FALSE;
break;
case (NM_AP_ENC_METHOD_40_BIT_PASSPHRASE):
nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_HEX_KEY);
ask_for_key = FALSE;
break;
default:
break;
}
}
if (ask_for_key)
{
dev->options.wireless.user_key_received = FALSE;
nm_dbus_get_user_key_for_network (dev->app_data->dbus_connection, dev, best_ap);
/* Wait for the key to come back */
while (!dev->options.wireless.user_key_received && !dev->quit_activation)
g_usleep (G_USEC_PER_SEC / 2);
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received!", nm_device_get_iface (dev));
}
/* If we were told to quit activation, stop the thread and return */
if (dev->quit_activation)
@ -938,8 +983,6 @@ static gpointer nm_device_activation_worker (gpointer user_data)
nm_device_unref (dev);
return (NULL);
}
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received!", nm_device_get_iface (dev));
}
nm_device_activate_wireless (dev);
@ -957,6 +1000,9 @@ static gpointer nm_device_activation_worker (gpointer user_data)
}
}
/* Since we've got a link, the encryption method must be good */
nm_ap_set_enc_method_good (nm_device_get_best_ap (dev), TRUE);
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): using ESSID '%s'", nm_device_get_iface (dev),
nm_ap_get_essid (nm_device_get_best_ap (dev)));
}
@ -986,7 +1032,7 @@ static gpointer nm_device_activation_worker (gpointer user_data)
if (nm_device_is_wireless (dev))
{
nm_device_set_essid (dev, "");
nm_device_set_wep_key (dev, NULL);
nm_device_set_enc_key (dev, NULL);
}
nm_device_bring_up (dev);
@ -1105,7 +1151,7 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
if (nm_device_is_wireless (dev))
{
nm_device_set_essid (dev, "");
nm_device_set_wep_key (dev, NULL);
nm_device_set_enc_key (dev, NULL);
nm_device_bring_down (dev);
}
@ -1151,9 +1197,12 @@ void nm_device_set_user_key_for_network (NMDevice *dev, NMAccessPointList *inval
* then set the new key on the access point.
*/
if (nm_null_safe_strcmp (network, nm_ap_get_essid (best_ap)) == 0)
nm_ap_set_wep_key (best_ap, key);
{
nm_ap_set_enc_key_source (best_ap, key);
nm_ap_set_enc_method (best_ap, NM_AP_ENC_METHOD_UNKNOWN);
}
}
fprintf( stderr, "Got user key\n");
dev->options.wireless.user_key_received = TRUE;
}
@ -1348,7 +1397,7 @@ gboolean nm_device_need_ap_switch (NMDevice *dev)
*/
void nm_device_update_best_ap (NMDevice *dev)
{
int highest_priority = NM_AP_PRIORITY_WORST;
time_t latest_timestamp = 0;
NMAccessPointList *ap_list;
NMAPListIter *iter;
NMAccessPoint *ap = NULL;
@ -1368,12 +1417,12 @@ void nm_device_update_best_ap (NMDevice *dev)
*/
if (nm_device_get_best_ap_frozen (dev))
{
g_mutex_lock (dev->options.wireless.best_ap_mutex);
best_ap = nm_device_get_best_ap (dev);
/* If its in the device's ap list still, don't change the
* best ap, since its frozen.
*/
g_mutex_lock (dev->options.wireless.best_ap_mutex);
if ( best_ap
&& !nm_ap_list_get_ap_by_essid (dev->app_data->invalid_ap_list, nm_ap_get_essid (best_ap))
&& nm_device_ap_list_get_ap_by_essid (dev, nm_ap_get_essid (best_ap)))
@ -1399,13 +1448,13 @@ void nm_device_update_best_ap (NMDevice *dev)
{
NMAccessPoint *tmp_ap = nm_ap_list_get_ap_by_essid (dev->app_data->trusted_ap_list, ap_essid);
/* If it exists in the trusted ap list, and it has a better priority than
* an access points already tested, make it the best for now.
/* If it exists in the trusted ap list, and it is more recent than
* access points already tested, make it the best for now.
*/
if (tmp_ap && (nm_ap_get_priority (tmp_ap) < highest_priority))
if (tmp_ap && (nm_ap_get_timestamp (tmp_ap) > latest_timestamp))
{
latest_timestamp = nm_ap_get_timestamp (tmp_ap);
best_ap = ap;
highest_priority = nm_ap_get_priority (ap);
}
}
}
@ -1414,7 +1463,7 @@ void nm_device_update_best_ap (NMDevice *dev)
/* If its not in the trusted list, check the preferred list */
if (!best_ap)
{
highest_priority = NM_AP_PRIORITY_WORST;
latest_timestamp = 0;
if (!(iter = nm_ap_list_iter_new (ap_list)))
return;
@ -1427,13 +1476,13 @@ void nm_device_update_best_ap (NMDevice *dev)
{
NMAccessPoint *tmp_ap = nm_ap_list_get_ap_by_essid (dev->app_data->preferred_ap_list, ap_essid);
/* If it exists in the preferred ap list, and it has a better priority than
* an access points already tested, make it the best for now.
/* If it exists in the preferred ap list, and it is more recent than
* access points already tested, make it the best for now.
*/
if ( tmp_ap && (nm_ap_get_priority (tmp_ap) < highest_priority))
if ( tmp_ap && (nm_ap_get_timestamp (tmp_ap) > latest_timestamp))
{
latest_timestamp = nm_ap_get_timestamp (tmp_ap);
best_ap = ap;
highest_priority = nm_ap_get_priority (ap);
}
}
}
@ -1520,9 +1569,15 @@ static void nm_device_do_normal_scan (NMDevice *dev)
nm_ap_set_essid (nm_ap, tmp_ap->b.essid);
if (tmp_ap->b.has_key && (tmp_ap->b.key_flags & IW_ENCODE_DISABLED))
{
nm_ap_set_encrypted (nm_ap, FALSE);
nm_ap_set_enc_method (nm_ap, NM_AP_ENC_METHOD_NONE);
}
else
{
nm_ap_set_encrypted (nm_ap, TRUE);
nm_ap_set_enc_method (nm_ap, NM_AP_ENC_METHOD_UNKNOWN);
}
if (tmp_ap->has_ap_addr)
nm_ap_set_address (nm_ap, (const struct ether_addr *)(tmp_ap->ap_addr.sa_data));
@ -1538,8 +1593,8 @@ static void nm_device_do_normal_scan (NMDevice *dev)
list_ap = nm_ap_list_get_ap_by_essid (data->preferred_ap_list, nm_ap_get_essid (nm_ap));
if (list_ap)
{
nm_ap_set_priority (nm_ap, nm_ap_get_priority (list_ap));
nm_ap_set_wep_key (nm_ap, nm_ap_get_wep_key (list_ap));
nm_ap_set_timestamp (nm_ap, nm_ap_get_timestamp (list_ap));
nm_ap_set_enc_key_source (nm_ap, nm_ap_get_enc_key_source (list_ap));
}
/* Add the AP to the device's AP list */
@ -1551,9 +1606,7 @@ static void nm_device_do_normal_scan (NMDevice *dev)
close (iwlib_socket);
/* Now do a diff of the old and new networks that we can see, and
* signal any changes over dbus, but only if we are the pending or active device.
* Users shouldn't get notification of new wireless networks if the device isn't the
* one that will provide their network connection.
* signal any changes over dbus, but only if we are active device.
*/
if (dev == data->active_device)
nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev));
@ -1608,10 +1661,10 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
nm_device_get_ap_address (dev, &save_ap_addr);
nm_device_set_essid (dev, nm_ap_get_essid (ap));
if (nm_ap_get_wep_key (ap))
nm_device_set_wep_key (dev, nm_ap_get_wep_key (ap));
if (nm_ap_get_enc_key_source (ap))
nm_device_set_enc_key (dev, nm_ap_get_enc_key_source (ap));
else
nm_device_set_wep_key (dev, NULL);
nm_device_set_enc_key (dev, NULL);
/* Wait a bit for association */
g_usleep (G_USEC_PER_SEC);

View file

@ -82,7 +82,7 @@ gboolean nm_device_get_best_ap_frozen (NMDevice *dev);
char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap);
/* There is no function to get the WEP key since that's a slight security risk */
void nm_device_set_wep_key (NMDevice *dev, const char *wep_key);
void nm_device_set_enc_key (NMDevice *dev, const char *key);
gboolean nm_device_activation_begin (NMDevice *dev);
void nm_device_activation_cancel (NMDevice *dev);

View file

@ -51,7 +51,7 @@ gboolean nm_try_acquire_mutex (GMutex *mutex, const char *func)
{
if (g_mutex_trylock (mutex))
{
#ifdef LOCKING_DEBUG
#ifdef LOCKING_DEBUG
if (func) syslog (LOG_DEBUG, "MUTEX: %s got mutex 0x%X", func, mutex);
#endif
return (TRUE);