diff options
Diffstat (limited to 'src/supplicant')
| -rw-r--r-- | src/supplicant/nm-supplicant-config.c | 75 | ||||
| -rw-r--r-- | src/supplicant/nm-supplicant-interface.c | 43 | ||||
| -rw-r--r-- | src/supplicant/nm-supplicant-manager.c | 70 | ||||
| -rw-r--r-- | src/supplicant/nm-supplicant-manager.h | 3 | ||||
| -rw-r--r-- | src/supplicant/nm-supplicant-settings-verify.c | 20 | ||||
| -rw-r--r-- | src/supplicant/tests/meson.build | 1 | ||||
| -rw-r--r-- | src/supplicant/tests/test-supplicant-config.c | 72 |
7 files changed, 209 insertions, 75 deletions
diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 4acb634e..7708224b 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -23,7 +23,6 @@ #include "nm-supplicant-config.h" -#include <string.h> #include <stdlib.h> #include "nm-core-internal.h" @@ -404,11 +403,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self, value = nm_setting_macsec_get_mka_cak (setting); if ( !value - || !_nm_utils_hexstr2bin_buf (value, - FALSE, - FALSE, - NULL, - buffer_cak)) { + || !nm_utils_hexstr2bin_buf (value, + FALSE, + FALSE, + NULL, + buffer_cak)) { g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, @@ -425,11 +424,11 @@ nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self, value = nm_setting_macsec_get_mka_ckn (setting); if ( !value - || !_nm_utils_hexstr2bin_buf (value, - FALSE, - FALSE, - NULL, - buffer_ckn)) { + || !nm_utils_hexstr2bin_buf (value, + FALSE, + FALSE, + NULL, + buffer_ckn)) { g_set_error_literal (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, @@ -705,14 +704,14 @@ add_wep_key (NMSupplicantConfig *self, if ((key_len == 10) || (key_len == 26)) { guint8 buffer[26/2]; - if (!_nm_utils_hexstr2bin_full (key, - FALSE, - FALSE, - NULL, - key_len / 2, - buffer, - sizeof (buffer), - NULL)) { + if (!nm_utils_hexstr2bin_full (key, + FALSE, + FALSE, + NULL, + key_len / 2, + buffer, + sizeof (buffer), + NULL)) { g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "cannot add wep-key %s to suplicant config because key is not hex", name); @@ -807,15 +806,30 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, if (psk) { size_t psk_len = strlen (psk); - if (psk_len == 64) { + + if (psk_len >= 8 && psk_len <= 63) { + /* Use TYPE_STRING here so that it gets pushed to the + * supplicant as a string, and therefore gets quoted, + * and therefore the supplicant will interpret it as a + * passphrase and not a hex key. + */ + if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, "<hidden>", error)) + return FALSE; + } else if (nm_streq (key_mgmt, "sae")) { + /* If the SAE password doesn't comply with WPA-PSK limitation, + * we need to call it "sae_password" instead of "psk". + */ + if (!nm_supplicant_config_add_option_with_type (self, "sae_password", psk, -1, TYPE_STRING, "<hidden>", error)) + return FALSE; + } else if (psk_len == 64) { guint8 buffer[32]; /* Hex PSK */ - if (!_nm_utils_hexstr2bin_buf (psk, - FALSE, - FALSE, - NULL, - buffer)) { + if (!nm_utils_hexstr2bin_buf (psk, + FALSE, + FALSE, + NULL, + buffer)) { g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "Cannot add psk to supplicant config due to invalid hex"); return FALSE; @@ -827,14 +841,6 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, "<hidden>", error)) return FALSE; - } else if (psk_len >= 8 && psk_len <= 63) { - /* Use TYPE_STRING here so that it gets pushed to the - * supplicant as a string, and therefore gets quoted, - * and therefore the supplicant will interpret it as a - * passphrase and not a hex key. - */ - if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, "<hidden>", error)) - return FALSE; } else { g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "Cannot add psk to supplicant config due to invalid PSK length %u (not between 8 and 63 characters)", @@ -861,7 +867,8 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, /* Only WPA-specific things when using WPA */ if ( !strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk") - || !strcmp (key_mgmt, "wpa-eap")) { + || !strcmp (key_mgmt, "wpa-eap") + || !strcmp (key_mgmt, "sae")) { if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, proto, protos, "proto", ' ', TRUE, NULL, error)) return FALSE; if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, pairwise, pairwise, "pairwise", ' ', TRUE, NULL, error)) diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c index c30adc58..f46689eb 100644 --- a/src/supplicant/nm-supplicant-interface.c +++ b/src/supplicant/nm-supplicant-interface.c @@ -25,7 +25,6 @@ #include "nm-supplicant-manager.h" #include <stdio.h> -#include <string.h> #include "NetworkManagerUtils.h" #include "nm-supplicant-config.h" @@ -729,9 +728,8 @@ iface_set_pmf_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) self = NM_SUPPLICANT_INTERFACE (user_data); - /* This can fail if the supplicant doesn't support PMF */ if (error) - _LOGD ("failed to set Pmf=1: %s", error->message); + _LOGW ("failed to set Pmf=1: %s", error->message); iface_check_ready (self); } @@ -1452,7 +1450,7 @@ p2p_props_changed_cb (GDBusProxy *proxy, /* We already have the proxy, nothing to do. */ } else if (path && g_strcmp0 (path, "/") != 0) { if (priv->group_proxy != NULL) { - _LOGW ("P2P: Unexpected udpate of the group object path"); + _LOGW ("P2P: Unexpected update of the group object path"); priv->group_proxy_acquired = FALSE; _notify (self, PROP_P2P_GROUP_JOINED); _notify (self, PROP_P2P_GROUP_PATH); @@ -1548,7 +1546,7 @@ p2p_group_started (GDBusProxy *proxy, } } - /* Signal existance of the (new) interface. */ + /* Signal existence of the (new) interface. */ g_signal_emit (self, signals[GROUP_STARTED], 0, iface); g_object_unref (iface); } @@ -1639,21 +1637,9 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ NULL, NULL); - /* Initialize global PMF setting to 'optional' */ - priv->ready_count++; - g_dbus_proxy_call (priv->iface_proxy, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new ("(ssv)", - WPAS_DBUS_IFACE_INTERFACE, - "Pmf", - g_variant_new_string ("1")), - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->init_cancellable, - (GAsyncReadyCallback) iface_set_pmf_cb, - self); - - /* Check whether NetworkReply and AP mode are supported */ + /* Check whether NetworkReply and AP mode are supported. + * ready_count was initialized to 1 in interface_add_done(). + */ g_dbus_proxy_call (priv->iface_proxy, "NetworkReply", g_variant_new ("(oss)", @@ -1666,6 +1652,22 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_ (GAsyncReadyCallback) iface_check_netreply_cb, self); + if (priv->pmf_support == NM_SUPPLICANT_FEATURE_YES) { + /* Initialize global PMF setting to 'optional' */ + priv->ready_count++; + g_dbus_proxy_call (priv->iface_proxy, + DBUS_INTERFACE_PROPERTIES ".Set", + g_variant_new ("(ssv)", + WPAS_DBUS_IFACE_INTERFACE, + "Pmf", + g_variant_new_string ("1")), + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->init_cancellable, + (GAsyncReadyCallback) iface_set_pmf_cb, + self); + } + if (priv->ap_support == NM_SUPPLICANT_FEATURE_UNKNOWN) { /* If the global supplicant capabilities property is not present, we can * fall back to checking whether the ProbeRequest method is supported. If @@ -2482,7 +2484,6 @@ nm_supplicant_interface_p2p_start_find (NMSupplicantInterface *self, priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - /* Find parameters */ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&builder, "{sv}", "Timeout", g_variant_new_int32 (timeout)); diff --git a/src/supplicant/nm-supplicant-manager.c b/src/supplicant/nm-supplicant-manager.c index 64a057f3..104aeee7 100644 --- a/src/supplicant/nm-supplicant-manager.c +++ b/src/supplicant/nm-supplicant-manager.c @@ -23,8 +23,6 @@ #include "nm-supplicant-manager.h" -#include <string.h> - #include "nm-supplicant-interface.h" #include "nm-supplicant-types.h" #include "nm-core-internal.h" @@ -71,7 +69,7 @@ NM_CACHED_QUARK_FCN ("nm-supplicant-error-quark", nm_supplicant_error_quark) /*****************************************************************************/ -static inline gboolean +static gboolean die_count_exceeded (guint32 count) { return count > 2; @@ -125,6 +123,72 @@ _sup_iface_last_ref (gpointer data, g_object_remove_toggle_ref ((GObject *) sup_iface, _sup_iface_last_ref, self); } +static void +on_supplicant_wfd_ies_set (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + gs_unref_variant GVariant *result = NULL; + gs_free_error GError *error = NULL; + + result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); + + if (!result) + _LOGW ("failed to set WFD IEs on wpa_supplicant: %s", error->message); +} + +/** + * nm_supplicant_manager_set_wfd_ies: + * @self: the #NMSupplicantManager + * @wfd_ies: a #GBytes with the WFD IEs or %NULL + * + * This function sets the global WFD IEs on wpa_supplicant. Note that + * it would make more sense if this was per-device, but wpa_supplicant + * simply does not work that way. + * */ +void +nm_supplicant_manager_set_wfd_ies (NMSupplicantManager *self, + GBytes *wfd_ies) +{ + NMSupplicantManagerPrivate *priv; + GVariantBuilder params; + GVariant *val; + + g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self)); + + priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + + _LOGD ("setting WFD IEs for P2P operation"); + + if (wfd_ies) + val = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + g_bytes_get_data (wfd_ies, NULL), + g_bytes_get_size (wfd_ies), + sizeof (guint8)); + else + val = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + NULL, 0, sizeof (guint8)); + + g_variant_builder_init (¶ms, G_VARIANT_TYPE ("(ssv)")); + + g_variant_builder_add (¶ms, "s", g_dbus_proxy_get_interface_name (priv->proxy)); + g_variant_builder_add (¶ms, "s", "WFDIEs"); + g_variant_builder_add_value (¶ms, g_variant_new_variant (val)); + + g_dbus_connection_call (g_dbus_proxy_get_connection (priv->proxy), + g_dbus_proxy_get_name (priv->proxy), + g_dbus_proxy_get_object_path (priv->proxy), + "org.freedesktop.DBus.Properties", + "Set", + g_variant_builder_end (¶ms), + G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 1000, + NULL, + on_supplicant_wfd_ies_set, + NULL); +} + /** * nm_supplicant_manager_create_interface: * @self: the #NMSupplicantManager diff --git a/src/supplicant/nm-supplicant-manager.h b/src/supplicant/nm-supplicant-manager.h index 7225a36b..058745fb 100644 --- a/src/supplicant/nm-supplicant-manager.h +++ b/src/supplicant/nm-supplicant-manager.h @@ -38,6 +38,9 @@ GType nm_supplicant_manager_get_type (void); NMSupplicantManager *nm_supplicant_manager_get (void); +void nm_supplicant_manager_set_wfd_ies (NMSupplicantManager *self, + GBytes *wfd_ies); + NMSupplicantInterface *nm_supplicant_manager_create_interface (NMSupplicantManager *mgr, const char *ifname, NMSupplicantDriver driver); diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c index 1e25675d..f10bbb04 100644 --- a/src/supplicant/nm-supplicant-settings-verify.c +++ b/src/supplicant/nm-supplicant-settings-verify.c @@ -24,8 +24,6 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <errno.h> struct Opt { const char * key; @@ -72,7 +70,7 @@ const char * proto_allowed[] = { "WPA", "RSN", NULL }; const char * key_mgmt_allowed[] = { "WPA-PSK", "WPA-PSK-SHA256", "WPA-EAP", "WPA-EAP-SHA256", "FILS-SHA256", "FILS-SHA384", - "IEEE8021X", "WPA-NONE", + "IEEE8021X", "WPA-NONE", "SAE", "NONE", NULL }; const char * auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL }; const char * eap_allowed[] = { "LEAP", "MD5", "TLS", "PEAP", "TTLS", "SIM", @@ -159,23 +157,13 @@ validate_type_int (const struct Opt * opt, const char * value, const guint32 len) { - long int intval; + gint64 v; g_return_val_if_fail (opt != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); - errno = 0; - intval = strtol (value, NULL, 10); - if (errno != 0) - return FALSE; - - /* strtol returns a long, but we are dealing with ints */ - if (intval > INT_MAX || intval < INT_MIN) - return FALSE; - if (intval > opt->int_high || intval < opt->int_low) - return FALSE; - - return TRUE; + v = _nm_utils_ascii_str_to_int64 (value, 10, opt->int_low, opt->int_high, G_MININT64); + return v != G_MININT64 || errno == 0; } static gboolean diff --git a/src/supplicant/tests/meson.build b/src/supplicant/tests/meson.build index 7cc9d6af..fbccb313 100644 --- a/src/supplicant/tests/meson.build +++ b/src/supplicant/tests/meson.build @@ -10,4 +10,5 @@ test( 'supplicant/' + test_unit, test_script, args: test_args + [exe.full_path()], + timeout: default_test_timeout, ) diff --git a/src/supplicant/tests/test-supplicant-config.c b/src/supplicant/tests/test-supplicant-config.c index d7ec1fe2..2c7a71a3 100644 --- a/src/supplicant/tests/test-supplicant-config.c +++ b/src/supplicant/tests/test-supplicant-config.c @@ -23,7 +23,6 @@ #include <stdio.h> #include <stdarg.h> #include <unistd.h> -#include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> @@ -389,6 +388,76 @@ test_wifi_wpa_psk (const char *detail, } static void +test_wifi_sae_psk (const char *psk) +{ + gs_unref_object NMConnection *connection = NULL; + gs_unref_variant GVariant *config_dict = NULL; + NMSettingWirelessSecurity *s_wsec; + gboolean success; + GError *error = NULL; + const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + gs_unref_bytes GBytes *ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); + const char *bssid_str = "11:22:33:44:55:66"; + int short_psk = strlen (psk) < 8; + + connection = new_basic_connection ("Test Wifi SAE", ssid, bssid_str); + + /* Wifi Security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", + NM_SETTING_WIRELESS_SECURITY_PSK, psk, + NULL); + nm_setting_wireless_security_add_proto (s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + nm_setting_wireless_security_add_group (s_wsec, "ccmp"); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + NMTST_EXPECT_NM_INFO ("Config: added 'ssid' value 'Test SSID'*"); + NMTST_EXPECT_NM_INFO ("Config: added 'scan_ssid' value '1'*"); + NMTST_EXPECT_NM_INFO ("Config: added 'bssid' value '11:22:33:44:55:66'*"); + NMTST_EXPECT_NM_INFO ("Config: added 'freq_list' value *"); + NMTST_EXPECT_NM_INFO ("Config: added 'key_mgmt' value 'SAE'"); + if (short_psk) + NMTST_EXPECT_NM_INFO ("Config: added 'sae_password' value *"); + else + NMTST_EXPECT_NM_INFO ("Config: added 'psk' value *"); + NMTST_EXPECT_NM_INFO ("Config: added 'proto' value 'RSN'"); + NMTST_EXPECT_NM_INFO ("Config: added 'pairwise' value 'TKIP CCMP'"); + NMTST_EXPECT_NM_INFO ("Config: added 'group' value 'TKIP CCMP'"); + NMTST_EXPECT_NM_INFO ("Config: added 'ieee80211w' value '0'"); + config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE); + + g_test_assert_expected_messages (); + g_assert (config_dict); + + validate_opt ("wifi-sae", config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1)); + validate_opt ("wifi-sae", config_dict, "ssid", TYPE_BYTES, ssid); + validate_opt ("wifi-sae", config_dict, "bssid", TYPE_KEYWORD, bssid_str); + validate_opt ("wifi-sae", config_dict, "key_mgmt", TYPE_KEYWORD, "SAE"); + validate_opt ("wifi-sae", config_dict, "proto", TYPE_KEYWORD, "RSN"); + validate_opt ("wifi-sae", config_dict, "pairwise", TYPE_KEYWORD, "TKIP CCMP"); + validate_opt ("wifi-sae", config_dict, "group", TYPE_KEYWORD, "TKIP CCMP"); + if (short_psk) + validate_opt ("wifi-sae", config_dict, "sae_password", TYPE_KEYWORD, psk); + else + validate_opt ("wifi-sae", config_dict, "psk", TYPE_KEYWORD, psk); +} + +static void +test_wifi_sae (void) +{ + test_wifi_sae_psk ("Moo"); + test_wifi_sae_psk ("Hello World!"); +} + +static void test_wifi_wpa_psk_types (void) { const char *key1 = "d4721e911461d3cdef9793858e977fcda091779243abb7316c2f11605a160893"; @@ -580,6 +649,7 @@ int main (int argc, char **argv) g_test_add_func ("/supplicant-config/wifi-eap/locked-bssid", test_wifi_eap_locked_bssid); g_test_add_func ("/supplicant-config/wifi-eap/unlocked-bssid", test_wifi_eap_unlocked_bssid); g_test_add_func ("/supplicant-config/wifi-eap/fils-disabled", test_wifi_eap_fils_disabled); + g_test_add_func ("/supplicant-config/wifi-sae", test_wifi_sae); return g_test_run (); } |