summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2017-12-15 15:30:18 +0100
committerThomas Haller <thaller@redhat.com>2017-12-21 11:07:55 +0100
commitb2ee8e87040fb4265d3f7c10109da085c79d3ea7 (patch)
treee1de5a76df8bc718f58faf66278af8f5172fe001
parentab8fc076408d1859e740f1f2ada7f48b3fe0444e (diff)
downloadNetworkManager-b2ee8e87040fb4265d3f7c10109da085c79d3ea7.tar.gz
iwd: Track IWD Known Networks
Keep a list of IWD's Known Networks which are networks that have their configurations stored by IWD including the secrets, either because they have been connected to before or because they were preprovisioned on the machine.
-rw-r--r--src/devices/wifi/nm-device-iwd.c34
-rw-r--r--src/devices/wifi/nm-iwd-manager.c174
-rw-r--r--src/devices/wifi/nm-iwd-manager.h12
3 files changed, 203 insertions, 17 deletions
diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c
index 44a3dee66f..29a0371805 100644
--- a/src/devices/wifi/nm-device-iwd.c
+++ b/src/devices/wifi/nm-device-iwd.c
@@ -399,6 +399,29 @@ deactivate (NMDevice *device)
cleanup_association_attempt (NM_DEVICE_IWD (device), TRUE);
}
+static NMIwdNetworkSecurity
+get_connection_iwd_security (NMConnection *connection)
+{
+ NMSettingWirelessSecurity *s_wireless_sec;
+ const char *key_mgmt = NULL;
+
+ s_wireless_sec = nm_connection_get_setting_wireless_security (connection);
+ if (!s_wireless_sec)
+ return NM_IWD_NETWORK_SECURITY_NONE;
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec);
+ nm_assert (key_mgmt);
+
+ if (!strcmp (key_mgmt, "none") || !strcmp (key_mgmt, "ieee8021x"))
+ return NM_IWD_NETWORK_SECURITY_WEP;
+
+ if (!strcmp (key_mgmt, "wpa-psk"))
+ return NM_IWD_NETWORK_SECURITY_PSK;
+
+ nm_assert (!strcmp (key_mgmt, "wpa-eap"));
+ return NM_IWD_NETWORK_SECURITY_8021X;
+}
+
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
@@ -1029,6 +1052,7 @@ network_connect_cb (GObject *source, GAsyncResult *res, gpointer user_data)
NMConnection *connection;
NMSettingWireless *s_wifi;
GBytes *ssid;
+ gs_free gchar *str_ssid = NULL;
if (!_nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), res,
G_VARIANT_TYPE ("()"),
@@ -1083,11 +1107,17 @@ network_connect_cb (GObject *source, GAsyncResult *res, gpointer user_data)
if (!ssid)
goto failed;
+ str_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL),
+ g_bytes_get_size (ssid));
+
_LOGI (LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Connected to '%s'.",
- ssid ? nm_utils_escape_ssid (g_bytes_get_data (ssid, NULL),
- g_bytes_get_size (ssid)) : "(none)");
+ str_ssid);
nm_device_activate_schedule_stage3_ip_config_start (device);
+
+ nm_iwd_manager_network_connected (nm_iwd_manager_get (), str_ssid,
+ get_connection_iwd_security (connection));
+
return;
failed:
diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c
index e5ff930ca5..4eda5ebac4 100644
--- a/src/devices/wifi/nm-iwd-manager.c
+++ b/src/devices/wifi/nm-iwd-manager.c
@@ -26,6 +26,7 @@
#include <net/if.h>
#include "nm-logging.h"
+#include "nm-core-internal.h"
#include "nm-manager.h"
#include "nm-device-iwd.h"
#include "nm-utils/nm-random-utils.h"
@@ -33,11 +34,17 @@
/*****************************************************************************/
typedef struct {
+ gchar *name;
+ NMIwdNetworkSecurity security;
+} KnownNetworkData;
+
+typedef struct {
GCancellable *cancellable;
gboolean running;
GDBusObjectManager *object_manager;
guint agent_id;
gchar *agent_path;
+ GSList *known_networks;
} NMIwdManagerPrivate;
struct _NMIwdManager {
@@ -232,6 +239,26 @@ psk_agent_export (GDBusConnection *connection, gpointer user_data,
return id;
}
+static void
+register_agent (NMIwdManager *self)
+{
+ NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self);
+ GDBusInterface *agent_manager;
+
+ agent_manager = g_dbus_object_manager_get_interface (priv->object_manager,
+ "/",
+ NM_IWD_AGENT_MANAGER_INTERFACE);
+
+ /* Register our agent */
+ g_dbus_proxy_call (G_DBUS_PROXY (agent_manager),
+ "RegisterAgent",
+ g_variant_new ("(o)", priv->agent_path),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, NULL, NULL);
+
+ g_object_unref (agent_manager);
+}
+
/*****************************************************************************/
static void
@@ -337,6 +364,99 @@ object_added (NMIwdManager *self, GDBusObject *object)
}
static void
+known_network_free (KnownNetworkData *network)
+{
+ g_free (network->name);
+ g_free (network);
+}
+
+static void
+list_known_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ NMIwdManager *self = user_data;
+ NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self);
+ gs_free_error GError *error = NULL;
+ gs_unref_variant GVariant *variant = NULL;
+ GVariantIter *networks, *props;
+
+ variant = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), res,
+ G_VARIANT_TYPE ("(aa{sv})"),
+ &error);
+ if (!variant) {
+ _LOGE ("ListKnownNetworks() failed: %s", error->message);
+ return;
+ }
+
+ g_slist_free_full (priv->known_networks, (GDestroyNotify) known_network_free);
+ priv->known_networks = NULL;
+
+ g_variant_get (variant, "(aa{sv})", &networks);
+
+ while (g_variant_iter_next (networks, "a{sv}", &props)) {
+ const gchar *key;
+ const gchar *name = NULL;
+ const gchar *type = NULL;
+ GVariant *val;
+ KnownNetworkData *network_data;
+
+ while (g_variant_iter_next (props, "{&sv}", &key, &val)) {
+ if (!strcmp (key, "Name"))
+ name = g_variant_get_string (val, NULL);
+
+ if (!strcmp (key, "Type"))
+ type = g_variant_get_string (val, NULL);
+
+ g_variant_unref (val);
+ }
+
+ if (!name || !type)
+ goto next;
+
+ network_data = g_new (KnownNetworkData, 1);
+ network_data->name = g_strdup (name);
+ if (!strcmp (type, "open"))
+ network_data->security = NM_IWD_NETWORK_SECURITY_NONE;
+ else if (!strcmp (type, "psk"))
+ network_data->security = NM_IWD_NETWORK_SECURITY_PSK;
+ else if (!strcmp (type, "8021x"))
+ network_data->security = NM_IWD_NETWORK_SECURITY_8021X;
+
+ priv->known_networks = g_slist_append (priv->known_networks,
+ network_data);
+
+next:
+ g_variant_iter_free (props);
+ }
+
+ g_variant_iter_free (networks);
+
+ /* For completness we may want to call nm_device_emit_recheck_auto_activate
+ * and nm_device_recheck_available_connections for all affected devices
+ * now but the ListKnownNetworks call should have been really fast,
+ * faster than any scan on any newly created devices could have happened.
+ */
+}
+
+static void
+update_known_networks (NMIwdManager *self)
+{
+ NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self);
+ GDBusInterface *known_networks_if;
+
+ known_networks_if = g_dbus_object_manager_get_interface (priv->object_manager,
+ "/",
+ NM_IWD_KNOWN_NETWORKS_INTERFACE);
+
+ g_dbus_proxy_call (G_DBUS_PROXY (known_networks_if),
+ "ListKnownNetworks",
+ g_variant_new ("()"),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ priv->cancellable, list_known_networks_cb, self);
+
+ g_object_unref (known_networks_if);
+}
+
+static void
name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
{
NMIwdManager *self = user_data;
@@ -356,22 +476,10 @@ name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
g_list_free_full (objects, g_object_unref);
- if (priv->agent_id) {
- GDBusInterface *agent_manager;
-
- agent_manager = g_dbus_object_manager_get_interface (object_manager,
- "/",
- NM_IWD_AGENT_MANAGER_INTERFACE);
+ if (priv->agent_id)
+ register_agent (self);
- /* Register our agent */
- g_dbus_proxy_call (G_DBUS_PROXY (agent_manager),
- "RegisterAgent",
- g_variant_new ("(o)", priv->agent_path),
- G_DBUS_CALL_FLAGS_NONE, -1,
- NULL, NULL, NULL);
-
- g_object_unref (agent_manager);
- }
+ update_known_networks (self);
} else {
NMManager *manager = nm_manager_get ();
const GSList *devices, *iter;
@@ -498,6 +606,39 @@ prepare_object_manager (NMIwdManager *self)
got_object_manager, self);
}
+gboolean
+nm_iwd_manager_is_known_network (NMIwdManager *self, const gchar *name,
+ NMIwdNetworkSecurity security)
+{
+ NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self);
+ const GSList *iter;
+
+ for (iter = priv->known_networks; iter; iter = g_slist_next (iter)) {
+ const KnownNetworkData *network = iter->data;
+
+ if (!strcmp (network->name, name) && network->security == security)
+ return true;
+ }
+
+ return false;
+}
+
+void
+nm_iwd_manager_network_connected (NMIwdManager *self, const gchar *name,
+ NMIwdNetworkSecurity security)
+{
+ NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self);
+ KnownNetworkData *network_data;
+
+ if (nm_iwd_manager_is_known_network (self, name, security))
+ return;
+
+ network_data = g_new (KnownNetworkData, 1);
+ network_data->name = g_strdup (name);
+ network_data->security = security;
+ priv->known_networks = g_slist_append (priv->known_networks, network_data);
+}
+
/*****************************************************************************/
NM_DEFINE_SINGLETON_GETTER (NMIwdManager, nm_iwd_manager_get,
@@ -540,6 +681,9 @@ dispose (GObject *object)
nm_clear_g_cancellable (&priv->cancellable);
+ g_slist_free_full (priv->known_networks, (GDestroyNotify) known_network_free);
+ priv->known_networks = NULL;
+
G_OBJECT_CLASS (nm_iwd_manager_parent_class)->dispose (object);
}
diff --git a/src/devices/wifi/nm-iwd-manager.h b/src/devices/wifi/nm-iwd-manager.h
index 197020bb86..8e6b66ff2d 100644
--- a/src/devices/wifi/nm-iwd-manager.h
+++ b/src/devices/wifi/nm-iwd-manager.h
@@ -36,6 +36,13 @@
#define NM_IWD_KNOWN_NETWORKS_INTERFACE "net.connman.iwd.KnownNetworks"
#define NM_IWD_SIGNAL_AGENT_INTERFACE "net.connman.iwd.SignalLevelAgent"
+typedef enum {
+ NM_IWD_NETWORK_SECURITY_NONE,
+ NM_IWD_NETWORK_SECURITY_WEP,
+ NM_IWD_NETWORK_SECURITY_PSK,
+ NM_IWD_NETWORK_SECURITY_8021X,
+} NMIwdNetworkSecurity;
+
#define NM_TYPE_IWD_MANAGER (nm_iwd_manager_get_type ())
#define NM_IWD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IWD_MANAGER, NMIwdManager))
#define NM_IWD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IWD_MANAGER, NMIwdManagerClass))
@@ -50,4 +57,9 @@ GType nm_iwd_manager_get_type (void);
NMIwdManager *nm_iwd_manager_get (void);
+gboolean nm_iwd_manager_is_known_network (NMIwdManager *self, const gchar *name,
+ NMIwdNetworkSecurity security);
+void nm_iwd_manager_network_connected (NMIwdManager *self, const gchar *name,
+ NMIwdNetworkSecurity security);
+
#endif /* __NETWORKMANAGER_IWD_MANAGER_H__ */