mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-02 22:50:12 +01:00
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.
This commit is contained in:
parent
ab8fc07640
commit
b2ee8e8704
3 changed files with 203 additions and 17 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -26,18 +26,25 @@
|
|||
#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"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
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
|
||||
|
|
@ -336,6 +363,99 @@ object_added (NMIwdManager *self, GDBusObject *object)
|
|||
g_list_free_full (interfaces, g_object_unref);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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;
|
||||
if (priv->agent_id)
|
||||
register_agent (self);
|
||||
|
||||
agent_manager = g_dbus_object_manager_get_interface (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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue