|
Packit Service |
87a54e |
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
Packit |
5756e2 |
/*
|
|
Packit |
5756e2 |
* Copyright (C) 2017 Intel Corporation
|
|
Packit |
5756e2 |
*/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-default.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-iwd-manager.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include <net/if.h>
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-logging.h"
|
|
Packit |
5756e2 |
#include "nm-core-internal.h"
|
|
Packit |
5756e2 |
#include "nm-manager.h"
|
|
Packit |
5756e2 |
#include "nm-device-iwd.h"
|
|
Packit |
5756e2 |
#include "nm-wifi-utils.h"
|
|
Packit |
5756e2 |
#include "nm-glib-aux/nm-random-utils.h"
|
|
Packit |
5756e2 |
#include "settings/nm-settings.h"
|
|
Packit Service |
a1bd4f |
#include "nm-std-aux/nm-dbus-compat.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
const char * name;
|
|
Packit Service |
a1bd4f |
NMIwdNetworkSecurity security;
|
|
Packit Service |
a1bd4f |
char buf[0];
|
|
Packit |
5756e2 |
} KnownNetworkId;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
GDBusProxy * known_network;
|
|
Packit Service |
a1bd4f |
NMSettingsConnection *mirror_connection;
|
|
Packit |
5756e2 |
} KnownNetworkData;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
NMManager * manager;
|
|
Packit Service |
a1bd4f |
NMSettings * settings;
|
|
Packit Service |
a1bd4f |
GCancellable * cancellable;
|
|
Packit Service |
a1bd4f |
gboolean running;
|
|
Packit Service |
a1bd4f |
GDBusObjectManager *object_manager;
|
|
Packit Service |
a1bd4f |
guint agent_id;
|
|
Packit Service |
a1bd4f |
char * agent_path;
|
|
Packit Service |
a1bd4f |
GHashTable * known_networks;
|
|
Packit Service |
a1bd4f |
NMDeviceIwd * last_agent_call_device;
|
|
Packit |
5756e2 |
} NMIwdManagerPrivate;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
struct _NMIwdManager {
|
|
Packit Service |
a1bd4f |
GObject parent;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate _priv;
|
|
Packit |
5756e2 |
};
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
struct _NMIwdManagerClass {
|
|
Packit Service |
a1bd4f |
GObjectClass parent;
|
|
Packit |
5756e2 |
};
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_DEFINE_TYPE(NMIwdManager, nm_iwd_manager, G_TYPE_OBJECT)
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
#define NM_IWD_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIwdManager, NM_IS_IWD_MANAGER)
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
#define _NMLOG_PREFIX_NAME "iwd-manager"
|
|
Packit Service |
a1bd4f |
#define _NMLOG_DOMAIN LOGD_WIFI
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
#define _NMLOG(level, ...) \
|
|
Packit Service |
a1bd4f |
G_STMT_START \
|
|
Packit Service |
a1bd4f |
{ \
|
|
Packit Service |
a1bd4f |
if (nm_logging_enabled(level, _NMLOG_DOMAIN)) { \
|
|
Packit Service |
a1bd4f |
char __prefix[32]; \
|
|
Packit Service |
a1bd4f |
\
|
|
Packit Service |
a1bd4f |
if (self) \
|
|
Packit Service |
a1bd4f |
g_snprintf(__prefix, \
|
|
Packit Service |
a1bd4f |
sizeof(__prefix), \
|
|
Packit Service |
a1bd4f |
"%s[%p]", \
|
|
Packit Service |
a1bd4f |
""_NMLOG_PREFIX_NAME \
|
|
Packit Service |
a1bd4f |
"", \
|
|
Packit Service |
a1bd4f |
(self)); \
|
|
Packit Service |
a1bd4f |
else \
|
|
Packit Service |
a1bd4f |
g_strlcpy(__prefix, _NMLOG_PREFIX_NAME, sizeof(__prefix)); \
|
|
Packit Service |
a1bd4f |
_nm_log((level), \
|
|
Packit Service |
a1bd4f |
(_NMLOG_DOMAIN), \
|
|
Packit Service |
a1bd4f |
0, \
|
|
Packit Service |
a1bd4f |
NULL, \
|
|
Packit Service |
a1bd4f |
NULL, \
|
|
Packit Service |
a1bd4f |
"%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
|
Packit Service |
a1bd4f |
__prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
|
Packit Service |
a1bd4f |
} \
|
|
Packit Service |
a1bd4f |
} \
|
|
Packit Service |
a1bd4f |
G_STMT_END
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void mirror_connection_take_and_delete(NMSettingsConnection *sett_conn,
|
|
Packit Service |
a1bd4f |
KnownNetworkData * data);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static const char *
|
|
Packit Service |
a1bd4f |
get_variant_string_or_null(GVariant *v)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
if (!v)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!g_variant_is_of_type(v, G_VARIANT_TYPE_STRING)
|
|
Packit Service |
a1bd4f |
&& !g_variant_is_of_type(v, G_VARIANT_TYPE_OBJECT_PATH))
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return g_variant_get_string(v, NULL);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static const char *
|
|
Packit Service |
a1bd4f |
get_property_string_or_null(GDBusProxy *proxy, const char *property)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gs_unref_variant GVariant *value = NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!proxy || !property)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
value = g_dbus_proxy_get_cached_property(proxy, property);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return get_variant_string_or_null(value);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static gboolean
|
|
Packit Service |
a1bd4f |
get_property_bool(GDBusProxy *proxy, const char *property, gboolean default_val)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gs_unref_variant GVariant *value = NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!proxy || !property)
|
|
Packit Service |
a1bd4f |
return default_val;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
value = g_dbus_proxy_get_cached_property(proxy, property);
|
|
Packit Service |
a1bd4f |
if (!value || !g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN))
|
|
Packit Service |
a1bd4f |
return default_val;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return g_variant_get_boolean(value);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static NMDeviceIwd *
|
|
Packit Service |
a1bd4f |
get_device_from_network(NMIwdManager *self, GDBusProxy *network)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
const char * ifname;
|
|
Packit Service |
a1bd4f |
const char * device_path;
|
|
Packit Service |
a1bd4f |
NMDevice * device;
|
|
Packit Service |
a1bd4f |
gs_unref_object GDBusInterface *device_obj = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Try not to rely on the path of the Device being a prefix of the
|
|
Packit Service |
a1bd4f |
* Network's object path.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
device_path = get_property_string_or_null(network, "Device");
|
|
Packit Service |
a1bd4f |
if (!device_path) {
|
|
Packit Service |
a1bd4f |
_LOGD("Device not cached for network at %s", g_dbus_proxy_get_object_path(network));
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
device_obj = g_dbus_object_manager_get_interface(priv->object_manager,
|
|
Packit Service |
a1bd4f |
device_path,
|
|
Packit Service |
a1bd4f |
NM_IWD_DEVICE_INTERFACE);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
ifname = get_property_string_or_null(G_DBUS_PROXY(device_obj), "Name");
|
|
Packit Service |
a1bd4f |
if (!ifname) {
|
|
Packit Service |
a1bd4f |
_LOGD("Name not cached for device at %s", device_path);
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
device = nm_manager_get_device(priv->manager, ifname, NM_DEVICE_TYPE_WIFI);
|
|
Packit Service |
a1bd4f |
if (!device || !NM_IS_DEVICE_IWD(device)) {
|
|
Packit Service |
a1bd4f |
_LOGD("NM device %s is not an IWD-managed device", ifname);
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return NM_DEVICE_IWD(device);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
agent_dbus_method_cb(GDBusConnection * connection,
|
|
Packit Service |
a1bd4f |
const char * sender,
|
|
Packit Service |
a1bd4f |
const char * object_path,
|
|
Packit Service |
a1bd4f |
const char * interface_name,
|
|
Packit Service |
a1bd4f |
const char * method_name,
|
|
Packit Service |
a1bd4f |
GVariant * parameters,
|
|
Packit Service |
a1bd4f |
GDBusMethodInvocation *invocation,
|
|
Packit Service |
a1bd4f |
gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
const char * network_path;
|
|
Packit Service |
a1bd4f |
NMDeviceIwd * device;
|
|
Packit Service |
a1bd4f |
gs_free char * name_owner = NULL;
|
|
Packit Service |
a1bd4f |
gs_unref_object GDBusInterface *network = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Be paranoid and check the sender address */
|
|
Packit Service |
a1bd4f |
name_owner = g_dbus_object_manager_client_get_name_owner(
|
|
Packit Service |
a1bd4f |
G_DBUS_OBJECT_MANAGER_CLIENT(priv->object_manager));
|
|
Packit Service |
a1bd4f |
if (!nm_streq0(name_owner, sender))
|
|
Packit Service |
a1bd4f |
goto return_error;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!strcmp(method_name, "Cancel")) {
|
|
Packit Service |
a1bd4f |
const char *reason = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_variant_get(parameters, "(&s)", &reason);
|
|
Packit Service |
a1bd4f |
_LOGD("agent-request: Cancel reason: %s", reason);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!priv->last_agent_call_device)
|
|
Packit Service |
a1bd4f |
goto return_error;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_device_iwd_agent_query(priv->last_agent_call_device, NULL)) {
|
|
Packit Service |
a1bd4f |
priv->last_agent_call_device = NULL;
|
|
Packit Service |
a1bd4f |
g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
priv->last_agent_call_device = NULL;
|
|
Packit Service |
a1bd4f |
goto return_error;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!strcmp(method_name, "RequestUserPassword"))
|
|
Packit Service |
a1bd4f |
g_variant_get(parameters, "(&os)", &network_path, NULL);
|
|
Packit Service |
a1bd4f |
else
|
|
Packit Service |
a1bd4f |
g_variant_get(parameters, "(&o)", &network_path);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
network = g_dbus_object_manager_get_interface(priv->object_manager,
|
|
Packit Service |
a1bd4f |
network_path,
|
|
Packit Service |
a1bd4f |
NM_IWD_NETWORK_INTERFACE);
|
|
Packit Service |
a1bd4f |
if (!network) {
|
|
Packit Service |
a1bd4f |
_LOGE("agent-request: unable to find the network object");
|
|
Packit Service |
a1bd4f |
goto return_error;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
device = get_device_from_network(self, G_DBUS_PROXY(network));
|
|
Packit Service |
a1bd4f |
if (!device) {
|
|
Packit Service |
a1bd4f |
_LOGD("agent-request: device not found in IWD Agent request");
|
|
Packit Service |
a1bd4f |
goto return_error;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_device_iwd_agent_query(device, invocation)) {
|
|
Packit Service |
a1bd4f |
priv->last_agent_call_device = device;
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
_LOGD("agent-request: device %s did not handle the IWD Agent request",
|
|
Packit Service |
a1bd4f |
nm_device_get_iface(NM_DEVICE(device)));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return_error:
|
|
Packit Service |
a1bd4f |
/* IWD doesn't look at the specific error */
|
|
Packit Service |
a1bd4f |
g_dbus_method_invocation_return_error_literal(invocation,
|
|
Packit Service |
a1bd4f |
NM_DEVICE_ERROR,
|
|
Packit Service |
a1bd4f |
NM_DEVICE_ERROR_INVALID_CONNECTION,
|
|
Packit Service |
a1bd4f |
"Secrets not available for this connection");
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static const GDBusInterfaceInfo iwd_agent_iface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
|
|
Packit Service |
a1bd4f |
"net.connman.iwd.Agent",
|
|
Packit Service |
a1bd4f |
.methods = NM_DEFINE_GDBUS_METHOD_INFOS(
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_METHOD_INFO(
|
|
Packit Service |
a1bd4f |
"RequestPassphrase",
|
|
Packit Service |
a1bd4f |
.in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ),
|
|
Packit Service |
a1bd4f |
.out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("passphrase", "s"), ), ),
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_METHOD_INFO(
|
|
Packit Service |
a1bd4f |
"RequestPrivateKeyPassphrase",
|
|
Packit Service |
a1bd4f |
.in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ),
|
|
Packit Service |
a1bd4f |
.out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("passphrase", "s"), ), ),
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_METHOD_INFO(
|
|
Packit Service |
a1bd4f |
"RequestUserNameAndPassword",
|
|
Packit Service |
a1bd4f |
.in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ),
|
|
Packit Service |
a1bd4f |
.out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("user", "s"),
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_ARG_INFO("password", "s"), ), ),
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_METHOD_INFO(
|
|
Packit Service |
a1bd4f |
"RequestUserPassword",
|
|
Packit Service |
a1bd4f |
.in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"),
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_ARG_INFO("user", "s"), ),
|
|
Packit Service |
a1bd4f |
.out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("password", "s"), ), ),
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_METHOD_INFO("Cancel",
|
|
Packit Service |
a1bd4f |
.in_args = NM_DEFINE_GDBUS_ARG_INFOS(
|
|
Packit Service |
a1bd4f |
NM_DEFINE_GDBUS_ARG_INFO("reason", "s"), ), ), ), );
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static guint
|
|
Packit Service |
a1bd4f |
iwd_agent_export(GDBusConnection *connection, gpointer user_data, char **agent_path, GError **error)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
static const GDBusInterfaceVTable vtable = {
|
|
Packit Service |
a1bd4f |
.method_call = agent_dbus_method_cb,
|
|
Packit Service |
a1bd4f |
};
|
|
Packit Service |
a1bd4f |
char path[50];
|
|
Packit Service |
a1bd4f |
unsigned int rnd;
|
|
Packit Service |
a1bd4f |
guint id;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_utils_random_bytes(&rnd, sizeof(rnd));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_sprintf_buf(path, "/agent/%u", rnd);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
id =
|
|
Packit Service |
a1bd4f |
g_dbus_connection_register_object(connection,
|
|
Packit Service |
a1bd4f |
path,
|
|
Packit Service |
a1bd4f |
NM_UNCONST_PTR(GDBusInterfaceInfo, &iwd_agent_iface_info),
|
|
Packit Service |
a1bd4f |
&vtable,
|
|
Packit Service |
a1bd4f |
user_data,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
error);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (id)
|
|
Packit Service |
a1bd4f |
*agent_path = g_strdup(path);
|
|
Packit Service |
a1bd4f |
return id;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void
|
|
Packit Service |
a1bd4f |
register_agent(NMIwdManager *self)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
GDBusInterface * agent_manager;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
agent_manager = g_dbus_object_manager_get_interface(priv->object_manager,
|
|
Packit Service |
a1bd4f |
"/net/connman/iwd", /* IWD 1.0+ */
|
|
Packit Service |
a1bd4f |
NM_IWD_AGENT_MANAGER_INTERFACE);
|
|
Packit Service |
a1bd4f |
if (!agent_manager) {
|
|
Packit Service |
a1bd4f |
_LOGE("unable to register the IWD Agent: PSK/8021x Wi-Fi networks may not work");
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Register our agent */
|
|
Packit Service |
a1bd4f |
g_dbus_proxy_call(G_DBUS_PROXY(agent_manager),
|
|
Packit Service |
a1bd4f |
"RegisterAgent",
|
|
Packit Service |
a1bd4f |
g_variant_new("(o)", priv->agent_path),
|
|
Packit Service |
a1bd4f |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
a1bd4f |
-1,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
NULL);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_object_unref(agent_manager);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static KnownNetworkId *
|
|
Packit Service |
a1bd4f |
known_network_id_new(const char *name, NMIwdNetworkSecurity security)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
KnownNetworkId *id;
|
|
Packit Service |
a1bd4f |
gsize strsize = strlen(name) + 1;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
id = g_malloc(sizeof(KnownNetworkId) + strsize);
|
|
Packit Service |
a1bd4f |
id->name = id->buf;
|
|
Packit Service |
a1bd4f |
id->security = security;
|
|
Packit Service |
a1bd4f |
memcpy(id->buf, name, strsize);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return id;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static guint
|
|
Packit Service |
a1bd4f |
known_network_id_hash(KnownNetworkId *id)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMHashState h;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_hash_init(&h, 1947951703u);
|
|
Packit Service |
a1bd4f |
nm_hash_update_val(&h, id->security);
|
|
Packit Service |
a1bd4f |
nm_hash_update_str(&h, id->name);
|
|
Packit Service |
a1bd4f |
return nm_hash_complete(&h);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit Service |
a1bd4f |
known_network_id_equal(KnownNetworkId *a, KnownNetworkId *b)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
return a->security == b->security && nm_streq(a->name, b->name);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
known_network_data_free(KnownNetworkData *network)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
if (!network)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_object_unref(network->known_network);
|
|
Packit Service |
a1bd4f |
mirror_connection_take_and_delete(network->mirror_connection, network);
|
|
Packit Service |
a1bd4f |
g_slice_free(KnownNetworkData, network);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
set_device_dbus_object(NMIwdManager *self, GDBusProxy *proxy, GDBusObject *object)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
const char * ifname;
|
|
Packit Service |
a1bd4f |
int ifindex;
|
|
Packit Service |
a1bd4f |
NMDevice * device;
|
|
Packit Service |
a1bd4f |
int errsv;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
ifname = get_property_string_or_null(proxy, "Name");
|
|
Packit Service |
a1bd4f |
if (!ifname) {
|
|
Packit Service |
a1bd4f |
_LOGE("Name not cached for Device at %s", g_dbus_proxy_get_object_path(proxy));
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
ifindex = if_nametoindex(ifname);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!ifindex) {
|
|
Packit Service |
a1bd4f |
errsv = errno;
|
|
Packit Service |
a1bd4f |
_LOGE("if_nametoindex failed for Name %s for Device at %s: %i",
|
|
Packit Service |
a1bd4f |
ifname,
|
|
Packit Service |
a1bd4f |
g_dbus_proxy_get_object_path(proxy),
|
|
Packit Service |
a1bd4f |
errsv);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
device = nm_manager_get_device_by_ifindex(priv->manager, ifindex);
|
|
Packit Service |
a1bd4f |
if (!NM_IS_DEVICE_IWD(device)) {
|
|
Packit Service |
a1bd4f |
_LOGE("IWD device named %s is not a Wifi device", ifname);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_device_iwd_set_dbus_object(NM_DEVICE_IWD(device), object);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
known_network_update_cb(GObject *source, GAsyncResult *res, gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
gs_unref_variant GVariant *variant = NULL;
|
|
Packit Service |
a1bd4f |
gs_free_error GError *error = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error);
|
|
Packit Service |
a1bd4f |
if (!variant) {
|
|
Packit Service |
a1bd4f |
nm_log_warn(LOGD_WIFI,
|
|
Packit Service |
a1bd4f |
"Updating %s on IWD known network %s failed: %s",
|
|
Packit Service |
a1bd4f |
(const char *) user_data,
|
|
Packit Service |
a1bd4f |
g_dbus_proxy_get_object_path(G_DBUS_PROXY(source)),
|
|
Packit Service |
a1bd4f |
error->message);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
sett_conn_changed(NMSettingsConnection *sett_conn, guint update_reason, KnownNetworkData *data)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMSettingsConnectionIntFlags flags;
|
|
Packit Service |
a1bd4f |
NMConnection * conn = nm_settings_connection_get_connection(sett_conn);
|
|
Packit Service |
a1bd4f |
NMSettingConnection * s_conn = nm_connection_get_setting_connection(conn);
|
|
Packit Service |
a1bd4f |
gboolean nm_autoconnectable = nm_setting_connection_get_autoconnect(s_conn);
|
|
Packit Service |
a1bd4f |
gboolean iwd_autoconnectable = get_property_bool(data->known_network, "AutoConnect", TRUE);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(sett_conn == data->mirror_connection);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (iwd_autoconnectable == nm_autoconnectable)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* If this is a generated connection it may be ourselves updating it */
|
|
Packit Service |
a1bd4f |
flags = nm_settings_connection_get_flags(data->mirror_connection);
|
|
Packit Service |
a1bd4f |
if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED))
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_log_dbg(LOGD_WIFI,
|
|
Packit Service |
a1bd4f |
"Updating AutoConnect on known network at %s based on connection %s",
|
|
Packit Service |
a1bd4f |
g_dbus_proxy_get_object_path(data->known_network),
|
|
Packit Service |
a1bd4f |
nm_settings_connection_get_id(data->mirror_connection));
|
|
Packit Service |
a1bd4f |
g_dbus_proxy_call(data->known_network,
|
|
Packit Service |
a1bd4f |
DBUS_INTERFACE_PROPERTIES ".Set",
|
|
Packit Service |
a1bd4f |
g_variant_new("(ssv)",
|
|
Packit Service |
a1bd4f |
NM_IWD_KNOWN_NETWORK_INTERFACE,
|
|
Packit Service |
a1bd4f |
"AutoConnect",
|
|
Packit Service |
a1bd4f |
g_variant_new_boolean(nm_autoconnectable)),
|
|
Packit Service |
a1bd4f |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
a1bd4f |
-1,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
known_network_update_cb,
|
|
Packit Service |
a1bd4f |
"AutoConnect");
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* Look up an existing NMSettingsConnection for a network that has been
|
|
Packit Service |
a1bd4f |
* preprovisioned with an IWD config file or has been connected to before,
|
|
Packit Service |
a1bd4f |
* or create a new in-memory NMSettingsConnection object. This will let
|
|
Packit Service |
a1bd4f |
* users control the few supported properties (mainly make it
|
|
Packit Service |
a1bd4f |
* IWD-autoconnectable or not), remove/forget the network, or, for a
|
|
Packit Service |
a1bd4f |
* WPA2-Enterprise type network it will inform the NM autoconnect mechanism
|
|
Packit Service |
a1bd4f |
* and the clients that this networks needs no additional EAP configuration
|
|
Packit Service |
a1bd4f |
* from the user.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
static NMSettingsConnection *
|
|
Packit Service |
a1bd4f |
mirror_connection(NMIwdManager * self,
|
|
Packit Service |
a1bd4f |
const KnownNetworkId *id,
|
|
Packit Service |
a1bd4f |
gboolean create_new,
|
|
Packit Service |
a1bd4f |
GDBusProxy * known_network)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate * priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
NMSettingsConnection *const *iter;
|
|
Packit Service |
a1bd4f |
gs_unref_object NMConnection *connection = NULL;
|
|
Packit Service |
a1bd4f |
NMSettingsConnection * settings_connection = NULL;
|
|
Packit Service |
a1bd4f |
char uuid[37];
|
|
Packit Service |
a1bd4f |
NMSetting * setting;
|
|
Packit Service |
a1bd4f |
gs_free_error GError *error = NULL;
|
|
Packit Service |
a1bd4f |
gs_unref_bytes GBytes *new_ssid = NULL;
|
|
Packit Service |
a1bd4f |
gsize ssid_len = strlen(id->name);
|
|
Packit Service |
a1bd4f |
gboolean autoconnectable = TRUE;
|
|
Packit Service |
a1bd4f |
gboolean hidden = FALSE;
|
|
Packit Service |
a1bd4f |
gboolean exact_match = TRUE;
|
|
Packit Service |
a1bd4f |
const char * key_mgmt = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (known_network) {
|
|
Packit Service |
a1bd4f |
autoconnectable = get_property_bool(known_network, "AutoConnect", TRUE);
|
|
Packit Service |
a1bd4f |
hidden = get_property_bool(known_network, "Hidden", FALSE);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (iter = nm_settings_get_connections(priv->settings, NULL); *iter; iter++) {
|
|
Packit Service |
a1bd4f |
NMSettingsConnection *sett_conn = *iter;
|
|
Packit Service |
a1bd4f |
NMConnection * conn = nm_settings_connection_get_connection(sett_conn);
|
|
Packit Service |
a1bd4f |
NMIwdNetworkSecurity security;
|
|
Packit Service |
a1bd4f |
NMSettingWireless * s_wifi;
|
|
Packit Service |
a1bd4f |
const guint8 * ssid_bytes;
|
|
Packit Service |
a1bd4f |
gsize ssid_len2;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &security))
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (security != id->security)
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
s_wifi = nm_connection_get_setting_wireless(conn);
|
|
Packit Service |
a1bd4f |
if (!s_wifi)
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* The SSID must be UTF-8 if it matches since id->name is known to be
|
|
Packit Service |
a1bd4f |
* valid UTF-8, so just memcmp them.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
ssid_bytes = g_bytes_get_data(nm_setting_wireless_get_ssid(s_wifi), &ssid_len2);
|
|
Packit Service |
a1bd4f |
if (!ssid_bytes || ssid_len2 != ssid_len || memcmp(ssid_bytes, id->name, ssid_len))
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
exact_match = TRUE;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (known_network) {
|
|
Packit Service |
a1bd4f |
NMSettingConnection *s_conn = nm_connection_get_setting_connection(conn);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_setting_connection_get_autoconnect(s_conn) != autoconnectable
|
|
Packit Service |
a1bd4f |
|| nm_setting_wireless_get_hidden(s_wifi) != hidden)
|
|
Packit Service |
a1bd4f |
exact_match = FALSE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
switch (id->security) {
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_WEP:
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_NONE:
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_PSK:
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_8021X:
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMSetting8021x *s_8021x = nm_connection_get_setting_802_1x(conn);
|
|
Packit Service |
a1bd4f |
gboolean external = FALSE;
|
|
Packit Service |
a1bd4f |
guint i;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (i = 0; i < nm_setting_802_1x_get_num_eap_methods(s_8021x); i++) {
|
|
Packit Service |
a1bd4f |
if (nm_streq(nm_setting_802_1x_get_eap_method(s_8021x, i), "external")) {
|
|
Packit Service |
a1bd4f |
external = TRUE;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Prefer returning connections with EAP method "external" */
|
|
Packit Service |
a1bd4f |
if (!external)
|
|
Packit Service |
a1bd4f |
exact_match = FALSE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!settings_connection || exact_match)
|
|
Packit Service |
a1bd4f |
settings_connection = sett_conn;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (exact_match)
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (settings_connection && known_network && !exact_match) {
|
|
Packit Service |
a1bd4f |
NMSettingsConnectionIntFlags flags = nm_settings_connection_get_flags(settings_connection);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* If we found a connection and it's generated (likely by ourselves)
|
|
Packit Service |
a1bd4f |
* it may have been created on a request by
|
|
Packit Service |
a1bd4f |
* nm_iwd_manager_get_ap_mirror_connection() when no Known Network
|
|
Packit Service |
a1bd4f |
* was available so we didn't have access to its properties other
|
|
Packit Service |
a1bd4f |
* than Name and Security. Copy their values to the generated
|
|
Packit Service |
a1bd4f |
* NMConnection.
|
|
Packit Service |
a1bd4f |
* TODO: avoid notify signals triggering our own watch.
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* If on the other hand this is a user-created NMConnection we
|
|
Packit Service |
a1bd4f |
* should try to copy the properties from it to IWD's Known Network
|
|
Packit Service |
a1bd4f |
* using the Properties DBus interface in case the user created an
|
|
Packit Service |
a1bd4f |
* NM connection before IWD appeared on the bus, or before IWD
|
|
Packit Service |
a1bd4f |
* created its Known Network object.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) {
|
|
Packit Service |
a1bd4f |
NMConnection *tmp_conn = nm_settings_connection_get_connection(settings_connection);
|
|
Packit Service |
a1bd4f |
NMSettingConnection *s_conn = nm_connection_get_setting_connection(tmp_conn);
|
|
Packit Service |
a1bd4f |
NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(tmp_conn);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_object_set(G_OBJECT(s_conn),
|
|
Packit Service |
a1bd4f |
NM_SETTING_CONNECTION_AUTOCONNECT,
|
|
Packit Service |
a1bd4f |
autoconnectable,
|
|
Packit Service |
a1bd4f |
NULL);
|
|
Packit Service |
a1bd4f |
g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_HIDDEN, hidden, NULL);
|
|
Packit Service |
a1bd4f |
} else {
|
|
Packit Service |
a1bd4f |
KnownNetworkData data = {known_network, settings_connection};
|
|
Packit Service |
a1bd4f |
sett_conn_changed(settings_connection, 0, &data);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (settings_connection && known_network) {
|
|
Packit Service |
a1bd4f |
/* Reset NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL now that the
|
|
Packit Service |
a1bd4f |
* connection is going to be referenced by a known network, we don't
|
|
Packit Service |
a1bd4f |
* want it to be deleted when activation fails anymore.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
nm_settings_connection_set_flags_full(settings_connection,
|
|
Packit Service |
a1bd4f |
NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL,
|
|
Packit Service |
a1bd4f |
0);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* If we already have an NMSettingsConnection matching this
|
|
Packit Service |
a1bd4f |
* KnownNetwork, whether it's saved or an in-memory connection
|
|
Packit Service |
a1bd4f |
* potentially created by ourselves then we have nothing left to
|
|
Packit Service |
a1bd4f |
* do here.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
if (settings_connection || !create_new)
|
|
Packit Service |
a1bd4f |
return settings_connection;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
connection = nm_simple_connection_new();
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_CONNECTION,
|
|
Packit Service |
a1bd4f |
NM_SETTING_CONNECTION_TYPE,
|
|
Packit Service |
a1bd4f |
NM_SETTING_WIRELESS_SETTING_NAME,
|
|
Packit Service |
a1bd4f |
NM_SETTING_CONNECTION_ID,
|
|
Packit Service |
a1bd4f |
id->name,
|
|
Packit Service |
a1bd4f |
NM_SETTING_CONNECTION_UUID,
|
|
Packit Service |
a1bd4f |
nm_utils_uuid_generate_buf(uuid),
|
|
Packit Service |
a1bd4f |
NM_SETTING_CONNECTION_AUTOCONNECT,
|
|
Packit Service |
a1bd4f |
autoconnectable,
|
|
Packit Service |
a1bd4f |
NULL));
|
|
Packit Service |
a1bd4f |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
new_ssid = g_bytes_new(id->name, ssid_len);
|
|
Packit Service |
a1bd4f |
setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_WIRELESS,
|
|
Packit Service |
a1bd4f |
NM_SETTING_WIRELESS_SSID,
|
|
Packit Service |
a1bd4f |
new_ssid,
|
|
Packit Service |
a1bd4f |
NM_SETTING_WIRELESS_MODE,
|
|
Packit Service |
a1bd4f |
NM_SETTING_WIRELESS_MODE_INFRA,
|
|
Packit Service |
a1bd4f |
NM_SETTING_WIRELESS_HIDDEN,
|
|
Packit Service |
a1bd4f |
hidden,
|
|
Packit Service |
a1bd4f |
NULL));
|
|
Packit Service |
a1bd4f |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
switch (id->security) {
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_WEP:
|
|
Packit Service |
a1bd4f |
key_mgmt = "none";
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_NONE:
|
|
Packit Service |
a1bd4f |
key_mgmt = NULL;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_PSK:
|
|
Packit Service |
a1bd4f |
key_mgmt = "wpa-psk";
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case NM_IWD_NETWORK_SECURITY_8021X:
|
|
Packit Service |
a1bd4f |
key_mgmt = "wpa-eap";
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (key_mgmt) {
|
|
Packit Service |
a1bd4f |
setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_WIRELESS_SECURITY,
|
|
Packit Service |
a1bd4f |
NM_SETTING_WIRELESS_SECURITY_AUTH_ALG,
|
|
Packit Service |
a1bd4f |
"open",
|
|
Packit Service |
a1bd4f |
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,
|
|
Packit Service |
a1bd4f |
key_mgmt,
|
|
Packit Service |
a1bd4f |
NULL));
|
|
Packit Service |
a1bd4f |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (id->security == NM_IWD_NETWORK_SECURITY_8021X) {
|
|
Packit Service |
a1bd4f |
/* "password" and "private-key-password" may be requested by the IWD agent
|
|
Packit Service |
a1bd4f |
* from NM and IWD will implement a specific secret cache policy so by
|
|
Packit Service |
a1bd4f |
* default respect that policy and don't save copies of those secrets in
|
|
Packit Service |
a1bd4f |
* NM settings. The saved values can not be used anyway because of our
|
|
Packit Service |
a1bd4f |
* use of NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_802_1X,
|
|
Packit Service |
a1bd4f |
NM_SETTING_802_1X_PASSWORD_FLAGS,
|
|
Packit Service |
a1bd4f |
NM_SETTING_SECRET_FLAG_NOT_SAVED,
|
|
Packit Service |
a1bd4f |
NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS,
|
|
Packit Service |
a1bd4f |
NM_SETTING_SECRET_FLAG_NOT_SAVED,
|
|
Packit Service |
a1bd4f |
NULL));
|
|
Packit Service |
a1bd4f |
nm_setting_802_1x_add_eap_method(NM_SETTING_802_1X(setting), "external");
|
|
Packit Service |
a1bd4f |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!nm_connection_normalize(connection, NULL, NULL, NULL))
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!nm_settings_add_connection(
|
|
Packit Service |
a1bd4f |
priv->settings,
|
|
Packit Service |
a1bd4f |
connection,
|
|
Packit Service |
a1bd4f |
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
|
Packit Service |
a1bd4f |
NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
|
Packit Service |
a1bd4f |
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED
|
|
Packit Service |
a1bd4f |
| (known_network ? 0 : NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL),
|
|
Packit Service |
a1bd4f |
&settings_connection,
|
|
Packit Service |
a1bd4f |
&error)) {
|
|
Packit Service |
a1bd4f |
_LOGW("failed to add a mirror NMConnection for IWD's Known Network '%s': %s",
|
|
Packit Service |
a1bd4f |
id->name,
|
|
Packit Service |
a1bd4f |
error->message);
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return settings_connection;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void
|
|
Packit Service |
a1bd4f |
mirror_connection_take_and_delete(NMSettingsConnection *sett_conn, KnownNetworkData *data)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMSettingsConnectionIntFlags flags;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!sett_conn)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
flags = nm_settings_connection_get_flags(sett_conn);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* If connection has not been saved since we created it
|
|
Packit Service |
a1bd4f |
* in interface_added it too can be removed now. */
|
|
Packit Service |
a1bd4f |
if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED))
|
|
Packit Service |
a1bd4f |
nm_settings_connection_delete(sett_conn, FALSE);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_signal_handlers_disconnect_by_data(sett_conn, data);
|
|
Packit Service |
a1bd4f |
g_object_unref(sett_conn);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
interface_added(GDBusObjectManager *object_manager,
|
|
Packit Service |
a1bd4f |
GDBusObject * object,
|
|
Packit Service |
a1bd4f |
GDBusInterface * interface,
|
|
Packit Service |
a1bd4f |
gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
GDBusProxy * proxy;
|
|
Packit Service |
a1bd4f |
const char * iface_name;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!priv->running)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_return_if_fail(G_IS_DBUS_PROXY(interface));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
proxy = G_DBUS_PROXY(interface);
|
|
Packit Service |
a1bd4f |
iface_name = g_dbus_proxy_get_interface_name(proxy);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(iface_name, NM_IWD_DEVICE_INTERFACE)) {
|
|
Packit Service |
a1bd4f |
set_device_dbus_object(self, proxy, object);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) {
|
|
Packit Service |
a1bd4f |
KnownNetworkId * id;
|
|
Packit Service |
a1bd4f |
KnownNetworkId * orig_id;
|
|
Packit Service |
a1bd4f |
KnownNetworkData * data;
|
|
Packit Service |
a1bd4f |
NMIwdNetworkSecurity security;
|
|
Packit Service |
a1bd4f |
const char * type_str, *name;
|
|
Packit Service |
a1bd4f |
NMSettingsConnection *sett_conn = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
type_str = get_property_string_or_null(proxy, "Type");
|
|
Packit Service |
a1bd4f |
name = get_property_string_or_null(proxy, "Name");
|
|
Packit Service |
a1bd4f |
if (!type_str || !name)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(type_str, "open"))
|
|
Packit Service |
a1bd4f |
security = NM_IWD_NETWORK_SECURITY_NONE;
|
|
Packit Service |
a1bd4f |
else if (nm_streq(type_str, "psk"))
|
|
Packit Service |
a1bd4f |
security = NM_IWD_NETWORK_SECURITY_PSK;
|
|
Packit Service |
a1bd4f |
else if (nm_streq(type_str, "8021x"))
|
|
Packit Service |
a1bd4f |
security = NM_IWD_NETWORK_SECURITY_8021X;
|
|
Packit Service |
a1bd4f |
else
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
id = known_network_id_new(name, security);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (g_hash_table_lookup_extended(priv->known_networks,
|
|
Packit Service |
a1bd4f |
id,
|
|
Packit Service |
a1bd4f |
(void **) &orig_id,
|
|
Packit Service |
a1bd4f |
(void **) &data)) {
|
|
Packit Service |
a1bd4f |
_LOGW("DBus error: KnownNetwork already exists ('%s', %s)", name, type_str);
|
|
Packit Service |
a1bd4f |
nm_g_object_ref_set(&data->known_network, proxy);
|
|
Packit Service |
a1bd4f |
g_free(id);
|
|
Packit Service |
a1bd4f |
id = orig_id;
|
|
Packit Service |
a1bd4f |
} else {
|
|
Packit Service |
a1bd4f |
data = g_slice_new0(KnownNetworkData);
|
|
Packit Service |
a1bd4f |
data->known_network = g_object_ref(proxy);
|
|
Packit Service |
a1bd4f |
g_hash_table_insert(priv->known_networks, id, data);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
sett_conn = mirror_connection(self, id, TRUE, proxy);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (sett_conn && sett_conn != data->mirror_connection) {
|
|
Packit Service |
a1bd4f |
NMSettingsConnection *sett_conn_old = data->mirror_connection;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
data->mirror_connection = nm_g_object_ref(sett_conn);
|
|
Packit Service |
a1bd4f |
mirror_connection_take_and_delete(sett_conn_old, data);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_signal_connect(sett_conn,
|
|
Packit Service |
a1bd4f |
NM_SETTINGS_CONNECTION_UPDATED_INTERNAL,
|
|
Packit Service |
a1bd4f |
G_CALLBACK(sett_conn_changed),
|
|
Packit Service |
a1bd4f |
data);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(iface_name, NM_IWD_NETWORK_INTERFACE)) {
|
|
Packit Service |
a1bd4f |
NMDeviceIwd *device = get_device_from_network(self, proxy);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (device)
|
|
Packit Service |
a1bd4f |
nm_device_iwd_network_add_remove(device, proxy, TRUE);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
interface_removed(GDBusObjectManager *object_manager,
|
|
Packit Service |
a1bd4f |
GDBusObject * object,
|
|
Packit Service |
a1bd4f |
GDBusInterface * interface,
|
|
Packit Service |
a1bd4f |
gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
GDBusProxy * proxy;
|
|
Packit Service |
a1bd4f |
const char * iface_name;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_return_if_fail(G_IS_DBUS_PROXY(interface));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
proxy = G_DBUS_PROXY(interface);
|
|
Packit Service |
a1bd4f |
iface_name = g_dbus_proxy_get_interface_name(proxy);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(iface_name, NM_IWD_DEVICE_INTERFACE)) {
|
|
Packit Service |
a1bd4f |
set_device_dbus_object(self, proxy, NULL);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) {
|
|
Packit Service |
a1bd4f |
KnownNetworkId id;
|
|
Packit Service |
a1bd4f |
const char * type_str;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
type_str = get_property_string_or_null(proxy, "Type");
|
|
Packit Service |
a1bd4f |
id.name = get_property_string_or_null(proxy, "Name");
|
|
Packit Service |
a1bd4f |
if (!type_str || !id.name)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(type_str, "open"))
|
|
Packit Service |
a1bd4f |
id.security = NM_IWD_NETWORK_SECURITY_NONE;
|
|
Packit Service |
a1bd4f |
else if (nm_streq(type_str, "psk"))
|
|
Packit Service |
a1bd4f |
id.security = NM_IWD_NETWORK_SECURITY_PSK;
|
|
Packit Service |
a1bd4f |
else if (nm_streq(type_str, "8021x"))
|
|
Packit Service |
a1bd4f |
id.security = NM_IWD_NETWORK_SECURITY_8021X;
|
|
Packit Service |
a1bd4f |
else
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_hash_table_remove(priv->known_networks, &id;;
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (nm_streq(iface_name, NM_IWD_NETWORK_INTERFACE)) {
|
|
Packit Service |
a1bd4f |
NMDeviceIwd *device = get_device_from_network(self, proxy);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (device)
|
|
Packit Service |
a1bd4f |
nm_device_iwd_network_add_remove(device, proxy, FALSE);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
object_added(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
GList *interfaces, *iter;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
interfaces = g_dbus_object_get_interfaces(object);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
for (iter = interfaces; iter; iter = iter->next) {
|
|
Packit Service |
a1bd4f |
GDBusInterface *interface = G_DBUS_INTERFACE(iter->data);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
interface_added(NULL, object, interface, user_data);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_list_free_full(interfaces, g_object_unref);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
object_removed(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
GList *interfaces, *iter;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
interfaces = g_dbus_object_get_interfaces(object);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
for (iter = interfaces; iter; iter = iter->next) {
|
|
Packit Service |
a1bd4f |
GDBusInterface *interface = G_DBUS_INTERFACE(iter->data);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
interface_removed(NULL, object, interface, user_data);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_list_free_full(interfaces, g_object_unref);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate * priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
NMConnection * conn = nm_settings_connection_get_connection(sett_conn);
|
|
Packit Service |
a1bd4f |
NMSettingWireless * s_wireless;
|
|
Packit Service |
a1bd4f |
KnownNetworkData * data;
|
|
Packit Service |
a1bd4f |
KnownNetworkId id;
|
|
Packit Service |
a1bd4f |
char ssid_buf[33];
|
|
Packit Service |
a1bd4f |
const guint8 * ssid_bytes;
|
|
Packit Service |
a1bd4f |
gsize ssid_len;
|
|
Packit Service |
a1bd4f |
NMSettingsConnection *new_mirror_conn;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &id.security))
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
s_wireless = nm_connection_get_setting_wireless(conn);
|
|
Packit Service |
a1bd4f |
if (!s_wireless)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
ssid_bytes = g_bytes_get_data(nm_setting_wireless_get_ssid(s_wireless), &ssid_len);
|
|
Packit Service |
a1bd4f |
if (!ssid_bytes || ssid_len > 32 || memchr(ssid_bytes, 0, ssid_len))
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
memcpy(ssid_buf, ssid_bytes, ssid_len);
|
|
Packit Service |
a1bd4f |
ssid_buf[ssid_len] = '\0';
|
|
Packit Service |
a1bd4f |
id.name = ssid_buf;
|
|
Packit Service |
a1bd4f |
data = g_hash_table_lookup(priv->known_networks, &id;;
|
|
Packit Service |
a1bd4f |
if (!data)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (data->mirror_connection != sett_conn)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_clear_object(&data->mirror_connection);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Don't call Forget on the Known Network until there's no longer *any*
|
|
Packit Service |
a1bd4f |
* matching NMSettingsConnection (debatable)
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
new_mirror_conn = mirror_connection(self, &id, FALSE, NULL);
|
|
Packit Service |
a1bd4f |
if (new_mirror_conn) {
|
|
Packit Service |
a1bd4f |
data->mirror_connection = g_object_ref(new_mirror_conn);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!priv->running)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_dbus_proxy_call(data->known_network,
|
|
Packit Service |
a1bd4f |
"Forget",
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
a1bd4f |
-1,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
NULL);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static gboolean
|
|
Packit Service |
a1bd4f |
_om_has_name_owner(GDBusObjectManager *object_manager)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
gs_free char *name_owner = NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_assert(G_IS_DBUS_OBJECT_MANAGER_CLIENT(object_manager));
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
name_owner =
|
|
Packit Service |
a1bd4f |
g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIENT(object_manager));
|
|
Packit Service |
a1bd4f |
return !!name_owner;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
release_object_manager(NMIwdManager *self)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!priv->object_manager)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_signal_handlers_disconnect_by_data(priv->object_manager, self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (priv->agent_id) {
|
|
Packit Service |
a1bd4f |
GDBusConnection * agent_connection;
|
|
Packit Service |
a1bd4f |
GDBusObjectManagerClient *omc = G_DBUS_OBJECT_MANAGER_CLIENT(priv->object_manager);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
agent_connection = g_dbus_object_manager_client_get_connection(omc);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* We're is called when we're shutting down (i.e. our DBus connection
|
|
Packit Service |
a1bd4f |
* is being closed, and IWD will detect this) or IWD was stopped so
|
|
Packit Service |
a1bd4f |
* in either case calling UnregisterAgent will not do anything.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
g_dbus_connection_unregister_object(agent_connection, priv->agent_id);
|
|
Packit Service |
a1bd4f |
priv->agent_id = 0;
|
|
Packit Service |
a1bd4f |
nm_clear_g_free(&priv->agent_path);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
g_clear_object(&priv->object_manager);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void prepare_object_manager(NMIwdManager *self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void
|
|
Packit Service |
a1bd4f |
name_owner_changed(GObject *object, GParamSpec *pspec, gpointer user_data)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
GDBusObjectManager * object_manager = G_DBUS_OBJECT_MANAGER(object);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(object_manager == priv->object_manager);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (_om_has_name_owner(object_manager)) {
|
|
Packit Service |
a1bd4f |
release_object_manager(self);
|
|
Packit Service |
a1bd4f |
prepare_object_manager(self);
|
|
Packit Service |
a1bd4f |
} else {
|
|
Packit Service |
a1bd4f |
const CList *tmp_lst;
|
|
Packit Service |
a1bd4f |
NMDevice * device;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!priv->running)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
priv->running = false;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_manager_for_each_device (priv->manager, device, tmp_lst) {
|
|
Packit Service |
a1bd4f |
if (NM_IS_DEVICE_IWD(device)) {
|
|
Packit Service |
a1bd4f |
nm_device_iwd_set_dbus_object(NM_DEVICE_IWD(device), NULL);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void
|
|
Packit Service |
a1bd4f |
device_added(NMManager *manager, NMDevice *device, gpointer user_data)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
GList * objects, *iter;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!NM_IS_DEVICE_IWD(device))
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!priv->running)
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Here we handle a potential scenario where IWD's DBus objects for the
|
|
Packit Service |
a1bd4f |
* new device popped up before the NMDevice. The
|
|
Packit Service |
a1bd4f |
* interface_added/object_added signals have been received already and
|
|
Packit Service |
a1bd4f |
* the handlers couldn't do much because the NMDevice wasn't there yet
|
|
Packit Service |
a1bd4f |
* so now we go over the Network and Device interfaces again. In this
|
|
Packit Service |
a1bd4f |
* exact order for "object path" property consistency -- see reasoning
|
|
Packit Service |
a1bd4f |
* in object_compare_interfaces.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
objects = g_dbus_object_manager_get_objects(priv->object_manager);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (iter = objects; iter; iter = iter->next) {
|
|
Packit Service |
a1bd4f |
GDBusObject * object = G_DBUS_OBJECT(iter->data);
|
|
Packit Service |
a1bd4f |
gs_unref_object GDBusInterface *interface = NULL;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
interface = g_dbus_object_get_interface(object, NM_IWD_NETWORK_INTERFACE);
|
|
Packit Service |
a1bd4f |
if (!interface)
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (NM_DEVICE_IWD(device) == get_device_from_network(self, (GDBusProxy *) interface))
|
|
Packit Service |
a1bd4f |
nm_device_iwd_network_add_remove(NM_DEVICE_IWD(device), (GDBusProxy *) interface, TRUE);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (iter = objects; iter; iter = iter->next) {
|
|
Packit Service |
a1bd4f |
GDBusObject * object = G_DBUS_OBJECT(iter->data);
|
|
Packit Service |
a1bd4f |
gs_unref_object GDBusInterface *interface = NULL;
|
|
Packit Service |
a1bd4f |
const char * obj_ifname;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
interface = g_dbus_object_get_interface(object, NM_IWD_DEVICE_INTERFACE);
|
|
Packit Service |
a1bd4f |
obj_ifname = get_property_string_or_null((GDBusProxy *) interface, "Name");
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!obj_ifname || strcmp(nm_device_get_iface(device), obj_ifname))
|
|
Packit Service |
a1bd4f |
continue;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_device_iwd_set_dbus_object(NM_DEVICE_IWD(device), object);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_list_free_full(objects, g_object_unref);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void
|
|
Packit Service |
a1bd4f |
device_removed(NMManager *manager, NMDevice *device, gpointer user_data)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!NM_IS_DEVICE_IWD(device))
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (priv->last_agent_call_device == NM_DEVICE_IWD(device))
|
|
Packit Service |
a1bd4f |
priv->last_agent_call_device = NULL;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* This is used to sort the list of objects returned by GetManagedObjects()
|
|
Packit Service |
a1bd4f |
* based on the DBus interfaces available on these objects in such a way that
|
|
Packit Service |
a1bd4f |
* the interface_added calls happen in the right order. The order is defined
|
|
Packit Service |
a1bd4f |
* by how some DBus interfaces point to interfaces on other objects using
|
|
Packit Service |
a1bd4f |
* DBus properties of the type "object path" ("o" signature). This creates
|
|
Packit Service |
a1bd4f |
* "dependencies" between objects.
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* When NM and IWD are running, the InterfacesAdded signals should come in
|
|
Packit Service |
a1bd4f |
* an order that ensures consistency of those object paths. For example
|
|
Packit Service |
a1bd4f |
* when a Network interface is added with a KnownNetwork property, or that
|
|
Packit Service |
a1bd4f |
* property is assigned a new value, the KnownNetwork object pointed to by
|
|
Packit Service |
a1bd4f |
* it will have been added in an earlier InterfacesAdded signal. Similarly
|
|
Packit Service |
a1bd4f |
* Station.ConnectedNetwork and Station.GetOrdereNetworks() only point to
|
|
Packit Service |
a1bd4f |
* existing Network objects. (There may be circular dependencies but during
|
|
Packit Service |
a1bd4f |
* initialization we only need a subset of those properties that doesn't
|
|
Packit Service |
a1bd4f |
* have this problem.)
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* But GetManagedObjects doesn't guarantee this kind of consistency so we
|
|
Packit Service |
a1bd4f |
* order the returned object list ourselves to simplify the job of
|
|
Packit Service |
a1bd4f |
* interface_added(). Objects that don't have any interfaces listed in
|
|
Packit Service |
a1bd4f |
* interface_order are moved to the end of the list.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
static int
|
|
Packit Service |
a1bd4f |
object_compare_interfaces(gconstpointer a, gconstpointer b)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
static const char *interface_order[] = {
|
|
Packit Service |
a1bd4f |
NM_IWD_KNOWN_NETWORK_INTERFACE,
|
|
Packit Service |
a1bd4f |
NM_IWD_NETWORK_INTERFACE,
|
|
Packit Service |
a1bd4f |
NM_IWD_DEVICE_INTERFACE,
|
|
Packit Service |
a1bd4f |
};
|
|
Packit Service |
a1bd4f |
int rank_a = G_N_ELEMENTS(interface_order);
|
|
Packit Service |
a1bd4f |
int rank_b = G_N_ELEMENTS(interface_order);
|
|
Packit Service |
a1bd4f |
guint pos;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
for (pos = 0; interface_order[pos]; pos++) {
|
|
Packit Service |
a1bd4f |
GDBusInterface *iface_a;
|
|
Packit Service |
a1bd4f |
GDBusInterface *iface_b;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (rank_a == G_N_ELEMENTS(interface_order)
|
|
Packit Service |
a1bd4f |
&& (iface_a = g_dbus_object_get_interface(G_DBUS_OBJECT(a), interface_order[pos]))) {
|
|
Packit Service |
a1bd4f |
rank_a = pos;
|
|
Packit Service |
a1bd4f |
g_object_unref(iface_a);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (rank_b == G_N_ELEMENTS(interface_order)
|
|
Packit Service |
a1bd4f |
&& (iface_b = g_dbus_object_get_interface(G_DBUS_OBJECT(b), interface_order[pos]))) {
|
|
Packit Service |
a1bd4f |
rank_b = pos;
|
|
Packit Service |
a1bd4f |
g_object_unref(iface_b);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return rank_a - rank_b;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = user_data;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
GError * error = NULL;
|
|
Packit Service |
a1bd4f |
GDBusObjectManager * object_manager;
|
|
Packit Service |
a1bd4f |
GDBusConnection * connection;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
object_manager = g_dbus_object_manager_client_new_for_bus_finish(result, &error);
|
|
Packit Service |
a1bd4f |
if (object_manager == NULL) {
|
|
Packit Service |
a1bd4f |
_LOGE("failed to acquire IWD Object Manager: Wi-Fi will not be available (%s)",
|
|
Packit Service |
a1bd4f |
error->message);
|
|
Packit Service |
a1bd4f |
g_clear_error(&error);
|
|
Packit Service |
a1bd4f |
return;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
priv->object_manager = object_manager;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->object_manager,
|
|
Packit Service |
a1bd4f |
"notify::name-owner",
|
|
Packit Service |
a1bd4f |
G_CALLBACK(name_owner_changed),
|
|
Packit Service |
a1bd4f |
self);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nm_assert(G_IS_DBUS_OBJECT_MANAGER_CLIENT(object_manager));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
connection =
|
|
Packit Service |
a1bd4f |
g_dbus_object_manager_client_get_connection(G_DBUS_OBJECT_MANAGER_CLIENT(object_manager));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
priv->agent_id = iwd_agent_export(connection, self, &priv->agent_path, &error);
|
|
Packit Service |
a1bd4f |
if (!priv->agent_id) {
|
|
Packit Service |
a1bd4f |
_LOGE("failed to export the IWD Agent: PSK/8021x Wi-Fi networks may not work: %s",
|
|
Packit Service |
a1bd4f |
error->message);
|
|
Packit Service |
a1bd4f |
g_clear_error(&error);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (_om_has_name_owner(object_manager)) {
|
|
Packit Service |
a1bd4f |
GList *objects, *iter;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
priv->running = true;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->object_manager,
|
|
Packit Service |
a1bd4f |
"interface-added",
|
|
Packit Service |
a1bd4f |
G_CALLBACK(interface_added),
|
|
Packit Service |
a1bd4f |
self);
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->object_manager,
|
|
Packit Service |
a1bd4f |
"interface-removed",
|
|
Packit Service |
a1bd4f |
G_CALLBACK(interface_removed),
|
|
Packit Service |
a1bd4f |
self);
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->object_manager, "object-added", G_CALLBACK(object_added), self);
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->object_manager, "object-removed", G_CALLBACK(object_removed), self);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_hash_table_remove_all(priv->known_networks);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
objects = g_dbus_object_manager_get_objects(object_manager);
|
|
Packit Service |
a1bd4f |
objects = g_list_sort(objects, object_compare_interfaces);
|
|
Packit Service |
a1bd4f |
for (iter = objects; iter; iter = iter->next)
|
|
Packit Service |
a1bd4f |
object_added(NULL, G_DBUS_OBJECT(iter->data), self);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_list_free_full(objects, g_object_unref);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (priv->agent_id)
|
|
Packit Service |
a1bd4f |
register_agent(self);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
static void
|
|
Packit Service |
a1bd4f |
prepare_object_manager(NMIwdManager *self)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_dbus_object_manager_client_new_for_bus(NM_IWD_BUS_TYPE,
|
|
Packit Service |
a1bd4f |
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
|
|
Packit Service |
a1bd4f |
NM_IWD_SERVICE,
|
|
Packit Service |
a1bd4f |
"/",
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
priv->cancellable,
|
|
Packit Service |
a1bd4f |
got_object_manager,
|
|
Packit Service |
a1bd4f |
self);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gboolean
|
|
Packit Service |
a1bd4f |
nm_iwd_manager_is_known_network(NMIwdManager *self, const char *name, NMIwdNetworkSecurity security)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
KnownNetworkId kn_id = {name, security};
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return g_hash_table_contains(priv->known_networks, &kn_id);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
NMSettingsConnection *
|
|
Packit Service |
a1bd4f |
nm_iwd_manager_get_ap_mirror_connection(NMIwdManager *self, NMWifiAP *ap)
|
|
Packit Service |
a1bd4f |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate * priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
KnownNetworkData * data;
|
|
Packit Service |
a1bd4f |
char name_buf[33];
|
|
Packit Service |
a1bd4f |
KnownNetworkId kn_id = {name_buf, NM_IWD_NETWORK_SECURITY_NONE};
|
|
Packit Service |
a1bd4f |
const guint8 * ssid_bytes;
|
|
Packit Service |
a1bd4f |
gsize ssid_len;
|
|
Packit Service |
a1bd4f |
NM80211ApFlags flags = nm_wifi_ap_get_flags(ap);
|
|
Packit Service |
a1bd4f |
NM80211ApSecurityFlags sec_flags = nm_wifi_ap_get_wpa_flags(ap) | nm_wifi_ap_get_rsn_flags(ap);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
ssid_bytes = g_bytes_get_data(nm_wifi_ap_get_ssid(ap), &ssid_len);
|
|
Packit Service |
a1bd4f |
ssid_len = MIN(ssid_len, 32);
|
|
Packit Service |
a1bd4f |
memcpy(name_buf, ssid_bytes, ssid_len);
|
|
Packit Service |
a1bd4f |
name_buf[ssid_len] = '\0';
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (flags & NM_802_11_AP_FLAGS_PRIVACY)
|
|
Packit Service |
a1bd4f |
kn_id.security = NM_IWD_NETWORK_SECURITY_WEP;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (sec_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
|
|
Packit Service |
a1bd4f |
kn_id.security = NM_IWD_NETWORK_SECURITY_PSK;
|
|
Packit Service |
a1bd4f |
else if (sec_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
|
|
Packit Service |
a1bd4f |
kn_id.security = NM_IWD_NETWORK_SECURITY_8021X;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* Right now it's easier for us to do a name+security lookup than to use
|
|
Packit Service |
a1bd4f |
* the Network.KnownNetwork property to look up by path.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
data = g_hash_table_lookup(priv->known_networks, &kn_id);
|
|
Packit Service |
a1bd4f |
if (data)
|
|
Packit Service |
a1bd4f |
return data->mirror_connection;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* We have no KnownNetwork for this AP, we're probably connecting to it for
|
|
Packit Service |
a1bd4f |
* the first time. This is not a usual/supported scenario so we don't need
|
|
Packit Service |
a1bd4f |
* to bother too much about creating a great mirror connection, we don't
|
|
Packit Service |
a1bd4f |
* even have any more information than the Name & Type properties on the
|
|
Packit Service |
a1bd4f |
* Network interface. This *should* never happen for an 8021x type network.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
return mirror_connection(self, &kn_id, TRUE, NULL);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
GDBusProxy *
|
|
Packit Service |
a1bd4f |
nm_iwd_manager_get_dbus_interface(NMIwdManager *self, const char *path, const char *name)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
GDBusInterface * interface;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (!priv->object_manager)
|
|
Packit Service |
a1bd4f |
return NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
interface = g_dbus_object_manager_get_interface(priv->object_manager, path, name);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return interface ? G_DBUS_PROXY(interface) : NULL;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
NM_DEFINE_SINGLETON_GETTER(NMIwdManager, nm_iwd_manager_get, NM_TYPE_IWD_MANAGER);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nm_iwd_manager_init(NMIwdManager *self)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
priv->manager = g_object_ref(NM_MANAGER_GET);
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK(device_added), self);
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK(device_removed), self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
priv->settings = g_object_ref(NM_SETTINGS_GET);
|
|
Packit Service |
a1bd4f |
g_signal_connect(priv->settings,
|
|
Packit Service |
a1bd4f |
NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
|
|
Packit Service |
a1bd4f |
G_CALLBACK(connection_removed),
|
|
Packit Service |
a1bd4f |
self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
priv->cancellable = g_cancellable_new();
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
priv->known_networks = g_hash_table_new_full((GHashFunc) known_network_id_hash,
|
|
Packit Service |
a1bd4f |
(GEqualFunc) known_network_id_equal,
|
|
Packit Service |
a1bd4f |
g_free,
|
|
Packit Service |
a1bd4f |
(GDestroyNotify) known_network_data_free);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
prepare_object_manager(self);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
dispose(GObject *object)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NMIwdManager * self = (NMIwdManager *) object;
|
|
Packit Service |
a1bd4f |
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
release_object_manager(self);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
nm_clear_g_cancellable(&priv->cancellable);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (priv->settings) {
|
|
Packit Service |
a1bd4f |
g_signal_handlers_disconnect_by_data(priv->settings, self);
|
|
Packit Service |
a1bd4f |
g_clear_object(&priv->settings);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
/* This may trigger mirror connection removals so it happens
|
|
Packit Service |
a1bd4f |
* after the g_signal_handlers_disconnect_by_data above.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
nm_clear_pointer(&priv->known_networks, g_hash_table_destroy);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (priv->manager) {
|
|
Packit Service |
a1bd4f |
g_signal_handlers_disconnect_by_data(priv->manager, self);
|
|
Packit Service |
a1bd4f |
g_clear_object(&priv->manager);
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
priv->last_agent_call_device = NULL;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_OBJECT_CLASS(nm_iwd_manager_parent_class)->dispose(object);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nm_iwd_manager_class_init(NMIwdManagerClass *klass)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
object_class->dispose = dispose;
|
|
Packit |
5756e2 |
}
|