diff --git a/ChangeLog b/ChangeLog index 31f5ee0dbe..90512e23e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +2006-03-03 Dan Williams + + Fix a crash if an "Other wireless network" was chosen, failed, then + chosen again from the applet's menu. If the other network wasn't + noticed in a scan, it wouldn't have any capabilities, but would still + be listed because the user forced the network. To fix this, we set + sensible capabilities on the forced network, which will get overwritten + with the correct ones if the network shows up later in a scan. + + * src/nm-ap-security.h + - Add a new "get_default_capabilities_func" member to the + NMAPSecurity class + + * src/nm-ap-security.c + - (nm_ap_security_get_default_capabilities): new function + + * src/nm-ap-security.c + src/nm-ap-security-wep.c + src/nm-ap-security-wpa-psk.c + src/nm-ap-security-wpa-eap.c + - Implement get_default_capabilities_func() for all, which + uses the information contained in a specific NMAPSecurity + object to determine default AP capabilites necessary + to support that object + + As a secondary measure, we now prune artificial access points that fail + to be activated right away. The thing failed, and we have no scan data for + it, so it's pretty much useless since security information is only saved + in the applets when a connection is successful. + + * src/NetworkManagerAPList.c + - (nm_ap_list_merge_scanned_ap): mark any ap noticed in a scan + not artificial. If we see it, it's no longer a figment of the + user's imagination :) + + * src/NetworkManagerPolicy.c + - (nm_policy_activation_failed): send along the failed AP if we + have it + + * src/nm-device-802-11-wireless.c + - (real_activation_failure_handler): remove artificial APs from + the device list, because activation failed + 2006-03-02 Robert Love Add support for retrieving both the per-device speed and the diff --git a/src/NetworkManagerAPList.c b/src/NetworkManagerAPList.c index f97a4d5f6c..32e5964933 100644 --- a/src/NetworkManagerAPList.c +++ b/src/NetworkManagerAPList.c @@ -480,6 +480,11 @@ gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointL nm_ap_set_last_seen (list_ap, merge_ap_seen); nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap)); + /* If the AP is noticed in a scan, it's automatically no longer + * artificial, since it clearly exists somewhere. + */ + nm_ap_set_artificial (list_ap, FALSE); + /* Have to change AP's name _after_ dbus signal for old network name * has gone out. */ @@ -511,6 +516,11 @@ gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointL } nm_ap_set_last_seen (list_ap, merge_ap_seen); nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap)); + + /* If the AP is noticed in a scan, it's automatically no longer + * artificial, since it clearly exists somewhere. + */ + nm_ap_set_artificial (list_ap, FALSE); } else { diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index fc7dd31337..fda29a6efc 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -113,6 +113,7 @@ static gboolean nm_policy_activation_failed (NMActRequest *req) { NMDevice * dev = NULL; NMData * data = NULL; + NMAccessPoint *ap = NULL; g_return_val_if_fail (req != NULL, FALSE); @@ -124,8 +125,11 @@ static gboolean nm_policy_activation_failed (NMActRequest *req) nm_device_activation_failure_handler (dev, req); + if (nm_device_is_802_11_wireless (dev)) + ap = nm_act_request_get_ap (req); + nm_info ("Activation (%s) failed.", nm_device_get_iface (dev)); - nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ACTIVATION_FAILED); + nm_dbus_schedule_device_status_change_signal (data, dev, ap, DEVICE_ACTIVATION_FAILED); nm_device_deactivate (dev); nm_schedule_state_change_signal_broadcast (data); diff --git a/src/nm-ap-security-wep.c b/src/nm-ap-security-wep.c index ff8f9ef3b5..bfe487420d 100644 --- a/src/nm-ap-security-wep.c +++ b/src/nm-ap-security-wep.c @@ -140,6 +140,25 @@ out: return success; } +static guint32 +real_get_default_capabilities (NMAPSecurity *instance) +{ + guint32 caps = NM_802_11_CAP_NONE; + + switch (nm_ap_security_get_we_cipher (instance)) + { + case IW_AUTH_CIPHER_WEP40: + caps |= (NM_802_11_CAP_PROTO_WEP | NM_802_11_CAP_CIPHER_WEP40); + break; + case IW_AUTH_CIPHER_WEP104: + caps |= (NM_802_11_CAP_PROTO_WEP | NM_802_11_CAP_CIPHER_WEP104); + break; + default: + break; + } + return caps; +} + static NMAPSecurity * real_copy_constructor (NMAPSecurity *instance) { @@ -167,6 +186,7 @@ nm_ap_security_wep_class_init (NMAPSecurityWEPClass *klass) par_class->copy_constructor_func = real_copy_constructor; 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; g_type_class_add_private (object_class, sizeof (NMAPSecurityWEPPrivate)); } diff --git a/src/nm-ap-security-wpa-eap.c b/src/nm-ap-security-wpa-eap.c index 14dca5ae4f..4ad74053b2 100644 --- a/src/nm-ap-security-wpa-eap.c +++ b/src/nm-ap-security-wpa-eap.c @@ -84,7 +84,6 @@ nm_ap_security_wpa_eap_new_deserialize (DBusMessageIter *iter) security->priv->private_key_file = g_strdup (private_key_file); security->priv->client_cert_file = g_strdup (client_cert_file); security->priv->ca_cert_file = g_strdup (ca_cert_file); - security->priv->wpa_version = wpa_version; if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) nm_ap_security_set_description (NM_AP_SECURITY (security), _("WPA2 Enterprise")); @@ -282,6 +281,22 @@ out: return success; } +static guint32 +real_get_default_capabilities (NMAPSecurity *instance) +{ + NMAPSecurityWPA_EAP *self = NM_AP_SECURITY_WPA_EAP (instance); + guint32 caps = NM_802_11_CAP_NONE; + + if (self->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA) + caps |= NM_802_11_CAP_PROTO_WPA | NM_802_11_CAP_CIPHER_TKIP; + else if (self->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA2) + caps |= NM_802_11_CAP_PROTO_WPA2 | NM_802_11_CAP_CIPHER_CCMP; + + if (self->priv->key_mgmt == IW_AUTH_KEY_MGMT_802_1X) + caps |= NM_802_11_CAP_KEY_MGMT_802_1X; + + return caps; +} static NMAPSecurity * real_copy_constructor (NMAPSecurity *instance) @@ -332,6 +347,7 @@ nm_ap_security_wpa_eap_class_init (NMAPSecurityWPA_EAPClass *klass) par_class->copy_constructor_func = real_copy_constructor; 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; g_type_class_add_private (object_class, sizeof (NMAPSecurityWPA_EAPPrivate)); } diff --git a/src/nm-ap-security-wpa-psk.c b/src/nm-ap-security-wpa-psk.c index 5a234dfaa3..0c1372efd8 100644 --- a/src/nm-ap-security-wpa-psk.c +++ b/src/nm-ap-security-wpa-psk.c @@ -210,6 +210,30 @@ out: return success; } +static guint32 +real_get_default_capabilities (NMAPSecurity *instance) +{ + NMAPSecurityWPA_PSK * self = NM_AP_SECURITY_WPA_PSK (instance); + guint32 caps = NM_802_11_CAP_NONE; + int we_cipher = nm_ap_security_get_we_cipher (instance); + + if (we_cipher == IW_AUTH_CIPHER_TKIP) + caps |= NM_802_11_CAP_CIPHER_TKIP; + else if (we_cipher == IW_AUTH_CIPHER_CCMP) + caps |= NM_802_11_CAP_CIPHER_CCMP; + else if (we_cipher == NM_AUTH_TYPE_WPA_PSK_AUTO) + caps |= (NM_802_11_CAP_CIPHER_TKIP | NM_802_11_CAP_CIPHER_CCMP); + + if (self->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA) + caps |= NM_802_11_CAP_PROTO_WPA; + else if (self->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA2) + caps |= NM_802_11_CAP_PROTO_WPA2; + + if (self->priv->key_mgt == IW_AUTH_KEY_MGMT_PSK) + caps |= NM_802_11_CAP_KEY_MGMT_PSK; + return caps; +} + static NMAPSecurity * real_copy_constructor (NMAPSecurity *instance) { @@ -239,6 +263,7 @@ nm_ap_security_wpa_psk_class_init (NMAPSecurityWPA_PSKClass *klass) par_class->copy_constructor_func = real_copy_constructor; 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; g_type_class_add_private (object_class, sizeof (NMAPSecurityWPA_PSKPrivate)); } diff --git a/src/nm-ap-security.c b/src/nm-ap-security.c index 1722e9fde8..ffeabe14ea 100644 --- a/src/nm-ap-security.c +++ b/src/nm-ap-security.c @@ -142,6 +142,15 @@ nm_ap_security_new_from_ap (NMAccessPoint *ap) } +guint32 +nm_ap_security_get_default_capabilities (NMAPSecurity *self) +{ + g_return_val_if_fail (self != NULL, NM_802_11_CAP_PROTO_NONE); + + return NM_AP_SECURITY_GET_CLASS (self)->get_default_capabilities_func (self); +} + + gboolean nm_ap_security_write_supplicant_config (NMAPSecurity *self, struct wpa_ctrl *ctrl, @@ -223,6 +232,12 @@ real_write_supplicant_config (NMAPSecurity *self, return TRUE; } +static guint32 +real_get_default_capabilities (NMAPSecurity *self) +{ + return NM_802_11_CAP_PROTO_NONE; +} + int nm_ap_security_get_we_cipher (NMAPSecurity *self) { @@ -360,6 +375,7 @@ nm_ap_security_class_init (NMAPSecurityClass *klass) klass->copy_constructor_func = real_copy_constructor; klass->serialize_func = real_serialize; klass->write_supplicant_config_func = real_write_supplicant_config; + klass->get_default_capabilities_func = real_get_default_capabilities; g_type_class_add_private (object_class, sizeof (NMAPSecurityPrivate)); } diff --git a/src/nm-ap-security.h b/src/nm-ap-security.h index f2999a6090..a2344b74ee 100644 --- a/src/nm-ap-security.h +++ b/src/nm-ap-security.h @@ -68,6 +68,8 @@ struct _NMAPSecurityClass struct wpa_ctrl *ctrl, int nwid, gboolean user_created); + + guint32 (*get_default_capabilities_func)(NMAPSecurity *self); }; @@ -93,6 +95,8 @@ gboolean nm_ap_security_write_supplicant_config (NMAPSecurity *self, const char * nm_ap_security_get_description (NMAPSecurity *self); +guint32 nm_ap_security_get_default_capabilities (NMAPSecurity *self); + G_END_DECLS #endif /* NM_AP_SECURITY_H */ diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index cdafc846b5..228a139efc 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -699,6 +699,10 @@ nm_device_802_11_wireless_get_activation_ap (NMDevice80211Wireless *self, nm_ap_set_essid (ap, essid); nm_ap_set_artificial (ap, TRUE); nm_ap_set_broadcast (ap, FALSE); + /* Ensure the AP has some capabilities. They will get overwritten + * with the correct ones next time the AP is seen in a scan. + */ + nm_ap_set_capabilities (ap, nm_ap_security_get_default_capabilities (security)); nm_ap_list_append_ap (dev_ap_list, ap); nm_ap_unref (ap); } @@ -2783,6 +2787,7 @@ real_activation_failure_handler (NMDevice *dev, NMActRequest *req) { NMData * app_data; + NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); NMAccessPoint * ap; app_data = nm_act_request_get_data (req); @@ -2790,9 +2795,25 @@ real_activation_failure_handler (NMDevice *dev, if ((ap = nm_act_request_get_ap (req))) { - /* Add the AP to the invalid list and force a best ap update */ - nm_ap_set_invalid (ap, TRUE); - nm_ap_list_append_ap (app_data->invalid_ap_list, ap); + if (nm_ap_get_artificial (ap)) + { + NMAccessPointList * dev_list; + + /* Artificial APs are ones that don't show up in scans, + * but which the user explicitly attempted to connect to. + * However, if we fail on one of these, remove it from the + * list because we don't have any scan or capability info + * for it, and they are pretty much useless. + */ + dev_list = nm_device_802_11_wireless_ap_list_get (self); + nm_ap_list_remove_ap (dev_list, ap); + } + else + { + /* Add the AP to the invalid list */ + nm_ap_set_invalid (ap, TRUE); + nm_ap_list_append_ap (app_data->invalid_ap_list, ap); + } } nm_info ("Activation (%s) failed for access point (%s)", nm_device_get_iface (dev),