diff options
| author | Michael Biebl <biebl@debian.org> | 2011-05-27 19:57:25 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2011-05-27 19:57:25 +0200 |
| commit | d465e5fac63f36bcf4069e36827f4b62c494556d (patch) | |
| tree | 65f4ba9567e091233cdf3279f7ba3c9479e74a1c /src | |
| parent | 9f806e97a24bba61417ae312fcc0da40914266fb (diff) | |
Imported Upstream version 0.8.9997 upstream/0.8.9997
Diffstat (limited to 'src')
39 files changed, 707 insertions, 436 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index d069eca7..5a6a61b6 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -391,6 +391,38 @@ dump_object_to_props (GObject *object, GHashTable *hash) } static void +dump_dhcp4_to_props (NMDHCP4Config *config, GHashTable *hash) +{ + GSList *options, *iter; + + options = nm_dhcp4_config_list_options (config); + for (iter = options; iter; iter = g_slist_next (iter)) { + const char *option = (const char *) iter->data; + const char *val; + + val = nm_dhcp4_config_get_option (config, option); + value_hash_add_str (hash, option, val); + } + g_slist_free (options); +} + +static void +dump_dhcp6_to_props (NMDHCP6Config *config, GHashTable *hash) +{ + GSList *options, *iter; + + options = nm_dhcp6_config_list_options (config); + for (iter = options; iter; iter = g_slist_next (iter)) { + const char *option = (const char *) iter->data; + const char *val; + + val = nm_dhcp6_config_get_option (config, option); + value_hash_add_str (hash, option, val); + } + g_slist_free (options); +} + +static void fill_device_props (NMDevice *device, GHashTable *dev_hash, GHashTable *ip4_hash, @@ -420,11 +452,11 @@ fill_device_props (NMDevice *device, dhcp4_config = nm_device_get_dhcp4_config (device); if (dhcp4_config) - dump_object_to_props (G_OBJECT (dhcp4_config), dhcp4_hash); + dump_dhcp4_to_props (dhcp4_config, dhcp4_hash); dhcp6_config = nm_device_get_dhcp6_config (device); if (dhcp6_config) - dump_object_to_props (G_OBJECT (dhcp6_config), dhcp6_hash); + dump_dhcp6_to_props (dhcp6_config, dhcp6_hash); } static void diff --git a/src/backends/Makefile.am b/src/backends/Makefile.am index fbec9aaf..c0780d0b 100644 --- a/src/backends/Makefile.am +++ b/src/backends/Makefile.am @@ -63,10 +63,12 @@ endif libnmbackend_la_LIBADD += \ $(top_builddir)/src/logging/libnm-logging.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) libnmbackend_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED \ diff --git a/src/backends/Makefile.in b/src/backends/Makefile.in index a9ea3e80..2f489e75 100644 --- a/src/backends/Makefile.in +++ b/src/backends/Makefile.in @@ -71,7 +71,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libnmbackend_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(top_builddir)/src/logging/libnm-logging.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am__libnmbackend_la_SOURCES_DIST = NetworkManagerGeneric.c \ NetworkManagerGeneric.h NetworkManagerRedHat.c \ NetworkManagerSuSE.c NetworkManagerGentoo.c \ @@ -362,9 +363,10 @@ libnmbackend_la_SOURCES = NetworkManagerGeneric.c \ $(am__append_10) $(am__append_11) $(am__append_12) \ $(am__append_13) libnmbackend_la_LIBADD = $(am__append_9) \ - $(top_builddir)/src/logging/libnm-logging.la $(DBUS_LIBS) \ - $(GLIB_LIBS) + $(top_builddir)/src/logging/libnm-logging.la $(LIBNL_LIBS) \ + $(DBUS_LIBS) $(GLIB_LIBS) libnmbackend_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED \ diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index cc5255ab..caf90f11 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -14,7 +14,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #include <config.h> @@ -166,8 +166,19 @@ nm_dhcp_dhclient_create_config (const char *interface, } if (hostname) { - g_string_append_printf (new_contents, HOSTNAME_FORMAT "\n", hostname); + char *plain_hostname, *dot; + + plain_hostname = g_strdup (hostname); + dot = strchr (plain_hostname, '.'); + + /* get rid of the domain */ + if (dot) + *dot = '\0'; + + g_string_append_printf (new_contents, HOSTNAME_FORMAT "\n", plain_hostname); added = TRUE; + + g_free (plain_hostname); } if (added) diff --git a/src/dns-manager/Makefile.am b/src/dns-manager/Makefile.am index 7b5fc4f8..b51f667b 100644 --- a/src/dns-manager/Makefile.am +++ b/src/dns-manager/Makefile.am @@ -19,12 +19,14 @@ libdns_manager_la_SOURCES = \ nm-dns-utils.c libdns_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DLOCALSTATEDIR=\"$(localstatedir)\" libdns_manager_la_LIBADD = \ $(top_builddir)/src/logging/libnm-logging.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/dns-manager/Makefile.in b/src/dns-manager/Makefile.in index 4937a601..aad1c562 100644 --- a/src/dns-manager/Makefile.in +++ b/src/dns-manager/Makefile.in @@ -58,7 +58,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libdns_manager_la_DEPENDENCIES = \ $(top_builddir)/src/logging/libnm-logging.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libdns_manager_la_OBJECTS = libdns_manager_la-nm-dns-manager.lo \ libdns_manager_la-nm-dns-plugin.lo \ libdns_manager_la-nm-dns-dnsmasq.lo \ @@ -325,12 +326,14 @@ libdns_manager_la_SOURCES = \ nm-dns-utils.c libdns_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DLOCALSTATEDIR=\"$(localstatedir)\" libdns_manager_la_LIBADD = \ $(top_builddir)/src/logging/libnm-logging.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/ip6-manager/Makefile.am b/src/ip6-manager/Makefile.am index b56b197e..b98d6def 100644 --- a/src/ip6-manager/Makefile.am +++ b/src/ip6-manager/Makefile.am @@ -13,6 +13,7 @@ libip6_manager_la_SOURCES = \ nm-ip6-manager.h libip6_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED @@ -20,6 +21,7 @@ libip6_manager_la_CPPFLAGS = \ libip6_manager_la_LIBADD = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/ip6-manager/Makefile.in b/src/ip6-manager/Makefile.in index 344ca0ea..33539f51 100644 --- a/src/ip6-manager/Makefile.in +++ b/src/ip6-manager/Makefile.in @@ -59,7 +59,8 @@ am__DEPENDENCIES_1 = libip6_manager_la_DEPENDENCIES = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libip6_manager_la_OBJECTS = libip6_manager_la-nm-ip6-manager.lo libip6_manager_la_OBJECTS = $(am_libip6_manager_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) @@ -316,6 +317,7 @@ libip6_manager_la_SOURCES = \ nm-ip6-manager.h libip6_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED @@ -323,6 +325,7 @@ libip6_manager_la_CPPFLAGS = \ libip6_manager_la_LIBADD = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c index 1e289d37..d8353f27 100644 --- a/src/logging/nm-logging.c +++ b/src/logging/nm-logging.c @@ -218,6 +218,12 @@ nm_logging_level_enabled (guint32 level) return !!(log_level & level); } +gboolean +nm_logging_domain_enabled (guint32 domain) +{ + return !!(log_domains & domain); +} + void _nm_log (const char *loc, const char *func, diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h index 44e49a71..e3e05f59 100644 --- a/src/logging/nm-logging.h +++ b/src/logging/nm-logging.h @@ -95,6 +95,7 @@ void _nm_log (const char *loc, const char *nm_logging_level_to_string (void); char *nm_logging_domains_to_string (void); gboolean nm_logging_level_enabled (guint32 level); +gboolean nm_logging_domain_enabled (guint32 domain); /* Undefine the nm-utils.h logging stuff to ensure errors */ #undef nm_print_backtrace diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am index db680aea..3c3af16c 100644 --- a/src/modem-manager/Makefile.am +++ b/src/modem-manager/Makefile.am @@ -19,10 +19,12 @@ libmodem_manager_la_SOURCES = \ nm-modem-types.h libmodem_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) libmodem_manager_la_LIBADD = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) diff --git a/src/modem-manager/Makefile.in b/src/modem-manager/Makefile.in index 66f7c1bc..2a054f70 100644 --- a/src/modem-manager/Makefile.in +++ b/src/modem-manager/Makefile.in @@ -59,7 +59,7 @@ am__DEPENDENCIES_1 = libmodem_manager_la_DEPENDENCIES = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ - $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libmodem_manager_la_OBJECTS = libmodem_manager_la-nm-modem.lo \ libmodem_manager_la-nm-modem-cdma.lo \ libmodem_manager_la-nm-modem-gsm.lo \ @@ -325,11 +325,13 @@ libmodem_manager_la_SOURCES = \ nm-modem-types.h libmodem_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) libmodem_manager_la_LIBADD = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) all: all-am diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index 6d2b8762..fb471f57 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -166,6 +166,14 @@ nm_device_interface_init (gpointer g_iface) g_object_interface_install_property (g_iface, + g_param_spec_boxed (NM_DEVICE_INTERFACE_ACTIVE_CONNECTION, + "ActiveConnection", + "ActiveConnection", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, g_param_spec_uint (NM_DEVICE_INTERFACE_DEVICE_TYPE, "DeviceType", "DeviceType", diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index f39e8459..560cdfe5 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -58,6 +58,7 @@ typedef enum #define NM_DEVICE_INTERFACE_IP6_CONFIG "ip6-config" #define NM_DEVICE_INTERFACE_DHCP6_CONFIG "dhcp6-config" #define NM_DEVICE_INTERFACE_STATE "state" +#define NM_DEVICE_INTERFACE_ACTIVE_CONNECTION "active-connection" #define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ #define NM_DEVICE_INTERFACE_MANAGED "managed" #define NM_DEVICE_INTERFACE_FIRMWARE_MISSING "firmware-missing" @@ -79,6 +80,7 @@ typedef enum { NM_DEVICE_INTERFACE_PROP_IP6_CONFIG, NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG, NM_DEVICE_INTERFACE_PROP_STATE, + NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION, NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, NM_DEVICE_INTERFACE_PROP_MANAGED, NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING, diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 9258f77c..7a6e7528 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -1460,6 +1460,26 @@ real_complete_connection (NMDevice *device, if (ap) { ssid = nm_ap_get_ssid (ap); + if (ssid == NULL) { + /* The AP must be hidden. Connecting to a WiFi AP requires the SSID + * as part of the initial handshake, so check the connection details + * for the SSID. The AP object will still be used for encryption + * settings and such. + */ + ssid = nm_setting_wireless_get_ssid (s_wifi); + } + + if (ssid == NULL) { + /* If there's no SSID on the AP itself, and no SSID in the + * connection data, then we cannot connect at all. Return an error. + */ + g_set_error_literal (error, + NM_WIFI_ERROR, + NM_WIFI_ERROR_CONNECTION_INVALID, + "A 'wireless' setting with a valid SSID is required for hidden access points."); + return FALSE; + } + /* If the SSID is a well-known SSID, lock the connection to the AP's * specific BSSID so NM doesn't autoconnect to some random wifi net. */ @@ -2851,7 +2871,7 @@ remove_supplicant_timeouts (NMDeviceWifi *self) } static guint32 -find_supported_frequency (NMDeviceWifi *self, guint32 *freqs) +find_supported_frequency (NMDeviceWifi *self, const guint32 *freqs) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); int i; @@ -2887,25 +2907,25 @@ build_supplicant_config (NMDeviceWifi *self, if (!config) return NULL; - /* Figure out the Ad-Hoc frequency to use if creating an adhoc network; if - * nothing was specified then pick something usable. + /* Supplicant requires an initial frequency for Ad-Hoc networks; if the user + * didn't specify one and we didn't find an AP that matched the connection, + * just pick a frequency the device supports. */ - if ((nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) && nm_ap_get_user_created (ap)) { + if (nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) { const char *band = nm_setting_wireless_get_band (s_wireless); + const guint32 a_freqs[] = { 5180, 5200, 5220, 5745, 5765, 5785, 5805, 0 }; + const guint32 bg_freqs[] = { 2412, 2437, 2462, 2472, 0 }; adhoc_freq = nm_ap_get_freq (ap); if (!adhoc_freq) { - if (band && !strcmp (band, "a")) { - guint32 a_freqs[] = {5180, 5200, 5220, 5745, 5765, 5785, 5805, 0}; + if (g_strcmp0 (band, "a") == 0) adhoc_freq = find_supported_frequency (self, a_freqs); - } else { - guint32 bg_freqs[] = {2412, 2437, 2462, 2472, 0}; + else adhoc_freq = find_supported_frequency (self, bg_freqs); - } } if (!adhoc_freq) { - if (band && !strcmp (band, "a")) + if (g_strcmp0 (band, "a") == 0) adhoc_freq = 5180; else adhoc_freq = 2462; @@ -3098,15 +3118,8 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) ap = nm_ap_new_fake_from_connection (connection); g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE); - switch (nm_ap_get_mode (ap)) { - case NM_802_11_MODE_ADHOC: - nm_ap_set_user_created (ap, TRUE); - break; - case NM_802_11_MODE_INFRA: - default: - nm_ap_set_broadcast (ap, FALSE); - break; - } + if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA) + nm_ap_set_broadcast (ap, FALSE); priv->ap_list = g_slist_prepend (priv->ap_list, ap); nm_ap_export_to_dbus (ap); @@ -3399,7 +3412,7 @@ activation_success_handler (NMDevice *dev) nm_ap_set_address (ap, &bssid); if (!nm_ap_get_freq (ap)) nm_ap_set_freq (ap, nm_device_wifi_get_frequency (self)); - if (!nm_ap_get_max_bitrate (ap) && nm_ap_get_user_created (ap)) + if (!nm_ap_get_max_bitrate (ap)) nm_ap_set_max_bitrate (ap, nm_device_wifi_get_bitrate (self)); tmp_ap = get_active_ap (self, ap, TRUE); diff --git a/src/nm-device.c b/src/nm-device.c index ebd8cdb9..4b7ec5df 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -3463,6 +3463,7 @@ get_property (GObject *object, guint prop_id, NMDevice *self = NM_DEVICE (object); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState state; + const char *ac_path = NULL; state = nm_device_get_state (self); @@ -3518,6 +3519,11 @@ get_property (GObject *object, guint prop_id, case NM_DEVICE_INTERFACE_PROP_STATE: g_value_set_uint (value, priv->state); break; + case NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION: + if (priv->act_request) + ac_path = nm_act_request_get_active_connection_path (priv->act_request); + g_value_set_boxed (value, ac_path ? ac_path : "/"); + break; case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE: g_value_set_uint (value, priv->type); break; @@ -3616,6 +3622,10 @@ nm_device_class_init (NMDeviceClass *klass) NM_DEVICE_INTERFACE_STATE); g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_ACTIVE_CONNECTION, + NM_DEVICE_INTERFACE_ACTIVE_CONNECTION); + + g_object_class_override_property (object_class, NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, NM_DEVICE_INTERFACE_DEVICE_TYPE); @@ -3809,7 +3819,7 @@ reason_to_string (NMDeviceStateReason reason) case NM_DEVICE_STATE_REASON_USER_REQUESTED: return "user-requested"; case NM_DEVICE_STATE_REASON_CARRIER: - return "carrier-chagned"; + return "carrier-changed"; case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: return "connection-assumed"; case NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: diff --git a/src/nm-dhcp4-config.c b/src/nm-dhcp4-config.c index 5acf053f..567ba687 100644 --- a/src/nm-dhcp4-config.c +++ b/src/nm-dhcp4-config.c @@ -101,6 +101,23 @@ nm_dhcp4_config_get_option (NMDHCP4Config *self, const char *key) return value ? g_value_get_string (value) : NULL; } +/* Caller owns the list, but not the values in the list */ +GSList * +nm_dhcp4_config_list_options (NMDHCP4Config *self) +{ + GHashTableIter iter; + const char *option = NULL; + GSList *list = NULL; + + g_return_val_if_fail (NM_IS_DHCP4_CONFIG (self), NULL); + + g_hash_table_iter_init (&iter, NM_DHCP4_CONFIG_GET_PRIVATE (self)->options); + while (g_hash_table_iter_next (&iter, (gpointer) &option, NULL)) + list = g_slist_prepend (list, (gpointer) option); + + return list; +} + const char * nm_dhcp4_config_get_dbus_path (NMDHCP4Config *self) { diff --git a/src/nm-dhcp4-config.h b/src/nm-dhcp4-config.h index ffaa8430..4729da4c 100644 --- a/src/nm-dhcp4-config.h +++ b/src/nm-dhcp4-config.h @@ -58,4 +58,6 @@ void nm_dhcp4_config_reset (NMDHCP4Config *config); const char *nm_dhcp4_config_get_option (NMDHCP4Config *config, const char *option); +GSList *nm_dhcp4_config_list_options (NMDHCP4Config *config); + #endif /* NM_DHCP4_CONFIG_H */ diff --git a/src/nm-dhcp6-config.c b/src/nm-dhcp6-config.c index fb6ccce5..885e5f84 100644 --- a/src/nm-dhcp6-config.c +++ b/src/nm-dhcp6-config.c @@ -101,6 +101,23 @@ nm_dhcp6_config_get_option (NMDHCP6Config *self, const char *key) return value ? g_value_get_string (value) : NULL; } +/* Caller owns the list, but not the values in the list */ +GSList * +nm_dhcp6_config_list_options (NMDHCP6Config *self) +{ + GHashTableIter iter; + const char *option = NULL; + GSList *list = NULL; + + g_return_val_if_fail (NM_IS_DHCP6_CONFIG (self), NULL); + + g_hash_table_iter_init (&iter, NM_DHCP6_CONFIG_GET_PRIVATE (self)->options); + while (g_hash_table_iter_next (&iter, (gpointer) &option, NULL)) + list = g_slist_prepend (list, (gpointer) option); + + return list; +} + const char * nm_dhcp6_config_get_dbus_path (NMDHCP6Config *self) { diff --git a/src/nm-dhcp6-config.h b/src/nm-dhcp6-config.h index 90eb10ff..5e83b904 100644 --- a/src/nm-dhcp6-config.h +++ b/src/nm-dhcp6-config.h @@ -58,4 +58,6 @@ void nm_dhcp6_config_reset (NMDHCP6Config *config); const char *nm_dhcp6_config_get_option (NMDHCP6Config *config, const char *option); +GSList *nm_dhcp6_config_list_options (NMDHCP6Config *self); + #endif /* NM_DHCP6_CONFIG_H */ diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index 8515959e..9171663b 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -18,17 +18,25 @@ * Copyright (C) 2010 Red Hat, Inc. */ +#include <config.h> #include <string.h> #include <dbus/dbus-glib-lowlevel.h> +#include <gio/gio.h> -#include <nm-setting-connection.h> +#if WITH_POLKIT +#include <polkit/polkit.h> +#endif + +#include "nm-setting-connection.h" #include "nm-manager-auth.h" #include "nm-logging.h" #include "nm-dbus-manager.h" struct NMAuthChain { guint32 refcount; +#if WITH_POLKIT PolkitAuthority *authority; +#endif GSList *calls; GHashTable *data; @@ -37,7 +45,6 @@ struct NMAuthChain { GError *error; NMAuthChainResultFunc done_func; - NMAuthChainCallFunc call_func; gpointer user_data; }; @@ -45,8 +52,9 @@ typedef struct { NMAuthChain *chain; GCancellable *cancellable; char *permission; + guint idle_id; gboolean disposed; -} PolkitCall; +} AuthCall; typedef struct { gpointer data; @@ -64,20 +72,31 @@ free_data (gpointer data) g_free (tmp); } -static void -default_call_func (NMAuthChain *chain, - const char *permission, - GError *error, - NMAuthCallResult result, - gpointer user_data) +#if WITH_POLKIT +static PolkitAuthority * +pk_authority_get (void) { - if (!error) - nm_auth_chain_set_data (chain, permission, GUINT_TO_POINTER (result), NULL); + static PolkitAuthority *authority = NULL; + GError *error = NULL; + + if (authority == NULL) { + authority = polkit_authority_get_sync (NULL, &error); + if (authority == NULL) { + nm_log_err (LOGD_CORE, "Failed to initialize PolicyKit: (%d) %s", + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + return NULL; + } + } + + /* Yes, ref every time; we want to keep the object alive */ + return g_object_ref (authority); } +#endif static NMAuthChain * -_auth_chain_new (PolkitAuthority *authority, - DBusGMethodInvocation *context, +_auth_chain_new (DBusGMethodInvocation *context, DBusGProxy *proxy, DBusMessage *message, const char *dbus_sender, @@ -90,10 +109,11 @@ _auth_chain_new (PolkitAuthority *authority, self = g_malloc0 (sizeof (NMAuthChain)); self->refcount = 1; - self->authority = g_object_ref (authority); +#if WITH_POLKIT + self->authority = pk_authority_get (); +#endif self->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_data); self->done_func = done_func; - self->call_func = /* call_func ? call_func : */ default_call_func; self->user_data = user_data; self->context = context; @@ -117,31 +137,28 @@ _auth_chain_new (PolkitAuthority *authority, } NMAuthChain * -nm_auth_chain_new (PolkitAuthority *authority, - DBusGMethodInvocation *context, +nm_auth_chain_new (DBusGMethodInvocation *context, DBusGProxy *proxy, NMAuthChainResultFunc done_func, gpointer user_data) { - return _auth_chain_new (authority, context, proxy, NULL, NULL, done_func, user_data); + return _auth_chain_new (context, proxy, NULL, NULL, done_func, user_data); } NMAuthChain * -nm_auth_chain_new_raw_message (PolkitAuthority *authority, - DBusMessage *message, +nm_auth_chain_new_raw_message (DBusMessage *message, NMAuthChainResultFunc done_func, gpointer user_data) { - return _auth_chain_new (authority, NULL, NULL, message, NULL, done_func, user_data); + return _auth_chain_new (NULL, NULL, message, NULL, done_func, user_data); } NMAuthChain * -nm_auth_chain_new_dbus_sender (PolkitAuthority *authority, - const char *dbus_sender, +nm_auth_chain_new_dbus_sender (const char *dbus_sender, NMAuthChainResultFunc done_func, gpointer user_data) { - return _auth_chain_new (authority, NULL, NULL, NULL, dbus_sender, done_func, user_data); + return _auth_chain_new (NULL, NULL, NULL, dbus_sender, done_func, user_data); } gpointer @@ -229,14 +246,36 @@ nm_auth_chain_check_done (NMAuthChain *self) } static void -polkit_call_cancel (PolkitCall *call) +nm_auth_chain_remove_call (NMAuthChain *self, AuthCall *call) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (call != NULL); + + self->calls = g_slist_remove (self->calls, call); +} + +static AuthCall * +auth_call_new (NMAuthChain *chain, const char *permission) +{ + AuthCall *call; + + call = g_malloc0 (sizeof (AuthCall)); + call->chain = chain; + call->permission = g_strdup (permission); + call->cancellable = g_cancellable_new (); + chain->calls = g_slist_append (chain->calls, call); + return call; +} + +static void +auth_call_cancel (AuthCall *call) { call->disposed = TRUE; g_cancellable_cancel (call->cancellable); } static void -polkit_call_free (PolkitCall *call) +auth_call_free (AuthCall *call) { g_return_if_fail (call != NULL); @@ -246,30 +285,49 @@ polkit_call_free (PolkitCall *call) call->chain = NULL; g_object_unref (call->cancellable); call->cancellable = NULL; + if (call->idle_id) + g_source_remove (call->idle_id); + memset (call, 0, sizeof (*call)); g_free (call); } +/* This can get used from scheduled idles, hence the boolean return */ +static gboolean +auth_call_complete (AuthCall *call) +{ + g_return_val_if_fail (call != NULL, FALSE); + + call->idle_id = 0; + nm_auth_chain_remove_call (call->chain, call); + nm_auth_chain_check_done (call->chain); + auth_call_free (call); + return FALSE; +} + +static void +auth_call_schedule_early_finish (AuthCall *call, GError *error) +{ + if (!call->chain->error) + call->chain->error = error; + call->idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); +} + +#if WITH_POLKIT static void pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data) { - PolkitCall *call = user_data; - NMAuthChain *chain; + AuthCall *call = user_data; + NMAuthChain *chain = call->chain; PolkitAuthorizationResult *pk_result; GError *error = NULL; - guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN; /* If the call is already disposed do nothing */ if (call->disposed) { - polkit_call_free (call); + auth_call_free (call); return; } - chain = call->chain; - chain->calls = g_slist_remove (chain->calls, call); - - pk_result = polkit_authority_check_authorization_finish (chain->authority, - result, - &error); + pk_result = polkit_authority_check_authorization_finish (chain->authority, result, &error); if (error) { if (!chain->error) chain->error = g_error_copy (error); @@ -279,6 +337,8 @@ pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data) error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } else { + guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN; + if (polkit_authorization_result_get_is_authorized (pk_result)) { /* Caller has the permission */ call_result = NM_AUTH_CALL_RESULT_YES; @@ -287,23 +347,26 @@ pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data) call_result = NM_AUTH_CALL_RESULT_AUTH; } else call_result = NM_AUTH_CALL_RESULT_NO; - } - chain->call_func (chain, call->permission, error, call_result, chain->user_data); - nm_auth_chain_check_done (chain); + nm_auth_chain_set_data (chain, call->permission, GUINT_TO_POINTER (call_result), NULL); + } g_clear_error (&error); - polkit_call_free (call); if (pk_result) g_object_unref (pk_result); + + auth_call_complete (call); } +#endif gboolean nm_auth_chain_add_call (NMAuthChain *self, const char *permission, gboolean allow_interaction) { - PolkitCall *call; + AuthCall *call; + +#if WITH_POLKIT PolkitSubject *subject; PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; @@ -315,12 +378,14 @@ nm_auth_chain_add_call (NMAuthChain *self, if (!subject) return FALSE; - call = g_malloc0 (sizeof (PolkitCall)); - call->chain = self; - call->permission = g_strdup (permission); - call->cancellable = g_cancellable_new (); + call = auth_call_new (self, permission); - self->calls = g_slist_append (self->calls, call); + if (self->authority == NULL) { + /* No polkit, no authorization */ + auth_call_schedule_early_finish (call, g_error_new_literal (0, 0, "PolicyKit unavailable")); + g_object_unref (subject); + return FALSE; + } if (allow_interaction) flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION; @@ -334,6 +399,17 @@ nm_auth_chain_add_call (NMAuthChain *self, pk_call_cb, call); g_object_unref (subject); +#else + /* -- NO POLKIT -- */ + + g_return_val_if_fail (self != NULL, FALSE); + + /* When PolicyKit is disabled, everything is authorized */ + call = auth_call_new (self, permission); + nm_auth_chain_set_data (self, permission, GUINT_TO_POINTER (NM_AUTH_CALL_RESULT_YES), NULL); + auth_call_schedule_early_finish (call, NULL); +#endif + return TRUE; } @@ -348,11 +424,14 @@ nm_auth_chain_unref (NMAuthChain *self) if (self->refcount > 0) return; - g_object_unref (self->authority); +#if WITH_POLKIT + if (self->authority) + g_object_unref (self->authority); +#endif g_free (self->owner); for (iter = self->calls; iter; iter = g_slist_next (iter)) - polkit_call_cancel ((PolkitCall *) iter->data); + auth_call_cancel ((AuthCall *) iter->data); g_slist_free (self->calls); g_clear_error (&self->error); @@ -460,3 +539,50 @@ nm_auth_uid_in_acl (NMConnection *connection, return TRUE; } +typedef struct { + GDestroyNotify changed_callback; + gpointer changed_data; +} PkChangedInfo; + +#if WITH_POLKIT +static void +pk_authority_changed_cb (GObject *object, PkChangedInfo *info) +{ + info->changed_callback (info->changed_data); +} +#endif + +void +nm_auth_set_changed_func (GDestroyNotify callback, gpointer callback_data) +{ +#if WITH_POLKIT + static PkChangedInfo info = { NULL, NULL }; + static guint32 changed_id = 0; + PolkitAuthority *authority; + + authority = pk_authority_get (); + if (!authority) + return; + + if (callback == NULL) { + /* Clearing the callback */ + info.changed_callback = NULL; + info.changed_data = NULL; + g_signal_handler_disconnect (authority, changed_id); + changed_id = 0; + } else { + info.changed_callback = callback; + info.changed_data= callback_data; + + if (changed_id == 0) { + changed_id = g_signal_connect (authority, + "changed", + G_CALLBACK (pk_authority_changed_cb), + &info); + } + } + + g_object_unref (authority); +#endif +} + diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 7e7ff7a1..ad14d306 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -21,7 +21,6 @@ #ifndef NM_MANAGER_AUTH_H #define NM_MANAGER_AUTH_H -#include <polkit/polkit.h> #include <glib.h> #include <dbus/dbus-glib.h> @@ -56,25 +55,16 @@ typedef void (*NMAuthChainResultFunc) (NMAuthChain *chain, DBusGMethodInvocation *context, gpointer user_data); -typedef void (*NMAuthChainCallFunc) (NMAuthChain *chain, - const char *permission, - GError *error, - NMAuthCallResult result, - gpointer user_data); - -NMAuthChain *nm_auth_chain_new (PolkitAuthority *authority, - DBusGMethodInvocation *context, +NMAuthChain *nm_auth_chain_new (DBusGMethodInvocation *context, DBusGProxy *proxy, NMAuthChainResultFunc done_func, gpointer user_data); -NMAuthChain *nm_auth_chain_new_raw_message (PolkitAuthority *authority, - DBusMessage *message, +NMAuthChain *nm_auth_chain_new_raw_message (DBusMessage *message, NMAuthChainResultFunc done_func, gpointer user_data); -NMAuthChain *nm_auth_chain_new_dbus_sender (PolkitAuthority *authority, - const char *dbus_sender, +NMAuthChain *nm_auth_chain_new_dbus_sender (const char *dbus_sender, NMAuthChainResultFunc done_func, gpointer user_data); @@ -112,5 +102,7 @@ gboolean nm_auth_uid_in_acl (NMConnection *connection, gulong uid, char **out_error_desc); +void nm_auth_set_changed_func (GDestroyNotify callback, gpointer callback_data); + #endif /* NM_MANAGER_AUTH_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 568ff2ae..961c9d8c 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -28,6 +28,7 @@ #include <string.h> #include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib.h> +#include <gio/gio.h> #include <glib/gi18n.h> #include "nm-glib-compat.h" @@ -158,22 +159,6 @@ static GSList * remove_one_device (NMManager *manager, NMDevice *device, gboolean quitting); -static NMDevice *nm_manager_get_device_by_udi (NMManager *manager, const char *udi); - -/* Fix for polkit 0.97 and later */ -#if !HAVE_POLKIT_AUTHORITY_GET_SYNC -static inline PolkitAuthority * -polkit_authority_get_sync (GCancellable *cancellable, GError **error) -{ - PolkitAuthority *authority; - - authority = polkit_authority_get (); - if (!authority) - g_set_error (error, 0, 0, "failed to get the PolicyKit authority"); - return authority; -} -#endif - #define SSD_POKE_INTERVAL 120 #define ORIGDEV_TAG "originating-device" @@ -185,7 +170,6 @@ struct PendingActivation { NMManager *manager; DBusGMethodInvocation *context; - PolkitAuthority *authority; PendingActivationFunc callback; NMAuthChain *chain; @@ -237,8 +221,6 @@ typedef struct { DBusGProxy *aipd_proxy; DBusGProxy *upower_proxy; - PolkitAuthority *authority; - guint auth_changed_id; GSList *auth_chains; /* Firmware dir monitor */ @@ -679,7 +661,6 @@ try_complete_vpn (NMConnection *connection, GSList *existing, GError **error) static PendingActivation * pending_activation_new (NMManager *manager, - PolkitAuthority *authority, DBusGMethodInvocation *context, const char *device_path, const char *connection_path, @@ -696,7 +677,6 @@ pending_activation_new (NMManager *manager, gboolean success; g_return_val_if_fail (manager != NULL, NULL); - g_return_val_if_fail (authority != NULL, NULL); g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (device_path != NULL, NULL); @@ -744,7 +724,6 @@ pending_activation_new (NMManager *manager, pending = g_slice_new0 (PendingActivation); pending->manager = manager; - pending->authority = authority; pending->context = context; pending->callback = callback; @@ -767,31 +746,23 @@ pending_auth_net_done (NMAuthChain *chain, { PendingActivation *pending = user_data; NMAuthCallResult result; + GError *tmp_error = NULL; pending->chain = NULL; - if (error) { - pending->callback (pending, error); - goto out; - } - /* Caller has had a chance to obtain authorization, so we only need to * check for 'yes' here. */ result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL)); if (result != NM_AUTH_CALL_RESULT_YES) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Not authorized to control networking."); - pending->callback (pending, error); - g_error_free (error); - goto out; + tmp_error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Not authorized to control networking."); } - pending->callback (pending, NULL); - -out: + pending->callback (pending, tmp_error); nm_auth_chain_unref (chain); + g_clear_error (&tmp_error); } static void @@ -827,8 +798,7 @@ pending_activation_check_authorized (PendingActivation *pending, /* First check if the user is allowed to use networking at all, giving * the user a chance to authenticate to gain the permission. */ - pending->chain = nm_auth_chain_new (pending->authority, - pending->context, + pending->chain = nm_auth_chain_new (pending->context, NULL, pending_auth_net_done, pending); @@ -1110,7 +1080,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, struct ether_addr seen_addr; if (ether_aton_r (seen_bssid, &seen_addr)) { - if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr))) { + if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr)) == 0) { /* Copy the SSID from the connection to the AP */ nm_ap_set_ssid (ap, ssid); done = TRUE; @@ -1388,7 +1358,7 @@ manager_device_disconnect_request (NMDevice *device, NMAuthChain *chain; /* Otherwise validate the user request */ - chain = nm_auth_chain_new (priv->authority, context, NULL, disconnect_net_auth_done_cb, self); + chain = nm_auth_chain_new (context, NULL, disconnect_net_auth_done_cb, self); g_assert (chain); priv->auth_chains = g_slist_append (priv->auth_chains, chain); @@ -2103,7 +2073,6 @@ impl_manager_activate_connection (NMManager *self, * activate the connection. */ pending = pending_activation_new (self, - priv->authority, context, device_path, connection_path, @@ -2172,7 +2141,6 @@ impl_manager_add_and_activate_connection (NMManager *self, * activate the connection. */ pending = pending_activation_new (self, - priv->authority, context, device_path, NULL, @@ -2236,37 +2204,35 @@ done: static void deactivate_net_auth_done_cb (NMAuthChain *chain, - GError *error, + GError *auth_error, DBusGMethodInvocation *context, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *ret_error = NULL; + GError *error = NULL; NMAuthCallResult result; const char *active_path; priv->auth_chains = g_slist_remove (priv->auth_chains, chain); result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL)); - ret_error = deactivate_disconnect_check_error (error, result, "Deactivate"); - if (ret_error) { - dbus_g_method_return_error (context, ret_error); - g_error_free (ret_error); - goto done; + error = deactivate_disconnect_check_error (auth_error, result, "Deactivate"); + if (!error) { + active_path = nm_auth_chain_get_data (chain, "path"); + if (!nm_manager_deactivate_connection (self, + active_path, + NM_DEVICE_STATE_REASON_USER_REQUESTED, + &error)) + g_assert (error); } - active_path = nm_auth_chain_get_data (chain, "path"); - if (!nm_manager_deactivate_connection (self, - active_path, - NM_DEVICE_STATE_REASON_USER_REQUESTED, - &ret_error)) { - dbus_g_method_return_error (context, ret_error); - g_clear_error (&ret_error); - } else + if (error) + dbus_g_method_return_error (context, error); + else dbus_g_method_return (context); -done: + g_clear_error (&error); nm_auth_chain_unref (chain); } @@ -2342,7 +2308,7 @@ impl_manager_deactivate_connection (NMManager *self, } /* Otherwise validate the user request */ - chain = nm_auth_chain_new (priv->authority, context, NULL, deactivate_net_auth_done_cb, self); + chain = nm_auth_chain_new (context, NULL, deactivate_net_auth_done_cb, self); g_assert (chain); priv->auth_chains = g_slist_append (priv->auth_chains, chain); @@ -2415,25 +2381,6 @@ do_sleep_wake (NMManager *self) nm_manager_update_state (self); } -static gboolean -return_no_pk_error (PolkitAuthority *authority, - const char *detail, - DBusGMethodInvocation *context) -{ - GError *error; - - if (!authority) { - error = g_error_new (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "%s request failed: PolicyKit not initialized", - detail); - dbus_g_method_return_error (context, error); - g_error_free (error); - return FALSE; - } - return TRUE; -} - static void _internal_sleep (NMManager *self, gboolean do_sleep) { @@ -2550,10 +2497,7 @@ impl_manager_sleep (NMManager *self, return; } - if (!return_no_pk_error (priv->authority, "Sleep/wake", context)) - return; - - chain = nm_auth_chain_new (priv->authority, context, NULL, sleep_auth_done_cb, self); + chain = nm_auth_chain_new (context, NULL, sleep_auth_done_cb, self); g_assert (chain); priv->auth_chains = g_slist_append (priv->auth_chains, chain); @@ -2688,10 +2632,7 @@ impl_manager_enable (NMManager *self, return; } - if (!return_no_pk_error (priv->authority, "Enable/disable", context)) - return; - - chain = nm_auth_chain_new (priv->authority, context, NULL, enable_net_done_cb, self); + chain = nm_auth_chain_new (context, NULL, enable_net_done_cb, self); g_assert (chain); priv->auth_chains = g_slist_append (priv->auth_chains, chain); @@ -2702,13 +2643,6 @@ impl_manager_enable (NMManager *self, /* Permissions */ static void -pk_authority_changed_cb (GObject *object, gpointer user_data) -{ - /* Let clients know they should re-check their authorization */ - g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0); -} - -static void get_perm_add_result (NMAuthChain *chain, GHashTable *results, const char *permission) { NMAuthCallResult result; @@ -2772,10 +2706,7 @@ impl_manager_get_permissions (NMManager *self, NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; - if (!return_no_pk_error (priv->authority, "Permissions", context)) - return; - - chain = nm_auth_chain_new (priv->authority, context, NULL, get_permissions_done_cb, self); + chain = nm_auth_chain_new (context, NULL, get_permissions_done_cb, self); g_assert (chain); priv->auth_chains = g_slist_append (priv->auth_chains, chain); @@ -3059,7 +2990,7 @@ prop_filter (DBusConnection *connection, if (uid > 0) { /* Otherwise validate the user request */ - chain = nm_auth_chain_new_raw_message (priv->authority, message, prop_set_auth_done_cb, self); + chain = nm_auth_chain_new_raw_message (message, prop_set_auth_done_cb, self); g_assert (chain); priv->auth_chains = g_slist_append (priv->auth_chains, chain); nm_auth_chain_set_data (chain, "prop", g_strdup (glib_propname), g_free); @@ -3189,7 +3120,8 @@ dispose (GObject *object) g_slist_foreach (priv->auth_chains, (GFunc) nm_auth_chain_unref, NULL); g_slist_free (priv->auth_chains); - g_object_unref (priv->authority); + + nm_auth_set_changed_func (NULL, NULL); while (g_slist_length (priv->devices)) { priv->devices = remove_one_device (manager, @@ -3466,13 +3398,19 @@ periodic_update_active_connection_timestamps (gpointer user_data) } static void +authority_changed_cb (gpointer user_data) +{ + /* Let clients know they should re-check their authorization */ + g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0); +} + +static void nm_manager_init (NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); DBusGConnection *g_connection; guint id, i; GFile *file; - GError *error = NULL; /* Initialize rfkill structures and states */ memset (priv->radio_states, 0, sizeof (priv->radio_states)); @@ -3563,18 +3501,8 @@ nm_manager_init (NMManager *manager) } else nm_log_warn (LOGD_SUSPEND, "could not initialize UPower D-Bus proxy"); - priv->authority = polkit_authority_get_sync (NULL, &error); - if (priv->authority) { - priv->auth_changed_id = g_signal_connect (priv->authority, - "changed", - G_CALLBACK (pk_authority_changed_cb), - manager); - } else { - nm_log_warn (LOGD_CORE, "failed to create PolicyKit authority: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - } + /* Listen for authorization changes */ + nm_auth_set_changed_func (authority_changed_cb, manager); /* Monitor the firmware directory */ if (strlen (KERNEL_FIRMWARE_DIR)) { diff --git a/src/nm-policy.c b/src/nm-policy.c index 5c30828b..194d1111 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2010 Red Hat, Inc. + * Copyright (C) 2004 - 2011 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ @@ -817,22 +817,28 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) } static void +reset_retries_all (NMSettings *settings) +{ + GSList *connections, *iter; + + connections = nm_settings_get_connections (settings); + for (iter = connections; iter; iter = g_slist_next (iter)) + set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT); + g_slist_free (connections); +} + +static void sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) { NMPolicy *policy = user_data; gboolean sleeping = FALSE, enabled = FALSE; - GSList *connections, *iter; g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL); g_object_get (G_OBJECT (manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL); /* Reset retries on all connections so they'll checked on wakeup */ - if (sleeping || !enabled) { - connections = nm_settings_get_connections (policy->settings); - for (iter = connections; iter; iter = g_slist_next (iter)) - set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT); - g_slist_free (connections); - } + if (sleeping || !enabled) + reset_retries_all (policy->settings); } static void @@ -1045,9 +1051,15 @@ connection_added (NMSettings *settings, } static void -connections_loaded (NMSettings *settings, - gpointer user_data) +connections_loaded (NMSettings *settings, gpointer user_data) { + // FIXME: "connections-loaded" signal is emmitted *before* we connect to it + // in nm_policy_new(). So this function is never called. Currently we work around + // that by calling reset_retries_all() in nm_policy_new() + + /* Initialize connections' auto-retries */ + reset_retries_all (settings); + schedule_activate_all ((NMPolicy *) user_data); } @@ -1175,6 +1187,9 @@ nm_policy_new (NMManager *manager, _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, connection_visibility_changed); + /* Initialize connections' auto-retries */ + reset_retries_all (policy->settings); + initialized = TRUE; return policy; } diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index c163ee6a..7ee9013a 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -74,6 +74,7 @@ typedef enum { NM_SESSION_MONITOR_ERROR_IO_ERROR = 0, NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + NM_SESSION_MONITOR_ERROR_NO_DATABASE, } NMSessionMonitorError; GQuark @@ -101,6 +102,8 @@ nm_session_monitor_error_get_type (void) ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "MalformedDatabase"), /* Username or UID could could not be found */ ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "UnknownUser"), + /* No ConsoleKit database */ + ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_NO_DATABASE, "NoDatabase"), { 0, 0, 0 } }; @@ -226,10 +229,11 @@ reload_database (NMSessionMonitor *self, GError **error) free_database (self); + errno = 0; if (stat (CKDB_PATH, &statbuf) != 0) { g_set_error (error, NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_IO_ERROR, + errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, "Error statting file " CKDB_PATH ": %s", strerror (errno)); goto error; @@ -292,10 +296,11 @@ ensure_database (NMSessionMonitor *self, GError **error) if (self->database != NULL) { struct stat statbuf; + errno = 0; if (stat (CKDB_PATH, &statbuf) != 0) { g_set_error (error, NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_IO_ERROR, + errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, "Error statting file " CKDB_PATH " to check timestamp: %s", strerror (errno)); goto out; @@ -346,7 +351,12 @@ nm_session_monitor_init (NMSessionMonitor *self) error = NULL; if (!ensure_database (self, &error)) { - nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message); + /* Ignore the first error if the CK database isn't found yet */ + if (g_error_matches (error, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_NO_DATABASE) == FALSE) { + nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message); + } g_error_free (error); } diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index 41a4e15b..e0795e81 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -439,9 +439,13 @@ device_creator (NMUdevManager *manager, if (parent) { driver = g_udev_device_get_driver (parent); if (!driver) { - /* try the grandparent only if it's an ibmebus device */ + /* try the grandparent if it's an ibmebus device or if the + * subsys is NULL which usually indicates some sort of + * platform device like a 'gadget' net interface. + */ subsys = g_udev_device_get_subsystem (parent); - if (subsys && !strcmp (subsys, "ibmebus")) { + if ( (g_strcmp0 (subsys, "ibmebus") == 0) + || (subsys == NULL)) { grandparent = g_udev_device_get_parent (parent); if (grandparent) driver = g_udev_device_get_driver (grandparent); diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c index 6eab9581..f9c66473 100644 --- a/src/nm-wifi-ap.c +++ b/src/nm-wifi-ap.c @@ -58,12 +58,6 @@ typedef struct /* Non-scanned attributes */ gboolean fake; /* Whether or not the AP is from a scan */ gboolean broadcast; /* Whether or not the AP is broadcasting (hidden) */ - gboolean user_created; /* Whether or not the AP was created - * by the user with "Create network..." - * A subset of Ad-Hoc mode. user_created - * implies Ad-Hoc, but not necessarily - * the other way around. - */ glong last_seen; /* Last time the AP was seen in a scan in seconds */ /* Things from user prefs/NetworkManagerInfo */ @@ -863,9 +857,14 @@ nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid) } if (ssid) { - priv->ssid = g_byte_array_sized_new (ssid->len); - priv->ssid->len = ssid->len; - memcpy (priv->ssid->data, ssid->data, ssid->len); + /* Should never get zero-length SSIDs */ + g_warn_if_fail (ssid->len > 0); + + if (ssid->len) { + priv->ssid = g_byte_array_sized_new (ssid->len); + priv->ssid->len = ssid->len; + memcpy (priv->ssid->data, ssid->data, ssid->len); + } } g_object_notify (G_OBJECT (ap), NM_AP_SSID); @@ -1154,28 +1153,6 @@ void nm_ap_set_last_seen (NMAccessPoint *ap, const glong last_seen) /* - * Get/Set functions to indicate that an access point is - * user-created, ie whether or not its a network filled with - * information from the user and intended to create a new Ad-Hoc - * wireless network. - * - */ -gboolean nm_ap_get_user_created (const NMAccessPoint *ap) -{ - g_return_val_if_fail (NM_IS_AP (ap), FALSE); - - return NM_AP_GET_PRIVATE (ap)->user_created; -} - -void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created) -{ - g_return_if_fail (NM_IS_AP (ap)); - - NM_AP_GET_PRIVATE (ap)->user_created = user_created; -} - - -/* * Get/Set functions for user address list * * The internal address list is always "owned" by the AP and diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h index 4c98f248..95514ba6 100644 --- a/src/nm-wifi-ap.h +++ b/src/nm-wifi-ap.h @@ -104,9 +104,6 @@ void nm_ap_set_broadcast (NMAccessPoint *ap, gboolean broadcast); glong nm_ap_get_last_seen (const NMAccessPoint *ap); void nm_ap_set_last_seen (NMAccessPoint *ap, const glong last_seen); -gboolean nm_ap_get_user_created (const NMAccessPoint *ap); -void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created); - GSList * nm_ap_get_user_addresses (const NMAccessPoint *ap); void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list); diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 767b9315..e863aaba 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -798,7 +798,7 @@ create_pppd_cmd_line (NMPPPManager *self, NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); const char *ppp_binary; NMCmdLine *cmd; - const char *ppp_debug; + gboolean ppp_debug; g_return_val_if_fail (setting != NULL, NULL); @@ -819,7 +819,11 @@ create_pppd_cmd_line (NMPPPManager *self, /* NM handles setting the default route */ nm_cmd_line_add_string (cmd, "nodefaultroute"); - ppp_debug = getenv ("NM_PPP_DEBUG"); + ppp_debug = !!getenv ("NM_PPP_DEBUG"); + if ( nm_logging_level_enabled (LOGL_DEBUG) + && nm_logging_domain_enabled (LOGD_PPP)) + ppp_debug = TRUE; + if (ppp_debug) nm_cmd_line_add_string (cmd, "debug"); diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am index 55b5b7ef..21dc5bb0 100644 --- a/src/settings/Makefile.am +++ b/src/settings/Makefile.am @@ -32,7 +32,6 @@ libsettings_la_SOURCES = \ nm-settings.h \ nm-inotify-helper.c \ nm-inotify-helper.h \ - nm-polkit-helpers.h \ nm-settings-error.c \ nm-settings-error.h \ nm-system-config-interface.c \ diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in index 123132b7..980f35cb 100644 --- a/src/settings/Makefile.in +++ b/src/settings/Makefile.in @@ -396,7 +396,6 @@ libsettings_la_SOURCES = \ nm-settings.h \ nm-inotify-helper.c \ nm-inotify-helper.h \ - nm-polkit-helpers.h \ nm-settings-error.c \ nm-settings-error.h \ nm-system-config-interface.c \ diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index dbc29cae..8a5ea106 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -33,7 +33,6 @@ #include "nm-secret-agent.h" #include "nm-manager-auth.h" #include "nm-dbus-glib-types.h" -#include "nm-polkit-helpers.h" #include "nm-manager-auth.h" #include "nm-setting-vpn.h" #include "nm-setting-connection.h" @@ -49,7 +48,6 @@ typedef struct { NMDBusManager *dbus_mgr; NMSessionMonitor *session_monitor; - PolkitAuthority *authority; /* Hashed by owner name, not identifier, since two agents in different * sessions can use the same identifier. @@ -338,7 +336,6 @@ typedef void (*RequestCancelFunc) (Request *req); struct _Request { guint32 reqid; - PolkitAuthority *authority; NMAuthChain *chain; NMConnection *connection; @@ -381,7 +378,6 @@ static guint32 next_req_id = 1; static Request * request_new_get (NMConnection *connection, - PolkitAuthority *authority, gboolean filter_by_uid, gulong uid_filter, GHashTable *existing_secrets, @@ -402,7 +398,6 @@ request_new_get (NMConnection *connection, req = g_malloc0 (sizeof (Request)); req->reqid = next_req_id++; req->connection = g_object_ref (connection); - req->authority = g_object_ref (authority); req->filter_by_uid = filter_by_uid; req->uid_filter = uid_filter; if (existing_secrets) @@ -462,8 +457,6 @@ request_free (Request *req) g_hash_table_unref (req->existing_secrets); if (req->chain) nm_auth_chain_unref (req->chain); - if (req->authority) - g_object_unref (req->authority); memset (req, 0, sizeof (Request)); g_free (req); } @@ -853,10 +846,10 @@ check_system_secrets_cb (NMSetting *setting, /* VPNs are special; need to handle each secret separately */ g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { - if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { - if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) - *has_system = TRUE; - } + secret_flags = NM_SETTING_SECRET_FLAG_NONE; + nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL); + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) + *has_system = TRUE; } } else { nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); @@ -896,8 +889,7 @@ get_next_cb (Request *req) nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY", req, req->setting_name, agent_dbus_owner); - req->chain = nm_auth_chain_new_dbus_sender (req->authority, - agent_dbus_owner, + req->chain = nm_auth_chain_new_dbus_sender (agent_dbus_owner, get_agent_modify_auth_cb, req); g_assert (req->chain); @@ -1050,7 +1042,6 @@ nm_agent_manager_get_secrets (NMAgentManager *self, */ req = request_new_get (connection, - priv->authority, filter_by_uid, uid_filter, existing_secrets, @@ -1335,15 +1326,6 @@ static void nm_agent_manager_init (NMAgentManager *self) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - GError *error = NULL; - - priv->authority = polkit_authority_get_sync (NULL, &error); - if (!priv->authority) { - nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - } priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); priv->requests = g_hash_table_new_full (g_direct_hash, @@ -1365,7 +1347,6 @@ dispose (GObject *object) g_object_unref (priv->session_monitor); g_object_unref (priv->dbus_mgr); - g_object_unref (priv->authority); } G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); diff --git a/src/settings/nm-polkit-helpers.h b/src/settings/nm-polkit-helpers.h deleted file mode 100644 index d812e944..00000000 --- a/src/settings/nm-polkit-helpers.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2010 Red Hat, Inc. - */ - -#ifndef NM_POLKIT_HELPERS_H -#define NM_POLKIT_HELPERS_H - -#include <polkit/polkit.h> - -/* Fix for polkit 0.97 and later */ -#if !HAVE_POLKIT_AUTHORITY_GET_SYNC -static inline PolkitAuthority * -polkit_authority_get_sync (GCancellable *cancellable, GError **error) -{ - PolkitAuthority *authority; - - authority = polkit_authority_get (); - if (!authority) - g_set_error (error, 0, 0, "failed to get the PolicyKit authority"); - return authority; -} -#endif - -#endif /* NM_POLKIT_HELPERS_H */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 22aef716..60de6b06 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -34,7 +34,6 @@ #include "nm-dbus-manager.h" #include "nm-settings-error.h" #include "nm-dbus-glib-types.h" -#include "nm-polkit-helpers.h" #include "nm-logging.h" #include "nm-manager-auth.h" #include "nm-marshal.h" @@ -83,7 +82,6 @@ typedef struct { NMDBusManager *dbus_mgr; NMAgentManager *agent_mgr; - PolkitAuthority *authority; GSList *pending_auths; /* List of pending authentication requests */ NMConnection *secrets; gboolean visible; /* Is this connection is visible by some session? */ @@ -98,6 +96,83 @@ typedef struct { /**************************************************************/ +/* Return TRUE to continue, FALSE to stop */ +typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data); + +static void +for_each_secret (NMConnection *connection, + GHashTable *secrets, + ForEachSecretFunc callback, + gpointer callback_data) +{ + GHashTableIter iter; + const char *setting_name; + GHashTable *setting_hash; + + /* This function, given a hash of hashes representing new secrets of + * an NMConnection, walks through each toplevel hash (which represents a + * NMSetting), and for each setting, walks through that setting hash's + * properties. For each property that's a secret, it will check that + * secret's flags in the backing NMConnection object, and call a supplied + * callback. + * + * The one complexity is that the VPN setting's 'secrets' property is + * *also* a hash table (since the key/value pairs are arbitrary and known + * only to the VPN plugin itself). That means we have three levels of + * GHashTables that we potentially have to traverse here. When we hit the + * VPN setting's 'secrets' property, we special-case that and iterate over + * each item in that 'secrets' hash table, calling the supplied callback + * each time. + */ + + /* Walk through the list of setting hashes */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { + NMSetting *setting; + GHashTableIter secret_iter; + const char *secret_name; + GValue *val; + + /* Get the actual NMSetting from the connection so we can get secret flags + * from the connection data, since flags aren't secrets. What we're + * iterating here is just the secrets, not a whole connection. + */ + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (setting == NULL) + continue; + + /* Walk through the list of keys in each setting hash */ + g_hash_table_iter_init (&secret_iter, setting_hash); + while (g_hash_table_iter_next (&secret_iter, (gpointer) &secret_name, (gpointer) &val)) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + /* VPN secrets need slightly different treatment here since the + * "secrets" property is actually a hash table of secrets. + */ + if (NM_IS_SETTING_VPN (setting) && (g_strcmp0 (secret_name, NM_SETTING_VPN_SECRETS) == 0)) { + GHashTableIter vpn_secrets_iter; + + /* Iterate through each secret from the VPN hash in the overall secrets hash */ + g_hash_table_iter_init (&vpn_secrets_iter, g_value_get_boxed (val)); + while (g_hash_table_iter_next (&vpn_secrets_iter, (gpointer) &secret_name, NULL)) { + secret_flags = NM_SETTING_SECRET_FLAG_NONE; + nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL); + if (callback (&vpn_secrets_iter, secret_flags, callback_data) == FALSE) + return; + } + } else { + nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL); + if (callback (&secret_iter, secret_flags, callback_data) == FALSE) + return; + } + } + } +} + +/**************************************************************/ + static void set_visible (NMSettingsConnection *self, gboolean new_visible) { @@ -112,7 +187,8 @@ set_visible (NMSettingsConnection *self, gboolean new_visible) gboolean nm_settings_connection_is_visible (NMSettingsConnection *self) { - g_return_val_if_fail (NM_SETTINGS_CONNECTION (self), FALSE); + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->visible; } @@ -124,7 +200,8 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self) NMSettingConnection *s_con; guint32 num, i; - g_return_if_fail (NM_SETTINGS_CONNECTION (self)); + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); @@ -178,10 +255,10 @@ only_system_secrets_cb (NMSetting *setting, g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { - if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { - if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) - nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); - } + secret_flags = NM_SETTING_SECRET_FLAG_NONE; + nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); } } else { nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); @@ -204,15 +281,26 @@ update_secrets_cache (NMSettingsConnection *self) nm_connection_for_each_setting_value (priv->secrets, only_system_secrets_cb, NULL); } +static gboolean +clear_system_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) +{ + if (flags == NM_SETTING_SECRET_FLAG_NONE) + g_hash_table_iter_remove (iter); + return TRUE; +} + /* Update the settings of this connection to match that of 'new', taking care to - * make a private copy of secrets. */ + * make a private copy of secrets. + */ gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self, NMConnection *new, GError **error) { NMSettingsConnectionPrivate *priv; - GHashTable *new_settings; + GHashTable *new_settings, *transient_secrets; gboolean success = FALSE; g_return_val_if_fail (self != NULL, FALSE); @@ -222,18 +310,48 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + /* Replacing the settings might replace transient secrets, such as when + * a user agent returns secrets, which might trigger the connection to be + * written out, which triggers an inotify event to re-read and update the + * connection, which, if we're not careful, could wipe out the transient + * secrets the user agent just sent us. Basically, only + * nm_connection_clear_secrets() should wipe out transient secrets but + * re-reading a connection from on-disk and updating our in-memory copy + * should not. Thus we preserve non-system-owned secrets here. + */ + transient_secrets = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS); + if (transient_secrets) + for_each_secret (NM_CONNECTION (self), transient_secrets, clear_system_secrets, NULL); + new_settings = nm_connection_to_hash (new, NM_SETTING_HASH_FLAG_ALL); g_assert (new_settings); if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) { + GHashTableIter iter; + NMSetting *setting; + const char *setting_name; + GHashTable *setting_hash; + /* Copy the connection to keep its secrets around even if NM * calls nm_connection_clear_secrets(). */ update_secrets_cache (self); + /* And add the transient secrets back */ + if (transient_secrets) { + g_hash_table_iter_init (&iter, transient_secrets); + while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { + setting = nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name); + if (setting) + nm_setting_update_secrets (setting, setting_hash, NULL); + } + } + nm_settings_connection_recheck_visibility (self); success = TRUE; } g_hash_table_destroy (new_settings); + if (transient_secrets) + g_hash_table_destroy (transient_secrets); return success; } @@ -398,11 +516,6 @@ supports_secrets (NMSettingsConnection *connection, const char *setting_name) return TRUE; } -/* Return TRUE to continue, FALSE to stop */ -typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter, - NMSettingSecretFlags flags, - gpointer user_data); - static gboolean clear_nonagent_secrets (GHashTableIter *iter, NMSettingSecretFlags flags, @@ -430,7 +543,7 @@ has_system_owned_secrets (GHashTableIter *iter, { gboolean *has_system_owned = user_data; - if (!(flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) { + if (flags == NM_SETTING_SECRET_FLAG_NONE) { *has_system_owned = TRUE; return FALSE; } @@ -438,40 +551,6 @@ has_system_owned_secrets (GHashTableIter *iter, } static void -for_each_secret (NMConnection *connection, - GHashTable *secrets, - ForEachSecretFunc callback, - gpointer callback_data) -{ - GHashTableIter iter; - const char *setting_name; - GHashTable *setting_hash; - - /* Walk through the list of setting hashes */ - g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, - (gpointer *) &setting_name, - (gpointer *) &setting_hash)) { - GHashTableIter setting_iter; - const char *secret_name; - - /* Walk through the list of keys in each setting hash */ - g_hash_table_iter_init (&setting_iter, setting_hash); - while (g_hash_table_iter_next (&setting_iter, (gpointer *) &secret_name, NULL)) { - NMSetting *setting; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; - - /* Get the actual NMSetting from the connection so we can get secret flags */ - setting = nm_connection_get_setting_by_name (connection, setting_name); - if (setting && nm_setting_get_secret_flags (setting, secret_name, &flags, NULL)) { - if (callback (&setting_iter, flags, callback_data) == FALSE) - return; - } - } - } -} - -static void new_secrets_commit_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) @@ -850,7 +929,7 @@ auth_start (NMSettingsConnection *self, } if (check_permission) { - chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self); + chain = nm_auth_chain_new (context, NULL, pk_auth_cb, self); g_assert (chain); nm_auth_chain_set_data (chain, "perm", (gpointer) check_permission, NULL); nm_auth_chain_set_data (chain, "callback", callback, NULL); @@ -980,10 +1059,10 @@ only_agent_secrets_cb (NMSetting *setting, /* VPNs are special; need to handle each secret separately */ g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { - if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { - if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) - nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); - } + secret_flags = NM_SETTING_SECRET_FLAG_NONE; + nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); } } else { nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); @@ -1271,7 +1350,8 @@ nm_settings_connection_signal_remove (NMSettingsConnection *self) guint64 nm_settings_connection_get_timestamp (NMSettingsConnection *connection) { - g_return_val_if_fail (NM_SETTINGS_CONNECTION (connection), 0); + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), 0); return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->timestamp; } @@ -1368,18 +1448,9 @@ nm_settings_connection_init (NMSettingsConnection *self) NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); static guint32 dbus_counter = 0; char *dbus_path; - GError *error = NULL; priv->dbus_mgr = nm_dbus_manager_get (); - priv->authority = polkit_authority_get_sync (NULL, &error); - if (!priv->authority) { - nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - } - dbus_path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, dbus_counter++); nm_connection_set_path (NM_CONNECTION (self), dbus_path); g_free (dbus_path); @@ -1421,10 +1492,11 @@ dispose (GObject *object) set_visible (self, FALSE); + if (priv->session_changed_id) + g_signal_handler_disconnect (priv->session_monitor, priv->session_changed_id); g_object_unref (priv->session_monitor); g_object_unref (priv->agent_mgr); g_object_unref (priv->dbus_mgr); - g_object_unref (priv->authority); out: G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 87fa4b6c..e23e8d13 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -56,7 +56,6 @@ #include "nm-dbus-glib-types.h" #include "nm-settings.h" #include "nm-settings-connection.h" -#include "nm-polkit-helpers.h" #include "nm-settings-error.h" #include "nm-default-wired-connection.h" #include "nm-logging.h" @@ -114,8 +113,6 @@ typedef struct { NMAgentManager *agent_mgr; - PolkitAuthority *authority; - guint auth_changed_id; char *config_file; NMSessionMonitor *session_monitor; @@ -702,6 +699,46 @@ connection_visibility_changed (NMSettingsConnection *connection, connection); } +#define NM_DBUS_SERVICE_OPENCONNECT "org.freedesktop.NetworkManager.openconnect" +#define NM_OPENCONNECT_KEY_GATEWAY "gateway" +#define NM_OPENCONNECT_KEY_COOKIE "cookie" +#define NM_OPENCONNECT_KEY_GWCERT "gwcert" +#define NM_OPENCONNECT_KEY_XMLCONFIG "xmlconfig" +#define NM_OPENCONNECT_KEY_LASTHOST "lasthost" +#define NM_OPENCONNECT_KEY_AUTOCONNECT "autoconnect" +#define NM_OPENCONNECT_KEY_CERTSIGS "certsigs" + +static void +openconnect_migrate_hack (NMConnection *connection) +{ + NMSettingVPN *s_vpn; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NOT_SAVED; + + /* Huge hack. There were some openconnect changes that needed to happen + * pretty late, too late to get into distros. Migration has already + * happened for many people, and their secret flags are wrong. But we + * don't want to requrie re-migration, so we have to fix it up here. Ugh. + */ + + s_vpn = nm_connection_get_setting_vpn (connection); + if (s_vpn == NULL) + return; + + if (g_strcmp0 (nm_setting_vpn_get_service_type (s_vpn), NM_DBUS_SERVICE_OPENCONNECT) == 0) { + /* These are different for every login session, and should not be stored */ + nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_GATEWAY, flags, NULL); + nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_COOKIE, flags, NULL); + nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_GWCERT, flags, NULL); + + /* These are purely internal data for the auth-dialog, and should be stored */ + flags = 0; + nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_XMLCONFIG, flags, NULL); + nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_LASTHOST, flags, NULL); + nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_AUTOCONNECT, flags, NULL); + nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_CERTSIGS, flags, NULL); + } +} + static void claim_connection (NMSettings *self, NMSettingsConnection *connection, @@ -739,6 +776,9 @@ claim_connection (NMSettings *self, /* Ensure it's initial visibility is up-to-date */ nm_settings_connection_recheck_visibility (connection); + /* Evil openconnect migration hack */ + openconnect_migrate_hack (NM_CONNECTION (connection)); + id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); @@ -999,7 +1039,7 @@ nm_settings_add_connection (NMSettings *self, perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; /* Otherwise validate the user request */ - chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self); + chain = nm_auth_chain_new (context, NULL, pk_add_cb, self); g_assert (chain); priv->auths = g_slist_append (priv->auths, chain); nm_auth_chain_add_call (chain, perm, TRUE); @@ -1111,7 +1151,7 @@ impl_settings_save_hostname (NMSettings *self, } /* Otherwise validate the user request */ - chain = nm_auth_chain_new (priv->authority, context, NULL, pk_hostname_cb, self); + chain = nm_auth_chain_new (context, NULL, pk_hostname_cb, self); g_assert (chain); priv->auths = g_slist_append (priv->auths, chain); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE); @@ -1476,18 +1516,9 @@ static void nm_settings_init (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GError *error = NULL; priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); - priv->authority = polkit_authority_get_sync (NULL, &error); - if (!priv->authority) { - nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - } - priv->session_monitor = nm_session_monitor_get (); /* Hold a reference to the agent manager so it stays alive; the only @@ -1505,11 +1536,6 @@ dispose (GObject *object) NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; - if (priv->auth_changed_id) { - g_signal_handler_disconnect (priv->authority, priv->auth_changed_id); - priv->auth_changed_id = 0; - } - for (iter = priv->auths; iter; iter = g_slist_next (iter)) nm_auth_chain_unref ((NMAuthChain *) iter->data); g_slist_free (priv->auths); diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c index 5ecf5891..eeb14556 100644 --- a/src/settings/plugins/keyfile/writer.c +++ b/src/settings/plugins/keyfile/writer.c @@ -453,17 +453,22 @@ write_hash_of_string (GKeyFile *file, g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) { - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + gboolean write_item = TRUE; /* Handle VPN secrets specially; they are nested in the property's hash; - * we don't want to write them if the secret is not saved or not required. + * we don't want to write them if the secret is not saved, not required, + * or owned by a user's secret agent. */ - if (vpn_secrets && nm_setting_get_secret_flags (setting, property, &flags, NULL)) { - if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) - continue; + if (vpn_secrets) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + nm_setting_get_secret_flags (setting, property, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + write_item = FALSE; } - g_key_file_set_string (file, group_name, property, data); + if (write_item) + g_key_file_set_string (file, group_name, property, data); } } @@ -799,7 +804,6 @@ write_setting_value (NMSetting *setting, GType type = G_VALUE_TYPE (value); KeyWriter *writer = &key_writers[0]; GParamSpec *pspec; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; /* Setting name gets picked up from the keyfile's section name instead */ if (!strcmp (key, NM_SETTING_NAME)) @@ -822,12 +826,17 @@ write_setting_value (NMSetting *setting, } /* Don't write secrets that are owned by user secret agents or aren't - * supposed to be saved. + * supposed to be saved. VPN secrets are handled specially though since + * the secret flags there are in a third-level hash in the 'secrets' + * property. */ - if ( (pspec->flags & NM_SETTING_PARAM_SECRET) - && nm_setting_get_secret_flags (setting, key, &flags, NULL) - && (flags != NM_SETTING_SECRET_FLAG_NONE)) - return; + if (pspec->flags & NM_SETTING_PARAM_SECRET && !NM_IS_SETTING_VPN (setting)) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + return; + } /* Look through the list of handlers for non-standard format key values */ while (writer->setting_name) { diff --git a/src/vpn-manager/Makefile.am b/src/vpn-manager/Makefile.am index 3b206617..ce99728e 100644 --- a/src/vpn-manager/Makefile.am +++ b/src/vpn-manager/Makefile.am @@ -22,6 +22,7 @@ libvpn_manager_la_SOURCES = \ nm-vpn-connection.h libvpn_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED @@ -30,6 +31,7 @@ libvpn_manager_la_LIBADD = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/vpn-manager/Makefile.in b/src/vpn-manager/Makefile.in index a8fea32d..3785667e 100644 --- a/src/vpn-manager/Makefile.in +++ b/src/vpn-manager/Makefile.in @@ -60,7 +60,7 @@ libvpn_manager_la_DEPENDENCIES = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libvpn_manager_la_OBJECTS = libvpn_manager_la-nm-vpn-manager.lo \ libvpn_manager_la-nm-vpn-service.lo \ libvpn_manager_la-nm-vpn-connection-base.lo \ @@ -328,6 +328,7 @@ libvpn_manager_la_SOURCES = \ nm-vpn-connection.h libvpn_manager_la_CPPFLAGS = \ + $(LIBNL_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED @@ -336,6 +337,7 @@ libvpn_manager_la_LIBADD = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ $(top_builddir)/libnm-util/libnm-util.la \ + $(LIBNL_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 12db7e27..9dff503d 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -278,6 +278,8 @@ remove_all_nsps (NMDeviceWimax *self) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + set_current_nsp (self, NULL); + while (g_slist_length (priv->nsp_list)) { NMWimaxNsp *nsp = NM_WIMAX_NSP (priv->nsp_list->data); @@ -717,29 +719,43 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) NMActRequest *req; GSList *iter; const char *path; + NMWimaxNsp *nsp = NULL; clear_link_timeout (NM_DEVICE_WIMAX (device)); + *reason = NM_DEVICE_STATE_REASON_NONE; + req = nm_device_get_act_request (device); if (!req) - goto err; + return NM_ACT_STAGE_RETURN_FAILURE; path = nm_act_request_get_specific_object (req); if (!path) - goto err; + return NM_ACT_STAGE_RETURN_FAILURE; + /* Find the NSP in the scan list */ for (iter = priv->nsp_list; iter; iter = iter->next) { - NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data); + NMWimaxNsp *candidate = NM_WIMAX_NSP (iter->data); - if (!strcmp (path, nm_wimax_nsp_get_dbus_path (nsp))) { - set_current_nsp (NM_DEVICE_WIMAX (device), nsp); - return NM_ACT_STAGE_RETURN_SUCCESS; + if (!strcmp (path, nm_wimax_nsp_get_dbus_path (candidate))) { + nsp = candidate; + break; } } - err: - *reason = NM_DEVICE_STATE_REASON_NONE; - return NM_ACT_STAGE_RETURN_FAILURE; + /* Couldn't find the NSP for some reason */ + if (nsp == NULL) + return NM_ACT_STAGE_RETURN_FAILURE; + + set_current_nsp (NM_DEVICE_WIMAX (device), nsp); + + /* If the device is scanning, it won't connect, so we have to wait until + * it's not scanning to proceed to stage 2. + */ + if (priv->status == WIMAX_API_DEVICE_STATUS_Scanning) + return NM_ACT_STAGE_RETURN_POSTPONE; + + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn @@ -857,11 +873,11 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, if (priv->current_nsp) nsp_name = nm_wimax_nsp_get_name (priv->current_nsp); - nm_log_dbg (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)", - iface, - iwmx_sdk_dev_status_to_str (old_status), - iwmx_sdk_dev_status_to_str (new_status), - reason); + nm_log_info (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)", + iface, + iwmx_sdk_dev_status_to_str (old_status), + iwmx_sdk_dev_status_to_str (new_status), + reason); switch (new_status) { case WIMAX_API_DEVICE_STATUS_UnInitialized: @@ -915,6 +931,18 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, NM_DEVICE_STATE_REASON_CONFIG_FAILED); return; } + + /* If stage2 was postponed because the device was scanning or something, + * then check if we need to move to stage2 now that the device might be + * ready. + */ + if (state == NM_DEVICE_STATE_PREPARE) { + if ( new_status == WIMAX_API_DEVICE_STATUS_Ready + || new_status == WIMAX_API_DEVICE_STATUS_Connecting) { + nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self)); + return; + } + } } /* Handle disconnection */ @@ -1252,15 +1280,17 @@ device_state_changed (NMDevice *device, if (new_state < NM_DEVICE_STATE_DISCONNECTED) remove_all_nsps (self); - /* Request initial NSP list */ + /* Request initial NSP list when device is first started */ if ( new_state == NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED) { if (priv->sdk) iwmx_sdk_get_networks (priv->sdk); } - if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED) + if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED) { + set_current_nsp (self, NULL); clear_activation_timeout (self); + } if (new_state == NM_DEVICE_STATE_ACTIVATED) { /* poll link quality and BSID */ |