2006-08-10 Dan Williams <dcbw@redhat.com>
Patch from Valentine Sinitsyn <e_val@inbox.ru> * src/nm-ap-security.c src/nm-ap-security.h - Add authentication_required bits for subclasses to specify whether or not real authentication is required for connections, i.e. whether the AP rejects us when an encryption key is wrong or not. * src/nm-ap-security-wep.c src/nm-ap-security-wpa-eap.c src/nm-ap-security-wpa-psk.c src/nm-ap-security-leap.c - Implement authentication_required appropriately for each method * src/nm-device-802-11-wireless.c - Be smarter about when to request a key; for example, using a wrong key in WEP shared key mode previously just timed out and did not request a new key git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1954 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
20
ChangeLog
20
ChangeLog
@@ -1,3 +1,23 @@
|
||||
2006-08-10 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
Patch from Valentine Sinitsyn <e_val@inbox.ru>
|
||||
* src/nm-ap-security.c
|
||||
src/nm-ap-security.h
|
||||
- Add authentication_required bits for subclasses to specify whether
|
||||
or not real authentication is required for connections, i.e. whether
|
||||
the AP rejects us when an encryption key is wrong or not.
|
||||
|
||||
* src/nm-ap-security-wep.c
|
||||
src/nm-ap-security-wpa-eap.c
|
||||
src/nm-ap-security-wpa-psk.c
|
||||
src/nm-ap-security-leap.c
|
||||
- Implement authentication_required appropriately for each method
|
||||
|
||||
* src/nm-device-802-11-wireless.c
|
||||
- Be smarter about when to request a key; for example, using a wrong key
|
||||
in WEP shared key mode previously just timed out and did not request
|
||||
a new key
|
||||
|
||||
2006-08-13 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* gnome/libnm_glib/libnm_glib.c
|
||||
|
@@ -152,6 +152,13 @@ real_get_default_capabilities (NMAPSecurity *instance)
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_get_authentication_required (NMAPSecurity *instance)
|
||||
{
|
||||
/* LEAP always requires authentication. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMAPSecurity *
|
||||
real_copy_constructor (NMAPSecurity *instance)
|
||||
{
|
||||
@@ -186,6 +193,7 @@ nm_ap_security_leap_class_init (NMAPSecurityLEAPClass *klass)
|
||||
par_class->serialize_func = real_serialize;
|
||||
par_class->write_supplicant_config_func = real_write_supplicant_config;
|
||||
par_class->get_default_capabilities_func = real_get_default_capabilities;
|
||||
par_class->get_authentication_required_func = real_get_authentication_required;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMAPSecurityLEAPPrivate));
|
||||
}
|
||||
|
@@ -174,6 +174,13 @@ real_get_default_capabilities (NMAPSecurity *instance)
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_get_authentication_required (NMAPSecurity *instance)
|
||||
{
|
||||
/* WEP really requires authentication in Shared mode only */
|
||||
return (get_auth_algorithm (NM_AP_SECURITY_WEP (instance)) == IW_AUTH_ALG_SHARED_KEY);
|
||||
}
|
||||
|
||||
static NMAPSecurity *
|
||||
real_copy_constructor (NMAPSecurity *instance)
|
||||
{
|
||||
@@ -202,6 +209,7 @@ nm_ap_security_wep_class_init (NMAPSecurityWEPClass *klass)
|
||||
par_class->serialize_func = real_serialize;
|
||||
par_class->write_supplicant_config_func = real_write_supplicant_config;
|
||||
par_class->get_default_capabilities_func = real_get_default_capabilities;
|
||||
par_class->get_authentication_required_func = real_get_authentication_required;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMAPSecurityWEPPrivate));
|
||||
}
|
||||
|
@@ -321,6 +321,13 @@ real_get_default_capabilities (NMAPSecurity *instance)
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_get_authentication_required (NMAPSecurity *instance)
|
||||
{
|
||||
/* WPA Enterprise is all about strong security */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMAPSecurity *
|
||||
real_copy_constructor (NMAPSecurity *instance)
|
||||
{
|
||||
@@ -372,6 +379,7 @@ nm_ap_security_wpa_eap_class_init (NMAPSecurityWPA_EAPClass *klass)
|
||||
par_class->serialize_func = real_serialize;
|
||||
par_class->write_supplicant_config_func = real_write_supplicant_config;
|
||||
par_class->get_default_capabilities_func = real_get_default_capabilities;
|
||||
par_class->get_authentication_required_func = real_get_authentication_required;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMAPSecurityWPA_EAPPrivate));
|
||||
}
|
||||
|
@@ -234,6 +234,13 @@ real_get_default_capabilities (NMAPSecurity *instance)
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_get_authentication_required (NMAPSecurity *instance)
|
||||
{
|
||||
/* WPA Personal always requires authentication in the infrastructure mode. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMAPSecurity *
|
||||
real_copy_constructor (NMAPSecurity *instance)
|
||||
{
|
||||
@@ -264,6 +271,7 @@ nm_ap_security_wpa_psk_class_init (NMAPSecurityWPA_PSKClass *klass)
|
||||
par_class->serialize_func = real_serialize;
|
||||
par_class->write_supplicant_config_func = real_write_supplicant_config;
|
||||
par_class->get_default_capabilities_func = real_get_default_capabilities;
|
||||
par_class->get_authentication_required_func = real_get_authentication_required;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMAPSecurityWPA_PSKPrivate));
|
||||
}
|
||||
|
@@ -158,6 +158,14 @@ nm_ap_security_get_default_capabilities (NMAPSecurity *self)
|
||||
return NM_AP_SECURITY_GET_CLASS (self)->get_default_capabilities_func (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ap_security_get_authentication_required (NMAPSecurity *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
return NM_AP_SECURITY_GET_CLASS (self)->get_authentication_required_func (self);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
nm_ap_security_write_supplicant_config (NMAPSecurity *self,
|
||||
|
@@ -70,6 +70,7 @@ struct _NMAPSecurityClass
|
||||
gboolean adhoc);
|
||||
|
||||
guint32 (*get_default_capabilities_func)(NMAPSecurity *self);
|
||||
gboolean (*get_authentication_required_func)(NMAPSecurity *self);
|
||||
};
|
||||
|
||||
|
||||
@@ -99,6 +100,8 @@ const char * nm_ap_security_get_description (NMAPSecurity *self);
|
||||
|
||||
guint32 nm_ap_security_get_default_capabilities (NMAPSecurity *self);
|
||||
|
||||
gboolean nm_ap_security_get_authentication_required (NMAPSecurity *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_AP_SECURITY_H */
|
||||
|
@@ -2333,6 +2333,62 @@ ap_need_key (NMDevice80211Wireless *self,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ap_is_auth_required
|
||||
*
|
||||
* Checks whether or not there is an encryption key present for
|
||||
* this connection, and whether or not the authentication method
|
||||
* in use will result in an authentication rejection if the key
|
||||
* is wrong. For example, Ad Hoc mode networks don't have a
|
||||
* master node and therefore nothing exists to reject the station.
|
||||
* Similarly, Open System WEP access points don't reject a station
|
||||
* when the key is wrong. Shared Key WEP access points will.
|
||||
*
|
||||
* Theory of operation here is that if:
|
||||
* (a) the NMAPSecurity object specifies that authentication is
|
||||
* required, and the AP rejects our authentication attempt during
|
||||
* connection (which shows up as a wpa_supplicant disconnection
|
||||
* event); or
|
||||
* (b) the NMAPSecurity object specifies that no authentiation is
|
||||
* required, and either DHCP times out or wpa_supplicant times out;
|
||||
*
|
||||
* then we need a new key from the user because our currenty key
|
||||
* and/or authentication method is likely wrong.
|
||||
*
|
||||
*/
|
||||
static gboolean
|
||||
ap_is_auth_required (NMAccessPoint *ap, gboolean *has_key)
|
||||
{
|
||||
NMAPSecurity *security;
|
||||
int we_cipher;
|
||||
gboolean auth_required = FALSE;
|
||||
|
||||
g_return_val_if_fail (ap != NULL, FALSE);
|
||||
g_return_val_if_fail (has_key != NULL, FALSE);
|
||||
|
||||
*has_key = FALSE;
|
||||
|
||||
/* Ad Hoc mode doesn't have any master station to validate
|
||||
* security credentials, so no auth can possibly be required.
|
||||
*/
|
||||
if (nm_ap_get_mode(ap) == IW_MODE_ADHOC)
|
||||
return FALSE;
|
||||
|
||||
/* No encryption obviously means no possiblity of auth
|
||||
* rejection due to a wrong encryption key.
|
||||
*/
|
||||
security = nm_ap_get_security (ap);
|
||||
we_cipher = nm_ap_security_get_we_cipher (security);
|
||||
if (we_cipher == IW_AUTH_CIPHER_NONE)
|
||||
return FALSE;
|
||||
|
||||
auth_required = nm_ap_security_get_authentication_required (security);
|
||||
*has_key = TRUE;
|
||||
|
||||
return auth_required;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* WPA Supplicant control stuff
|
||||
*
|
||||
@@ -2459,15 +2515,42 @@ supplicant_watch_cb (GPid pid,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* link_timeout_cb
|
||||
*
|
||||
* Called when the link to the access point has been down for a specified
|
||||
* period of time.
|
||||
*/
|
||||
static gboolean
|
||||
link_timeout_cb (gpointer user_data)
|
||||
{
|
||||
NMDevice * dev = NM_DEVICE (user_data);
|
||||
NMDevice * dev = NM_DEVICE (user_data);
|
||||
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
|
||||
NMActRequest * req = nm_device_get_act_request (dev);
|
||||
NMAccessPoint * ap = nm_act_request_get_ap (req);
|
||||
NMData * data = nm_device_get_app_data (dev);
|
||||
gboolean has_key;
|
||||
|
||||
g_assert (dev);
|
||||
|
||||
nm_info ("%s: link timed out.", nm_device_get_iface (dev));
|
||||
nm_device_set_active_link (dev, FALSE);
|
||||
/* Disconnect event during initial authentication and credentials
|
||||
* ARE checked - we are likely to have wrong key. Ask the user for
|
||||
* another one.
|
||||
*/
|
||||
if ( (nm_act_request_get_stage (req) == NM_ACT_STAGE_DEVICE_CONFIG)
|
||||
&& (ap_is_auth_required (ap, &has_key) && has_key))
|
||||
{
|
||||
/* Association/authentication failed, we must have bad encryption key */
|
||||
nm_info ("Activation (%s/wireless): disconnected during association,"
|
||||
" asking for new key.", nm_device_get_iface (dev));
|
||||
supplicant_remove_timeout(self);
|
||||
nm_dbus_get_user_key_for_network (data->dbus_connection, req, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
nm_info ("%s: link timed out.", nm_device_get_iface (dev));
|
||||
nm_device_set_active_link (dev, FALSE);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2561,19 +2644,43 @@ get_supplicant_timeout (NMDevice80211Wireless *self)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* supplicant_timeout_cb
|
||||
*
|
||||
* Called when the supplicant has been unable to connect to an access point
|
||||
* within a specified period of time.
|
||||
*/
|
||||
static gboolean
|
||||
supplicant_timeout_cb (gpointer user_data)
|
||||
{
|
||||
NMDevice * dev = NM_DEVICE (user_data);
|
||||
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
|
||||
NMActRequest * req = nm_device_get_act_request (dev);
|
||||
NMAccessPoint * ap = nm_act_request_get_ap (req);
|
||||
NMData * data = nm_device_get_app_data (dev);
|
||||
gboolean has_key;
|
||||
|
||||
g_assert (self);
|
||||
|
||||
nm_info ("Activation (%s/wireless): association took too long (>%us), failing activation.",
|
||||
nm_device_get_iface (dev), get_supplicant_timeout (self));
|
||||
|
||||
if (nm_device_is_activating (dev))
|
||||
nm_policy_schedule_activation_failed (nm_device_get_act_request (dev));
|
||||
|
||||
/* Timed out waiting for authentication success; if the security method
|
||||
* in use does not require access point side authentication (Open System
|
||||
* WEP, for example) then we are likely using the wrong authentication
|
||||
* algorithm or key. Request new one from the user.
|
||||
*/
|
||||
if (!ap_is_auth_required (ap, &has_key) && has_key)
|
||||
{
|
||||
/* Activation failed, we must have bad encryption key */
|
||||
nm_info ("Activation (%s/wireless): association took too long (>%us), asking for new key.",
|
||||
nm_device_get_iface (dev), get_supplicant_timeout (self));
|
||||
nm_dbus_get_user_key_for_network (data->dbus_connection, req, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
nm_info ("Activation (%s/wireless): association took too long (>%us), failing activation.",
|
||||
nm_device_get_iface (dev), get_supplicant_timeout (self));
|
||||
if (nm_device_is_activating (dev))
|
||||
nm_policy_schedule_activation_failed (nm_device_get_act_request (dev));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3034,6 +3141,7 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
|
||||
NMIP4Config * real_config = NULL;
|
||||
NMAPSecurity * security;
|
||||
NMData * data;
|
||||
gboolean has_key;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
@@ -3046,10 +3154,13 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
|
||||
security = nm_ap_get_security (ap);
|
||||
g_assert (security);
|
||||
|
||||
/* FIXME: should we only ask for a new key if the activation request is user-requested? */
|
||||
if (nm_ap_security_get_we_cipher (security) != IW_AUTH_CIPHER_NONE)
|
||||
/* If the security credentials' validity was not checked by any
|
||||
* peer during authentication process, and DHCP times out, then
|
||||
* the encryption key is likely wrong. Ask the user for a new one.
|
||||
*/
|
||||
if (!ap_is_auth_required (ap, &has_key) && has_key)
|
||||
{
|
||||
/* Activation failed, we must have bad WEP key */
|
||||
/* Activation failed, we must have bad encryption key */
|
||||
nm_debug ("Activation (%s/wireless): could not get IP configuration info for '%s', asking for new key.",
|
||||
nm_device_get_iface (dev), nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)");
|
||||
nm_dbus_get_user_key_for_network (data->dbus_connection, req, TRUE);
|
||||
|
Reference in New Issue
Block a user