|
Packit Service |
b23acc |
// SPDX-License-Identifier: GPL-2.0+
|
|
Packit Service |
b23acc |
/*
|
|
Packit Service |
b23acc |
* Copyright (C) 2005 - 2013 Red Hat, Inc.
|
|
Packit Service |
b23acc |
* Copyright (C) 2006 - 2008 Novell, Inc.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#include "nm-default.h"
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#include "nm-vpn-connection.h"
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#include <sys/socket.h>
|
|
Packit Service |
b23acc |
#include <netinet/in.h>
|
|
Packit Service |
b23acc |
#include <arpa/inet.h>
|
|
Packit Service |
b23acc |
#include <stdlib.h>
|
|
Packit Service |
b23acc |
#include <unistd.h>
|
|
Packit Service |
b23acc |
#include <syslog.h>
|
|
Packit Service |
b23acc |
#include <linux/rtnetlink.h>
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#include "nm-proxy-config.h"
|
|
Packit Service |
b23acc |
#include "nm-ip4-config.h"
|
|
Packit Service |
b23acc |
#include "nm-ip6-config.h"
|
|
Packit Service |
b23acc |
#include "platform/nm-platform.h"
|
|
Packit Service |
b23acc |
#include "nm-active-connection.h"
|
|
Packit Service |
b23acc |
#include "NetworkManagerUtils.h"
|
|
Packit Service |
b23acc |
#include "settings/nm-settings-connection.h"
|
|
Packit Service |
b23acc |
#include "nm-dispatcher.h"
|
|
Packit Service |
b23acc |
#include "nm-netns.h"
|
|
Packit Service |
b23acc |
#include "settings/nm-agent-manager.h"
|
|
Packit Service |
b23acc |
#include "nm-core-internal.h"
|
|
Packit Service |
b23acc |
#include "nm-pacrunner-manager.h"
|
|
Packit Service |
b23acc |
#include "nm-firewall-manager.h"
|
|
Packit Service |
b23acc |
#include "nm-config.h"
|
|
Packit Service |
b23acc |
#include "nm-vpn-plugin-info.h"
|
|
Packit Service |
b23acc |
#include "nm-vpn-manager.h"
|
|
Packit Service |
b23acc |
#include "dns/nm-dns-manager.h"
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
typedef enum {
|
|
Packit Service |
b23acc |
/* Only system secrets */
|
|
Packit Service |
b23acc |
SECRETS_REQ_SYSTEM = 0,
|
|
Packit Service |
b23acc |
/* All existing secrets including agent secrets */
|
|
Packit Service |
b23acc |
SECRETS_REQ_EXISTING = 1,
|
|
Packit Service |
b23acc |
/* New secrets required; ask an agent */
|
|
Packit Service |
b23acc |
SECRETS_REQ_NEW = 2,
|
|
Packit Service |
b23acc |
/* Plugin requests secrets interactively */
|
|
Packit Service |
b23acc |
SECRETS_REQ_INTERACTIVE = 3,
|
|
Packit Service |
b23acc |
/* Placeholder for bounds checking */
|
|
Packit Service |
b23acc |
SECRETS_REQ_LAST
|
|
Packit Service |
b23acc |
} SecretsReq;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Internal VPN states, private to NMVpnConnection */
|
|
Packit Service |
b23acc |
typedef enum {
|
|
Packit Service |
b23acc |
STATE_UNKNOWN = 0,
|
|
Packit Service |
b23acc |
STATE_WAITING,
|
|
Packit Service |
b23acc |
STATE_PREPARE,
|
|
Packit Service |
b23acc |
STATE_NEED_AUTH,
|
|
Packit Service |
b23acc |
STATE_CONNECT,
|
|
Packit Service |
b23acc |
STATE_IP_CONFIG_GET,
|
|
Packit Service |
b23acc |
STATE_PRE_UP,
|
|
Packit Service |
b23acc |
STATE_ACTIVATED,
|
|
Packit Service |
b23acc |
STATE_DEACTIVATING,
|
|
Packit Service |
b23acc |
STATE_DISCONNECTED,
|
|
Packit Service |
b23acc |
STATE_FAILED,
|
|
Packit Service |
b23acc |
} VpnState;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
enum {
|
|
Packit Service |
b23acc |
INTERNAL_STATE_CHANGED,
|
|
Packit Service |
b23acc |
INTERNAL_RETRY_AFTER_FAILURE,
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
LAST_SIGNAL
|
|
Packit Service |
b23acc |
};
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static guint signals[LAST_SIGNAL] = { 0 };
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NM_GOBJECT_PROPERTIES_DEFINE (NMVpnConnection,
|
|
Packit Service |
b23acc |
PROP_VPN_STATE,
|
|
Packit Service |
b23acc |
PROP_BANNER,
|
|
Packit Service |
b23acc |
#define PROP_IP4_CONFIG 2000
|
|
Packit Service |
b23acc |
#define PROP_IP6_CONFIG 2001
|
|
Packit Service |
b23acc |
#define PROP_MASTER 2002
|
|
Packit Service |
b23acc |
);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
typedef struct {
|
|
Packit Service |
b23acc |
gboolean service_can_persist;
|
|
Packit Service |
b23acc |
gboolean connection_can_persist;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMSettingsConnectionCallId *secrets_id;
|
|
Packit Service |
b23acc |
SecretsReq secrets_idx;
|
|
Packit Service |
b23acc |
char *username;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
VpnState vpn_state;
|
|
Packit Service |
b23acc |
NMDispatcherCallId *dispatcher_id;
|
|
Packit Service |
b23acc |
NMActiveConnectionStateReason failure_reason;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMVpnServiceState service_state;
|
|
Packit Service |
b23acc |
guint start_timeout;
|
|
Packit Service |
b23acc |
gboolean service_running;
|
|
Packit Service |
b23acc |
NMVpnPluginInfo *plugin_info;
|
|
Packit Service |
b23acc |
char *bus_name;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMFirewallManagerCallId *fw_call;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMNetns *netns;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
GPtrArray *ip4_dev_route_blacklist;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
GDBusProxy *proxy;
|
|
Packit Service |
b23acc |
GCancellable *cancellable;
|
|
Packit Service |
b23acc |
GVariant *connect_hash;
|
|
Packit Service |
b23acc |
guint connect_timeout;
|
|
Packit Service |
b23acc |
NMProxyConfig *proxy_config;
|
|
Packit Service |
b23acc |
NMPacrunnerConfId *pacrunner_conf_id;
|
|
Packit Service |
b23acc |
gboolean has_ip4;
|
|
Packit Service |
b23acc |
NMIP4Config *ip4_config;
|
|
Packit Service |
b23acc |
guint32 ip4_internal_gw;
|
|
Packit Service |
b23acc |
guint32 ip4_external_gw;
|
|
Packit Service |
b23acc |
gboolean has_ip6;
|
|
Packit Service |
b23acc |
NMIP6Config *ip6_config;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* These config instances are passed on to NMDevice and modified by NMDevice.
|
|
Packit Service |
b23acc |
* This pointer is only useful for nm_device_replace_vpn4_config() to clear the
|
|
Packit Service |
b23acc |
* previous configuration. Consider these instances to be owned by NMDevice. */
|
|
Packit Service |
b23acc |
NMIP4Config *last_device_ip4_config;
|
|
Packit Service |
b23acc |
NMIP6Config *last_device_ip6_config;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
struct in6_addr *ip6_internal_gw;
|
|
Packit Service |
b23acc |
struct in6_addr *ip6_external_gw;
|
|
Packit Service |
b23acc |
char *ip_iface;
|
|
Packit Service |
b23acc |
int ip_ifindex;
|
|
Packit Service |
b23acc |
char *banner;
|
|
Packit Service |
b23acc |
guint32 mtu;
|
|
Packit Service |
b23acc |
} NMVpnConnectionPrivate;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
struct _NMVpnConnection {
|
|
Packit Service |
b23acc |
NMActiveConnection parent;
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate _priv;
|
|
Packit Service |
b23acc |
};
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
struct _NMVpnConnectionClass {
|
|
Packit Service |
b23acc |
NMActiveConnectionClass parent;
|
|
Packit Service |
b23acc |
};
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION)
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#define NM_VPN_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMVpnConnection, NM_IS_VPN_CONNECTION, NMActiveConnection)
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/*****************************************************************************/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static const NMDBusInterfaceInfoExtended interface_info_vpn_connection;
|
|
Packit Service |
b23acc |
static const GDBusSignalInfo signal_info_vpn_state_changed;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static NMSettingsConnection *_get_settings_connection (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
gboolean allow_missing);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void get_secrets (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
SecretsReq secrets_idx,
|
|
Packit Service |
b23acc |
const char *const*hints);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static guint32 get_route_table (NMVpnConnection *self, int addr_family, gboolean fallback_main);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void plugin_interactive_secrets_required (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
const char *message,
|
|
Packit Service |
b23acc |
const char *const*secrets);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void _set_vpn_state (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
VpnState vpn_state,
|
|
Packit Service |
b23acc |
NMActiveConnectionStateReason reason,
|
|
Packit Service |
b23acc |
gboolean quitting);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/*****************************************************************************/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#define _NMLOG_DOMAIN LOGD_VPN
|
|
Packit Service |
b23acc |
#define _NMLOG_PREFIX_NAME "vpn-connection"
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#define __NMLOG_prefix_buf_len 128
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static const char *
|
|
Packit Service |
b23acc |
__LOG_create_prefix (char *buf, NMVpnConnection *self, NMSettingsConnection *con)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
const char *id;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!self)
|
|
Packit Service |
b23acc |
return _NMLOG_PREFIX_NAME;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
id = con ? nm_settings_connection_get_id (con) : NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_snprintf (buf, __NMLOG_prefix_buf_len,
|
|
Packit Service |
b23acc |
"%s["
|
|
Packit Service |
b23acc |
"%p" /*self*/
|
|
Packit Service |
b23acc |
"%s%s" /*con-uuid*/
|
|
Packit Service |
b23acc |
"%s%s%s%s" /*con-id*/
|
|
Packit Service |
b23acc |
",%d" /*ifindex*/
|
|
Packit Service |
b23acc |
"%s%s%s" /*iface*/
|
|
Packit Service |
b23acc |
"]",
|
|
Packit Service |
b23acc |
_NMLOG_PREFIX_NAME,
|
|
Packit Service |
b23acc |
self,
|
|
Packit Service |
b23acc |
con ? "," : "--", con ? (nm_settings_connection_get_uuid (con) ?: "??") : "",
|
|
Packit Service |
b23acc |
con ? "," : "", NM_PRINT_FMT_QUOTED (id, "\"", id, "\"", con ? "??" : ""),
|
|
Packit Service |
b23acc |
priv->ip_ifindex,
|
|
Packit Service |
b23acc |
NM_PRINT_FMT_QUOTED (priv->ip_iface, ":(", priv->ip_iface, ")", "")
|
|
Packit Service |
b23acc |
);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return buf;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#define _NMLOG(level, ...) \
|
|
Packit Service |
b23acc |
G_STMT_START { \
|
|
Packit Service |
b23acc |
const NMLogLevel _level = (level); \
|
|
Packit Service |
b23acc |
NMSettingsConnection *_con = (self) ? _get_settings_connection (self, TRUE) : NULL; \
|
|
Packit Service |
b23acc |
\
|
|
Packit Service |
b23acc |
if (nm_logging_enabled (_level, _NMLOG_DOMAIN)) { \
|
|
Packit Service |
b23acc |
char __prefix[__NMLOG_prefix_buf_len]; \
|
|
Packit Service |
b23acc |
\
|
|
Packit Service |
b23acc |
_nm_log (_level, _NMLOG_DOMAIN, 0, \
|
|
Packit Service |
b23acc |
(self) ? NM_VPN_CONNECTION_GET_PRIVATE (self)->ip_iface : NULL, \
|
|
Packit Service |
b23acc |
(_con) ? nm_settings_connection_get_uuid (_con) : NULL, \
|
|
Packit Service |
b23acc |
"%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
|
|
Packit Service |
b23acc |
__LOG_create_prefix (__prefix, (self), _con) \
|
|
Packit Service |
b23acc |
_NM_UTILS_MACRO_REST (__VA_ARGS__)); \
|
|
Packit Service |
b23acc |
} \
|
|
Packit Service |
b23acc |
} G_STMT_END
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/*****************************************************************************/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
cancel_get_secrets (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->secrets_id) {
|
|
Packit Service |
b23acc |
nm_settings_connection_cancel_secrets (_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
priv->secrets_id);
|
|
Packit Service |
b23acc |
g_warn_if_fail (!priv->secrets_id);
|
|
Packit Service |
b23acc |
priv->secrets_id = NULL;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static NMVpnConnectionState
|
|
Packit Service |
b23acc |
_state_to_nm_vpn_state (VpnState state)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
switch (state) {
|
|
Packit Service |
b23acc |
case STATE_WAITING:
|
|
Packit Service |
b23acc |
case STATE_PREPARE:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_PREPARE;
|
|
Packit Service |
b23acc |
case STATE_NEED_AUTH:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_NEED_AUTH;
|
|
Packit Service |
b23acc |
case STATE_CONNECT:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_CONNECT;
|
|
Packit Service |
b23acc |
case STATE_IP_CONFIG_GET:
|
|
Packit Service |
b23acc |
case STATE_PRE_UP:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_IP_CONFIG_GET;
|
|
Packit Service |
b23acc |
case STATE_ACTIVATED:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_ACTIVATED;
|
|
Packit Service |
b23acc |
case STATE_DEACTIVATING: {
|
|
Packit Service |
b23acc |
/* Map DEACTIVATING to ACTIVATED to preserve external API behavior,
|
|
Packit Service |
b23acc |
* since our API has no DEACTIVATING state of its own. Since this can
|
|
Packit Service |
b23acc |
* take some time, and the VPN isn't actually disconnected until it
|
|
Packit Service |
b23acc |
* hits the DISCONNECTED state, to clients it should still appear
|
|
Packit Service |
b23acc |
* connected.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_ACTIVATED;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
case STATE_DISCONNECTED:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_DISCONNECTED;
|
|
Packit Service |
b23acc |
case STATE_FAILED:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_FAILED;
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_STATE_UNKNOWN;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static NMActiveConnectionState
|
|
Packit Service |
b23acc |
_state_to_ac_state (VpnState vpn_state)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
/* Set the NMActiveConnection state based on VPN state */
|
|
Packit Service |
b23acc |
switch (vpn_state) {
|
|
Packit Service |
b23acc |
case STATE_WAITING:
|
|
Packit Service |
b23acc |
case STATE_PREPARE:
|
|
Packit Service |
b23acc |
case STATE_NEED_AUTH:
|
|
Packit Service |
b23acc |
case STATE_CONNECT:
|
|
Packit Service |
b23acc |
case STATE_IP_CONFIG_GET:
|
|
Packit Service |
b23acc |
case STATE_PRE_UP:
|
|
Packit Service |
b23acc |
return NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
|
|
Packit Service |
b23acc |
case STATE_ACTIVATED:
|
|
Packit Service |
b23acc |
return NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
|
|
Packit Service |
b23acc |
case STATE_DEACTIVATING:
|
|
Packit Service |
b23acc |
return NM_ACTIVE_CONNECTION_STATE_DEACTIVATING;
|
|
Packit Service |
b23acc |
case STATE_DISCONNECTED:
|
|
Packit Service |
b23acc |
case STATE_FAILED:
|
|
Packit Service |
b23acc |
return NM_ACTIVE_CONNECTION_STATE_DEACTIVATED;
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
return NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static NMSettingsConnection *
|
|
Packit Service |
b23acc |
_get_settings_connection (NMVpnConnection *self, gboolean allow_missing)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMSettingsConnection *con;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Currently we operate on the assumption, that the settings-connection
|
|
Packit Service |
b23acc |
* never changes after it is set (though initially, it might be unset).
|
|
Packit Service |
b23acc |
* Later we might want to change that, but then we need fixes here too. */
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
con = _nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
b23acc |
if (!con && !allow_missing)
|
|
Packit Service |
b23acc |
g_return_val_if_reached (NULL);
|
|
Packit Service |
b23acc |
return con;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static NMConnection *
|
|
Packit Service |
b23acc |
_get_applied_connection (NMVpnConnection *connection)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMConnection *con;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
con = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (connection));
|
|
Packit Service |
b23acc |
g_return_val_if_fail (con, NULL);
|
|
Packit Service |
b23acc |
return con;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
disconnect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
GVariant *variant;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
variant = g_dbus_proxy_call_finish (proxy, result, NULL);
|
|
Packit Service |
b23acc |
if (variant)
|
|
Packit Service |
b23acc |
g_variant_unref (variant);
|
|
Packit Service |
b23acc |
g_object_unref (user_data);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
fw_call_cleanup (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->fw_call) {
|
|
Packit Service |
b23acc |
nm_firewall_manager_cancel_call (priv->fw_call);
|
|
Packit Service |
b23acc |
g_warn_if_fail (!priv->fw_call);
|
|
Packit Service |
b23acc |
priv->fw_call = NULL;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
remove_parent_device_config (NMVpnConnection *connection, NMDevice *device)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->last_device_ip4_config) {
|
|
Packit Service |
b23acc |
nm_device_replace_vpn4_config (device, priv->last_device_ip4_config, NULL);
|
|
Packit Service |
b23acc |
g_clear_object (&priv->last_device_ip4_config);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->last_device_ip6_config) {
|
|
Packit Service |
b23acc |
nm_device_replace_vpn6_config (device, priv->last_device_ip6_config, NULL);
|
|
Packit Service |
b23acc |
g_clear_object (&priv->last_device_ip6_config);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
vpn_cleanup (NMVpnConnection *self, NMDevice *parent_dev)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex) {
|
|
Packit Service |
b23acc |
NMPlatform *platform = nm_netns_get_platform (priv->netns);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_platform_link_set_down (platform, priv->ip_ifindex);
|
|
Packit Service |
b23acc |
nm_platform_ip_route_flush (platform, AF_UNSPEC, priv->ip_ifindex);
|
|
Packit Service |
b23acc |
nm_platform_ip_address_flush (platform, AF_UNSPEC, priv->ip_ifindex);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
remove_parent_device_config (self, parent_dev);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Remove zone from firewall */
|
|
Packit Service |
b23acc |
if (priv->ip_iface) {
|
|
Packit Service |
b23acc |
nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
/* Cancel pending firewall call */
|
|
Packit Service |
b23acc |
fw_call_cleanup (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_free (priv->banner);
|
|
Packit Service |
b23acc |
priv->banner = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_free (priv->ip_iface);
|
|
Packit Service |
b23acc |
priv->ip_iface = NULL;
|
|
Packit Service |
b23acc |
priv->ip_ifindex = 0;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_free (priv->bus_name);
|
|
Packit Service |
b23acc |
priv->bus_name = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Clear out connection secrets to ensure that the settings service
|
|
Packit Service |
b23acc |
* gets asked for them next time the connection is activated.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
dispatcher_pre_down_done (NMDispatcherCallId *call_id, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (call_id);
|
|
Packit Service |
b23acc |
nm_assert (priv->dispatcher_id == call_id);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->dispatcher_id = NULL;
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_DISCONNECTED, NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
dispatcher_pre_up_done (NMDispatcherCallId *call_id, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (call_id);
|
|
Packit Service |
b23acc |
nm_assert (priv->dispatcher_id == call_id);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->dispatcher_id = NULL;
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_ACTIVATED, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
dispatcher_cleanup (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->dispatcher_id)
|
|
Packit Service |
b23acc |
nm_dispatcher_call_cancel (g_steal_pointer (&priv->dispatcher_id));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
_set_vpn_state (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
VpnState vpn_state,
|
|
Packit Service |
b23acc |
NMActiveConnectionStateReason reason,
|
|
Packit Service |
b23acc |
gboolean quitting)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
VpnState old_vpn_state;
|
|
Packit Service |
b23acc |
NMVpnConnectionState new_external_state, old_external_state;
|
|
Packit Service |
b23acc |
NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
b23acc |
NMConnection *applied;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_VPN_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (vpn_state == priv->vpn_state)
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
old_vpn_state = priv->vpn_state;
|
|
Packit Service |
b23acc |
priv->vpn_state = vpn_state;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* The device gets destroyed by active connection when it enters
|
|
Packit Service |
b23acc |
* the deactivated state, so we need to ref it for usage below.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if (parent_dev)
|
|
Packit Service |
b23acc |
g_object_ref (parent_dev);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Update active connection base class state */
|
|
Packit Service |
b23acc |
nm_active_connection_set_state (NM_ACTIVE_CONNECTION (self),
|
|
Packit Service |
b23acc |
_state_to_ac_state (vpn_state),
|
|
Packit Service |
b23acc |
reason);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Clear any in-progress secrets request */
|
|
Packit Service |
b23acc |
cancel_get_secrets (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
dispatcher_cleanup (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* The connection gets destroyed by the VPN manager when it enters the
|
|
Packit Service |
b23acc |
* disconnected/failed state, but we need to keep it around for a bit
|
|
Packit Service |
b23acc |
* to send out signals and handle the dispatcher. So ref it.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
g_object_ref (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
old_external_state = _state_to_nm_vpn_state (old_vpn_state);
|
|
Packit Service |
b23acc |
new_external_state = _state_to_nm_vpn_state (priv->vpn_state);
|
|
Packit Service |
b23acc |
if (new_external_state != old_external_state) {
|
|
Packit Service |
b23acc |
nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self),
|
|
Packit Service |
b23acc |
&interface_info_vpn_connection,
|
|
Packit Service |
b23acc |
&signal_info_vpn_state_changed,
|
|
Packit Service |
b23acc |
"(uu)",
|
|
Packit Service |
b23acc |
(guint32) new_external_state,
|
|
Packit Service |
b23acc |
(guint32) reason);
|
|
Packit Service |
b23acc |
g_signal_emit (self, signals[INTERNAL_STATE_CHANGED], 0,
|
|
Packit Service |
b23acc |
new_external_state,
|
|
Packit Service |
b23acc |
old_external_state,
|
|
Packit Service |
b23acc |
reason);
|
|
Packit Service |
b23acc |
_notify (self, PROP_VPN_STATE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
switch (vpn_state) {
|
|
Packit Service |
b23acc |
case STATE_NEED_AUTH:
|
|
Packit Service |
b23acc |
/* Do nothing; not part of 'default' because we don't want to touch
|
|
Packit Service |
b23acc |
* priv->secrets_req as NEED_AUTH is re-entered during interactive
|
|
Packit Service |
b23acc |
* secrets.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case STATE_PRE_UP:
|
|
Packit Service |
b23acc |
if (!nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_PRE_UP,
|
|
Packit Service |
b23acc |
_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
_get_applied_connection (self),
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
priv->proxy_config,
|
|
Packit Service |
b23acc |
priv->ip4_config,
|
|
Packit Service |
b23acc |
priv->ip6_config,
|
|
Packit Service |
b23acc |
dispatcher_pre_up_done,
|
|
Packit Service |
b23acc |
self,
|
|
Packit Service |
b23acc |
&priv->dispatcher_id)) {
|
|
Packit Service |
b23acc |
/* Just proceed on errors */
|
|
Packit Service |
b23acc |
dispatcher_pre_up_done (0, self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case STATE_ACTIVATED:
|
|
Packit Service |
b23acc |
applied = _get_applied_connection (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Secrets no longer needed now that we're connected */
|
|
Packit Service |
b23acc |
nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Let dispatcher scripts know we're up and running */
|
|
Packit Service |
b23acc |
nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_UP,
|
|
Packit Service |
b23acc |
_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
applied,
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
priv->proxy_config,
|
|
Packit Service |
b23acc |
priv->ip4_config,
|
|
Packit Service |
b23acc |
priv->ip6_config,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->proxy_config) {
|
|
Packit Service |
b23acc |
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
|
Packit Service |
b23acc |
priv->pacrunner_conf_id = nm_pacrunner_manager_add (nm_pacrunner_manager_get (),
|
|
Packit Service |
b23acc |
priv->proxy_config,
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
priv->ip4_config,
|
|
Packit Service |
b23acc |
priv->ip6_config);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case STATE_DEACTIVATING:
|
|
Packit Service |
b23acc |
applied = _get_applied_connection (self);
|
|
Packit Service |
b23acc |
if (quitting) {
|
|
Packit Service |
b23acc |
nm_dispatcher_call_vpn_sync (NM_DISPATCHER_ACTION_VPN_PRE_DOWN,
|
|
Packit Service |
b23acc |
_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
applied,
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
priv->proxy_config,
|
|
Packit Service |
b23acc |
priv->ip4_config,
|
|
Packit Service |
b23acc |
priv->ip6_config);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
if (!nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_PRE_DOWN,
|
|
Packit Service |
b23acc |
_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
applied,
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
priv->proxy_config,
|
|
Packit Service |
b23acc |
priv->ip4_config,
|
|
Packit Service |
b23acc |
priv->ip6_config,
|
|
Packit Service |
b23acc |
dispatcher_pre_down_done,
|
|
Packit Service |
b23acc |
self,
|
|
Packit Service |
b23acc |
&priv->dispatcher_id)) {
|
|
Packit Service |
b23acc |
/* Just proceed on errors */
|
|
Packit Service |
b23acc |
dispatcher_pre_down_done (0, self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case STATE_FAILED:
|
|
Packit Service |
b23acc |
case STATE_DISCONNECTED:
|
|
Packit Service |
b23acc |
if ( old_vpn_state >= STATE_ACTIVATED
|
|
Packit Service |
b23acc |
&& old_vpn_state <= STATE_DEACTIVATING) {
|
|
Packit Service |
b23acc |
/* Let dispatcher scripts know we're about to go down */
|
|
Packit Service |
b23acc |
if (quitting) {
|
|
Packit Service |
b23acc |
nm_dispatcher_call_vpn_sync (NM_DISPATCHER_ACTION_VPN_DOWN,
|
|
Packit Service |
b23acc |
_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
_get_applied_connection (self),
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_DOWN,
|
|
Packit Service |
b23acc |
_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
_get_applied_connection (self),
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Tear down and clean up the connection */
|
|
Packit Service |
b23acc |
if (priv->proxy) {
|
|
Packit Service |
b23acc |
g_dbus_proxy_call (priv->proxy,
|
|
Packit Service |
b23acc |
"Disconnect",
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
b23acc |
-1,
|
|
Packit Service |
b23acc |
priv->cancellable,
|
|
Packit Service |
b23acc |
(GAsyncReadyCallback) disconnect_cb,
|
|
Packit Service |
b23acc |
g_object_ref (self));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
vpn_cleanup (self, parent_dev);
|
|
Packit Service |
b23acc |
/* fall-through */
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
priv->secrets_idx = SECRETS_REQ_SYSTEM;
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_object_unref (self);
|
|
Packit Service |
b23acc |
if (parent_dev)
|
|
Packit Service |
b23acc |
g_object_unref (parent_dev);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
_service_and_connection_can_persist (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->connection_can_persist &&
|
|
Packit Service |
b23acc |
NM_VPN_CONNECTION_GET_PRIVATE (self)->service_can_persist;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
_connection_only_can_persist (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->connection_can_persist &&
|
|
Packit Service |
b23acc |
!NM_VPN_CONNECTION_GET_PRIVATE (self)->service_can_persist;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
device_state_changed (NMActiveConnection *active,
|
|
Packit Service |
b23acc |
NMDevice *device,
|
|
Packit Service |
b23acc |
NMDeviceState new_state,
|
|
Packit Service |
b23acc |
NMDeviceState old_state)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
if (_service_and_connection_can_persist (NM_VPN_CONNECTION (active))) {
|
|
Packit Service |
b23acc |
if (new_state <= NM_DEVICE_STATE_DISCONNECTED ||
|
|
Packit Service |
b23acc |
new_state == NM_DEVICE_STATE_FAILED) {
|
|
Packit Service |
b23acc |
nm_active_connection_set_device (active, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (new_state <= NM_DEVICE_STATE_DISCONNECTED) {
|
|
Packit Service |
b23acc |
_set_vpn_state (NM_VPN_CONNECTION (active),
|
|
Packit Service |
b23acc |
STATE_DISCONNECTED,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED,
|
|
Packit Service |
b23acc |
FALSE);
|
|
Packit Service |
b23acc |
} else if (new_state == NM_DEVICE_STATE_FAILED) {
|
|
Packit Service |
b23acc |
_set_vpn_state (NM_VPN_CONNECTION (active),
|
|
Packit Service |
b23acc |
STATE_FAILED,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED,
|
|
Packit Service |
b23acc |
FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* FIXME: map device DEACTIVATING state to VPN DEACTIVATING state and
|
|
Packit Service |
b23acc |
* block device deactivation on VPN deactivation.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
add_ip4_vpn_gateway_route (NMIP4Config *config,
|
|
Packit Service |
b23acc |
NMDevice *parent_device,
|
|
Packit Service |
b23acc |
in_addr_t vpn_gw,
|
|
Packit Service |
b23acc |
NMPlatform *platform)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
guint32 parent_gw = 0;
|
|
Packit Service |
b23acc |
gboolean has_parent_gw = FALSE;
|
|
Packit Service |
b23acc |
NMPlatformIP4Route route;
|
|
Packit Service |
b23acc |
int ifindex;
|
|
Packit Service |
b23acc |
guint32 route_metric;
|
|
Packit Service |
b23acc |
nm_auto_nmpobj const NMPObject *route_resolved = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_DEVICE (parent_device));
|
|
Packit Service |
b23acc |
g_return_if_fail (vpn_gw != 0);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
ifindex = nm_ip4_config_get_ifindex (config);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (ifindex > 0);
|
|
Packit Service |
b23acc |
nm_assert (ifindex == nm_device_get_ip_ifindex (parent_device));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Ask kernel how to reach @vpn_gw. We can only inject the route in
|
|
Packit Service |
b23acc |
* @parent_device, so whatever we resolve, it can only be on @ifindex. */
|
|
Packit Service |
b23acc |
if (nm_platform_ip_route_get (platform,
|
|
Packit Service |
b23acc |
AF_INET,
|
|
Packit Service |
b23acc |
&vpn_gw,
|
|
Packit Service |
b23acc |
ifindex,
|
|
Packit Service |
b23acc |
(NMPObject **) &route_resolved) >= 0) {
|
|
Packit Service |
b23acc |
const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (route_resolved);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (r->ifindex == ifindex) {
|
|
Packit Service |
b23acc |
const NMPObject *obj;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* `ip route get` always resolves the route, even if the destination is unreachable.
|
|
Packit Service |
b23acc |
* In which case, it pretends the destination is directly reachable.
|
|
Packit Service |
b23acc |
*
|
|
Packit Service |
b23acc |
* So, only accept direct routes if @vpn_gw is a private network
|
|
Packit Service |
b23acc |
* or if the parent device also has a direct default route */
|
|
Packit Service |
b23acc |
if (nm_platform_route_table_is_main (r->table_coerced)) {
|
|
Packit Service |
b23acc |
if (r->gateway) {
|
|
Packit Service |
b23acc |
parent_gw = r->gateway;
|
|
Packit Service |
b23acc |
has_parent_gw = TRUE;
|
|
Packit Service |
b23acc |
} else if (nm_utils_ip_is_site_local (AF_INET, &vpn_gw)) {
|
|
Packit Service |
b23acc |
has_parent_gw = TRUE;
|
|
Packit Service |
b23acc |
} else if ( (obj = nm_device_get_best_default_route (parent_device, AF_INET))
|
|
Packit Service |
b23acc |
&& !NMP_OBJECT_CAST_IP4_ROUTE (obj)->gateway) {
|
|
Packit Service |
b23acc |
has_parent_gw = TRUE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!has_parent_gw)
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
route_metric = nm_device_get_route_metric (parent_device, AF_INET);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
memset (&route, 0, sizeof (route));
|
|
Packit Service |
b23acc |
route.ifindex = ifindex;
|
|
Packit Service |
b23acc |
route.network = vpn_gw;
|
|
Packit Service |
b23acc |
route.plen = 32;
|
|
Packit Service |
b23acc |
route.gateway = parent_gw;
|
|
Packit Service |
b23acc |
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
route.metric = route_metric;
|
|
Packit Service |
b23acc |
nm_ip4_config_add_route (config, &route, NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (parent_gw) {
|
|
Packit Service |
b23acc |
/* Ensure there's a route to the parent device's gateway through the
|
|
Packit Service |
b23acc |
* parent device, since if the VPN claims the default route and the VPN
|
|
Packit Service |
b23acc |
* routes include a subnet that matches the parent device's subnet,
|
|
Packit Service |
b23acc |
* the parent device's gateway would get routed through the VPN and fail.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
memset (&route, 0, sizeof (route));
|
|
Packit Service |
b23acc |
route.network = parent_gw;
|
|
Packit Service |
b23acc |
route.plen = 32;
|
|
Packit Service |
b23acc |
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
route.metric = route_metric;
|
|
Packit Service |
b23acc |
nm_ip4_config_add_route (config, &route, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
add_ip6_vpn_gateway_route (NMIP6Config *config,
|
|
Packit Service |
b23acc |
NMDevice *parent_device,
|
|
Packit Service |
b23acc |
const struct in6_addr *vpn_gw,
|
|
Packit Service |
b23acc |
NMPlatform *platform)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
const struct in6_addr *parent_gw = NULL;
|
|
Packit Service |
b23acc |
gboolean has_parent_gw = FALSE;
|
|
Packit Service |
b23acc |
NMPlatformIP6Route route;
|
|
Packit Service |
b23acc |
int ifindex;
|
|
Packit Service |
b23acc |
guint32 route_metric;
|
|
Packit Service |
b23acc |
nm_auto_nmpobj const NMPObject *route_resolved = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_IP6_CONFIG (config));
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_DEVICE (parent_device));
|
|
Packit Service |
b23acc |
g_return_if_fail (vpn_gw != NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
ifindex = nm_ip6_config_get_ifindex (config);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (ifindex > 0);
|
|
Packit Service |
b23acc |
nm_assert (ifindex == nm_device_get_ip_ifindex (parent_device));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Ask kernel how to reach @vpn_gw. We can only inject the route in
|
|
Packit Service |
b23acc |
* @parent_device, so whatever we resolve, it can only be on @ifindex. */
|
|
Packit Service |
b23acc |
if (nm_platform_ip_route_get (platform,
|
|
Packit Service |
b23acc |
AF_INET6,
|
|
Packit Service |
b23acc |
vpn_gw,
|
|
Packit Service |
b23acc |
ifindex,
|
|
Packit Service |
b23acc |
(NMPObject **) &route_resolved) >= 0) {
|
|
Packit Service |
b23acc |
const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (route_resolved);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (r->ifindex == ifindex) {
|
|
Packit Service |
b23acc |
const NMPObject *obj;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* `ip route get` always resolves the route, even if the destination is unreachable.
|
|
Packit Service |
b23acc |
* In which case, it pretends the destination is directly reachable.
|
|
Packit Service |
b23acc |
*
|
|
Packit Service |
b23acc |
* So, only accept direct routes if @vpn_gw is a private network
|
|
Packit Service |
b23acc |
* or if the parent device also has a direct default route */
|
|
Packit Service |
b23acc |
if (nm_platform_route_table_is_main (r->table_coerced)) {
|
|
Packit Service |
b23acc |
if (!IN6_IS_ADDR_UNSPECIFIED (&r->gateway)) {
|
|
Packit Service |
b23acc |
parent_gw = &r->gateway;
|
|
Packit Service |
b23acc |
has_parent_gw = TRUE;
|
|
Packit Service |
b23acc |
} else if (nm_utils_ip_is_site_local (AF_INET6, &vpn_gw)) {
|
|
Packit Service |
b23acc |
has_parent_gw = TRUE;
|
|
Packit Service |
b23acc |
} else if ( (obj = nm_device_get_best_default_route (parent_device, AF_INET6))
|
|
Packit Service |
b23acc |
&& IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (obj)->gateway)) {
|
|
Packit Service |
b23acc |
has_parent_gw = TRUE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!has_parent_gw)
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
route_metric = nm_device_get_route_metric (parent_device, AF_INET6);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
memset (&route, 0, sizeof (route));
|
|
Packit Service |
b23acc |
route.ifindex = ifindex;
|
|
Packit Service |
b23acc |
route.network = *vpn_gw;
|
|
Packit Service |
b23acc |
route.plen = 128;
|
|
Packit Service |
b23acc |
if (parent_gw)
|
|
Packit Service |
b23acc |
route.gateway = *parent_gw;
|
|
Packit Service |
b23acc |
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
route.metric = route_metric;
|
|
Packit Service |
b23acc |
nm_ip6_config_add_route (config, &route, NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Ensure there's a route to the parent device's gateway through the
|
|
Packit Service |
b23acc |
* parent device, since if the VPN claims the default route and the VPN
|
|
Packit Service |
b23acc |
* routes include a subnet that matches the parent device's subnet,
|
|
Packit Service |
b23acc |
* the parent device's gateway would get routed through the VPN and fail.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if (parent_gw && !IN6_IS_ADDR_UNSPECIFIED (parent_gw)) {
|
|
Packit Service |
b23acc |
memset (&route, 0, sizeof (route));
|
|
Packit Service |
b23acc |
route.network = *parent_gw;
|
|
Packit Service |
b23acc |
route.plen = 128;
|
|
Packit Service |
b23acc |
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
route.metric = route_metric;
|
|
Packit Service |
b23acc |
nm_ip6_config_add_route (config, &route, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMVpnConnection *
|
|
Packit Service |
b23acc |
nm_vpn_connection_new (NMSettingsConnection *settings_connection,
|
|
Packit Service |
b23acc |
NMDevice *parent_device,
|
|
Packit Service |
b23acc |
const char *specific_object,
|
|
Packit Service |
b23acc |
NMActivationReason activation_reason,
|
|
Packit Service |
b23acc |
NMActivationStateFlags initial_state_flags,
|
|
Packit Service |
b23acc |
NMAuthSubject *subject)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
|
|
Packit Service |
b23acc |
g_return_val_if_fail (specific_object, NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return (NMVpnConnection *) g_object_new (NM_TYPE_VPN_CONNECTION,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, settings_connection,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_INT_DEVICE, parent_device,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_INT_ACTIVATION_REASON, activation_reason,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_VPN, TRUE,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_STATE_FLAGS, (guint) initial_state_flags,
|
|
Packit Service |
b23acc |
NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
const char *
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_service (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMSettingVpn *s_vpn;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self));
|
|
Packit Service |
b23acc |
return nm_setting_vpn_get_service_type (s_vpn);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_DEFINE (_vpn_plugin_failure_to_string, NMVpnPluginFailure,
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_DEFAULT (NULL),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED, "login-failed"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED, "connect-failed"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG, "bad-ip-config"),
|
|
Packit Service |
b23acc |
);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#define vpn_plugin_failure_to_string_a(failure) NM_UTILS_LOOKUP_STR_A (_vpn_plugin_failure_to_string, failure)
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
plugin_failed (NMVpnConnection *self, guint reason)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGW ("VPN plugin: failed: %s (%d)", vpn_plugin_failure_to_string_a (reason), reason);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
switch (reason) {
|
|
Packit Service |
b23acc |
case NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED:
|
|
Packit Service |
b23acc |
priv->failure_reason = NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED;
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG:
|
|
Packit Service |
b23acc |
priv->failure_reason = NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID;
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
priv->failure_reason = NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN;
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_DEFINE (_vpn_service_state_to_string, NMVpnServiceState,
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_DEFAULT (NULL),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_SERVICE_STATE_UNKNOWN, "unknown"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_SERVICE_STATE_INIT, "init"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_SERVICE_STATE_SHUTDOWN, "shutdown"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_SERVICE_STATE_STARTING, "starting"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_SERVICE_STATE_STARTED, "started"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_SERVICE_STATE_STOPPING, "stopping"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (NM_VPN_SERVICE_STATE_STOPPED, "stopped"),
|
|
Packit Service |
b23acc |
);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#define vpn_service_state_to_string_a(state) NM_UTILS_LOOKUP_STR_A (_vpn_service_state_to_string, state)
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_DEFINE (_vpn_state_to_string, VpnState,
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_DEFAULT (NULL),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_UNKNOWN, "unknown"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_WAITING, "waiting"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_PREPARE, "prepare"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_NEED_AUTH, "need-auth"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_CONNECT, "connect"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_IP_CONFIG_GET, "ip-config-get"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_PRE_UP, "pre-up"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_ACTIVATED, "activated"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_DEACTIVATING, "deactivating"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_DISCONNECTED, "disconnected"),
|
|
Packit Service |
b23acc |
NM_UTILS_LOOKUP_STR_ITEM (STATE_FAILED, "failed"),
|
|
Packit Service |
b23acc |
);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
#define vpn_state_to_string_a(state) NM_UTILS_LOOKUP_STR_A (_vpn_state_to_string, state)
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
plugin_state_changed (NMVpnConnection *self, NMVpnServiceState new_service_state)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
NMVpnServiceState old_service_state = priv->service_state;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("VPN plugin: state changed: %s (%d)",
|
|
Packit Service |
b23acc |
vpn_service_state_to_string_a (new_service_state), new_service_state);
|
|
Packit Service |
b23acc |
priv->service_state = new_service_state;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (new_service_state == NM_VPN_SERVICE_STATE_STOPPED) {
|
|
Packit Service |
b23acc |
/* Clear connection secrets to ensure secrets get requested each time the
|
|
Packit Service |
b23acc |
* connection is activated.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if ((priv->vpn_state >= STATE_WAITING) && (priv->vpn_state <= STATE_ACTIVATED)) {
|
|
Packit Service |
b23acc |
VpnState old_state = priv->vpn_state;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, priv->failure_reason, FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Reset the failure reason */
|
|
Packit Service |
b23acc |
priv->failure_reason = NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* If the connection failed, the service cannot persist, but the
|
|
Packit Service |
b23acc |
* connection can persist, ask listeners to re-activate the connection.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if ( old_state == STATE_ACTIVATED
|
|
Packit Service |
b23acc |
&& priv->vpn_state == STATE_FAILED
|
|
Packit Service |
b23acc |
&& _connection_only_can_persist (self))
|
|
Packit Service |
b23acc |
g_signal_emit (self, signals[INTERNAL_RETRY_AFTER_FAILURE], 0);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
} else if (new_service_state == NM_VPN_SERVICE_STATE_STARTING &&
|
|
Packit Service |
b23acc |
old_service_state == NM_VPN_SERVICE_STATE_STARTED) {
|
|
Packit Service |
b23acc |
/* The VPN service got disconnected and is attempting to reconnect */
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_CONNECT, NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
print_vpn_config (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
const NMPlatformIP4Address *address4;
|
|
Packit Service |
b23acc |
const NMPlatformIP6Address *address6;
|
|
Packit Service |
b23acc |
char *dns_domain = NULL;
|
|
Packit Service |
b23acc |
guint32 num, i;
|
|
Packit Service |
b23acc |
char b1[NM_UTILS_INET_ADDRSTRLEN];
|
|
Packit Service |
b23acc |
char b2[NM_UTILS_INET_ADDRSTRLEN];
|
|
Packit Service |
b23acc |
NMDedupMultiIter ipconf_iter;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip4_external_gw) {
|
|
Packit Service |
b23acc |
_LOGI ("Data: VPN Gateway: %s",
|
|
Packit Service |
b23acc |
_nm_utils_inet4_ntop (priv->ip4_external_gw, b1));
|
|
Packit Service |
b23acc |
} else if (priv->ip6_external_gw) {
|
|
Packit Service |
b23acc |
_LOGI ("Data: VPN Gateway: %s",
|
|
Packit Service |
b23acc |
_nm_utils_inet6_ntop (priv->ip6_external_gw, b1));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("Data: Tunnel Device: %s%s%s", NM_PRINT_FMT_QUOTE_STRING (priv->ip_iface));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip4_config) {
|
|
Packit Service |
b23acc |
const NMPlatformIP4Route *route;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("Data: IPv4 configuration:");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
address4 = nm_ip4_config_get_first_address (priv->ip4_config);
|
|
Packit Service |
b23acc |
nm_assert (address4);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip4_internal_gw)
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Gateway: %s", _nm_utils_inet4_ntop (priv->ip4_internal_gw, b1));
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Address: %s", address4 ? _nm_utils_inet4_ntop (address4->address, b1) : "??");
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Prefix: %d", address4 ? (int) address4->plen : -1);
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Point-to-Point Address: %s", _nm_utils_inet4_ntop (address4->peer_address, b1));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route) {
|
|
Packit Service |
b23acc |
_LOGI ("Data: Static Route: %s/%d Next Hop: %s",
|
|
Packit Service |
b23acc |
_nm_utils_inet4_ntop (route->network, b1),
|
|
Packit Service |
b23acc |
route->plen,
|
|
Packit Service |
b23acc |
_nm_utils_inet4_ntop (route->gateway, b2));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
num = nm_ip4_config_get_num_nameservers (priv->ip4_config);
|
|
Packit Service |
b23acc |
for (i = 0; i < num; i++) {
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal DNS: %s",
|
|
Packit Service |
b23acc |
_nm_utils_inet4_ntop (nm_ip4_config_get_nameserver (priv->ip4_config, i), b1));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (nm_ip4_config_get_num_domains (priv->ip4_config) > 0)
|
|
Packit Service |
b23acc |
dns_domain = (char *) nm_ip4_config_get_domain (priv->ip4_config, 0);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("Data: DNS Domain: '%s'", dns_domain ?: "(none)");
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
_LOGI ("Data: No IPv4 configuration");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip6_config) {
|
|
Packit Service |
b23acc |
const NMPlatformIP6Route *route;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("Data: IPv6 configuration:");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
address6 = nm_ip6_config_get_first_address (priv->ip6_config);
|
|
Packit Service |
b23acc |
nm_assert (address6);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip6_internal_gw)
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Gateway: %s", _nm_utils_inet6_ntop (priv->ip6_internal_gw, b1));
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Address: %s", _nm_utils_inet6_ntop (&address6->address, b1));
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Prefix: %d", address6->plen);
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal Point-to-Point Address: %s", _nm_utils_inet6_ntop (&address6->peer_address, b1));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, priv->ip6_config, &route) {
|
|
Packit Service |
b23acc |
_LOGI ("Data: Static Route: %s/%d Next Hop: %s",
|
|
Packit Service |
b23acc |
_nm_utils_inet6_ntop (&route->network, b1),
|
|
Packit Service |
b23acc |
route->plen,
|
|
Packit Service |
b23acc |
_nm_utils_inet6_ntop (&route->gateway, b2));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
num = nm_ip6_config_get_num_nameservers (priv->ip6_config);
|
|
Packit Service |
b23acc |
for (i = 0; i < num; i++) {
|
|
Packit Service |
b23acc |
_LOGI ("Data: Internal DNS: %s",
|
|
Packit Service |
b23acc |
_nm_utils_inet6_ntop (nm_ip6_config_get_nameserver (priv->ip6_config, i), b1));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (nm_ip6_config_get_num_domains (priv->ip6_config) > 0)
|
|
Packit Service |
b23acc |
dns_domain = (char *) nm_ip6_config_get_domain (priv->ip6_config, 0);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("Data: DNS Domain: '%s'", dns_domain ?: "(none)");
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
_LOGI ("Data: No IPv6 configuration");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->banner && strlen (priv->banner)) {
|
|
Packit Service |
b23acc |
_LOGI ("Data: Login Banner:");
|
|
Packit Service |
b23acc |
_LOGI ("Data: -----------------------------------------");
|
|
Packit Service |
b23acc |
_LOGI ("Data: %s", priv->banner);
|
|
Packit Service |
b23acc |
_LOGI ("Data: -----------------------------------------");
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
apply_parent_device_config (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
b23acc |
int ifindex;
|
|
Packit Service |
b23acc |
NMIP4Config *vpn4_parent_config = NULL;
|
|
Packit Service |
b23acc |
NMIP6Config *vpn6_parent_config = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
ifindex = nm_device_get_ip_ifindex (parent_dev);
|
|
Packit Service |
b23acc |
if (ifindex > 0) {
|
|
Packit Service |
b23acc |
/* If the VPN didn't return a network interface, it is a route-based
|
|
Packit Service |
b23acc |
* VPN (like kernel IPSec) and all IP addressing and routing should
|
|
Packit Service |
b23acc |
* be done on the parent interface instead.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if (priv->ip4_config) {
|
|
Packit Service |
b23acc |
vpn4_parent_config = nm_ip4_config_new (nm_netns_get_multi_idx (priv->netns),
|
|
Packit Service |
b23acc |
ifindex);
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex <= 0)
|
|
Packit Service |
b23acc |
nm_ip4_config_merge (vpn4_parent_config, priv->ip4_config, NM_IP_CONFIG_MERGE_NO_DNS, 0);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
if (priv->ip6_config) {
|
|
Packit Service |
b23acc |
vpn6_parent_config = nm_ip6_config_new (nm_netns_get_multi_idx (priv->netns),
|
|
Packit Service |
b23acc |
ifindex);
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex <= 0)
|
|
Packit Service |
b23acc |
nm_ip6_config_merge (vpn6_parent_config, priv->ip6_config, NM_IP_CONFIG_MERGE_NO_DNS, 0);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Add any explicit route to the VPN gateway through the parent device */
|
|
Packit Service |
b23acc |
if ( vpn4_parent_config
|
|
Packit Service |
b23acc |
&& priv->ip4_external_gw) {
|
|
Packit Service |
b23acc |
add_ip4_vpn_gateway_route (vpn4_parent_config,
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip4_external_gw,
|
|
Packit Service |
b23acc |
nm_netns_get_platform (priv->netns));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
if ( vpn6_parent_config
|
|
Packit Service |
b23acc |
&& priv->ip6_external_gw) {
|
|
Packit Service |
b23acc |
add_ip6_vpn_gateway_route (vpn6_parent_config,
|
|
Packit Service |
b23acc |
parent_dev,
|
|
Packit Service |
b23acc |
priv->ip6_external_gw,
|
|
Packit Service |
b23acc |
nm_netns_get_platform (priv->netns));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_device_replace_vpn4_config (parent_dev, priv->last_device_ip4_config, vpn4_parent_config);
|
|
Packit Service |
b23acc |
g_clear_object (&priv->last_device_ip4_config);
|
|
Packit Service |
b23acc |
priv->last_device_ip4_config = vpn4_parent_config;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_device_replace_vpn6_config (parent_dev, priv->last_device_ip6_config, vpn6_parent_config);
|
|
Packit Service |
b23acc |
g_clear_object (&priv->last_device_ip6_config);
|
|
Packit Service |
b23acc |
priv->last_device_ip6_config = vpn6_parent_config;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
nm_vpn_connection_apply_config (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
apply_parent_device_config (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex > 0) {
|
|
Packit Service |
b23acc |
nm_platform_link_set_up (nm_netns_get_platform (priv->netns), priv->ip_ifindex, NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip4_config) {
|
|
Packit Service |
b23acc |
nm_assert (priv->ip_ifindex == nm_ip4_config_get_ifindex (priv->ip4_config));
|
|
Packit Service |
b23acc |
if (!nm_ip4_config_commit (priv->ip4_config,
|
|
Packit Service |
b23acc |
nm_netns_get_platform (priv->netns),
|
|
Packit Service |
b23acc |
get_route_table (self, AF_INET, FALSE)
|
|
Packit Service |
b23acc |
? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL
|
|
Packit Service |
b23acc |
: NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN))
|
|
Packit Service |
b23acc |
return FALSE;
|
|
Packit Service |
b23acc |
nm_platform_ip4_dev_route_blacklist_set (nm_netns_get_platform (priv->netns),
|
|
Packit Service |
b23acc |
priv->ip_ifindex,
|
|
Packit Service |
b23acc |
priv->ip4_dev_route_blacklist);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip6_config) {
|
|
Packit Service |
b23acc |
nm_assert (priv->ip_ifindex == nm_ip6_config_get_ifindex (priv->ip6_config));
|
|
Packit Service |
b23acc |
if (!nm_ip6_config_commit (priv->ip6_config,
|
|
Packit Service |
b23acc |
nm_netns_get_platform (priv->netns),
|
|
Packit Service |
b23acc |
get_route_table (self, AF_INET6, FALSE)
|
|
Packit Service |
b23acc |
? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL
|
|
Packit Service |
b23acc |
: NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
|
Packit Service |
b23acc |
NULL))
|
|
Packit Service |
b23acc |
return FALSE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->mtu && priv->mtu != nm_platform_link_get_mtu (nm_netns_get_platform (priv->netns), priv->ip_ifindex))
|
|
Packit Service |
b23acc |
nm_platform_link_set_mtu (nm_netns_get_platform (priv->netns), priv->ip_ifindex, priv->mtu);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (IP Config Get) complete");
|
|
Packit Service |
b23acc |
if (priv->vpn_state < STATE_PRE_UP)
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_PRE_UP, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
return TRUE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
_cleanup_failed_config (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_dbus_object_clear_and_unexport (&priv->ip4_config);
|
|
Packit Service |
b23acc |
nm_dbus_object_clear_and_unexport (&priv->ip6_config);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGW ("VPN connection: did not receive valid IP config information");
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
fw_change_zone_cb (NMFirewallManager *firewall_manager,
|
|
Packit Service |
b23acc |
NMFirewallManagerCallId *call_id,
|
|
Packit Service |
b23acc |
GError *error,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = user_data;
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_VPN_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
g_return_if_fail (priv->fw_call == call_id);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->fw_call = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (nm_utils_error_is_cancelled (error))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (error) {
|
|
Packit Service |
b23acc |
// FIXME: fail the activation?
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!nm_vpn_connection_apply_config (self))
|
|
Packit Service |
b23acc |
_cleanup_failed_config (self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
gboolean success)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
NMConnection *base_con;
|
|
Packit Service |
b23acc |
NMSettingConnection *s_con;
|
|
Packit Service |
b23acc |
const char *zone;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->vpn_state < STATE_IP_CONFIG_GET || priv->vpn_state > STATE_ACTIVATED)
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (success) {
|
|
Packit Service |
b23acc |
if ( (priv->has_ip4 && !priv->ip4_config)
|
|
Packit Service |
b23acc |
|| (priv->has_ip6 && !priv->ip6_config)) {
|
|
Packit Service |
b23acc |
/* Need to wait for other config */
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_g_source (&priv->connect_timeout);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (success) {
|
|
Packit Service |
b23acc |
print_vpn_config (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Add the tunnel interface to the specified firewall zone */
|
|
Packit Service |
b23acc |
if (priv->ip_iface) {
|
|
Packit Service |
b23acc |
base_con = _get_applied_connection (self);
|
|
Packit Service |
b23acc |
s_con = nm_connection_get_setting_connection (base_con);
|
|
Packit Service |
b23acc |
zone = nm_setting_connection_get_zone (s_con);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGD ("setting firewall zone %s%s%s for '%s'",
|
|
Packit Service |
b23acc |
NM_PRINT_FMT_QUOTED (zone, "'", zone, "'", "(default)"),
|
|
Packit Service |
b23acc |
priv->ip_iface);
|
|
Packit Service |
b23acc |
fw_call_cleanup (self);
|
|
Packit Service |
b23acc |
priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
|
|
Packit Service |
b23acc |
priv->ip_iface,
|
|
Packit Service |
b23acc |
zone,
|
|
Packit Service |
b23acc |
FALSE,
|
|
Packit Service |
b23acc |
fw_change_zone_cb,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
if (nm_vpn_connection_apply_config (self))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_cleanup_failed_config (self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
ip6_addr_from_variant (GVariant *v, struct in6_addr *addr)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
const guint8 *bytes;
|
|
Packit Service |
b23acc |
gsize len;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_val_if_fail (v, FALSE);
|
|
Packit Service |
b23acc |
g_return_val_if_fail (addr, FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_is_of_type (v, G_VARIANT_TYPE ("ay"))) {
|
|
Packit Service |
b23acc |
bytes = g_variant_get_fixed_array (v, &len, sizeof (guint8));
|
|
Packit Service |
b23acc |
if (len == sizeof (struct in6_addr) && !IN6_IS_ADDR_UNSPECIFIED (bytes)) {
|
|
Packit Service |
b23acc |
memcpy (addr, bytes, len);
|
|
Packit Service |
b23acc |
return TRUE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
return FALSE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static struct in6_addr *
|
|
Packit Service |
b23acc |
ip6_addr_dup_from_variant (GVariant *v)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
struct in6_addr *addr;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
addr = g_malloc0 (sizeof (*addr));
|
|
Packit Service |
b23acc |
if (ip6_addr_from_variant (v, addr))
|
|
Packit Service |
b23acc |
return addr;
|
|
Packit Service |
b23acc |
g_free (addr);
|
|
Packit Service |
b23acc |
return NULL;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
process_generic_config (NMVpnConnection *self, GVariant *dict)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
const char *str;
|
|
Packit Service |
b23acc |
GVariant *v;
|
|
Packit Service |
b23acc |
guint32 u32;
|
|
Packit Service |
b23acc |
gboolean b;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CAN_PERSIST, "b", &b) && b) {
|
|
Packit Service |
b23acc |
/* Defaults to FALSE, so only let service indicate TRUE */
|
|
Packit Service |
b23acc |
priv->service_can_persist = TRUE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_g_free (&priv->ip_iface);
|
|
Packit Service |
b23acc |
priv->ip_ifindex = 0;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_TUNDEV, "&s", &str)) {
|
|
Packit Service |
b23acc |
/* Backwards compat with NM-openswan */
|
|
Packit Service |
b23acc |
if (g_strcmp0 (str, "_none_") != 0)
|
|
Packit Service |
b23acc |
priv->ip_iface = g_strdup (str);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip_iface) {
|
|
Packit Service |
b23acc |
/* Grab the interface index for address/routing operations */
|
|
Packit Service |
b23acc |
priv->ip_ifindex = nm_platform_link_get_ifindex (nm_netns_get_platform (priv->netns), priv->ip_iface);
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex <= 0) {
|
|
Packit Service |
b23acc |
nm_platform_process_events (nm_netns_get_platform (priv->netns));
|
|
Packit Service |
b23acc |
priv->ip_ifindex = nm_platform_link_get_ifindex (nm_netns_get_platform (priv->netns), priv->ip_iface);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex <= 0) {
|
|
Packit Service |
b23acc |
_LOGE ("failed to look up VPN interface index for \"%s\"", priv->ip_iface);
|
|
Packit Service |
b23acc |
nm_clear_g_free (&priv->ip_iface);
|
|
Packit Service |
b23acc |
priv->ip_ifindex = 0;
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, FALSE);
|
|
Packit Service |
b23acc |
return FALSE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_g_free (&priv->banner);
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_BANNER, "&s", &str)) {
|
|
Packit Service |
b23acc |
priv->banner = g_strdup (str);
|
|
Packit Service |
b23acc |
_notify (self, PROP_BANNER);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Proxy Config */
|
|
Packit Service |
b23acc |
g_clear_object (&priv->proxy_config);
|
|
Packit Service |
b23acc |
priv->proxy_config = nm_proxy_config_new ();
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_PROXY_PAC, "&s", &str)) {
|
|
Packit Service |
b23acc |
nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
|
|
Packit Service |
b23acc |
nm_proxy_config_set_pac_url (priv->proxy_config, str);
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* User overrides if any from the NMConnection's Proxy settings */
|
|
Packit Service |
b23acc |
nm_proxy_config_merge_setting (priv->proxy_config,
|
|
Packit Service |
b23acc |
nm_connection_get_setting_proxy (_get_applied_connection (self)));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* External world-visible address of the VPN server */
|
|
Packit Service |
b23acc |
priv->ip4_external_gw = 0;
|
|
Packit Service |
b23acc |
nm_clear_g_free (&priv->ip6_external_gw);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "u", &u32)) {
|
|
Packit Service |
b23acc |
priv->ip4_external_gw = u32;
|
|
Packit Service |
b23acc |
} else if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "@ay", &v)) {
|
|
Packit Service |
b23acc |
priv->ip6_external_gw = ip6_addr_dup_from_variant (v);
|
|
Packit Service |
b23acc |
g_variant_unref (v);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!priv->ip6_external_gw) {
|
|
Packit Service |
b23acc |
_LOGE ("Invalid IPv6 VPN gateway address received");
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, FALSE);
|
|
Packit Service |
b23acc |
return FALSE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->mtu = 0;
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_MTU, "u", &u32))
|
|
Packit Service |
b23acc |
priv->mtu = u32;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return TRUE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_get (NMVpnConnection *self, GVariant *dict)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
gboolean b;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (IP Config Get) reply received.");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->vpn_state == STATE_CONNECT)
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_IP_CONFIG_GET, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!process_generic_config (self, dict))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Note whether to expect IPv4 and IPv6 configs */
|
|
Packit Service |
b23acc |
priv->has_ip4 = FALSE;
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &b))
|
|
Packit Service |
b23acc |
priv->has_ip4 = b;
|
|
Packit Service |
b23acc |
nm_dbus_object_clear_and_unexport (&priv->ip4_config);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->has_ip6 = FALSE;
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &b))
|
|
Packit Service |
b23acc |
priv->has_ip6 = b;
|
|
Packit Service |
b23acc |
nm_dbus_object_clear_and_unexport (&priv->ip6_config);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, TRUE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
guint32
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip4_route_metric (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
gint64 route_metric;
|
|
Packit Service |
b23acc |
NMConnection *applied;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
applied = _get_applied_connection (self);
|
|
Packit Service |
b23acc |
route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (applied));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return (route_metric >= 0) ? route_metric : NM_VPN_ROUTE_METRIC_DEFAULT;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
guint32
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
gint64 route_metric;
|
|
Packit Service |
b23acc |
NMConnection *applied;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
applied = _get_applied_connection (self);
|
|
Packit Service |
b23acc |
route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (applied));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return (route_metric >= 0) ? route_metric : NM_VPN_ROUTE_METRIC_DEFAULT;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static guint32
|
|
Packit Service |
b23acc |
get_route_table (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
int addr_family,
|
|
Packit Service |
b23acc |
gboolean fallback_main)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMConnection *connection;
|
|
Packit Service |
b23acc |
NMSettingIPConfig *s_ip;
|
|
Packit Service |
b23acc |
guint32 route_table = 0;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
connection = _get_applied_connection (self);
|
|
Packit Service |
b23acc |
if (connection) {
|
|
Packit Service |
b23acc |
s_ip = nm_connection_get_setting_ip_config (connection, addr_family);
|
|
Packit Service |
b23acc |
if (s_ip)
|
|
Packit Service |
b23acc |
route_table = nm_setting_ip_config_get_route_table (s_ip);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return route_table ?: (fallback_main ? RT_TABLE_MAIN : 0);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
cc229f |
static gboolean
|
|
Packit Service |
cc229f |
_is_device_vrf (NMVpnConnection *self)
|
|
Packit Service |
cc229f |
{
|
|
Packit Service |
cc229f |
NMDevice *parent;
|
|
Packit Service |
cc229f |
NMDevice *master;
|
|
Packit Service |
cc229f |
|
|
Packit Service |
cc229f |
parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
cc229f |
if (!parent)
|
|
Packit Service |
cc229f |
return FALSE;
|
|
Packit Service |
cc229f |
|
|
Packit Service |
cc229f |
master = nm_device_get_master (parent);
|
|
Packit Service |
cc229f |
return master && nm_device_get_link_type (master) == NM_LINK_TYPE_VRF;
|
|
Packit Service |
cc229f |
}
|
|
Packit Service |
cc229f |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
NMPlatformIP4Address address;
|
|
Packit Service |
b23acc |
guint32 u32, route_metric;
|
|
Packit Service |
b23acc |
NMSettingIPConfig *s_ip;
|
|
Packit Service |
b23acc |
NMSettingConnection *s_con;
|
|
Packit Service |
b23acc |
guint32 route_table;
|
|
Packit Service |
b23acc |
NMIP4Config *config;
|
|
Packit Service |
b23acc |
GVariantIter *iter;
|
|
Packit Service |
b23acc |
const char *str;
|
|
Packit Service |
b23acc |
GVariant *v;
|
|
Packit Service |
b23acc |
gboolean b;
|
|
Packit Service |
b23acc |
int ip_ifindex;
|
|
Packit Service |
b23acc |
guint32 mss = 0;
|
|
Packit Service |
b23acc |
gboolean never_default = FALSE;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->vpn_state == STATE_CONNECT)
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_IP_CONFIG_GET, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->vpn_state > STATE_ACTIVATED) {
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (IP4 Config Get) ignoring, the connection is no longer active");
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->has_ip4) {
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (IP4 Config Get) reply received");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_n_children (dict) == 0) {
|
|
Packit Service |
b23acc |
priv->has_ip4 = FALSE;
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, TRUE);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (IP4 Config Get) reply received from old-style plugin");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* In the old API, the generic and IPv4 configuration items
|
|
Packit Service |
b23acc |
* were mixed together.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if (!process_generic_config (self, dict))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->has_ip4 = TRUE;
|
|
Packit Service |
b23acc |
priv->has_ip6 = FALSE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
ip_ifindex = nm_vpn_connection_get_ip_ifindex (self, TRUE);
|
|
Packit Service |
b23acc |
if (ip_ifindex <= 0)
|
|
Packit Service |
b23acc |
g_return_if_reached ();
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
config = nm_ip4_config_new (nm_netns_get_multi_idx (priv->netns),
|
|
Packit Service |
b23acc |
ip_ifindex);
|
|
Packit Service |
b23acc |
nm_ip4_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
memset (&address, 0, sizeof (address));
|
|
Packit Service |
b23acc |
address.plen = 24;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Internal address of the VPN subnet's gateway */
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, "u", &u32))
|
|
Packit Service |
b23acc |
priv->ip4_internal_gw = u32;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, "u", &u32))
|
|
Packit Service |
b23acc |
address.address = u32;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PTP, "u", &u32))
|
|
Packit Service |
b23acc |
address.peer_address = u32;
|
|
Packit Service |
b23acc |
else
|
|
Packit Service |
b23acc |
address.peer_address = address.address;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, "u", &u32))
|
|
Packit Service |
b23acc |
address.plen = u32;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (address.address && address.plen && address.plen <= 32) {
|
|
Packit Service |
b23acc |
address.addr_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
nm_ip4_config_add_address (config, &address);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
_LOGW ("invalid IP4 config received!");
|
|
Packit Service |
b23acc |
g_object_unref (config);
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, FALSE);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_DNS, "au", &iter)) {
|
|
Packit Service |
b23acc |
while (g_variant_iter_next (iter, "u", &u32))
|
|
Packit Service |
b23acc |
nm_ip4_config_add_nameserver (config, u32);
|
|
Packit Service |
b23acc |
g_variant_iter_free (iter);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_NBNS, "au", &iter)) {
|
|
Packit Service |
b23acc |
while (g_variant_iter_next (iter, "u", &u32))
|
|
Packit Service |
b23acc |
nm_ip4_config_add_wins (config, u32);
|
|
Packit Service |
b23acc |
g_variant_iter_free (iter);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_MSS, "u", &u32))
|
|
Packit Service |
b23acc |
mss = u32;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN, "&s", &str))
|
|
Packit Service |
b23acc |
nm_ip4_config_add_domain (config, str);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS, "as", &iter)) {
|
|
Packit Service |
b23acc |
while (g_variant_iter_next (iter, "&s", &str))
|
|
Packit Service |
b23acc |
nm_ip4_config_add_domain (config, str);
|
|
Packit Service |
b23acc |
g_variant_iter_free (iter);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
route_table = get_route_table (self, AF_INET, TRUE);
|
|
Packit Service |
b23acc |
route_metric = nm_vpn_connection_get_ip4_route_metric (self);
|
|
Packit Service |
b23acc |
s_ip = nm_connection_get_setting_ip4_config (_get_applied_connection (self));
|
|
Packit Service |
b23acc |
s_con = nm_connection_get_setting_connection (_get_applied_connection (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (nm_setting_ip_config_get_ignore_auto_routes (s_ip)) {
|
|
Packit Service |
b23acc |
/* ignore VPN routes */
|
|
Packit Service |
b23acc |
} else if ( g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, "b", &b)
|
|
Packit Service |
b23acc |
&& b) {
|
|
Packit Service |
b23acc |
if (priv->ip4_config) {
|
|
Packit Service |
b23acc |
NMDedupMultiIter ipconf_iter;
|
|
Packit Service |
b23acc |
const NMPlatformIP4Route *route;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route)
|
|
Packit Service |
b23acc |
nm_ip4_config_add_route (config, route, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
} else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &iter)) {
|
|
Packit Service |
b23acc |
while (g_variant_iter_next (iter, "@au", &v)) {
|
|
Packit Service |
b23acc |
NMPlatformIP4Route route = { 0, };
|
|
Packit Service |
b23acc |
guint32 plen;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
switch (g_variant_n_children (v)) {
|
|
Packit Service |
b23acc |
case 5:
|
|
Packit Service |
b23acc |
g_variant_get_child (v, 4, "u", &route.pref_src);
|
|
Packit Service |
b23acc |
/* fall-through */
|
|
Packit Service |
b23acc |
case 4:
|
|
Packit Service |
b23acc |
g_variant_get_child (v, 0, "u", &route.network);
|
|
Packit Service |
b23acc |
g_variant_get_child (v, 1, "u", &plen);
|
|
Packit Service |
b23acc |
g_variant_get_child (v, 2, "u", &route.gateway);
|
|
Packit Service |
b23acc |
/* 4th item is unused route metric */
|
|
Packit Service |
b23acc |
route.table_coerced = nm_platform_route_table_coerce (route_table);
|
|
Packit Service |
b23acc |
route.metric = route_metric;
|
|
Packit Service |
b23acc |
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (plen > 32 || plen == 0)
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
route.plen = plen;
|
|
Packit Service |
b23acc |
route.network = nm_utils_ip4_address_clear_host_address (route.network, plen);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if ( priv->ip4_external_gw
|
|
Packit Service |
b23acc |
&& route.network == priv->ip4_external_gw
|
|
Packit Service |
b23acc |
&& route.plen == 32) {
|
|
Packit Service |
b23acc |
/* Ignore host routes to the VPN gateway since NM adds one itself
|
|
Packit Service |
b23acc |
* below. Since NM knows more about the routing situation than
|
|
Packit Service |
b23acc |
* the VPN server, we want to use the NM created route instead of
|
|
Packit Service |
b23acc |
* whatever the server provides.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip4_config_add_route (config, &route, NULL);
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
g_variant_unref (v);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
g_variant_iter_free (iter);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT, "b", &b))
|
|
Packit Service |
b23acc |
never_default = b;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Merge in user overrides from the NMConnection's IPv4 setting */
|
|
Packit Service |
b23acc |
nm_ip4_config_merge_setting (config,
|
|
Packit Service |
b23acc |
s_ip,
|
|
Packit Service |
b23acc |
nm_setting_connection_get_mdns (s_con),
|
|
Packit Service |
b23acc |
nm_setting_connection_get_llmnr (s_con),
|
|
Packit Service |
b23acc |
route_table,
|
|
Packit Service |
b23acc |
route_metric);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if ( !never_default
|
|
Packit Service |
b23acc |
&& !nm_setting_ip_config_get_never_default (s_ip)) {
|
|
Packit Service |
b23acc |
const NMPlatformIP4Route r = {
|
|
Packit Service |
b23acc |
.ifindex = ip_ifindex,
|
|
Packit Service |
b23acc |
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
|
Packit Service |
b23acc |
.gateway = priv->ip4_internal_gw,
|
|
Packit Service |
b23acc |
.table_coerced = nm_platform_route_table_coerce (route_table),
|
|
Packit Service |
b23acc |
.metric = route_metric,
|
|
Packit Service |
b23acc |
.mss = mss,
|
|
Packit Service |
b23acc |
};
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip4_config_add_route (config, &r, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_pointer (&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip4_config_add_dependent_routes (config,
|
|
Packit Service |
b23acc |
route_table,
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip4_route_metric (self),
|
|
Packit Service |
cc229f |
_is_device_vrf (self),
|
|
Packit Service |
b23acc |
&priv->ip4_dev_route_blacklist);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip4_config) {
|
|
Packit Service |
b23acc |
nm_ip4_config_replace (priv->ip4_config, config, NULL);
|
|
Packit Service |
b23acc |
g_object_unref (config);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
priv->ip4_config = config;
|
|
Packit Service |
b23acc |
nm_dbus_object_export (NM_DBUS_OBJECT (config));
|
|
Packit Service |
b23acc |
g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP4_CONFIG);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, TRUE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
NMPlatformIP6Address address;
|
|
Packit Service |
b23acc |
guint32 u32, route_metric;
|
|
Packit Service |
b23acc |
NMSettingIPConfig *s_ip;
|
|
Packit Service |
b23acc |
guint32 route_table;
|
|
Packit Service |
b23acc |
NMIP6Config *config;
|
|
Packit Service |
b23acc |
GVariantIter *iter;
|
|
Packit Service |
b23acc |
const char *str;
|
|
Packit Service |
b23acc |
GVariant *v;
|
|
Packit Service |
b23acc |
gboolean b;
|
|
Packit Service |
b23acc |
int ip_ifindex;
|
|
Packit Service |
b23acc |
guint32 mss = 0;
|
|
Packit Service |
b23acc |
gboolean never_default = FALSE;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (IP6 Config Get) reply received");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->vpn_state == STATE_CONNECT)
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_IP_CONFIG_GET, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->vpn_state > STATE_ACTIVATED) {
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (IP6 Config Get) ignoring, the connection is no longer active");
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_n_children (dict) == 0) {
|
|
Packit Service |
b23acc |
priv->has_ip6 = FALSE;
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, TRUE);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
ip_ifindex = nm_vpn_connection_get_ip_ifindex (self, TRUE);
|
|
Packit Service |
b23acc |
if (ip_ifindex <= 0)
|
|
Packit Service |
b23acc |
g_return_if_reached ();
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
config = nm_ip6_config_new (nm_netns_get_multi_idx (priv->netns),
|
|
Packit Service |
b23acc |
ip_ifindex);
|
|
Packit Service |
b23acc |
nm_ip6_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
memset (&address, 0, sizeof (address));
|
|
Packit Service |
b23acc |
address.plen = 128;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Internal address of the VPN subnet's gateway */
|
|
Packit Service |
b23acc |
nm_clear_g_free (&priv->ip6_internal_gw);
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY, "@ay", &v)) {
|
|
Packit Service |
b23acc |
priv->ip6_internal_gw = ip6_addr_dup_from_variant (v);
|
|
Packit Service |
b23acc |
g_variant_unref (v);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS, "@ay", &v)) {
|
|
Packit Service |
b23acc |
ip6_addr_from_variant (v, &address.address);
|
|
Packit Service |
b23acc |
g_variant_unref (v);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_PTP, "@ay", &v)) {
|
|
Packit Service |
b23acc |
ip6_addr_from_variant (v, &address.peer_address);
|
|
Packit Service |
b23acc |
g_variant_unref (v);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_PREFIX, "u", &u32))
|
|
Packit Service |
b23acc |
address.plen = u32;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen && address.plen <= 128) {
|
|
Packit Service |
b23acc |
address.addr_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
nm_ip6_config_add_address (config, &address);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
_LOGW ("invalid IP6 config received!");
|
|
Packit Service |
b23acc |
g_object_unref (config);
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, FALSE);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_DNS, "aay", &iter)) {
|
|
Packit Service |
b23acc |
while (g_variant_iter_next (iter, "@ay", &v)) {
|
|
Packit Service |
b23acc |
struct in6_addr dns;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (ip6_addr_from_variant (v, &dns))
|
|
Packit Service |
b23acc |
nm_ip6_config_add_nameserver (config, &dns);
|
|
Packit Service |
b23acc |
g_variant_unref (v);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
g_variant_iter_free (iter);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_MSS, "u", &u32))
|
|
Packit Service |
b23acc |
mss = u32;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN, "&s", &str))
|
|
Packit Service |
b23acc |
nm_ip6_config_add_domain (config, str);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS, "as", &iter)) {
|
|
Packit Service |
b23acc |
while (g_variant_iter_next (iter, "&s", &str))
|
|
Packit Service |
b23acc |
nm_ip6_config_add_domain (config, str);
|
|
Packit Service |
b23acc |
g_variant_iter_free (iter);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
route_table = get_route_table (self, AF_INET6, TRUE);
|
|
Packit Service |
b23acc |
route_metric = nm_vpn_connection_get_ip6_route_metric (self);
|
|
Packit Service |
b23acc |
s_ip = nm_connection_get_setting_ip6_config (_get_applied_connection (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (nm_setting_ip_config_get_ignore_auto_routes (s_ip)) {
|
|
Packit Service |
b23acc |
/* Ignore VPN routes */
|
|
Packit Service |
b23acc |
} else if ( g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_PRESERVE_ROUTES, "b", &b)
|
|
Packit Service |
b23acc |
&& b) {
|
|
Packit Service |
b23acc |
if (priv->ip6_config) {
|
|
Packit Service |
b23acc |
NMDedupMultiIter ipconf_iter;
|
|
Packit Service |
b23acc |
const NMPlatformIP6Route *route;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, priv->ip6_config, &route)
|
|
Packit Service |
b23acc |
nm_ip6_config_add_route (config, route, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
} else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, "a(ayuayu)", &iter)) {
|
|
Packit Service |
b23acc |
GVariant *dest, *next_hop;
|
|
Packit Service |
b23acc |
guint32 prefix, metric;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
while (g_variant_iter_next (iter, "(@ayu@ayu)", &dest, &prefix, &next_hop, &metric)) {
|
|
Packit Service |
b23acc |
NMPlatformIP6Route route;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
memset (&route, 0, sizeof (route));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!ip6_addr_from_variant (dest, &route.network))
|
|
Packit Service |
b23acc |
goto next;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (prefix > 128 || prefix == 0)
|
|
Packit Service |
b23acc |
goto next;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
route.plen = prefix;
|
|
Packit Service |
b23acc |
ip6_addr_from_variant (next_hop, &route.gateway);
|
|
Packit Service |
b23acc |
route.table_coerced = nm_platform_route_table_coerce (route_table);
|
|
Packit Service |
b23acc |
route.metric = route_metric;
|
|
Packit Service |
b23acc |
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_utils_ip6_address_clear_host_address (&route.network, &route.network, route.plen);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if ( priv->ip6_external_gw
|
|
Packit Service |
b23acc |
&& IN6_ARE_ADDR_EQUAL (&route.network, priv->ip6_external_gw)
|
|
Packit Service |
b23acc |
&& route.plen == 128) {
|
|
Packit Service |
b23acc |
/* Ignore host routes to the VPN gateway since NM adds one itself.
|
|
Packit Service |
b23acc |
* Since NM knows more about the routing situation than the VPN
|
|
Packit Service |
b23acc |
* server, we want to use the NM created route instead of whatever
|
|
Packit Service |
b23acc |
* the server provides.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
goto next;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip6_config_add_route (config, &route, NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
next:
|
|
Packit Service |
b23acc |
g_variant_unref (dest);
|
|
Packit Service |
b23acc |
g_variant_unref (next_hop);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
g_variant_iter_free (iter);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT, "b", &b))
|
|
Packit Service |
b23acc |
never_default = b;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Merge in user overrides from the NMConnection's IPv6 setting */
|
|
Packit Service |
b23acc |
nm_ip6_config_merge_setting (config,
|
|
Packit Service |
b23acc |
s_ip,
|
|
Packit Service |
b23acc |
route_table,
|
|
Packit Service |
b23acc |
route_metric);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if ( !never_default
|
|
Packit Service |
b23acc |
&& !nm_setting_ip_config_get_never_default (s_ip)) {
|
|
Packit Service |
b23acc |
const NMPlatformIP6Route r = {
|
|
Packit Service |
b23acc |
.ifindex = ip_ifindex,
|
|
Packit Service |
b23acc |
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
|
Packit Service |
b23acc |
.gateway = *(priv->ip6_internal_gw ?: &in6addr_any),
|
|
Packit Service |
b23acc |
.table_coerced = nm_platform_route_table_coerce (route_table),
|
|
Packit Service |
b23acc |
.metric = route_metric,
|
|
Packit Service |
b23acc |
.mss = mss,
|
|
Packit Service |
b23acc |
};
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_ip6_config_add_route (config, &r, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
cc229f |
nm_ip6_config_add_dependent_routes (config, route_table, route_metric, _is_device_vrf (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip6_config) {
|
|
Packit Service |
b23acc |
nm_ip6_config_replace (priv->ip6_config, config, NULL);
|
|
Packit Service |
b23acc |
g_object_unref (config);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
priv->ip6_config = config;
|
|
Packit Service |
b23acc |
nm_dbus_object_export (NM_DBUS_OBJECT (config));
|
|
Packit Service |
b23acc |
g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP6_CONFIG);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_maybe_complete (self, TRUE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
connect_timeout_cb (gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->connect_timeout = 0;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Cancel activation if it's taken too long */
|
|
Packit Service |
b23acc |
if (priv->vpn_state == STATE_CONNECT ||
|
|
Packit Service |
b23acc |
priv->vpn_state == STATE_IP_CONFIG_GET) {
|
|
Packit Service |
b23acc |
_LOGW ("VPN connection: connect timeout exceeded.");
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return FALSE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
connect_success (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
NMSettingVpn *s_vpn;
|
|
Packit Service |
b23acc |
guint32 timeout;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self));
|
|
Packit Service |
b23acc |
g_assert (s_vpn);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Timeout waiting for IP config signal from VPN service
|
|
Packit Service |
b23acc |
* It is a configured value or 60 seconds */
|
|
Packit Service |
b23acc |
timeout = nm_setting_vpn_get_timeout (s_vpn);
|
|
Packit Service |
b23acc |
if (timeout == 0) {
|
|
Packit Service |
b23acc |
timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
|
|
Packit Service |
b23acc |
NM_CON_DEFAULT ("vpn.timeout"),
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
1, G_MAXUINT32, 60);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
priv->connect_timeout = g_timeout_add_seconds (timeout, connect_timeout_cb, self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_pointer (&priv->connect_hash, g_variant_unref);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
connect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self;
|
|
Packit Service |
b23acc |
gs_unref_variant GVariant *reply = NULL;
|
|
Packit Service |
b23acc |
gs_free_error GError *error = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
reply = g_dbus_proxy_call_finish (proxy, result, &error);
|
|
Packit Service |
b23acc |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (error) {
|
|
Packit Service |
b23acc |
g_dbus_error_strip_remote_error (error);
|
|
Packit Service |
b23acc |
_LOGW ("VPN connection: failed to connect: '%s'",
|
|
Packit Service |
b23acc |
error->message);
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED, FALSE);
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
connect_success (self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
connect_interactive_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self;
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
gs_unref_variant GVariant *reply = NULL;
|
|
Packit Service |
b23acc |
gs_free_error GError *error = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
reply = g_dbus_proxy_call_finish (proxy, result, &error);
|
|
Packit Service |
b23acc |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("VPN connection: (ConnectInteractive) reply received");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_error_matches (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED)) {
|
|
Packit Service |
b23acc |
_LOGD ("VPN connection: falling back to non-interactive connect");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Fall back to Connect() */
|
|
Packit Service |
b23acc |
g_dbus_proxy_call (priv->proxy,
|
|
Packit Service |
b23acc |
"Connect",
|
|
Packit Service |
b23acc |
g_variant_new ("(@a{sa{sv}})", priv->connect_hash),
|
|
Packit Service |
b23acc |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
b23acc |
-1,
|
|
Packit Service |
b23acc |
priv->cancellable,
|
|
Packit Service |
b23acc |
(GAsyncReadyCallback) connect_cb,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
} else if (error) {
|
|
Packit Service |
b23acc |
g_dbus_error_strip_remote_error (error);
|
|
Packit Service |
b23acc |
_LOGW ("VPN connection: failed to connect interactively: '%s'",
|
|
Packit Service |
b23acc |
error->message);
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED, FALSE);
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
connect_success (self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Add a username to a hashed connection */
|
|
Packit Service |
b23acc |
static GVariant *
|
|
Packit Service |
b23acc |
_hash_with_username (NMConnection *connection, const char *username)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
gs_unref_object NMConnection *dup = NULL;
|
|
Packit Service |
b23acc |
NMSettingVpn *s_vpn;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Shortcut if we weren't given a username or if there already was one in
|
|
Packit Service |
b23acc |
* the VPN setting; don't bother duplicating the connection and everything.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
s_vpn = nm_connection_get_setting_vpn (connection);
|
|
Packit Service |
b23acc |
g_assert (s_vpn);
|
|
Packit Service |
b23acc |
if (username == NULL || nm_setting_vpn_get_user_name (s_vpn))
|
|
Packit Service |
b23acc |
return nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
dup = nm_simple_connection_new_clone (connection);
|
|
Packit Service |
b23acc |
g_assert (dup);
|
|
Packit Service |
b23acc |
s_vpn = nm_connection_get_setting_vpn (dup);
|
|
Packit Service |
b23acc |
g_assert (s_vpn);
|
|
Packit Service |
b23acc |
g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, username, NULL);
|
|
Packit Service |
b23acc |
return nm_connection_to_dbus (dup, NM_CONNECTION_SERIALIZE_ALL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
really_activate (NMVpnConnection *self, const char *username)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
GVariantBuilder details;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_VPN_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
g_return_if_fail (priv->vpn_state == STATE_NEED_AUTH);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_pointer (&priv->connect_hash, g_variant_unref);
|
|
Packit Service |
b23acc |
priv->connect_hash = _hash_with_username (_get_applied_connection (self), username);
|
|
Packit Service |
b23acc |
g_variant_ref_sink (priv->connect_hash);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* If at least one agent doesn't support VPN hints, then we can't use
|
|
Packit Service |
b23acc |
* ConnectInteractive(), because that agent won't be able to pass hints
|
|
Packit Service |
b23acc |
* from the VPN plugin's interactive secrets requests to the VPN authentication
|
|
Packit Service |
b23acc |
* dialog and we won't get the secrets we need. In this case fall back to
|
|
Packit Service |
b23acc |
* the old Connect() call.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if (nm_agent_manager_all_agents_have_capability (nm_agent_manager_get (),
|
|
Packit Service |
b23acc |
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
|
|
Packit Service |
b23acc |
NM_SECRET_AGENT_CAPABILITY_VPN_HINTS)) {
|
|
Packit Service |
b23acc |
_LOGD ("Allowing interactive secrets as all agents have that capability");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_variant_builder_init (&details, G_VARIANT_TYPE_VARDICT);
|
|
Packit Service |
b23acc |
g_dbus_proxy_call (priv->proxy,
|
|
Packit Service |
b23acc |
"ConnectInteractive",
|
|
Packit Service |
b23acc |
g_variant_new ("(@a{sa{sv}}a{sv})", priv->connect_hash, &details),
|
|
Packit Service |
b23acc |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
b23acc |
-1,
|
|
Packit Service |
b23acc |
priv->cancellable,
|
|
Packit Service |
b23acc |
(GAsyncReadyCallback) connect_interactive_cb,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
_LOGD ("Calling old Connect function as not all agents support interactive secrets");
|
|
Packit Service |
b23acc |
g_dbus_proxy_call (priv->proxy,
|
|
Packit Service |
b23acc |
"Connect",
|
|
Packit Service |
b23acc |
g_variant_new ("(@a{sa{sv}})", priv->connect_hash),
|
|
Packit Service |
b23acc |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
b23acc |
-1,
|
|
Packit Service |
b23acc |
priv->cancellable,
|
|
Packit Service |
b23acc |
(GAsyncReadyCallback) connect_cb,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_CONNECT, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
failure_cb (GDBusProxy *proxy,
|
|
Packit Service |
b23acc |
guint32 reason,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
plugin_failed (self, reason);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
state_changed_cb (GDBusProxy *proxy,
|
|
Packit Service |
b23acc |
guint32 new_service_state,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
plugin_state_changed (self, new_service_state);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
secrets_required_cb (GDBusProxy *proxy,
|
|
Packit Service |
b23acc |
const char *message,
|
|
Packit Service |
b23acc |
const char *const*secrets,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
plugin_interactive_secrets_required (self, message, secrets);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
config_cb (GDBusProxy *proxy,
|
|
Packit Service |
b23acc |
GVariant *dict,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Only list to this signals during and after connection */
|
|
Packit Service |
b23acc |
if (priv->vpn_state >= STATE_NEED_AUTH)
|
|
Packit Service |
b23acc |
nm_vpn_connection_config_get (self, dict);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
ip4_config_cb (GDBusProxy *proxy,
|
|
Packit Service |
b23acc |
GVariant *dict,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Only list to this signals during and after connection */
|
|
Packit Service |
b23acc |
if (priv->vpn_state >= STATE_NEED_AUTH)
|
|
Packit Service |
b23acc |
nm_vpn_connection_ip4_config_get (self, dict);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
ip6_config_cb (GDBusProxy *proxy,
|
|
Packit Service |
b23acc |
GVariant *dict,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Only list to this signals during and after connection */
|
|
Packit Service |
b23acc |
if (priv->vpn_state >= STATE_NEED_AUTH)
|
|
Packit Service |
b23acc |
nm_vpn_connection_ip6_config_get (self, dict);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
_name_owner_changed (GObject *object,
|
|
Packit Service |
b23acc |
GParamSpec *pspec,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
char *owner;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (object));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (owner && !priv->service_running) {
|
|
Packit Service |
b23acc |
/* service appeared */
|
|
Packit Service |
b23acc |
priv->service_running = TRUE;
|
|
Packit Service |
b23acc |
_LOGI ("Saw the service appear; activating connection");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* No need to wait for the timeout any longer */
|
|
Packit Service |
b23acc |
nm_clear_g_source (&priv->start_timeout);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Expect success because the VPN service has already appeared */
|
|
Packit Service |
b23acc |
_nm_dbus_signal_connect (priv->proxy, "Failure", G_VARIANT_TYPE ("(u)"),
|
|
Packit Service |
b23acc |
G_CALLBACK (failure_cb), self);
|
|
Packit Service |
b23acc |
_nm_dbus_signal_connect (priv->proxy, "StateChanged", G_VARIANT_TYPE ("(u)"),
|
|
Packit Service |
b23acc |
G_CALLBACK (state_changed_cb), self);
|
|
Packit Service |
b23acc |
_nm_dbus_signal_connect (priv->proxy, "SecretsRequired", G_VARIANT_TYPE ("(sas)"),
|
|
Packit Service |
b23acc |
G_CALLBACK (secrets_required_cb), self);
|
|
Packit Service |
b23acc |
_nm_dbus_signal_connect (priv->proxy, "Config", G_VARIANT_TYPE ("(a{sv})"),
|
|
Packit Service |
b23acc |
G_CALLBACK (config_cb), self);
|
|
Packit Service |
b23acc |
_nm_dbus_signal_connect (priv->proxy, "Ip4Config", G_VARIANT_TYPE ("(a{sv})"),
|
|
Packit Service |
b23acc |
G_CALLBACK (ip4_config_cb), self);
|
|
Packit Service |
b23acc |
_nm_dbus_signal_connect (priv->proxy, "Ip6Config", G_VARIANT_TYPE ("(a{sv})"),
|
|
Packit Service |
b23acc |
G_CALLBACK (ip6_config_cb), self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_NEED_AUTH, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Kick off the secrets requests; first we get existing system secrets
|
|
Packit Service |
b23acc |
* and ask the plugin if these are sufficient, next we get all existing
|
|
Packit Service |
b23acc |
* secrets from system and from user agents and ask the plugin again,
|
|
Packit Service |
b23acc |
* and last we ask the user for new secrets if required.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
get_secrets (self, SECRETS_REQ_SYSTEM, NULL);
|
|
Packit Service |
b23acc |
} else if (!owner && priv->service_running) {
|
|
Packit Service |
b23acc |
/* service went away */
|
|
Packit Service |
b23acc |
priv->service_running = FALSE;
|
|
Packit Service |
b23acc |
_LOGI ("VPN service disappeared");
|
|
Packit Service |
b23acc |
nm_vpn_connection_disconnect (self, NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_free (owner);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
_daemon_exec_timeout (gpointer data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGW ("Timed out waiting for the service to start");
|
|
Packit Service |
b23acc |
priv->start_timeout = 0;
|
|
Packit Service |
b23acc |
nm_vpn_connection_disconnect (self, NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, FALSE);
|
|
Packit Service |
b23acc |
return G_SOURCE_REMOVE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static int
|
|
Packit Service |
b23acc |
_get_log_level (void)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMLogLevel level;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* curiously enough, nm-logging also uses syslog. But it
|
|
Packit Service |
b23acc |
* maps NMLogLevel differently to the syslog levels then we
|
|
Packit Service |
b23acc |
* do here.
|
|
Packit Service |
b23acc |
*
|
|
Packit Service |
b23acc |
* The reason is, that LOG_NOTICE is already something worth
|
|
Packit Service |
b23acc |
* highlighting in the journal, but we have 3 levels that are
|
|
Packit Service |
b23acc |
* lower then LOG_NOTICE (LOGL_TRACE, LOGL_DEBUG, LOGL_INFO),
|
|
Packit Service |
b23acc |
* On the other hand, syslog only defines LOG_DEBUG and LOG_INFO.
|
|
Packit Service |
b23acc |
* Thus, we must map them differently.
|
|
Packit Service |
b23acc |
*
|
|
Packit Service |
b23acc |
* Inside the VPN plugin, you might want to treat LOG_NOTICE as
|
|
Packit Service |
b23acc |
* as low severity, not worthy to be highlighted (like NM does). */
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
level = nm_logging_get_level (LOGD_VPN_PLUGIN);
|
|
Packit Service |
b23acc |
if (level != _LOGL_OFF) {
|
|
Packit Service |
b23acc |
if (level <= LOGL_TRACE)
|
|
Packit Service |
b23acc |
return LOG_DEBUG;
|
|
Packit Service |
b23acc |
if (level <= LOGL_DEBUG)
|
|
Packit Service |
b23acc |
return LOG_INFO;
|
|
Packit Service |
b23acc |
if (level <= LOGL_INFO)
|
|
Packit Service |
b23acc |
return LOG_NOTICE;
|
|
Packit Service |
b23acc |
if (level <= LOGL_WARN)
|
|
Packit Service |
b23acc |
return LOG_WARNING;
|
|
Packit Service |
b23acc |
if (level <= LOGL_ERR)
|
|
Packit Service |
b23acc |
return LOG_ERR;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return LOG_EMERG;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
nm_vpn_service_daemon_exec (NMVpnConnection *self, GError **error)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
GPid pid;
|
|
Packit Service |
b23acc |
char *vpn_argv[4];
|
|
Packit Service |
b23acc |
gboolean success = FALSE;
|
|
Packit Service |
b23acc |
GError *spawn_error = NULL;
|
|
Packit Service |
b23acc |
guint i, j, n_environ;
|
|
Packit Service |
b23acc |
gs_free char **envp = NULL;
|
|
Packit Service |
b23acc |
char env_log_level[NM_STRLEN ("NM_VPN_LOG_LEVEL=") + 100];
|
|
Packit Service |
b23acc |
char env_log_syslog[NM_STRLEN ("NM_VPN_LOG_SYSLOG=") + 10];
|
|
Packit Service |
b23acc |
const int N_ENVIRON_EXTRA = 3;
|
|
Packit Service |
b23acc |
char **p_environ;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
i = 0;
|
|
Packit Service |
b23acc |
vpn_argv[i++] = (char *) nm_vpn_plugin_info_get_program (priv->plugin_info);
|
|
Packit Service |
b23acc |
g_return_val_if_fail (vpn_argv[0], FALSE);
|
|
Packit Service |
b23acc |
if (nm_vpn_plugin_info_supports_multiple (priv->plugin_info)) {
|
|
Packit Service |
b23acc |
vpn_argv[i++] = "--bus-name";
|
|
Packit Service |
b23acc |
vpn_argv[i++] = priv->bus_name;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
vpn_argv[i++] = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* we include <unistd.h> and "config.h" defines _GNU_SOURCE for us. So, we have @environ. */
|
|
Packit Service |
b23acc |
p_environ = environ;
|
|
Packit Service |
b23acc |
n_environ = p_environ ? g_strv_length (p_environ) : 0;
|
|
Packit Service |
b23acc |
envp = g_new (char *, n_environ + N_ENVIRON_EXTRA);
|
|
Packit Service |
b23acc |
for (i = 0, j = 0; j < n_environ; j++) {
|
|
Packit Service |
b23acc |
if ( g_str_has_prefix (p_environ[j], "NM_VPN_LOG_LEVEL=")
|
|
Packit Service |
b23acc |
|| g_str_has_prefix (p_environ[j], "NM_VPN_LOG_SYSLOG="))
|
|
Packit Service |
b23acc |
continue;
|
|
Packit Service |
b23acc |
envp[i++] = p_environ[j];
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* NM_VPN_LOG_LEVEL: the syslog logging level for the plugin. */
|
|
Packit Service |
b23acc |
envp[i++] = nm_sprintf_buf (env_log_level, "NM_VPN_LOG_LEVEL=%d", _get_log_level ());
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* NM_VPN_LOG_SYSLOG: whether to log to stdout or syslog. If NetworkManager itself runs in
|
|
Packit Service |
b23acc |
* foreground, we also want the plugin to log to stdout.
|
|
Packit Service |
b23acc |
* If the plugin runs in background, the plugin should prefer logging to syslog. Otherwise
|
|
Packit Service |
b23acc |
* logging messages will be lost (unless using journald, in which case it wouldn't matter). */
|
|
Packit Service |
b23acc |
envp[i++] = nm_sprintf_buf (env_log_syslog, "NM_VPN_LOG_SYSLOG=%c", nm_logging_syslog_enabled () ? '1' : '0');
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
envp[i++] = NULL;
|
|
Packit Service |
b23acc |
nm_assert (i <= n_environ + N_ENVIRON_EXTRA);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
success = g_spawn_async (NULL, vpn_argv, envp, 0, nm_utils_setpgid, NULL, &pid, &spawn_error);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (success) {
|
|
Packit Service |
b23acc |
_LOGI ("Started the VPN service, PID %ld", (long int) pid);
|
|
Packit Service |
b23acc |
priv->start_timeout = g_timeout_add_seconds (5, _daemon_exec_timeout, self);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
g_set_error (error,
|
|
Packit Service |
b23acc |
NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
|
|
Packit Service |
b23acc |
"%s", spawn_error ? spawn_error->message : "unknown g_spawn_async() error");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (spawn_error)
|
|
Packit Service |
b23acc |
g_error_free (spawn_error);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return success;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
on_proxy_acquired (GObject *object, GAsyncResult *result, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self;
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
gs_free_error GError *error = NULL;
|
|
Packit Service |
b23acc |
GDBusProxy *proxy;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
|
|
Packit Service |
b23acc |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (error) {
|
|
Packit Service |
b23acc |
_LOGE ("failed to acquire dbus proxy for VPN service: %s",
|
|
Packit Service |
b23acc |
error->message);
|
|
Packit Service |
b23acc |
_set_vpn_state (self,
|
|
Packit Service |
b23acc |
STATE_FAILED,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED,
|
|
Packit Service |
b23acc |
FALSE);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->proxy = proxy;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_signal_connect (priv->proxy, "notify::g-name-owner",
|
|
Packit Service |
b23acc |
G_CALLBACK (_name_owner_changed), self);
|
|
Packit Service |
b23acc |
_name_owner_changed (G_OBJECT (priv->proxy), NULL, self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->service_running)
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!nm_vpn_service_daemon_exec (self, &error)) {
|
|
Packit Service |
b23acc |
_LOGW ("Could not launch the VPN service. error: %s.",
|
|
Packit Service |
b23acc |
error->message);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_vpn_connection_disconnect (self, NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
void
|
|
Packit Service |
b23acc |
nm_vpn_connection_activate (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
NMVpnPluginInfo *plugin_info)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
NMSettingVpn *s_vpn;
|
|
Packit Service |
b23acc |
const char *service;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_VPN_CONNECTION (self));
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
g_return_if_fail (!priv->plugin_info);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self));
|
|
Packit Service |
b23acc |
g_return_if_fail (s_vpn);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
service = nm_vpn_plugin_info_get_service (plugin_info);
|
|
Packit Service |
b23acc |
nm_assert (service);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (nm_vpn_plugin_info_supports_multiple (plugin_info)) {
|
|
Packit Service |
b23acc |
const char *path;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self));
|
|
Packit Service |
b23acc |
if (path)
|
|
Packit Service |
b23acc |
path = strrchr (path, '/');
|
|
Packit Service |
b23acc |
g_return_if_fail (path);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->bus_name = g_strdup_printf ("%s.Connection_%s", service, &path[1]);
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
priv->bus_name = g_strdup (service);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->connection_can_persist = nm_setting_vpn_get_persistent (s_vpn);
|
|
Packit Service |
b23acc |
priv->plugin_info = g_object_ref (plugin_info);
|
|
Packit Service |
b23acc |
priv->cancellable = g_cancellable_new ();
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
|
Packit Service |
b23acc |
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
priv->bus_name,
|
|
Packit Service |
b23acc |
NM_VPN_DBUS_PLUGIN_PATH,
|
|
Packit Service |
b23acc |
NM_VPN_DBUS_PLUGIN_INTERFACE,
|
|
Packit Service |
b23acc |
priv->cancellable,
|
|
Packit Service |
b23acc |
(GAsyncReadyCallback) on_proxy_acquired,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_PREPARE, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMVpnConnectionState
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_vpn_state (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NM_VPN_CONNECTION_STATE_UNKNOWN);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return _state_to_nm_vpn_state (NM_VPN_CONNECTION_GET_PRIVATE (self)->vpn_state);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
const char *
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_banner (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->banner;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMProxyConfig *
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_proxy_config (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->proxy_config;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMIP4Config *
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip4_config (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip4_config;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NMIP6Config *
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip6_config (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip6_config;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static int
|
|
Packit Service |
b23acc |
_get_ip_iface_for_device (NMVpnConnection *self, const char **out_iface)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMDevice *parent_dev;
|
|
Packit Service |
b23acc |
int ifindex;
|
|
Packit Service |
b23acc |
const char *iface;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_assert (NM_IS_VPN_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* the ifindex and the ifname in this case should come together.
|
|
Packit Service |
b23acc |
* They either must be both set, or none. */
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
|
|
Packit Service |
b23acc |
if (!parent_dev)
|
|
Packit Service |
b23acc |
goto none;
|
|
Packit Service |
b23acc |
ifindex = nm_device_get_ip_ifindex (parent_dev);
|
|
Packit Service |
b23acc |
if (ifindex <= 0)
|
|
Packit Service |
b23acc |
goto none;
|
|
Packit Service |
b23acc |
iface = nm_device_get_ip_iface (parent_dev);
|
|
Packit Service |
b23acc |
if (!iface)
|
|
Packit Service |
b23acc |
goto none;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
NM_SET_OUT (out_iface, iface);
|
|
Packit Service |
b23acc |
return ifindex;
|
|
Packit Service |
b23acc |
none:
|
|
Packit Service |
b23acc |
NM_SET_OUT (out_iface, NULL);
|
|
Packit Service |
b23acc |
return 0;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
const char *
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip_iface (NMVpnConnection *self, gboolean fallback_device)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
const char *iface;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip_iface || !fallback_device)
|
|
Packit Service |
b23acc |
return priv->ip_iface;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_get_ip_iface_for_device (self, &iface);
|
|
Packit Service |
b23acc |
return iface;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
int
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self, gboolean fallback_device)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), 0);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex > 0)
|
|
Packit Service |
b23acc |
return priv->ip_ifindex;
|
|
Packit Service |
b23acc |
if (!fallback_device)
|
|
Packit Service |
b23acc |
return 0;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return _get_ip_iface_for_device (self, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
guint32
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip4_internal_gateway (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), 0);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip4_internal_gw;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
struct in6_addr *
|
|
Packit Service |
b23acc |
nm_vpn_connection_get_ip6_internal_gateway (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), 0);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip6_internal_gw;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
void
|
|
Packit Service |
b23acc |
nm_vpn_connection_disconnect (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
NMActiveConnectionStateReason reason,
|
|
Packit Service |
b23acc |
gboolean quitting)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_VPN_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_DISCONNECTED, reason, quitting);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
gboolean
|
|
Packit Service |
b23acc |
nm_vpn_connection_deactivate (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
NMActiveConnectionStateReason reason,
|
|
Packit Service |
b23acc |
gboolean quitting)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
gboolean success = FALSE;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
if (priv->vpn_state > STATE_UNKNOWN && priv->vpn_state <= STATE_DEACTIVATING) {
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_DEACTIVATING, reason, quitting);
|
|
Packit Service |
b23acc |
success = TRUE;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
return success;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/*****************************************************************************/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
plugin_need_secrets_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self;
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
gs_unref_variant GVariant *reply = NULL;
|
|
Packit Service |
b23acc |
gs_free_error GError *error = NULL;
|
|
Packit Service |
b23acc |
const char *setting_name;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
reply = _nm_dbus_proxy_call_finish (proxy, result, G_VARIANT_TYPE ("(s)"), &error);
|
|
Packit Service |
b23acc |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (error) {
|
|
Packit Service |
b23acc |
g_dbus_error_strip_remote_error (error);
|
|
Packit Service |
b23acc |
_LOGE ("plugin NeedSecrets request #%d failed: %s",
|
|
Packit Service |
b23acc |
priv->secrets_idx + 1,
|
|
Packit Service |
b23acc |
error->message);
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS, FALSE);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_variant_get (reply, "(&s)", &setting_name);
|
|
Packit Service |
b23acc |
if (!strlen (setting_name)) {
|
|
Packit Service |
b23acc |
_LOGD ("service indicated no additional secrets required");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* No secrets required; we can start the VPN */
|
|
Packit Service |
b23acc |
really_activate (self, priv->username);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* More secrets required */
|
|
Packit Service |
b23acc |
if (priv->secrets_idx == SECRETS_REQ_NEW) {
|
|
Packit Service |
b23acc |
_LOGE ("final secrets request failed to provide sufficient secrets");
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS, FALSE);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
_LOGD ("service indicated additional secrets required");
|
|
Packit Service |
b23acc |
get_secrets (self, priv->secrets_idx + 1, NULL);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
plugin_new_secrets_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self;
|
|
Packit Service |
b23acc |
gs_unref_variant GVariant *reply = NULL;
|
|
Packit Service |
b23acc |
gs_free_error GError *error = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
reply = g_dbus_proxy_call_finish (proxy, result, &error);
|
|
Packit Service |
b23acc |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (error) {
|
|
Packit Service |
b23acc |
g_dbus_error_strip_remote_error (error);
|
|
Packit Service |
b23acc |
_LOGE ("sending new secrets to the plugin failed: %s",
|
|
Packit Service |
b23acc |
error->message);
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS, FALSE);
|
|
Packit Service |
b23acc |
} else
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_CONNECT, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
get_secrets_cb (NMSettingsConnection *connection,
|
|
Packit Service |
b23acc |
NMSettingsConnectionCallId *call_id,
|
|
Packit Service |
b23acc |
const char *agent_username,
|
|
Packit Service |
b23acc |
const char *setting_name,
|
|
Packit Service |
b23acc |
GError *error,
|
|
Packit Service |
b23acc |
gpointer user_data)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv;
|
|
Packit Service |
b23acc |
GVariant *dict;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (NM_IS_VPN_CONNECTION (self));
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (connection && connection == _get_settings_connection (self, FALSE));
|
|
Packit Service |
b23acc |
g_return_if_fail (call_id == priv->secrets_id);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->secrets_id = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (error && priv->secrets_idx >= SECRETS_REQ_NEW) {
|
|
Packit Service |
b23acc |
_LOGE ("Failed to request VPN secrets #%d: %s",
|
|
Packit Service |
b23acc |
priv->secrets_idx + 1, error->message);
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS, FALSE);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Cache the username for later */
|
|
Packit Service |
b23acc |
if (agent_username) {
|
|
Packit Service |
b23acc |
g_free (priv->username);
|
|
Packit Service |
b23acc |
priv->username = g_strdup (agent_username);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
dict = _hash_with_username (_get_applied_connection (self), priv->username);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->secrets_idx == SECRETS_REQ_INTERACTIVE) {
|
|
Packit Service |
b23acc |
_LOGD ("sending secrets to the plugin");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Send the secrets back to the plugin */
|
|
Packit Service |
b23acc |
g_dbus_proxy_call (priv->proxy,
|
|
Packit Service |
b23acc |
"NewSecrets",
|
|
Packit Service |
b23acc |
g_variant_new ("(@a{sa{sv}})", dict),
|
|
Packit Service |
b23acc |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
b23acc |
-1,
|
|
Packit Service |
b23acc |
priv->cancellable,
|
|
Packit Service |
b23acc |
(GAsyncReadyCallback) plugin_new_secrets_cb,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
} else {
|
|
Packit Service |
b23acc |
_LOGD ("asking service if additional secrets are required");
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Ask the VPN service if more secrets are required */
|
|
Packit Service |
b23acc |
g_dbus_proxy_call (priv->proxy,
|
|
Packit Service |
b23acc |
"NeedSecrets",
|
|
Packit Service |
b23acc |
g_variant_new ("(@a{sa{sv}})", dict),
|
|
Packit Service |
b23acc |
G_DBUS_CALL_FLAGS_NONE,
|
|
Packit Service |
b23acc |
-1,
|
|
Packit Service |
b23acc |
priv->cancellable,
|
|
Packit Service |
b23acc |
(GAsyncReadyCallback) plugin_need_secrets_cb,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
get_secrets (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
SecretsReq secrets_idx,
|
|
Packit Service |
b23acc |
const char *const*hints)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_return_if_fail (secrets_idx < SECRETS_REQ_LAST);
|
|
Packit Service |
b23acc |
priv->secrets_idx = secrets_idx;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
cancel_get_secrets (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGD ("requesting VPN secrets pass #%d",
|
|
Packit Service |
b23acc |
priv->secrets_idx + 1);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
switch (priv->secrets_idx) {
|
|
Packit Service |
b23acc |
case SECRETS_REQ_SYSTEM:
|
|
Packit Service |
b23acc |
flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM;
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case SECRETS_REQ_EXISTING:
|
|
Packit Service |
b23acc |
flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE;
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case SECRETS_REQ_NEW:
|
|
Packit Service |
b23acc |
case SECRETS_REQ_INTERACTIVE:
|
|
Packit Service |
b23acc |
flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
g_assert_not_reached ();
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self)))
|
|
Packit Service |
b23acc |
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->secrets_id = nm_settings_connection_get_secrets (_get_settings_connection (self, FALSE),
|
|
Packit Service |
b23acc |
_get_applied_connection (self),
|
|
Packit Service |
b23acc |
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
|
|
Packit Service |
b23acc |
NM_SETTING_VPN_SETTING_NAME,
|
|
Packit Service |
b23acc |
flags,
|
|
Packit Service |
b23acc |
hints,
|
|
Packit Service |
b23acc |
get_secrets_cb,
|
|
Packit Service |
b23acc |
self);
|
|
Packit Service |
b23acc |
g_return_if_fail (priv->secrets_id);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
plugin_interactive_secrets_required (NMVpnConnection *self,
|
|
Packit Service |
b23acc |
const char *message,
|
|
Packit Service |
b23acc |
const char *const*secrets)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
const gsize secrets_len = NM_PTRARRAY_LEN (secrets);
|
|
Packit Service |
b23acc |
gsize i;
|
|
Packit Service |
b23acc |
gs_free const char **hints = NULL;
|
|
Packit Service |
b23acc |
gs_free char *message_hint = NULL;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!NM_IN_SET (priv->vpn_state, STATE_CONNECT,
|
|
Packit Service |
b23acc |
STATE_NEED_AUTH)) {
|
|
Packit Service |
b23acc |
_LOGD ("VPN plugin: requested secrets; state %s (%d); ignore request in current state",
|
|
Packit Service |
b23acc |
vpn_state_to_string_a (priv->vpn_state), priv->vpn_state);
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
_LOGI ("VPN plugin: requested secrets; state %s (%d)",
|
|
Packit Service |
b23acc |
vpn_state_to_string_a (priv->vpn_state), priv->vpn_state);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->secrets_idx = SECRETS_REQ_INTERACTIVE;
|
|
Packit Service |
b23acc |
_set_vpn_state (self, STATE_NEED_AUTH, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Copy hints and add message to the end */
|
|
Packit Service |
b23acc |
hints = g_new (const char *, secrets_len + 2);
|
|
Packit Service |
b23acc |
for (i = 0; i < secrets_len; i++)
|
|
Packit Service |
b23acc |
hints[i] = secrets[i];
|
|
Packit Service |
b23acc |
if (message) {
|
|
Packit Service |
b23acc |
message_hint = g_strdup_printf ("x-vpn-message:%s", message);
|
|
Packit Service |
b23acc |
hints[i++] = message_hint;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
hints[i] = NULL;
|
|
Packit Service |
b23acc |
nm_assert (i < secrets_len + 2);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
get_secrets (self, SECRETS_REQ_INTERACTIVE, hints);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/*****************************************************************************/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
device_changed (NMActiveConnection *active,
|
|
Packit Service |
b23acc |
NMDevice *new_device,
|
|
Packit Service |
b23acc |
NMDevice *old_device)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (active);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (!_service_and_connection_can_persist (NM_VPN_CONNECTION (active)))
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
if (priv->vpn_state < STATE_CONNECT || priv->vpn_state > STATE_ACTIVATED)
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Route-based VPNs must update their routing and send a new IP config
|
|
Packit Service |
b23acc |
* since all their routes need to be adjusted for new_device.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if (priv->ip_ifindex <= 0)
|
|
Packit Service |
b23acc |
return;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/* Device changed underneath the VPN connection. Let the plugin figure
|
|
Packit Service |
b23acc |
* out that connectivity is down and start its reconnect attempt if it
|
|
Packit Service |
b23acc |
* needs to.
|
|
Packit Service |
b23acc |
*/
|
|
Packit Service |
b23acc |
if (old_device)
|
|
Packit Service |
b23acc |
remove_parent_device_config (NM_VPN_CONNECTION (active), old_device);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (new_device)
|
|
Packit Service |
b23acc |
apply_parent_device_config (NM_VPN_CONNECTION (active));
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
/*****************************************************************************/
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
nm_vpn_connection_init (NMVpnConnection *self)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
priv->vpn_state = STATE_WAITING;
|
|
Packit Service |
b23acc |
priv->secrets_idx = SECRETS_REQ_SYSTEM;
|
|
Packit Service |
b23acc |
priv->netns = g_object_ref (nm_netns_get ());
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
dispose (GObject *object)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnection *self = NM_VPN_CONNECTION (object);
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
if (priv->proxy)
|
|
Packit Service |
b23acc |
g_signal_handlers_disconnect_by_data (priv->proxy, self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_g_source (&priv->start_timeout);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_pointer (&priv->connect_hash, g_variant_unref);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_pointer (&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_g_source (&priv->connect_timeout);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
dispatcher_cleanup (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
cancel_get_secrets (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_clear_g_cancellable (&priv->cancellable);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_clear_object (&priv->proxy_config);
|
|
Packit Service |
b23acc |
nm_dbus_object_clear_and_unexport (&priv->ip4_config);
|
|
Packit Service |
b23acc |
nm_dbus_object_clear_and_unexport (&priv->ip6_config);
|
|
Packit Service |
b23acc |
g_clear_object (&priv->proxy);
|
|
Packit Service |
b23acc |
g_clear_object (&priv->plugin_info);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
fw_call_cleanup (self);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
finalize (GObject *object)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_free (priv->banner);
|
|
Packit Service |
b23acc |
g_free (priv->ip_iface);
|
|
Packit Service |
b23acc |
g_free (priv->username);
|
|
Packit Service |
b23acc |
g_free (priv->ip6_internal_gw);
|
|
Packit Service |
b23acc |
g_free (priv->ip6_external_gw);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_clear_object (&priv->netns);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static gboolean
|
|
Packit Service |
b23acc |
ip_config_valid (VpnState state)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
return (state == STATE_PRE_UP || state == STATE_ACTIVATED);
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
get_property (GObject *object, guint prop_id,
|
|
Packit Service |
b23acc |
GValue *value, GParamSpec *pspec)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
|
|
Packit Service |
b23acc |
NMDevice *parent_dev;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
switch (prop_id) {
|
|
Packit Service |
b23acc |
case PROP_VPN_STATE:
|
|
Packit Service |
b23acc |
g_value_set_uint (value, _state_to_nm_vpn_state (priv->vpn_state));
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case PROP_BANNER:
|
|
Packit Service |
b23acc |
g_value_set_string (value, priv->banner ?: "");
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case PROP_IP4_CONFIG:
|
|
Packit Service |
b23acc |
nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->vpn_state) ? priv->ip4_config : NULL);
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case PROP_IP6_CONFIG:
|
|
Packit Service |
b23acc |
nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->vpn_state) ? priv->ip6_config : NULL);
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
case PROP_MASTER:
|
|
Packit Service |
b23acc |
parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (object));
|
|
Packit Service |
b23acc |
nm_dbus_utils_g_value_set_object_path (value, parent_dev);
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
default:
|
|
Packit Service |
b23acc |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit Service |
b23acc |
break;
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
}
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static const GDBusSignalInfo signal_info_vpn_state_changed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT (
|
|
Packit Service |
b23acc |
"VpnStateChanged",
|
|
Packit Service |
b23acc |
.args = NM_DEFINE_GDBUS_ARG_INFOS (
|
|
Packit Service |
b23acc |
NM_DEFINE_GDBUS_ARG_INFO ("state", "u"),
|
|
Packit Service |
b23acc |
NM_DEFINE_GDBUS_ARG_INFO ("reason", "u"),
|
|
Packit Service |
b23acc |
),
|
|
Packit Service |
b23acc |
);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static const NMDBusInterfaceInfoExtended interface_info_vpn_connection = {
|
|
Packit Service |
b23acc |
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT (
|
|
Packit Service |
b23acc |
NM_DBUS_INTERFACE_VPN_CONNECTION,
|
|
Packit Service |
b23acc |
.signals = NM_DEFINE_GDBUS_SIGNAL_INFOS (
|
|
Packit Service |
b23acc |
&nm_signal_info_property_changed_legacy,
|
|
Packit Service |
b23acc |
&signal_info_vpn_state_changed,
|
|
Packit Service |
b23acc |
),
|
|
Packit Service |
b23acc |
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS (
|
|
Packit Service |
b23acc |
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("VpnState", "u", NM_VPN_CONNECTION_VPN_STATE),
|
|
Packit Service |
b23acc |
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Banner", "s", NM_VPN_CONNECTION_BANNER),
|
|
Packit Service |
b23acc |
),
|
|
Packit Service |
b23acc |
),
|
|
Packit Service |
b23acc |
.legacy_property_changed = TRUE,
|
|
Packit Service |
b23acc |
};
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
static void
|
|
Packit Service |
b23acc |
nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class)
|
|
Packit Service |
b23acc |
{
|
|
Packit Service |
b23acc |
GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
|
|
Packit Service |
b23acc |
NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (connection_class);
|
|
Packit Service |
b23acc |
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (connection_class);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_vpn_connection);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
object_class->get_property = get_property;
|
|
Packit Service |
b23acc |
object_class->dispose = dispose;
|
|
Packit Service |
b23acc |
object_class->finalize = finalize;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
active_class->device_state_changed = device_state_changed;
|
|
Packit Service |
b23acc |
active_class->device_changed = device_changed;
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
obj_properties[PROP_VPN_STATE] =
|
|
Packit Service |
b23acc |
g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, "", "",
|
|
Packit Service |
b23acc |
NM_VPN_CONNECTION_STATE_UNKNOWN,
|
|
Packit Service |
b23acc |
NM_VPN_CONNECTION_STATE_DISCONNECTED,
|
|
Packit Service |
b23acc |
NM_VPN_CONNECTION_STATE_UNKNOWN,
|
|
Packit Service |
b23acc |
G_PARAM_READABLE |
|
|
Packit Service |
b23acc |
G_PARAM_STATIC_STRINGS);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
obj_properties[PROP_BANNER] =
|
|
Packit Service |
b23acc |
g_param_spec_string (NM_VPN_CONNECTION_BANNER, "", "",
|
|
Packit Service |
b23acc |
NULL,
|
|
Packit Service |
b23acc |
G_PARAM_READABLE |
|
|
Packit Service |
b23acc |
G_PARAM_STATIC_STRINGS);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
g_object_class_override_property (object_class, PROP_MASTER,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_MASTER);
|
|
Packit Service |
b23acc |
g_object_class_override_property (object_class, PROP_IP4_CONFIG,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_IP4_CONFIG);
|
|
Packit Service |
b23acc |
g_object_class_override_property (object_class, PROP_IP6_CONFIG,
|
|
Packit Service |
b23acc |
NM_ACTIVE_CONNECTION_IP6_CONFIG);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
signals[INTERNAL_STATE_CHANGED] =
|
|
Packit Service |
b23acc |
g_signal_new (NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED,
|
|
Packit Service |
b23acc |
G_OBJECT_CLASS_TYPE (object_class),
|
|
Packit Service |
b23acc |
G_SIGNAL_RUN_FIRST,
|
|
Packit Service |
b23acc |
0, NULL, NULL, NULL,
|
|
Packit Service |
b23acc |
G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
|
Packit Service |
b23acc |
|
|
Packit Service |
b23acc |
signals[INTERNAL_RETRY_AFTER_FAILURE] =
|
|
Packit Service |
b23acc |
g_signal_new (NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE,
|
|
Packit Service |
b23acc |
G_OBJECT_CLASS_TYPE (object_class),
|
|
Packit Service |
b23acc |
G_SIGNAL_RUN_FIRST,
|
|
Packit Service |
b23acc |
0, NULL, NULL, NULL,
|
|
Packit Service |
b23acc |
G_TYPE_NONE, 0);
|
|
Packit Service |
b23acc |
}
|