diff options
-rw-r--r-- | libnm-core/nm-utils.c | 32 | ||||
-rw-r--r-- | src/devices/wifi/nm-wifi-ap.c | 30 | ||||
-rw-r--r-- | src/devices/wifi/nm-wifi-utils.c | 178 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 20 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc | 1 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 11 |
6 files changed, 151 insertions, 121 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index a39b6f87ea..cc701b3546 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1214,46 +1214,30 @@ nm_utils_security_valid (NMUtilsSecurityType type, break; case NMU_SEC_WPA_PSK: if (adhoc) - return FALSE; /* FIXME: Kernel WPA Ad-Hoc support is buggy */ + return FALSE; if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA)) return FALSE; if (have_ap) { - /* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and - * they don't have any pairwise ciphers. */ - if (adhoc) { - /* coverity[dead_error_line] */ - if ( (ap_wpa & NM_802_11_AP_SEC_GROUP_TKIP) + if (ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) { + if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_TKIP) && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) return TRUE; - if ( (ap_wpa & NM_802_11_AP_SEC_GROUP_CCMP) + if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_CCMP) && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) return TRUE; - } else { - if (ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) { - if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_TKIP) - && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) - return TRUE; - if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_CCMP) - && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) - return TRUE; - } } return FALSE; } break; case NMU_SEC_WPA2_PSK: - if (adhoc) - return FALSE; /* FIXME: Kernel WPA Ad-Hoc support is buggy */ if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) return FALSE; if (have_ap) { - /* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and - * they don't have any pairwise ciphers, nor any RSA flags yet. */ if (adhoc) { - /* coverity[dead_error_line] */ - if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) - return TRUE; - if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_IBSS_RSN)) + return FALSE; + if ( (ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) return TRUE; } else { if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK) { diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index f4ad7e8642..fe615be816 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -1232,7 +1232,7 @@ nm_wifi_ap_new_fake_from_connection (NMConnection *connection) const char *mode, *band, *key_mgmt; guint32 channel; NM80211ApSecurityFlags flags; - gboolean psk = FALSE, eap = FALSE; + gboolean psk = FALSE, eap = FALSE, adhoc = FALSE; g_return_val_if_fail (connection != NULL, NULL); @@ -1252,9 +1252,10 @@ nm_wifi_ap_new_fake_from_connection (NMConnection *connection) if (mode) { if (!strcmp (mode, "infrastructure")) nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); - else if (!strcmp (mode, "adhoc")) + else if (!strcmp (mode, "adhoc")) { nm_wifi_ap_set_mode (ap, NM_802_11_MODE_ADHOC); - else if (!strcmp (mode, "mesh")) + adhoc = TRUE; + } else if (!strcmp (mode, "mesh")) nm_wifi_ap_set_mode (ap, NM_802_11_MODE_MESH); else if (!strcmp (mode, "ap")) { nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); @@ -1293,7 +1294,7 @@ nm_wifi_ap_new_fake_from_connection (NMConnection *connection) psk = !strcmp (key_mgmt, "wpa-psk"); eap = !strcmp (key_mgmt, "wpa-eap"); - if (psk || eap) { + if (!adhoc && (psk || eap)) { if (has_proto (s_wireless_sec, PROTO_WPA)) { flags = priv->wpa_flags | (eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK); nm_wifi_ap_set_wpa_flags (ap, flags); @@ -1305,8 +1306,27 @@ nm_wifi_ap_new_fake_from_connection (NMConnection *connection) add_pair_ciphers (ap, s_wireless_sec); add_group_ciphers (ap, s_wireless_sec); + } else if (adhoc && psk) { + /* Ad-Hoc has special requirements: proto=RSN, pairwise=CCMP and + * group=CCMP. + */ + flags = priv->wpa_flags | NM_802_11_AP_SEC_KEY_MGMT_PSK; + + /* Clear ciphers; only CCMP is supported */ + 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_GROUP_WEP40 + | NM_802_11_AP_SEC_GROUP_WEP104 + | NM_802_11_AP_SEC_GROUP_TKIP); + + flags |= NM_802_11_AP_SEC_PAIR_CCMP; + flags |= NM_802_11_AP_SEC_GROUP_CCMP; + nm_wifi_ap_set_rsn_flags (ap, flags); + + /* Don't use Ad-Hoc WPA (WPA-none) anymore */ + nm_wifi_ap_set_wpa_flags (ap, NM_802_11_AP_SEC_NONE); } - done: return ap; diff --git a/src/devices/wifi/nm-wifi-utils.c b/src/devices/wifi/nm-wifi-utils.c index abebc0d7dd..6af76981ac 100644 --- a/src/devices/wifi/nm-wifi-utils.c +++ b/src/devices/wifi/nm-wifi-utils.c @@ -302,41 +302,74 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - if (key_mgmt) { - if (!strcmp (key_mgmt, "wpa-psk")) { - if (s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("WPA-PSK authentication is incompatible with 802.1x")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } + if (!nm_streq0 (key_mgmt, "wpa-psk")) + return TRUE; - if (auth_alg && strcmp (auth_alg, "open")) { - /* WPA must use "open" authentication */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA-PSK requires 'open' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } + if (s_8021x) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("WPA-PSK authentication is incompatible with 802.1x")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + + if (auth_alg && !nm_streq (auth_alg, "open")) { + /* WPA must use "open" authentication */ + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA-PSK requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + /* Make sure the AP's capabilities support WPA-PSK */ + if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point does not support PSK but setting requires it")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (adhoc) { + /* Ad-Hoc RSN requires 'rsn' proto, 'ccmp' pairwise, and 'ccmp' group */ + if ( nm_setting_wireless_security_get_num_protos (s_wsec) != 1 + || !nm_streq0 (nm_setting_wireless_security_get_proto (s_wsec, 0), "rsn")) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'rsn' protocol")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); + return FALSE; } - if (!strcmp (key_mgmt, "wpa-psk")) { - /* Make sure the AP's capabilities support WPA-PSK */ - if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) - && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Access point does not support PSK but setting requires it")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } + if ( nm_setting_wireless_security_get_num_pairwise (s_wsec) != 1 + || !nm_streq0 (nm_setting_wireless_security_get_pairwise (s_wsec, 0), "ccmp")) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'ccmp' pairwise cipher")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return FALSE; + } + + if ( nm_setting_wireless_security_get_num_groups (s_wsec) != 1 + || !nm_streq0 (nm_setting_wireless_security_get_group (s_wsec, 0), "ccmp")) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc requires 'ccmp' group cipher")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); + return FALSE; } } @@ -413,51 +446,52 @@ verify_adhoc (NMSettingWirelessSecurity *s_wsec, { const char *key_mgmt = NULL, *leap_username = NULL, *auth_alg = NULL; + if (!adhoc) + return TRUE; + if (s_wsec) { key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); } - if (adhoc) { - if (key_mgmt && !nm_streq (key_mgmt, "none")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Access point mode is Ad-Hoc but setting requires Infrastructure security")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } + if (key_mgmt && !NM_IN_STRSET (key_mgmt, "none", "wpa-psk")) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode requires 'none' or 'wpa-psk' key management")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } - if (s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("Ad-Hoc mode is incompatible with 802.1x security")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } + if (s_8021x) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Ad-Hoc mode is incompatible with 802.1x security")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } - if (leap_username) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Ad-Hoc mode is incompatible with LEAP security")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } + if (leap_username) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode is incompatible with LEAP security")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } - if (auth_alg && strcmp (auth_alg, "open")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Ad-Hoc mode requires 'open' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } + if (auth_alg && !nm_streq (auth_alg, "open")) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; } return TRUE; @@ -713,7 +747,13 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, return FALSE; if (adhoc) { - /* TODO */ + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", + NULL); + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); } else if (s_8021x) { g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index d7385d31a2..20b125a6d3 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -2954,22 +2954,6 @@ fill_wpa_ciphers (shvarFile *ifcfg, list = nm_utils_strsplit_set (p, " "); for (iter = list; iter && *iter; iter++, i++) { - /* Ad-Hoc configurations cannot have pairwise ciphers, and can only - * have one group cipher. Ignore any additional group ciphers and - * any pairwise ciphers specified. - */ - if (adhoc) { - if (group && (i > 0)) { - PARSE_WARNING ("ignoring group cipher '%s' (only one group cipher allowed " - "in Ad-Hoc mode)", *iter); - continue; - } else if (!group) { - PARSE_WARNING ("ignoring pairwise cipher '%s' (pairwise not used " - "in Ad-Hoc mode)", *iter); - continue; - } - } - if (!strcmp (*iter, "CCMP")) { if (group) nm_setting_wireless_security_add_group (wsec, "ccmp"); @@ -3644,8 +3628,8 @@ make_wpa_setting (shvarFile *ifcfg, /* WPA and/or RSN */ if (adhoc) { - /* Ad-Hoc mode only supports WPA proto for now */ - nm_setting_wireless_security_add_proto (wsec, "wpa"); + /* Ad-Hoc mode only supports RSN proto */ + nm_setting_wireless_security_add_proto (wsec, "rsn"); } else { gs_free char *value2 = NULL; const char *v2; diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc index aa00925e1a..c3cadbb857 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc @@ -12,5 +12,6 @@ USERCTL=yes PEERDNS=yes IPV6INIT=no CIPHER_GROUP=CCMP +CIPHER_PAIRWISE=CCMP KEY_MGMT=WPA-PSK diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 998c86f791..96be4880c3 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -3136,14 +3136,14 @@ test_read_wifi_wpa_psk_adhoc (void) g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk"); g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "I wonder what the king is doing tonight?"); - /* Pairwise cipher is unused in adhoc mode */ - g_assert_cmpint (nm_setting_wireless_security_get_num_pairwise (s_wsec), ==, 0); + g_assert_cmpint (nm_setting_wireless_security_get_num_pairwise (s_wsec), ==, 1); + g_assert_cmpstr (nm_setting_wireless_security_get_pairwise (s_wsec, 0), ==, "ccmp"); g_assert_cmpint (nm_setting_wireless_security_get_num_groups (s_wsec), ==, 1); g_assert_cmpstr (nm_setting_wireless_security_get_group (s_wsec, 0), ==, "ccmp"); g_assert_cmpint (nm_setting_wireless_security_get_num_protos (s_wsec), ==, 1); - g_assert_cmpstr (nm_setting_wireless_security_get_proto (s_wsec, 0), ==, "wpa"); + g_assert_cmpstr (nm_setting_wireless_security_get_proto (s_wsec, 0), ==, "rsn"); /* ===== IPv4 SETTING ===== */ @@ -6464,8 +6464,9 @@ test_write_wifi_wpa_psk_adhoc (void) NM_SETTING_WIRELESS_SECURITY_PSK, "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0", NULL); - nm_setting_wireless_security_add_proto (s_wsec, "wpa"); - nm_setting_wireless_security_add_group (s_wsec, "tkip"); + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); /* IP4 setting */ s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); |