static void add_group_ciphers (NMAccessPoint *ap, NMSettingWirelessSecurity *sec) { guint32 num = nm_setting_wireless_security_get_num_groups (sec); guint32 flags = NM_802_11_AP_SEC_NONE; guint32 i; /* If no ciphers are specified, that means "all" WPA ciphers */ if (num == 0) { flags |= NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_GROUP_CCMP; } else { for (i = 0; i < num; i++) { const char *cipher = nm_setting_wireless_security_get_group (sec, i); if (!strcmp (cipher, "wep40")) flags |= NM_802_11_AP_SEC_GROUP_WEP40; else if (!strcmp (cipher, "wep104")) flags |= NM_802_11_AP_SEC_GROUP_WEP104; else if (!strcmp (cipher, "tkip")) flags |= NM_802_11_AP_SEC_GROUP_TKIP; else if (!strcmp (cipher, "ccmp")) flags |= NM_802_11_AP_SEC_GROUP_CCMP; } } if (has_proto (sec, PROTO_WPA)) nm_ap_set_wpa_flags (ap, nm_ap_get_wpa_flags (ap) | flags); if (has_proto (sec, PROTO_RSN)) nm_ap_set_rsn_flags (ap, nm_ap_get_rsn_flags (ap) | flags); }
static void add_pair_ciphers (NMAccessPoint *ap, NMSettingWirelessSecurity *sec) { NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (ap); guint32 num = nm_setting_wireless_security_get_num_pairwise (sec); NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE; guint32 i; /* If no ciphers are specified, that means "all" WPA ciphers */ if (num == 0) { flags |= NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP; } else { for (i = 0; i < num; i++) { const char *cipher = nm_setting_wireless_security_get_pairwise (sec, i); if (!strcmp (cipher, "tkip")) flags |= NM_802_11_AP_SEC_PAIR_TKIP; else if (!strcmp (cipher, "ccmp")) flags |= NM_802_11_AP_SEC_PAIR_CCMP; } } if (has_proto (sec, PROTO_WPA)) nm_ap_set_wpa_flags (ap, priv->wpa_flags | flags); if (has_proto (sec, PROTO_RSN)) nm_ap_set_rsn_flags (ap, priv->rsn_flags | flags); }
NMAccessPoint * nm_ap_new_fake_from_connection (NMConnection *connection) { NMAccessPoint *ap; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; const GByteArray *ssid; const char *mode, *band, *key_mgmt; guint32 channel, flags; gboolean psk = FALSE, eap = FALSE; g_return_val_if_fail (connection != NULL, NULL); s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); g_return_val_if_fail (s_wireless != NULL, NULL); ssid = nm_setting_wireless_get_ssid (s_wireless); g_return_val_if_fail (ssid != NULL, NULL); g_return_val_if_fail (ssid->len > 0, NULL); ap = nm_ap_new (); nm_ap_set_fake (ap, TRUE); nm_ap_set_ssid (ap, ssid); // FIXME: bssid too? mode = nm_setting_wireless_get_mode (s_wireless); if (mode) { if (!strcmp (mode, "infrastructure")) nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); else if (!strcmp (mode, "adhoc")) nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); else goto error; } else { nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); } band = nm_setting_wireless_get_band (s_wireless); channel = nm_setting_wireless_get_channel (s_wireless); if (band && channel) { guint32 freq = channel_to_freq (channel, band); if (freq == 0) goto error; nm_ap_set_freq (ap, freq); } s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); /* Assume presence of a security setting means the AP is encrypted */ if (!s_wireless_sec) goto done; key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); /* Everything below here uses encryption */ nm_ap_set_flags (ap, nm_ap_get_flags (ap) | NM_802_11_AP_FLAGS_PRIVACY); /* Static & Dynamic WEP */ if (!strcmp (key_mgmt, "none") || !strcmp (key_mgmt, "ieee8021x")) goto done; psk = !strcmp (key_mgmt, "wpa-psk"); eap = !strcmp (key_mgmt, "wpa-eap"); if (psk || eap) { if (has_proto (s_wireless_sec, PROTO_WPA)) { flags = nm_ap_get_wpa_flags (ap); flags |= eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK; nm_ap_set_wpa_flags (ap, flags); } if (has_proto (s_wireless_sec, PROTO_RSN)) { flags = nm_ap_get_rsn_flags (ap); flags |= eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK; nm_ap_set_rsn_flags (ap, flags); } add_pair_ciphers (ap, s_wireless_sec); add_group_ciphers (ap, s_wireless_sec); } else if (!strcmp (key_mgmt, "wpa-none")) { guint32 i; /* Ad-Hoc has special requirements: proto=WPA, pairwise=(none), and * group=TKIP/CCMP (but not both). */ flags = nm_ap_get_wpa_flags (ap); flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; /* Clear ciphers; pairwise must be unset anyway, and group gets set below */ flags &= ~( NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104 | NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104 | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_GROUP_CCMP); for (i = 0; i < nm_setting_wireless_security_get_num_groups (s_wireless_sec); i++) { if (!strcmp (nm_setting_wireless_security_get_group (s_wireless_sec, i), "ccmp")) { flags |= NM_802_11_AP_SEC_GROUP_CCMP; break; } } /* Default to TKIP since not all WPA-capable cards can do CCMP */ if (!(flags & NM_802_11_AP_SEC_GROUP_CCMP)) flags |= NM_802_11_AP_SEC_GROUP_TKIP; nm_ap_set_wpa_flags (ap, flags); /* Don't use Ad-Hoc RSN yet */ nm_ap_set_rsn_flags (ap, NM_802_11_AP_SEC_NONE); } done: return ap; error: g_object_unref (ap); return NULL; }
static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; const char *ctype; const char *hwaddr, *setting_hwaddr; NMDeviceWifiCapabilities wifi_caps; const char *key_mgmt; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); ctype = nm_setting_connection_get_connection_type (s_con); if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) != 0) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_NOT_WIFI_CONNECTION, "The connection was not a Wi-Fi connection."); return FALSE; } s_wifi = nm_connection_get_setting_wireless (connection); if (!s_wifi) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_INVALID_WIFI_CONNECTION, "The connection was not a valid Wi-Fi connection."); return FALSE; } /* Check MAC address */ hwaddr = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); if (hwaddr) { if (!nm_utils_hwaddr_valid (hwaddr, ETH_ALEN)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_INVALID_DEVICE_MAC, "Invalid device MAC address."); return FALSE; } setting_hwaddr = nm_setting_wireless_get_mac_address (s_wifi); if (setting_hwaddr && !nm_utils_hwaddr_matches (setting_hwaddr, -1, hwaddr, -1)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_MAC_MISMATCH, "The MACs of the device and the connection didn't match."); return FALSE; } } /* Check device capabilities; we assume all devices can do WEP at least */ wifi_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device)); s_wsec = nm_connection_get_setting_wireless_security (connection); if (s_wsec) { /* Connection has security, verify it against the device's capabilities */ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); if ( !g_strcmp0 (key_mgmt, "wpa-none") || !g_strcmp0 (key_mgmt, "wpa-psk") || !g_strcmp0 (key_mgmt, "wpa-eap")) { /* Is device only WEP capable? */ if (!(wifi_caps & WPA_CAPS)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_MISSING_DEVICE_WPA_CAPS, "The device missed WPA capabilities required by the connection."); return FALSE; } /* Make sure WPA2/RSN-only connections don't get chosen for WPA-only cards */ if (has_proto (s_wsec, "rsn") && !has_proto (s_wsec, "wpa") && !(wifi_caps & RSN_CAPS)) { g_set_error (error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_MISSING_DEVICE_RSN_CAPS, "The device missed WPA2/RSN capabilities required by the connection."); return FALSE; } } } return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->connection_compatible (device, connection, error); }