diff options
| author | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
| commit | 80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch) | |
| tree | e3b229aa94e8dcf0590f2317664176e7b8f7607b /src/ppp/nm-ppp-manager.c | |
| parent | 65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff) | |
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/ppp/nm-ppp-manager.c')
| -rw-r--r-- | src/ppp/nm-ppp-manager.c | 1459 |
1 files changed, 0 insertions, 1459 deletions
diff --git a/src/ppp/nm-ppp-manager.c b/src/ppp/nm-ppp-manager.c deleted file mode 100644 index a200334c..00000000 --- a/src/ppp/nm-ppp-manager.c +++ /dev/null @@ -1,1459 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2012 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-ppp-manager.h" - -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <stdlib.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <asm/types.h> -#include <sys/stat.h> - -#include <linux/ppp_defs.h> -#ifndef aligned_u64 - #define aligned_u64 unsigned long long __attribute__((aligned(8))) -#endif -#include <linux/if.h> -#include <linux/if_ppp.h> -#include <linux/rtnetlink.h> - -#include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" -#include "nm-act-request.h" -#include "nm-ip4-config.h" -#include "nm-ip6-config.h" -#include "nm-dbus-object.h" - -#include "nm-pppd-plugin.h" -#include "nm-ppp-plugin-api.h" -#include "nm-ppp-status.h" - -#define NM_PPPD_PLUGIN PPPD_PLUGIN_DIR "/nm-pppd-plugin.so" - -static NM_CACHED_QUARK_FCN("ppp-manager-secret-tries", ppp_manager_secret_tries_quark); - -/*****************************************************************************/ - -#define NM_TYPE_PPP_MANAGER (nm_ppp_manager_get_type()) -#define NM_PPP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_PPP_MANAGER, NMPPPManager)) -#define NM_PPP_MANAGER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_PPP_MANAGER, NMPPPManagerClass)) -#define NM_IS_PPP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_PPP_MANAGER)) -#define NM_IS_PPP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_PPP_MANAGER)) -#define NM_PPP_MANAGER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_PPP_MANAGER, NMPPPManagerClass)) - -GType nm_ppp_manager_get_type(void); - -/*****************************************************************************/ - -enum { - STATE_CHANGED, - IFINDEX_SET, - IP4_CONFIG, - IP6_CONFIG, - STATS, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT_IFACE, ); - -typedef struct { - GPid pid; - - char *parent_iface; - char *ip_iface; - int ifindex; - - NMActRequest * act_req; - GDBusMethodInvocation * pending_secrets_context; - NMActRequestGetSecretsCallId *secrets_id; - const char * secrets_setting_name; - - guint ppp_watch_id; - guint ppp_timeout_handler; - - /* Monitoring */ - int monitor_fd; - guint monitor_id; - - guint32 ip4_route_table; - guint32 ip4_route_metric; - guint32 ip6_route_table; - guint32 ip6_route_metric; -} NMPPPManagerPrivate; - -struct _NMPPPManager { - NMDBusObject parent; - NMPPPManagerPrivate _priv; -}; - -typedef struct { - NMDBusObjectClass parent; -} NMPPPManagerClass; - -G_DEFINE_TYPE(NMPPPManager, nm_ppp_manager, NM_TYPE_DBUS_OBJECT) - -#define NM_PPP_MANAGER_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMPPPManager, NM_IS_PPP_MANAGER, NMDBusObject) - -/*****************************************************************************/ - -#define _NMLOG_DOMAIN LOGD_PPP -#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "ppp-manager", __VA_ARGS__) - -/*****************************************************************************/ - -static void _ppp_cleanup(NMPPPManager *self); - -static NMPPPManagerStopHandle *_ppp_manager_stop(NMPPPManager * self, - GCancellable * cancellable, - NMPPPManagerStopCallback callback, - gpointer user_data); - -static void _ppp_manager_stop_cancel(NMPPPManagerStopHandle *handle); - -/*****************************************************************************/ - -static void -_ppp_manager_set_route_parameters(NMPPPManager *self, - guint32 ip4_route_table, - guint32 ip4_route_metric, - guint32 ip6_route_table, - guint32 ip6_route_metric) -{ - NMPPPManagerPrivate *priv; - - g_return_if_fail(NM_IS_PPP_MANAGER(self)); - - priv = NM_PPP_MANAGER_GET_PRIVATE(self); - if (priv->ip4_route_table != ip4_route_table || priv->ip4_route_metric != ip4_route_metric - || priv->ip6_route_table != ip6_route_table || priv->ip6_route_metric != ip6_route_metric) { - priv->ip4_route_table = ip4_route_table; - priv->ip4_route_metric = ip4_route_metric; - priv->ip6_route_table = ip6_route_table; - priv->ip6_route_metric = ip6_route_metric; - - _LOGT("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u", - priv->ip4_route_table, - priv->ip4_route_metric, - priv->ip6_route_table, - priv->ip6_route_metric); - } -} - -/*****************************************************************************/ - -static gboolean -monitor_cb(gpointer user_data) -{ - NMPPPManager * self = NM_PPP_MANAGER(user_data); - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - const char * ifname; - int errsv; - - ifname = nm_platform_link_get_name(NM_PLATFORM_GET, priv->ifindex); - - if (ifname) { - struct ppp_stats stats = {}; - struct ifreq req = { - .ifr_data = (caddr_t) &stats, - }; - - nm_utils_ifname_cpy(req.ifr_name, ifname); - if (ioctl(priv->monitor_fd, SIOCGPPPSTATS, &req) < 0) { - errsv = errno; - if (errsv != ENODEV) - _LOGW("could not read ppp stats: %s", nm_strerror_native(errsv)); - } else { - g_signal_emit(self, - signals[STATS], - 0, - (guint) stats.p.ppp_ibytes, - (guint) stats.p.ppp_obytes); - } - } - - return G_SOURCE_CONTINUE; -} - -static void -monitor_stats(NMPPPManager *self) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - int errsv; - - /* already monitoring */ - if (priv->monitor_fd >= 0) - return; - - priv->monitor_fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (priv->monitor_fd < 0) { - errsv = errno; - _LOGW("could not monitor PPP stats: %s", nm_strerror_native(errsv)); - return; - } - - g_warn_if_fail(priv->monitor_id == 0); - if (priv->monitor_id) - g_source_remove(priv->monitor_id); - priv->monitor_id = g_timeout_add_seconds(5, monitor_cb, self); -} - -/*****************************************************************************/ - -static void -cancel_get_secrets(NMPPPManager *self) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - - if (priv->secrets_id) - nm_act_request_cancel_secrets(priv->act_req, priv->secrets_id); - - g_return_if_fail(!priv->secrets_id && !priv->secrets_setting_name); -} - -static gboolean -extract_details_from_connection(NMConnection *connection, - const char * secrets_setting_name, - const char ** username, - const char ** password, - GError ** error) -{ - NMSettingConnection *s_con; - NMSetting * setting; - const char * setting_name; - - g_return_val_if_fail(connection != NULL, FALSE); - g_return_val_if_fail(username != NULL, FALSE); - g_return_val_if_fail(password != NULL, FALSE); - - if (secrets_setting_name) - setting_name = secrets_setting_name; - else { - /* Get the setting matching the connection type */ - s_con = nm_connection_get_setting_connection(connection); - g_assert(s_con); - - setting_name = nm_setting_connection_get_connection_type(s_con); - g_assert(setting_name); - - /* In case of bluetooth connection, use GSM or CDMA setting */ - if (strcmp(setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0) { - if (nm_connection_get_setting_gsm(connection)) - setting_name = NM_SETTING_GSM_SETTING_NAME; - else - setting_name = NM_SETTING_CDMA_SETTING_NAME; - } - } - - setting = nm_connection_get_setting_by_name(connection, setting_name); - if (!setting) { - /* This shouldn't ever happen */ - g_set_error_literal(error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_FAILED, - "Missing type-specific setting; no secrets could be found."); - return FALSE; - } - - if (NM_IS_SETTING_PPPOE(setting)) { - *username = nm_setting_pppoe_get_username(NM_SETTING_PPPOE(setting)); - *password = nm_setting_pppoe_get_password(NM_SETTING_PPPOE(setting)); - } else if (NM_IS_SETTING_ADSL(setting)) { - *username = nm_setting_adsl_get_username(NM_SETTING_ADSL(setting)); - *password = nm_setting_adsl_get_password(NM_SETTING_ADSL(setting)); - } else if (NM_IS_SETTING_GSM(setting)) { - *username = nm_setting_gsm_get_username(NM_SETTING_GSM(setting)); - *password = nm_setting_gsm_get_password(NM_SETTING_GSM(setting)); - } else if (NM_IS_SETTING_CDMA(setting)) { - *username = nm_setting_cdma_get_username(NM_SETTING_CDMA(setting)); - *password = nm_setting_cdma_get_password(NM_SETTING_CDMA(setting)); - } - - return TRUE; -} - -static void -ppp_secrets_cb(NMActRequest * req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection * settings_connection, /* unused (we pass NULL here) */ - GError * error, - gpointer user_data) -{ - NMPPPManager * self = NM_PPP_MANAGER(user_data); - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - const char * username = NULL; - const char * password = NULL; - GError * local = NULL; - NMConnection * applied_connection; - - g_return_if_fail(priv->pending_secrets_context != NULL); - g_return_if_fail(req == priv->act_req); - g_return_if_fail(call_id == priv->secrets_id); - - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto out; - - if (error) { - _LOGW("%s", error->message); - g_dbus_method_invocation_return_gerror(priv->pending_secrets_context, error); - goto out; - } - - applied_connection = nm_act_request_get_applied_connection(req); - - if (!extract_details_from_connection(applied_connection, - priv->secrets_setting_name, - &username, - &password, - &local)) { - _LOGW("%s", local->message); - g_dbus_method_invocation_take_error(priv->pending_secrets_context, local); - goto out; - } - - /* This is sort of a hack but... - * pppd plugin only ever needs username and password. Passing the full - * connection there would mean some bloat: the plugin would need to link - * against libnm just to parse this. So instead, let's just send what - * it needs. - */ - g_dbus_method_invocation_return_value(priv->pending_secrets_context, - g_variant_new("(ss)", username ?: "", password ?: "")); - -out: - priv->pending_secrets_context = NULL; - priv->secrets_id = NULL; - priv->secrets_setting_name = NULL; -} - -static void -impl_ppp_manager_need_secrets(NMDBusObject * obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended * method_info, - GDBusConnection * connection, - const char * sender, - GDBusMethodInvocation * invocation, - GVariant * parameters) -{ - NMPPPManager * self = NM_PPP_MANAGER(obj); - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - NMConnection * applied_connection; - const char * username = NULL; - const char * password = NULL; - guint32 tries; - gs_unref_ptrarray GPtrArray *hints = NULL; - GError * error = NULL; - NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - - nm_active_connection_clear_secrets(NM_ACTIVE_CONNECTION(priv->act_req)); - - applied_connection = nm_act_request_get_applied_connection(priv->act_req); - - priv->secrets_setting_name = nm_connection_need_secrets(applied_connection, &hints); - if (!priv->secrets_setting_name) { - /* Use existing secrets from the connection */ - if (extract_details_from_connection(applied_connection, - NULL, - &username, - &password, - &error)) { - /* Send existing secrets to the PPP plugin */ - priv->pending_secrets_context = invocation; - ppp_secrets_cb(priv->act_req, priv->secrets_id, NULL, NULL, self); - } else { - _LOGW("%s", error->message); - g_dbus_method_invocation_take_error(priv->pending_secrets_context, error); - } - return; - } - - /* Only ask for completely new secrets after retrying them once; some devices - * appear to ask a few times when they actually don't even care what you - * pass back. - */ - tries = GPOINTER_TO_UINT( - g_object_get_qdata(G_OBJECT(applied_connection), ppp_manager_secret_tries_quark())); - if (tries > 1) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - - if (hints) - g_ptr_array_add(hints, NULL); - - priv->secrets_id = nm_act_request_get_secrets(priv->act_req, - FALSE, - priv->secrets_setting_name, - flags, - hints ? (const char *const *) hints->pdata : NULL, - ppp_secrets_cb, - self); - g_object_set_qdata(G_OBJECT(applied_connection), - ppp_manager_secret_tries_quark(), - GUINT_TO_POINTER(++tries)); - priv->pending_secrets_context = invocation; -} - -static void -impl_ppp_manager_set_state(NMDBusObject * obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended * method_info, - GDBusConnection * connection, - const char * sender, - GDBusMethodInvocation * invocation, - GVariant * parameters) -{ - NMPPPManager *self = NM_PPP_MANAGER(obj); - guint32 state; - - g_variant_get(parameters, "(u)", &state); - g_signal_emit(self, signals[STATE_CHANGED], 0, (guint) state); - g_dbus_method_invocation_return_value(invocation, NULL); -} - -static void -impl_ppp_manager_set_ifindex(NMDBusObject * obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended * method_info, - GDBusConnection * connection, - const char * sender, - GDBusMethodInvocation * invocation, - GVariant * parameters) -{ - NMPPPManager * self = NM_PPP_MANAGER(obj); - NMPPPManagerPrivate * priv = NM_PPP_MANAGER_GET_PRIVATE(self); - const NMPlatformLink *plink = NULL; - nm_auto_nmpobj const NMPObject *obj_keep_alive = NULL; - gint32 ifindex; - - g_variant_get(parameters, "(i)", &ifindex); - - if (priv->ifindex >= 0) { - if (priv->ifindex == ifindex) - _LOGD("set-ifindex: ignore repeated calls setting ifindex to %d", (int) ifindex); - else - _LOGW("set-ifindex: can't change the ifindex from %d to %d", - priv->ifindex, - (int) ifindex); - goto out; - } - - if (ifindex > 0) { - plink = nm_platform_link_get(NM_PLATFORM_GET, ifindex); - if (!plink) { - nm_platform_process_events(NM_PLATFORM_GET); - plink = nm_platform_link_get(NM_PLATFORM_GET, ifindex); - } - } - - if (!plink) { - _LOGW("set-ifindex: unknown interface with ifindex %d", ifindex); - ifindex = 0; - } else { - obj_keep_alive = nmp_object_ref(NMP_OBJECT_UP_CAST(plink)); - _LOGD("set-ifindex: %d, name \"%s\"", (int) ifindex, plink->name); - } - - priv->ifindex = ifindex; - - g_signal_emit(self, signals[IFINDEX_SET], 0, ifindex, plink ? plink->name : NULL); - -out: - g_dbus_method_invocation_return_value(invocation, NULL); -} - -static gboolean -set_ip_config_common(NMPPPManager *self, GVariant *config_dict, guint32 *out_mtu) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - NMConnection * applied_connection; - NMSettingPpp * s_ppp; - - if (priv->ifindex <= 0) - return FALSE; - - /* Got successful IP config; obviously the secrets worked */ - applied_connection = nm_act_request_get_applied_connection(priv->act_req); - g_object_set_qdata(G_OBJECT(applied_connection), ppp_manager_secret_tries_quark(), NULL); - - if (out_mtu) { - /* Get any custom MTU */ - s_ppp = nm_connection_get_setting_ppp(applied_connection); - *out_mtu = s_ppp ? nm_setting_ppp_get_mtu(s_ppp) : 0; - } - - monitor_stats(self); - return TRUE; -} - -static void -impl_ppp_manager_set_ip4_config(NMDBusObject * obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended * method_info, - GDBusConnection * connection, - const char * sender, - GDBusMethodInvocation * invocation, - GVariant * parameters) -{ - NMPPPManager * self = NM_PPP_MANAGER(obj); - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - gs_unref_object NMIP4Config *config = NULL; - NMPlatformIP4Address address; - guint32 u32, mtu; - GVariantIter * iter; - gs_unref_variant GVariant *config_dict = NULL; - - _LOGI("(IPv4 Config Get) reply received."); - - g_variant_get(parameters, "(@a{sv})", &config_dict); - - nm_clear_g_source(&priv->ppp_timeout_handler); - - if (!set_ip_config_common(self, config_dict, &mtu)) - goto out; - - config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), priv->ifindex); - - if (mtu) - nm_ip4_config_set_mtu(config, mtu, NM_IP_CONFIG_SOURCE_PPP); - - memset(&address, 0, sizeof(address)); - address.plen = 32; - - if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_ADDRESS, "u", &u32)) - address.address = u32; - - if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_GATEWAY, "u", &u32)) { - const NMPlatformIP4Route r = { - .ifindex = priv->ifindex, - .rt_source = NM_IP_CONFIG_SOURCE_PPP, - .gateway = u32, - .table_coerced = nm_platform_route_table_coerce(priv->ip4_route_table), - .metric = priv->ip4_route_metric, - }; - - nm_ip4_config_add_route(config, &r, NULL); - address.peer_address = u32; - } else - address.peer_address = address.address; - - if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_PREFIX, "u", &u32)) - address.plen = u32; - - if (address.address && address.plen && address.plen <= 32) { - address.addr_source = NM_IP_CONFIG_SOURCE_PPP; - nm_ip4_config_add_address(config, &address); - } else { - _LOGE("invalid IPv4 address received!"); - goto out; - } - - if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_DNS, "au", &iter)) { - while (g_variant_iter_next(iter, "u", &u32)) - nm_ip4_config_add_nameserver(config, u32); - g_variant_iter_free(iter); - } - - if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_WINS, "au", &iter)) { - while (g_variant_iter_next(iter, "u", &u32)) - nm_ip4_config_add_wins(config, u32); - g_variant_iter_free(iter); - } - - /* Push the IP4 config up to the device */ - g_signal_emit(self, signals[IP4_CONFIG], 0, config); - -out: - g_dbus_method_invocation_return_value(invocation, NULL); -} - -/* Converts the named Interface Identifier item to an IPv6 LL address and - * returns the IID. - */ -static gboolean -iid_value_to_ll6_addr(GVariant * dict, - const char * prop, - struct in6_addr * out_addr, - NMUtilsIPv6IfaceId *out_iid) -{ - guint64 iid; - - if (!g_variant_lookup(dict, prop, "t", &iid)) { - _LOGD("pppd plugin property '%s' missing or not a uint64", prop); - return FALSE; - } - g_return_val_if_fail(iid != 0, FALSE); - - /* Construct an IPv6 LL address from the interface identifier. See - * http://tools.ietf.org/html/rfc4291#section-2.5.1 (IPv6) and - * http://tools.ietf.org/html/rfc5072#section-4.1 (IPv6 over PPP). - */ - memset(out_addr->s6_addr, 0, sizeof(out_addr->s6_addr)); - out_addr->s6_addr16[0] = htons(0xfe80); - memcpy(out_addr->s6_addr + 8, &iid, sizeof(iid)); - if (out_iid) - nm_utils_ipv6_interface_identifier_get_from_addr(out_iid, out_addr); - return TRUE; -} - -static void -impl_ppp_manager_set_ip6_config(NMDBusObject * obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended * method_info, - GDBusConnection * connection, - const char * sender, - GDBusMethodInvocation * invocation, - GVariant * parameters) -{ - NMPPPManager * self = NM_PPP_MANAGER(obj); - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - gs_unref_object NMIP6Config *config = NULL; - NMPlatformIP6Address addr; - struct in6_addr a; - NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; - gboolean has_peer = FALSE; - gs_unref_variant GVariant *config_dict = NULL; - - _LOGI("(IPv6 Config Get) reply received."); - - g_variant_get(parameters, "(@a{sv})", &config_dict); - - nm_clear_g_source(&priv->ppp_timeout_handler); - - if (!set_ip_config_common(self, config_dict, NULL)) - goto out; - - config = nm_ip6_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), priv->ifindex); - - memset(&addr, 0, sizeof(addr)); - addr.plen = 64; - - if (iid_value_to_ll6_addr(config_dict, NM_PPP_IP6_CONFIG_PEER_IID, &a, NULL)) { - const NMPlatformIP6Route r = { - .ifindex = priv->ifindex, - .rt_source = NM_IP_CONFIG_SOURCE_PPP, - .gateway = a, - .table_coerced = nm_platform_route_table_coerce(priv->ip6_route_table), - .metric = priv->ip6_route_metric, - }; - - nm_ip6_config_add_route(config, &r, NULL); - addr.peer_address = a; - has_peer = TRUE; - } - - if (iid_value_to_ll6_addr(config_dict, NM_PPP_IP6_CONFIG_OUR_IID, &addr.address, &iid)) { - if (!has_peer) - addr.peer_address = addr.address; - nm_ip6_config_add_address(config, &addr); - - /* Push the IPv6 config and interface identifier up to the device */ - g_signal_emit(self, signals[IP6_CONFIG], 0, &iid, config); - } else - _LOGE("invalid IPv6 address received!"); - -out: - g_dbus_method_invocation_return_value(invocation, NULL); -} - -/*****************************************************************************/ - -static NM_UTILS_LOOKUP_STR_DEFINE( - pppd_exit_code_to_str, - int, - NM_UTILS_LOOKUP_DEFAULT("Unknown error"), - NM_UTILS_LOOKUP_STR_ITEM(1, "Fatal pppd error"); - NM_UTILS_LOOKUP_STR_ITEM(2, "pppd options error"), - NM_UTILS_LOOKUP_STR_ITEM(3, "No root priv error"), - NM_UTILS_LOOKUP_STR_ITEM(4, "No ppp module error"), - NM_UTILS_LOOKUP_STR_ITEM(5, "pppd received a signal"), - NM_UTILS_LOOKUP_STR_ITEM(6, "Serial port lock failed"), - NM_UTILS_LOOKUP_STR_ITEM(7, "Serial port open failed"), - NM_UTILS_LOOKUP_STR_ITEM(8, "Connect script failed"), - NM_UTILS_LOOKUP_STR_ITEM(9, "Pty program error"), - NM_UTILS_LOOKUP_STR_ITEM(10, "PPP negotiation failed"), - NM_UTILS_LOOKUP_STR_ITEM(11, "Peer didn't authenticatie itself"), - NM_UTILS_LOOKUP_STR_ITEM(12, "Link idle: Idle Seconds reached."), - NM_UTILS_LOOKUP_STR_ITEM(13, "Connect time limit reached."), - NM_UTILS_LOOKUP_STR_ITEM(14, "Callback negotiated, call should come back."), - NM_UTILS_LOOKUP_STR_ITEM(15, "Lack of LCP echo responses"), - NM_UTILS_LOOKUP_STR_ITEM(16, "A modem hung up the phone"), - NM_UTILS_LOOKUP_STR_ITEM(17, "Loopback detected"), - NM_UTILS_LOOKUP_STR_ITEM(18, "The init script failed"), - NM_UTILS_LOOKUP_STR_ITEM(19, - "Authentication error. " - "We failed to authenticate ourselves to the peer. " - "Maybe bad account or password?"), ); - -static void -ppp_watch_cb(GPid pid, int status, gpointer user_data) -{ - NMPPPManager * self = NM_PPP_MANAGER(user_data); - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - int err; - const long long lpid = (long long) pid; - - g_return_if_fail(pid == priv->pid); - - if (WIFEXITED(status)) { - err = WEXITSTATUS(status); - if (err) { - _LOGW("pppd pid %lld exited with error %d: %s", lpid, err, pppd_exit_code_to_str(err)); - } else - _LOGD("pppd pid %lld exited with success", lpid); - } else if (WIFSTOPPED(status)) { - _LOGW("pppd pid %lld stopped unexpectedly with signal %d", lpid, WSTOPSIG(status)); - } else if (WIFSIGNALED(status)) { - _LOGW("pppd pid %lld died with signal %d", lpid, WTERMSIG(status)); - } else - _LOGW("pppd pid %lld died from an unknown cause", lpid); - - priv->pid = 0; - priv->ppp_watch_id = 0; - _ppp_cleanup(self); - g_signal_emit(self, signals[STATE_CHANGED], 0, (guint) NM_PPP_STATUS_DEAD); -} - -static gboolean -pppd_timed_out(gpointer data) -{ - NMPPPManager *self = NM_PPP_MANAGER(data); - - _LOGW("pppd timed out or didn't initialize our dbus module"); - _ppp_manager_stop(self, NULL, NULL, NULL); - - g_signal_emit(self, signals[STATE_CHANGED], 0, (guint) NM_PPP_STATUS_DEAD); - - return FALSE; -} - -static GPtrArray * -create_pppd_cmd_line(NMPPPManager * self, - NMSettingPpp * setting, - NMSettingPppoe *pppoe, - NMSettingAdsl * adsl, - const char * ppp_name, - guint baud_override, - gboolean ip4_enabled, - gboolean ip6_enabled, - GError ** err) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - const char * pppd_binary = NULL; - gs_unref_ptrarray GPtrArray *cmd = NULL; - gboolean ppp_debug; - - g_return_val_if_fail(setting != NULL, NULL); - -#ifndef PPPD_PATH - #define PPPD_PATH NULL -#endif - - pppd_binary = nm_utils_find_helper("pppd", PPPD_PATH, err); - if (!pppd_binary) - return NULL; - - if (!ip4_enabled && !ip6_enabled) { - g_set_error_literal(err, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_FAILED, - "Neither IPv4 or IPv6 allowed."); - return NULL; - } - - cmd = g_ptr_array_new_with_free_func(g_free); - - nm_strv_ptrarray_add_string_dup(cmd, pppd_binary); - - nm_strv_ptrarray_add_string_dup(cmd, "nodetach"); - nm_strv_ptrarray_add_string_dup(cmd, "lock"); - - /* NM handles setting the default route */ - nm_strv_ptrarray_add_string_dup(cmd, "nodefaultroute"); - - if (!ip4_enabled) - nm_strv_ptrarray_add_string_dup(cmd, "noip"); - - if (ip6_enabled) { - /* Allow IPv6 to be configured by IPV6CP */ - nm_strv_ptrarray_add_string_dup(cmd, "ipv6"); - nm_strv_ptrarray_add_string_dup(cmd, ","); - } else - nm_strv_ptrarray_add_string_dup(cmd, "noipv6"); - - ppp_debug = !!getenv("NM_PPP_DEBUG"); - if (nm_logging_enabled(LOGL_DEBUG, LOGD_PPP)) - ppp_debug = TRUE; - - if (ppp_debug) - nm_strv_ptrarray_add_string_dup(cmd, "debug"); - - if (ppp_name) { - nm_strv_ptrarray_add_string_dup(cmd, "user"); - nm_strv_ptrarray_add_string_dup(cmd, ppp_name); - } - - if (pppoe) { - const char *pppoe_service; - - nm_strv_ptrarray_add_string_dup(cmd, "plugin"); - nm_strv_ptrarray_add_string_dup(cmd, "rp-pppoe.so"); - - nm_strv_ptrarray_add_string_concat(cmd, "nic-", priv->parent_iface); - - pppoe_service = nm_setting_pppoe_get_service(pppoe); - if (pppoe_service) { - nm_strv_ptrarray_add_string_dup(cmd, "rp_pppoe_service"); - nm_strv_ptrarray_add_string_dup(cmd, pppoe_service); - } - } else if (adsl) { - const char *protocol = nm_setting_adsl_get_protocol(adsl); - - if (!strcmp(protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA)) { - guint32 vpi = nm_setting_adsl_get_vpi(adsl); - guint32 vci = nm_setting_adsl_get_vci(adsl); - const char *encaps = nm_setting_adsl_get_encapsulation(adsl); - - nm_strv_ptrarray_add_string_dup(cmd, "plugin"); - nm_strv_ptrarray_add_string_dup(cmd, "pppoatm.so"); - - nm_strv_ptrarray_add_string_printf(cmd, "%d.%d", vpi, vci); - - if (g_strcmp0(encaps, NM_SETTING_ADSL_ENCAPSULATION_LLC) == 0) - nm_strv_ptrarray_add_string_dup(cmd, "llc-encaps"); - else /*if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) == 0)*/ - nm_strv_ptrarray_add_string_dup(cmd, "vc-encaps"); - - } else if (!strcmp(protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) { - nm_strv_ptrarray_add_string_dup(cmd, "plugin"); - nm_strv_ptrarray_add_string_dup(cmd, "rp-pppoe.so"); - nm_strv_ptrarray_add_string_dup(cmd, priv->parent_iface); - } - - nm_strv_ptrarray_add_string_dup(cmd, "noipdefault"); - } else { - nm_strv_ptrarray_add_string_dup(cmd, priv->parent_iface); - /* Don't send some random address as the local address */ - nm_strv_ptrarray_add_string_dup(cmd, "noipdefault"); - } - - if (nm_setting_ppp_get_baud(setting)) - nm_strv_ptrarray_add_int(cmd, nm_setting_ppp_get_baud(setting)); - else if (baud_override) - nm_strv_ptrarray_add_int(cmd, baud_override); - - /* noauth by default, because we certainly don't have any information - * with which to verify anything the peer gives us if we ask it to - * authenticate itself, which is what 'auth' really means. - */ - nm_strv_ptrarray_add_string_dup(cmd, "noauth"); - - if (nm_setting_ppp_get_refuse_eap(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "refuse-eap"); - if (nm_setting_ppp_get_refuse_pap(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "refuse-pap"); - if (nm_setting_ppp_get_refuse_chap(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "refuse-chap"); - if (nm_setting_ppp_get_refuse_mschap(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "refuse-mschap"); - if (nm_setting_ppp_get_refuse_mschapv2(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "refuse-mschap-v2"); - if (nm_setting_ppp_get_nobsdcomp(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "nobsdcomp"); - if (nm_setting_ppp_get_no_vj_comp(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "novj"); - if (nm_setting_ppp_get_nodeflate(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "nodeflate"); - if (nm_setting_ppp_get_require_mppe(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "require-mppe"); - if (nm_setting_ppp_get_require_mppe_128(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "require-mppe-128"); - if (nm_setting_ppp_get_mppe_stateful(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "mppe-stateful"); - if (nm_setting_ppp_get_crtscts(setting)) - nm_strv_ptrarray_add_string_dup(cmd, "crtscts"); - - /* Always ask for DNS, we don't have to use them if the connection - * overrides the returned servers. - */ - nm_strv_ptrarray_add_string_dup(cmd, "usepeerdns"); - - if (nm_setting_ppp_get_mru(setting)) { - nm_strv_ptrarray_add_string_dup(cmd, "mru"); - nm_strv_ptrarray_add_int(cmd, nm_setting_ppp_get_mru(setting)); - } - - if (nm_setting_ppp_get_mtu(setting)) { - nm_strv_ptrarray_add_string_dup(cmd, "mtu"); - nm_strv_ptrarray_add_int(cmd, nm_setting_ppp_get_mtu(setting)); - } - - nm_strv_ptrarray_add_string_dup(cmd, "lcp-echo-failure"); - nm_strv_ptrarray_add_int(cmd, nm_setting_ppp_get_lcp_echo_failure(setting)); - - nm_strv_ptrarray_add_string_dup(cmd, "lcp-echo-interval"); - nm_strv_ptrarray_add_int(cmd, nm_setting_ppp_get_lcp_echo_interval(setting)); - - /* Avoid pppd to exit if no traffic going through */ - nm_strv_ptrarray_add_string_dup(cmd, "idle"); - nm_strv_ptrarray_add_string_dup(cmd, "0"); - - nm_strv_ptrarray_add_string_dup(cmd, "ipparam"); - nm_strv_ptrarray_add_string_dup(cmd, nm_dbus_object_get_path(NM_DBUS_OBJECT(self))); - - nm_strv_ptrarray_add_string_dup(cmd, "plugin"); - nm_strv_ptrarray_add_string_dup(cmd, NM_PPPD_PLUGIN); - - if (pppoe && nm_setting_pppoe_get_parent(pppoe)) { - static int unit; - - /* The PPP interface is going to be renamed, so pass a - * different unit each time so that activations don't - * race with each others. */ - nm_strv_ptrarray_add_string_dup(cmd, "unit"); - nm_strv_ptrarray_add_int(cmd, unit); - unit = unit < G_MAXINT ? unit + 1 : 0; - } - - g_ptr_array_add(cmd, NULL); - return g_steal_pointer(&cmd); -} - -static void -pppoe_fill_defaults(NMSettingPpp *setting) -{ - if (!nm_setting_ppp_get_mtu(setting)) - g_object_set(setting, NM_SETTING_PPP_MTU, (guint32) 1492, NULL); - - if (!nm_setting_ppp_get_mru(setting)) - g_object_set(setting, NM_SETTING_PPP_MRU, (guint32) 1492, NULL); - - g_object_set(setting, NM_SETTING_PPP_NOAUTH, TRUE, NM_SETTING_PPP_NODEFLATE, TRUE, NULL); - - /* FIXME: These commented settings should be set as well, update NMSettingPpp first. */ -#if 0 - setting->noipdefault = TRUE; - setting->default_asyncmap = TRUE; - setting->defaultroute = TRUE; - setting->hide_password = TRUE; - setting->noaccomp = TRUE; - setting->nopcomp = TRUE; - setting->novj = TRUE; - setting->novjccomp = TRUE; -#endif -} - -static gboolean -_ppp_manager_start(NMPPPManager *self, - NMActRequest *req, - const char * ppp_name, - guint32 timeout_secs, - guint baud_override, - GError ** err) -{ - NMPPPManagerPrivate *priv; - NMConnection * connection; - NMSettingPpp * s_ppp; - gs_unref_object NMSettingPpp *s_ppp_free = NULL; - NMSettingPppoe * pppoe_setting; - NMSettingAdsl * adsl_setting; - gs_unref_ptrarray GPtrArray *ppp_cmd = NULL; - gs_free char * cmd_str = NULL; - struct stat st; - const char * ip6_method, *ip4_method; - gboolean ip6_enabled = FALSE; - gboolean ip4_enabled = FALSE; - - g_return_val_if_fail(NM_IS_PPP_MANAGER(self), FALSE); - g_return_val_if_fail(NM_IS_ACT_REQUEST(req), FALSE); - - priv = NM_PPP_MANAGER_GET_PRIVATE(self); - -#if !WITH_PPP - /* PPP support disabled */ - g_set_error_literal(err, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_FAILED, - "PPP support is not enabled."); - return FALSE; -#endif - - nm_dbus_object_export(NM_DBUS_OBJECT(self)); - - priv->pid = 0; - - /* Make sure /dev/ppp exists (bgo #533064) */ - if (stat("/dev/ppp", &st) || !S_ISCHR(st.st_mode)) - nm_utils_modprobe(NULL, FALSE, "ppp_generic", NULL); - - connection = nm_act_request_get_applied_connection(req); - g_return_val_if_fail(connection, FALSE); - - s_ppp = nm_connection_get_setting_ppp(connection); - if (!s_ppp) { - /* If the PPP settings are all default we may not have a PPP setting yet, - * so just make a default one here. - */ - s_ppp = s_ppp_free = NM_SETTING_PPP(nm_setting_ppp_new()); - } - - pppoe_setting = nm_connection_get_setting_pppoe(connection); - if (pppoe_setting) { - /* We can't modify the applied connection's setting, make a copy */ - if (!s_ppp_free) - s_ppp = s_ppp_free = NM_SETTING_PPP(nm_setting_duplicate((NMSetting *) s_ppp)); - pppoe_fill_defaults(s_ppp); - } - - adsl_setting = (NMSettingAdsl *) nm_connection_get_setting(connection, NM_TYPE_SETTING_ADSL); - - /* Figure out what address methods should be enabled */ - ip4_method = nm_utils_get_ip_config_method(connection, AF_INET); - ip4_enabled = nm_streq(ip4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - ip6_method = nm_utils_get_ip_config_method(connection, AF_INET6); - ip6_enabled = nm_streq(ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - - ppp_cmd = create_pppd_cmd_line(self, - s_ppp, - pppoe_setting, - adsl_setting, - ppp_name, - baud_override, - ip4_enabled, - ip6_enabled, - err); - if (!ppp_cmd) - goto fail; - - _LOGI("starting PPP connection"); - - _LOGD("command line: %s", (cmd_str = g_strjoinv(" ", (char **) ppp_cmd->pdata))); - - priv->pid = 0; - if (!g_spawn_async(NULL, - (char **) ppp_cmd->pdata, - NULL, - G_SPAWN_DO_NOT_REAP_CHILD, - nm_utils_setpgid, - NULL, - &priv->pid, - err)) - goto fail; - - nm_assert(priv->pid > 0); - - _LOGI("pppd started with pid %lld", (long long) priv->pid); - - priv->ppp_watch_id = g_child_watch_add(priv->pid, (GChildWatchFunc) ppp_watch_cb, self); - priv->ppp_timeout_handler = g_timeout_add_seconds(timeout_secs, pppd_timed_out, self); - priv->act_req = g_object_ref(req); - - return TRUE; -fail: - nm_dbus_object_unexport(NM_DBUS_OBJECT(self)); - return FALSE; -} - -static void -_ppp_cleanup(NMPPPManager *self) -{ - NMPPPManagerPrivate *priv; - - g_return_if_fail(NM_IS_PPP_MANAGER(self)); - - priv = NM_PPP_MANAGER_GET_PRIVATE(self); - - cancel_get_secrets(self); - - nm_clear_g_source(&priv->monitor_id); - - if (priv->monitor_fd >= 0) { - /* Get the stats one last time */ - monitor_cb(self); - nm_close(priv->monitor_fd); - priv->monitor_fd = -1; - } - - nm_clear_g_source(&priv->ppp_timeout_handler); - nm_clear_g_source(&priv->ppp_watch_id); -} - -/*****************************************************************************/ - -struct _NMPPPManagerStopHandle { - NMPPPManager * self; - NMPPPManagerStopCallback callback; - gpointer user_data; - - /* this object delays shutdown, because we still need to wait until - * pppd process terminated. */ - GObject *shutdown_waitobj; - - GCancellable *cancellable; - - gulong cancellable_id; - - guint idle_id; -}; - -static void -_stop_handle_complete(NMPPPManagerStopHandle *handle, gboolean was_cancelled) -{ - gs_unref_object NMPPPManager *self = NULL; - NMPPPManagerStopCallback callback; - - if (handle->cancellable_id) { - g_cancellable_disconnect(handle->cancellable, nm_steal_int(&handle->cancellable_id)); - } - - g_clear_object(&handle->cancellable); - - self = g_steal_pointer(&handle->self); - if (!self) - return; - - if (!handle->callback) - return; - - callback = handle->callback; - handle->callback = NULL; - callback(self, handle, was_cancelled, handle->user_data); -} - -static void -_stop_handle_destroy(NMPPPManagerStopHandle *handle, gboolean was_cancelled) -{ - _stop_handle_complete(handle, was_cancelled); - nm_clear_g_source(&handle->idle_id); - g_clear_object(&handle->shutdown_waitobj); - g_slice_free(NMPPPManagerStopHandle, handle); -} - -static void -_stop_child_cb(pid_t pid, gboolean success, int child_status, gpointer user_data) -{ - _stop_handle_destroy(user_data, FALSE); -} - -static gboolean -_stop_idle_cb(gpointer user_data) -{ - NMPPPManagerStopHandle *handle = user_data; - - handle->idle_id = 0; - _stop_handle_destroy(handle, FALSE); - return G_SOURCE_REMOVE; -} - -static void -_stop_cancelled_cb(GCancellable *cancellable, gpointer user_data) -{ - NMPPPManagerStopHandle *handle = user_data; - - nm_clear_g_signal_handler(handle->cancellable, &handle->cancellable_id); - _ppp_manager_stop_cancel(handle); -} - -static NMPPPManagerStopHandle * -_ppp_manager_stop(NMPPPManager * self, - GCancellable * cancellable, - NMPPPManagerStopCallback callback, - gpointer user_data) -{ - NMPPPManagerPrivate * priv = NM_PPP_MANAGER_GET_PRIVATE(self); - NMDBusObject * dbus = NM_DBUS_OBJECT(self); - NMPPPManagerStopHandle *handle; - - if (nm_dbus_object_is_exported(dbus)) - nm_dbus_object_unexport(dbus); - - _ppp_cleanup(self); - - if (!priv->pid && !callback) { - /* nothing to do further... - * - * In this case, we return a %NULL handle. The caller cannot cancel this - * event, but clearly he is not waiting for a callback anyway. */ - return NULL; - } - - handle = g_slice_new0(NMPPPManagerStopHandle); - handle->self = g_object_ref(self); - handle->callback = callback; - handle->user_data = user_data; - if (cancellable) { - handle->cancellable = g_object_ref(cancellable); - handle->cancellable_id = - g_cancellable_connect(cancellable, G_CALLBACK(_stop_cancelled_cb), handle, NULL); - } - - if (!priv->pid) { - /* No PID. There is nothing to kill, however, invoke the callback in - * an idle handler. - * - * Note that we don't register nm_shutdown_wait_obj_register_object(). - * In order for shutdown to work properly, the caller must always - * explicitly cancel the action to go down. With the idle-handler, - * cancelling the handle completes the request. */ - handle->idle_id = g_idle_add(_stop_idle_cb, handle); - return handle; - } - - /* we really want to kill the process and delay shutdown of NetworkManager - * until the process terminated. We do that, by registering an object - * that delays shutdown. */ - handle->shutdown_waitobj = g_object_new(G_TYPE_OBJECT, NULL); - nm_shutdown_wait_obj_register_object(handle->shutdown_waitobj, "ppp-manager-wait-kill-pppd"); - nm_utils_kill_child_async(nm_steal_int(&priv->pid), - SIGTERM, - LOGD_PPP, - "pppd", - NM_SHUTDOWN_TIMEOUT_MS, - _stop_child_cb, - handle); - - return handle; -} - -/*****************************************************************************/ - -static void -_ppp_manager_stop_cancel(NMPPPManagerStopHandle *handle) -{ - g_return_if_fail(handle); - g_return_if_fail(NM_IS_PPP_MANAGER(handle->self)); - - if (handle->idle_id) { - /* we can complete this fake handle right away. */ - _stop_handle_destroy(handle, TRUE); - return; - } - - /* a real handle. Only invoke the callback (synchronously). This marks - * the handle as handled, but it keeps shutdown_waitobj around, until - * nm_utils_kill_child_async() returns. */ - _stop_handle_complete(handle, TRUE); -} - -/*****************************************************************************/ - -static void -get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(object); - - switch (prop_id) { - case PROP_PARENT_IFACE: - g_value_set_string(value, priv->parent_iface); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(object); - - switch (prop_id) { - case PROP_PARENT_IFACE: - /* construct-only */ - priv->parent_iface = g_value_dup_string(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -/*****************************************************************************/ - -static void -nm_ppp_manager_init(NMPPPManager *self) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - - priv->ifindex = -1; - priv->monitor_fd = -1; - priv->ip4_route_table = RT_TABLE_MAIN; - priv->ip4_route_metric = 460; - priv->ip6_route_table = RT_TABLE_MAIN; - priv->ip6_route_metric = 460; -} - -static NMPPPManager * -_ppp_manager_new(const char *iface) -{ - g_return_val_if_fail(iface != NULL, NULL); - - return ( - NMPPPManager *) g_object_new(NM_TYPE_PPP_MANAGER, NM_PPP_MANAGER_PARENT_IFACE, iface, NULL); -} - -static void -dispose(GObject *object) -{ - NMPPPManager * self = (NMPPPManager *) object; - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(self); - - /* we expect the user to first stop the manager. As fallback, - * still stop. */ - g_warn_if_fail(!priv->pid); - g_warn_if_fail(!nm_dbus_object_is_exported(NM_DBUS_OBJECT(self))); - _ppp_manager_stop(self, NULL, NULL, NULL); - - g_clear_object(&priv->act_req); - - G_OBJECT_CLASS(nm_ppp_manager_parent_class)->dispose(object); -} - -static void -finalize(GObject *object) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE(object); - - g_free(priv->parent_iface); - - G_OBJECT_CLASS(nm_ppp_manager_parent_class)->finalize(object); -} - -static const NMDBusInterfaceInfoExtended interface_info_ppp = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( - NM_DBUS_INTERFACE_PPP, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS( - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( - NM_DEFINE_GDBUS_METHOD_INFO_INIT( - "NeedSecrets", - .out_args = - NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("username", "s"), - NM_DEFINE_GDBUS_ARG_INFO("password", "s"), ), ), - .handle = impl_ppp_manager_need_secrets, ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( - NM_DEFINE_GDBUS_METHOD_INFO_INIT( - "SetIp4Config", - .in_args = - NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("config", "a{sv}"), ), ), - .handle = impl_ppp_manager_set_ip4_config, ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( - NM_DEFINE_GDBUS_METHOD_INFO_INIT( - "SetIp6Config", - .in_args = - NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("config", "a{sv}"), ), ), - .handle = impl_ppp_manager_set_ip6_config, ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( - NM_DEFINE_GDBUS_METHOD_INFO_INIT("SetState", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS( - NM_DEFINE_GDBUS_ARG_INFO("state", "u"), ), ), - .handle = impl_ppp_manager_set_state, ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( - NM_DEFINE_GDBUS_METHOD_INFO_INIT("SetIfindex", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS( - NM_DEFINE_GDBUS_ARG_INFO("ifindex", "i"), ), ), - .handle = impl_ppp_manager_set_ifindex, ), ), ), -}; - -static void -nm_ppp_manager_class_init(NMPPPManagerClass *manager_class) -{ - GObjectClass * object_class = G_OBJECT_CLASS(manager_class); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(manager_class); - - object_class->dispose = dispose; - object_class->finalize = finalize; - object_class->get_property = get_property; - object_class->set_property = set_property; - - dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/PPP"); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_ppp); - - obj_properties[PROP_PARENT_IFACE] = - g_param_spec_string(NM_PPP_MANAGER_PARENT_IFACE, - "", - "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[STATE_CHANGED] = g_signal_new(NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_UINT); - - signals[IFINDEX_SET] = g_signal_new(NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 2, - G_TYPE_INT, - G_TYPE_STRING); - - signals[IP4_CONFIG] = g_signal_new(NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_OBJECT); - - signals[IP6_CONFIG] = g_signal_new(NM_PPP_MANAGER_SIGNAL_IP6_CONFIG, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 2, - G_TYPE_POINTER, - G_TYPE_OBJECT); - - signals[STATS] = g_signal_new(NM_PPP_MANAGER_SIGNAL_STATS, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 2, - G_TYPE_UINT /*guint32 in_bytes*/, - G_TYPE_UINT /*guint32 out_bytes*/); -} - -NMPPPOps ppp_ops = { - .create = _ppp_manager_new, - .set_route_parameters = _ppp_manager_set_route_parameters, - .start = _ppp_manager_start, - .stop = _ppp_manager_stop, - .stop_cancel = _ppp_manager_stop_cancel, -}; |