From cf7ec0e63e86771fb52830c5ee0b4a10f35577f3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Nov 2011 23:05:18 -0600 Subject: [PATCH] firewall: cleanups and code consolidation Consolidate the NMDevice firewall add code so that firewall handling is done in one place. --- src/firewall-manager/nm-firewall-manager.c | 101 ++++++++++------ src/firewall-manager/nm-firewall-manager.h | 14 ++- src/nm-device.c | 131 ++++++++------------- src/nm-policy.c | 31 ++--- 4 files changed, 137 insertions(+), 140 deletions(-) diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/firewall-manager/nm-firewall-manager.c index a278844c32..7b1ce2a730 100644 --- a/src/firewall-manager/nm-firewall-manager.c +++ b/src/firewall-manager/nm-firewall-manager.c @@ -50,60 +50,89 @@ typedef struct { /********************************************************************/ -DBusGProxyCall * -nm_firewall_manager_add_to_zone (NMFirewallManager *self, - const char *ip_iface, - const char *zone, - DBusGProxyCallNotify callback, - gpointer callback_data) -{ - NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); - DBusGProxyCall * call = NULL; +typedef struct { + char *iface; + FwAddToZoneFunc callback; + gpointer user_data1; + gpointer user_data2; +} AddInfo; - if (nm_firewall_manager_available (self)) { - nm_log_dbg (LOGD_DEVICE, "(%s) adding to firewall zone: %s", ip_iface, zone ); - call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, - "AddInterface", - callback, - callback_data, /* NMDevice */ - NULL, /* destroy callback_data */ - 10000, /* timeout */ - G_TYPE_STRING, ip_iface, - G_TYPE_STRING, zone ? zone : "", - DBUS_TYPE_G_MAP_OF_VARIANT, NULL, /* a{sv}:options */ - G_TYPE_INVALID); - } else { - nm_log_dbg (LOGD_DEVICE, "Firewall zone add skipped because firewall isn't running"); - callback (NULL, NULL, callback_data); +static void +add_info_free (AddInfo *info) +{ + g_return_if_fail (info != NULL); + g_free (info->iface); + g_free (info); +} + +static void +add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + AddInfo *info = user_data; + GError *error = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { + g_assert (error); + nm_log_warn (LOGD_DEVICE, "(%s) firewall zone change failed: (%d) %s", + info->iface, error->code, error->message); } - return call; + info->callback (error, info->user_data1, info->user_data2); + g_clear_error (&error); } -void nm_firewall_manager_cancel_add (NMFirewallManager *self, DBusGProxyCall * fw_call) +gpointer +nm_firewall_manager_add_to_zone (NMFirewallManager *self, + const char *iface, + const char *zone, + FwAddToZoneFunc callback, + gpointer user_data1, + gpointer user_data2) { NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + AddInfo *info; - dbus_g_proxy_cancel_call (priv->proxy, fw_call); + if (priv->running == FALSE) { + nm_log_dbg (LOGD_DEVICE, "(%s) firewall zone change skipped (not running)", iface); + callback (NULL, user_data1, user_data2); + return NULL; + } + + info = g_malloc0 (sizeof (*info)); + info->iface = g_strdup (iface); + info->callback = callback; + info->user_data1 = user_data1; + info->user_data2 = user_data2; + + nm_log_dbg (LOGD_DEVICE, "(%s) firewall zone change -> %s", iface, zone ); + return dbus_g_proxy_begin_call_with_timeout (priv->proxy, + "AddInterface", + add_cb, + info, + (GDestroyNotify) add_info_free, + 10000, /* timeout */ + G_TYPE_STRING, iface, + G_TYPE_STRING, zone ? zone : "", + DBUS_TYPE_G_MAP_OF_VARIANT, NULL, /* a{sv}:options */ + G_TYPE_INVALID); } -gboolean -nm_firewall_manager_available (NMFirewallManager *self) +void nm_firewall_manager_cancel_add (NMFirewallManager *self, gpointer call) { - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (NM_IS_FIREWALL_MANAGER (self), FALSE); - - return NM_FIREWALL_MANAGER_GET_PRIVATE (self)->running; + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_FIREWALL_MANAGER (self)); + dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy, + (DBusGProxyCall *) call); } static void set_running (NMFirewallManager *self, gboolean now_running) { NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); - gboolean old_available = nm_firewall_manager_available (self); + gboolean old_running = priv->running; priv->running = now_running; - if (old_available != nm_firewall_manager_available (self)) + if (old_running != priv->running) g_object_notify (G_OBJECT (self), NM_FIREWALL_MANAGER_AVAILABLE); } @@ -179,7 +208,7 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { switch (prop_id) { case PROP_AVAILABLE: - g_value_set_boolean (value, nm_firewall_manager_available (NM_FIREWALL_MANAGER (object))); + g_value_set_boolean (value, NM_FIREWALL_MANAGER_GET_PRIVATE (object)->running); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/src/firewall-manager/nm-firewall-manager.h b/src/firewall-manager/nm-firewall-manager.h index bd827c96a6..7d703b2910 100644 --- a/src/firewall-manager/nm-firewall-manager.h +++ b/src/firewall-manager/nm-firewall-manager.h @@ -55,9 +55,17 @@ GType nm_firewall_manager_get_type (void); NMFirewallManager *nm_firewall_manager_get (void); -gboolean nm_firewall_manager_available (NMFirewallManager *mgr); +typedef void (*FwAddToZoneFunc) (GError *error, + gpointer user_data1, + gpointer user_data2); -DBusGProxyCall *nm_firewall_manager_add_to_zone(NMFirewallManager *mgr, const char *ip_iface, const char *zone, DBusGProxyCallNotify callback, gpointer callback_data); -void nm_firewall_manager_cancel_add (NMFirewallManager *mgr, DBusGProxyCall * fw_call); +gpointer nm_firewall_manager_add_to_zone (NMFirewallManager *mgr, + const char *iface, + const char *zone, + FwAddToZoneFunc callback, + gpointer user_data1, + gpointer user_data2); + +void nm_firewall_manager_cancel_add (NMFirewallManager *mgr, gpointer fw_call); #endif /* NM_FIREWALL_MANAGER_H */ diff --git a/src/nm-device.c b/src/nm-device.c index ebbf5570ab..7b5cad515d 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -191,6 +191,8 @@ static gboolean nm_device_set_ip6_config (NMDevice *dev, gboolean assumed, NMDeviceStateReason *reason); +static gboolean nm_device_activate_ip6_config_commit (gpointer user_data); + static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release); static const char *reason_to_string (NMDeviceStateReason reason); @@ -2390,6 +2392,9 @@ nm_device_activate_ip4_config_commit (gpointer user_data) if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit) NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, config); + /* Merge with user overrides */ + nm_utils_merge_ip4_config (config, nm_connection_get_setting_ip4_config (connection)); + assumed = nm_act_request_get_assumed (priv->act_request); if (!nm_device_set_ip4_config (self, config, assumed, &reason)) { nm_log_info (LOGD_DEVICE | LOGD_IP4, @@ -2428,38 +2433,62 @@ out: } static void -ip4_add_to_zone_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +fw_add_to_zone_cb (GError *error, + gpointer user_data1, + gpointer user_data2) { - NMDevice *self = NM_DEVICE (user_data); + NMDevice *self = NM_DEVICE (user_data1); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - GError *error = NULL; + gboolean ip4 = GPOINTER_TO_UINT (user_data2); priv->fw_call = NULL; - if (proxy && call_id) { - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - nm_log_warn (LOGD_DEVICE, "adding iface to zone failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - - /* FIXME: fail the device activation? */ - } + if (error) { + /* FIXME: fail the device activation? */ } - activation_source_schedule (self, nm_device_activate_ip4_config_commit, AF_INET); + if (ip4) + activation_source_schedule (self, nm_device_activate_ip4_config_commit, AF_INET); + else + activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 5 of 5 (IPv4 Configure Commit) scheduled...", - nm_device_get_iface (self)); + nm_log_info (LOGD_DEVICE | (ip4 ? LOGD_IP4 : LOGD_IP6), + "Activation (%s) Stage 5 of 5 (IPv%c Configure Commit) scheduled...", + nm_device_get_iface (self), + ip4 ? '4' : '6'); +} + +static void +fw_add_to_zone (NMDevice *self, gboolean ip4) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + NMSettingConnection *s_con = NULL; + + /* Only set the interface's zone if the device isn't yet activated. If + * already activated, the zone has already been set. + */ + if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED) { + fw_add_to_zone_cb (NULL, self, GUINT_TO_POINTER (ip4)); + return; + } + + /* Otherwise tell the firewall to add the interface to the specified zone */ + connection = nm_act_request_get_connection (priv->act_request); + g_assert (connection); + s_con = nm_connection_get_setting_connection (connection); + priv->fw_call = nm_firewall_manager_add_to_zone (priv->fw_manager, + nm_device_get_ip_iface (self), + nm_setting_connection_get_zone (s_con), + fw_add_to_zone_cb, + self, + GUINT_TO_POINTER (ip4)); } void nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *config) { NMDevicePrivate *priv; - NMConnection *connection = NULL; - NMSettingConnection *s_con = NULL; g_return_if_fail (NM_IS_DEVICE (self)); @@ -2471,29 +2500,12 @@ nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *conf return; } - connection = nm_act_request_get_connection (priv->act_request); - g_assert (connection); - - /* Merge with user overrides and save the pending config */ - nm_utils_merge_ip4_config (config, nm_connection_get_setting_ip4_config (connection)); g_object_set_data_full (G_OBJECT (priv->act_request), PENDING_IP4_CONFIG, g_object_ref (config), g_object_unref); - /* Only set the interface's zone if the device isn't yet activated. If - * already activated, the zone has already been set. - */ - if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED) - ip4_add_to_zone_cb (NULL, NULL, self); - else { - s_con = nm_connection_get_setting_connection (connection); - priv->fw_call = nm_firewall_manager_add_to_zone (priv->fw_manager, - nm_device_get_ip_iface (self), - nm_setting_connection_get_zone (s_con), - ip4_add_to_zone_cb, - self); - } + fw_add_to_zone (self, AF_INET); } gboolean @@ -2560,40 +2572,10 @@ nm_device_activate_ip6_config_commit (gpointer user_data) return FALSE; } - -static void -ip6_add_to_zone_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - GError *error = NULL; - - priv->fw_call = NULL; - - if (proxy && call_id) { - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - nm_log_warn (LOGD_DEVICE, "adding iface to zone failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - - /* FIXME: fail the device activation? */ - } - } - - activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6); - - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 5 of 5 (IPv6 Commit) scheduled...", - nm_device_get_iface (self)); -} - void nm_device_activate_schedule_ip6_config_result (NMDevice *self, NMIP6Config *config) { NMDevicePrivate *priv; - NMConnection *connection = NULL; - NMSettingConnection *s_con = NULL; g_return_if_fail (NM_IS_DEVICE (self)); @@ -2605,28 +2587,13 @@ nm_device_activate_schedule_ip6_config_result (NMDevice *self, NMIP6Config *conf return; } - connection = nm_act_request_get_connection (priv->act_request); - g_assert (connection); - /* Save the pending config */ g_object_set_data_full (G_OBJECT (priv->act_request), PENDING_IP6_CONFIG, g_object_ref (config), g_object_unref); - /* Only set the interface's zone if the device isn't yet activated. If - * already activated, the zone has already been set. - */ - if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED) - ip6_add_to_zone_cb (NULL, NULL, self); - else { - s_con = nm_connection_get_setting_connection (connection); - priv->fw_call = nm_firewall_manager_add_to_zone (priv->fw_manager, - nm_device_get_ip_iface (self), - nm_setting_connection_get_zone (s_con), - ip6_add_to_zone_cb, - self); - } + fw_add_to_zone (self, AF_INET6); } gboolean diff --git a/src/nm-policy.c b/src/nm-policy.c index 3e70cc926c..923ad4d930 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1200,30 +1200,21 @@ connections_loaded (NMSettings *settings, gpointer user_data) } static void -add_to_zone_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - void *user_data) +add_to_zone_cb (GError *error, + gpointer user_data1, + gpointer user_data2) { - NMDevice *device = NM_DEVICE (user_data); - GError *error = NULL; + NMDevice *device = NM_DEVICE (user_data1); - if (proxy && call_id) { - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - nm_log_warn (LOGD_DEVICE, "(%s) addition to firewall zone failed: (%d) %s", - nm_device_get_ip_iface (device), - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - - /* FIXME: fail connection since firewall zone add failed? */ - } + if (error) { + /* FIXME: what do we do here? */ } + g_object_unref (device); } static void -inform_firewall_about_zone (NMPolicy * policy, - NMConnection *connection) +inform_firewall_about_zone (NMPolicy *policy, NMConnection *connection) { NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); GSList *iter, *devices; @@ -1232,12 +1223,14 @@ inform_firewall_about_zone (NMPolicy * policy, for (iter = devices; iter; iter = g_slist_next (iter)) { NMDevice *dev = NM_DEVICE (iter->data); - if (get_device_connection (dev) == connection) { + if ( (get_device_connection (dev) == connection) + && (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) { nm_firewall_manager_add_to_zone (policy->fw_manager, nm_device_get_ip_iface (dev), nm_setting_connection_get_zone (s_con), add_to_zone_cb, - g_object_ref (dev)); + g_object_ref (dev), + NULL); } } }