src: Fixes in nm-device.c and nm-vpn-connection.c to update PacRunner at the right place and moment. When a device goes up PacRunner is configured with the Device IPxConfigs and Proxy Config. When it goes down the same configuration is removed from PacRunner.
ifcfg-rh: Fixed to read and write proxy settings to the ifcfg network scripts. --- src/Makefile.am | 11 ++ src/devices/nm-device.c | 73 +++++++++++++- src/devices/nm-device.h | 3 +- src/nm-dispatcher.c | 78 +++++++++++++-- src/nm-dispatcher.h | 2 + src/nm-logging.c | 3 +- src/nm-logging.h | 1 + src/nm-types.h | 2 + src/settings/nm-settings.c | 1 + src/settings/plugins/ifcfg-rh/reader.c | 177 ++++++++++++++++++++++++++++++++- src/settings/plugins/ifcfg-rh/writer.c | 145 +++++++++++++++++++++++++++ src/vpn-manager/nm-vpn-connection.c | 43 ++++++++ src/vpn-manager/nm-vpn-connection.h | 2 + 13 files changed, 527 insertions(+), 14 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 41c3169..8ad0404 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -447,6 +447,8 @@ libNetworkManager_la_SOURCES = \ nm-exported-object.h \ nm-firewall-manager.c \ nm-firewall-manager.h \ + nm-proxy-config.c \ + nm-proxy-config.h \ nm-ip4-config.c \ nm-ip4-config.h \ nm-ip6-config.c \ @@ -461,6 +463,8 @@ libNetworkManager_la_SOURCES = \ nm-manager.h \ nm-multi-index.c \ nm-multi-index.h \ + nm-pacrunner-manager.c \ + nm-pacrunner-manager.h \ nm-policy.c \ nm-policy.h \ nm-rfkill-manager.c \ @@ -560,6 +564,11 @@ libnm_iface_helper_la_SOURCES = \ platform/wifi/wifi-utils.c \ platform/wifi/wifi-utils.h \ \ + nm-pacrunner-manager.c \ + nm-pacrunner-manager.h \ + \ + rdisc/nm-fake-rdisc.c \ + rdisc/nm-fake-rdisc.h \ rdisc/nm-lndp-rdisc.c \ rdisc/nm-lndp-rdisc.h \ rdisc/nm-rdisc.c \ @@ -570,6 +579,8 @@ libnm_iface_helper_la_SOURCES = \ \ nm-exported-object.c \ nm-exported-object.h \ + nm-proxy-config.c \ + nm-proxy-config.h \ nm-ip4-config.c \ nm-ip4-config.h \ nm-ip6-config.c \ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 177080d..c37f8ef 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -45,8 +45,10 @@ #include "nm-lndp-rdisc.h" #include "nm-dhcp-manager.h" #include "nm-activation-request.h" +#include "nm-proxy-config.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" +#include "nm-pacrunner-manager.h" #include "nm-dnsmasq-manager.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" @@ -301,6 +303,10 @@ typedef struct _NMDevicePrivate { guint32 dhcp_timeout; char * dhcp_anycast_address; + /* Proxy Configuration */ + NMProxyConfig * proxy_config; + NMPacRunnerManager * pacrunner_manager; + /* IP4 configuration info */ NMIP4Config * ip4_config; /* Combined config from VPN, settings, and device */ IpState ip4_state; @@ -409,6 +415,8 @@ typedef struct _NMDevicePrivate { guint check_delete_unrealized_id; } NMDevicePrivate; +static void nm_device_set_proxy_config (NMDevice *self, GHashTable *options); + static gboolean nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, guint32 default_route_metric, @@ -4888,6 +4896,8 @@ dhcp4_state_changed (NMDhcpClient *client, break; } + nm_device_set_proxy_config (self, options); + nm_dhcp4_config_set_options (priv->dhcp4.config, options); _notify (self, PROP_DHCP4_CONFIG); priv->dhcp4.num_tries_left = DHCP_NUM_TRIES_MAX; @@ -6792,6 +6802,9 @@ activate_stage3_ip_config_start (NMDevice *self) && !nm_device_activate_stage3_ip6_start (self)) return; + /* Proxy */ + nm_device_set_proxy_config (self, NULL); + check_ip_failed (self, TRUE); } @@ -8315,8 +8328,50 @@ nm_device_is_activating (NMDevice *self) return priv->act_handle4.id ? TRUE : FALSE; } -/* IP Configuration stuff */ +NMProxyConfig * +nm_device_get_proxy_config (NMDevice *self) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + + return NM_DEVICE_GET_PRIVATE (self)->proxy_config; +} +static void +nm_device_set_proxy_config (NMDevice *self, GHashTable *options) +{ + NMDevicePrivate *priv; + NMConnection *connection; + NMSettingProxy *s_proxy = NULL; + char *pac = NULL; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + + g_clear_object (&priv->proxy_config); + priv->proxy_config = nm_proxy_config_new (); + + if (options) { + pac = g_hash_table_lookup (options, "wpad"); + if (pac) { + nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO); + nm_proxy_config_set_pac_url (priv->proxy_config, pac); + _LOGD (LOGD_PROXY, "PAC url: %s",pac); + } else { + nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE); + _LOGI (LOGD_PROXY, "PAC url not obtained from DHCP server"); + } + } + + connection = nm_device_get_applied_connection (self); + if (connection) + s_proxy = nm_connection_get_setting_proxy (connection); + + if (s_proxy) + nm_proxy_config_merge_setting (priv->proxy_config, s_proxy); +} + +/* IP Configuration stuff */ NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *self) { @@ -10579,6 +10634,7 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) */ nm_device_set_ip4_config (self, NULL, 0, TRUE, TRUE, NULL); nm_device_set_ip6_config (self, NULL, TRUE, TRUE, NULL); + g_clear_object (&priv->proxy_config); g_clear_object (&priv->con_ip4_config); g_clear_object (&priv->dev_ip4_config); g_clear_object (&priv->ext_ip4_config); @@ -11166,6 +11222,9 @@ _set_state_full (NMDevice *self, deactivate_dispatcher_complete (0, self); } } + + /* Remove config from PacRunner */ + nm_pacrunner_manager_remove (priv->pacrunner_manager, nm_device_get_ip_iface (self)); break; case NM_DEVICE_STATE_DISCONNECTED: if ( priv->queued_act_request @@ -11189,6 +11248,14 @@ _set_state_full (NMDevice *self, nm_act_request_get_settings_connection (req), nm_act_request_get_applied_connection (req), self, NULL, NULL, NULL); + + /* Load PacRunner with Device's config */ + if (!nm_pacrunner_manager_send (priv->pacrunner_manager, + nm_device_get_ip_iface (self), + priv->proxy_config, + priv->ip4_config, + priv->ip6_config)) + _LOGI (LOGD_PROXY, "Couldn't update pacrunner for %s", nm_device_get_ip_iface (self)); break; case NM_DEVICE_STATE_FAILED: /* Usually upon failure the activation chain is interrupted in @@ -11952,6 +12019,8 @@ nm_device_init (NMDevice *self) priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); + priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ()); + priv->default_route.v4_is_assumed = TRUE; priv->default_route.v6_is_assumed = TRUE; @@ -12063,6 +12132,8 @@ dispose (GObject *object) dispatcher_cleanup (self); + g_clear_object (&priv->pacrunner_manager); + _cleanup_generic_pre (self, CLEANUP_TYPE_KEEP); g_warn_if_fail (priv->slaves == NULL); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 6a4f22a..6cbe0e3 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -366,9 +366,10 @@ const char * nm_device_get_permanent_hw_address (NMDevice *dev, gboolean fallback_fake); const char * nm_device_get_initial_hw_address (NMDevice *dev); +NMProxyConfig * nm_device_get_proxy_config (NMDevice *dev); + NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev); NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *dev); - NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); void nm_device_replace_vpn4_config (NMDevice *dev, NMIP4Config *old, diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index df9be2e..890e57d 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -32,6 +32,7 @@ #include "nm-device.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" +#include "nm-proxy-config.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" #include "nm-manager.h" @@ -91,6 +92,37 @@ _get_monitor_by_action (DispatcherAction action) } static void +dump_proxy_to_props (NMProxyConfig *proxy, GVariantBuilder *builder) +{ + char **proxies = NULL; + const char *pac_url = NULL, *pac_script = NULL; + + if (nm_proxy_config_get_method (proxy) == NM_PROXY_CONFIG_METHOD_NONE) + return; + + /* Proxies */ + proxies = nm_proxy_config_get_proxies (proxy); + if (proxies && g_strv_length (proxies) > 0) + g_variant_builder_add (builder, "{sv}", + "proxies", + g_variant_new_strv ((const char *const *) proxies, -1)); + + /* PAC Url */ + pac_url = nm_proxy_config_get_pac_url (proxy); + if (pac_url) + g_variant_builder_add (builder, "{sv}", + "pac-url", + g_variant_new_string (pac_url)); + + /* PAC Script */ + pac_script = nm_proxy_config_get_pac_script (proxy); + if (pac_script) + g_variant_builder_add (builder, "{sv}", + "pac-script", + g_variant_new_string (pac_script)); +} + +static void dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder) { GVariantBuilder int_builder; @@ -231,11 +263,13 @@ dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder) static void fill_device_props (NMDevice *device, GVariantBuilder *dev_builder, + GVariantBuilder *proxy_builder, GVariantBuilder *ip4_builder, GVariantBuilder *ip6_builder, GVariant **dhcp4_props, GVariant **dhcp6_props) { + NMProxyConfig *proxy_config; NMIP4Config *ip4_config; NMIP6Config *ip6_config; NMDhcp4Config *dhcp4_config; @@ -254,6 +288,10 @@ fill_device_props (NMDevice *device, g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_PATH, g_variant_new_object_path (nm_exported_object_get_path (NM_EXPORTED_OBJECT (device)))); + proxy_config = nm_device_get_proxy_config (device); + if (proxy_config) + dump_proxy_to_props (proxy_config, proxy_builder); + ip4_config = nm_device_get_ip4_config (device); if (ip4_config) dump_ip4_to_props (ip4_config, ip4_builder); @@ -272,11 +310,15 @@ fill_device_props (NMDevice *device, } static void -fill_vpn_props (NMIP4Config *ip4_config, +fill_vpn_props (NMProxyConfig *proxy_config, + NMIP4Config *ip4_config, NMIP6Config *ip6_config, + GVariantBuilder *proxy_builder, GVariantBuilder *ip4_builder, GVariantBuilder *ip6_builder) { + if (proxy_config) + dump_proxy_to_props (proxy_config, proxy_builder); if (ip4_config) dump_ip4_to_props (ip4_config, ip4_builder); if (ip6_config) @@ -454,6 +496,7 @@ _dispatcher_call (DispatcherAction action, NMDevice *device, NMConnectivityState connectivity_state, const char *vpn_iface, + NMProxyConfig *vpn_proxy_config, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config, DispatcherFunc callback, @@ -463,10 +506,12 @@ _dispatcher_call (DispatcherAction action, GVariant *connection_dict; GVariantBuilder connection_props; GVariantBuilder device_props; + GVariantBuilder device_proxy_props; GVariantBuilder device_ip4_props; GVariantBuilder device_ip6_props; GVariant *device_dhcp4_props = NULL; GVariant *device_dhcp6_props = NULL; + GVariantBuilder vpn_proxy_props; GVariantBuilder vpn_ip4_props; GVariantBuilder vpn_ip6_props; DispatchInfo *info = NULL; @@ -551,8 +596,10 @@ _dispatcher_call (DispatcherAction action, } g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT); + g_variant_builder_init (&device_proxy_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init (&device_ip4_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init (&device_ip6_props, G_VARIANT_TYPE_VARDICT); + g_variant_builder_init (&vpn_proxy_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init (&vpn_ip4_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT); @@ -561,13 +608,16 @@ _dispatcher_call (DispatcherAction action, && action != DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { fill_device_props (device, &device_props, + &device_proxy_props, &device_ip4_props, &device_ip6_props, &device_dhcp4_props, &device_dhcp6_props); if (vpn_ip4_config || vpn_ip6_config) { - fill_vpn_props (vpn_ip4_config, + fill_vpn_props (vpn_proxy_config, + vpn_ip4_config, vpn_ip6_config, + &vpn_proxy_props, &vpn_ip4_props, &vpn_ip6_props); } @@ -584,17 +634,19 @@ _dispatcher_call (DispatcherAction action, GVariantIter *results; ret = _nm_dbus_proxy_call_sync (dispatcher_proxy, "Action", - g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}b)", + g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}a{sv}b)", action_to_string (action), connection_dict, &connection_props, &device_props, + &device_proxy_props, &device_ip4_props, &device_ip6_props, device_dhcp4_props, device_dhcp6_props, nm_connectivity_state_to_string (connectivity_state), vpn_iface ? vpn_iface : "", + &vpn_proxy_props, &vpn_ip4_props, &vpn_ip6_props, nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH)), @@ -620,17 +672,19 @@ _dispatcher_call (DispatcherAction action, info->callback = callback; info->user_data = user_data; g_dbus_proxy_call (dispatcher_proxy, "Action", - g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}b)", + g_variant_new ("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}a{sv}b)", action_to_string (action), connection_dict, &connection_props, &device_props, + &device_proxy_props, &device_ip4_props, &device_ip6_props, device_dhcp4_props, device_dhcp6_props, nm_connectivity_state_to_string (connectivity_state), vpn_iface ? vpn_iface : "", + &vpn_proxy_props, &vpn_ip4_props, &vpn_ip6_props, nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH)), @@ -680,7 +734,7 @@ nm_dispatcher_call (DispatcherAction action, guint *out_call_id) { return _dispatcher_call (action, FALSE, settings_connection, applied_connection, device, - NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, + NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, callback, user_data, out_call_id); } @@ -703,7 +757,7 @@ nm_dispatcher_call_sync (DispatcherAction action, NMDevice *device) { return _dispatcher_call (action, TRUE, settings_connection, applied_connection, device, - NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL); + NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } /** @@ -713,6 +767,7 @@ nm_dispatcher_call_sync (DispatcherAction action, * @applied_connection: the currently applied connection * @parent_device: the parent #NMDevice of the VPN connection * @vpn_iface: the IP interface of the VPN tunnel, if any + * @vpn_proxy_config: the #NMProxyConfig of the VPN connection * @vpn_ip4_config: the #NMIP4Config of the VPN connection * @vpn_ip6_config: the #NMIP6Config of the VPN connection * @callback: a caller-supplied callback to execute when done @@ -731,6 +786,7 @@ nm_dispatcher_call_vpn (DispatcherAction action, NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, + NMProxyConfig *vpn_proxy_config, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config, DispatcherFunc callback, @@ -738,8 +794,8 @@ nm_dispatcher_call_vpn (DispatcherAction action, guint *out_call_id) { return _dispatcher_call (action, FALSE, settings_connection, applied_connection, - parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_ip4_config, - vpn_ip6_config, callback, user_data, out_call_id); + parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config, + vpn_ip4_config, vpn_ip6_config, callback, user_data, out_call_id); } /** @@ -749,6 +805,7 @@ nm_dispatcher_call_vpn (DispatcherAction action, * @applied_connection: the currently applied connection * @parent_device: the parent #NMDevice of the VPN connection * @vpn_iface: the IP interface of the VPN tunnel, if any + * @vpn_proxy_config: the #NMProxyConfig of the VPN connection * @vpn_ip4_config: the #NMIP4Config of the VPN connection * @vpn_ip6_config: the #NMIP6Config of the VPN connection * @@ -763,11 +820,12 @@ nm_dispatcher_call_vpn_sync (DispatcherAction action, NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, + NMProxyConfig *vpn_proxy_config, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config) { return _dispatcher_call (action, TRUE, settings_connection, applied_connection, - parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, + parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config, vpn_ip4_config, vpn_ip6_config, NULL, NULL, NULL); } @@ -785,7 +843,7 @@ nm_dispatcher_call_connectivity (DispatcherAction action, NMConnectivityState connectivity_state) { return _dispatcher_call (action, FALSE, NULL, NULL, NULL, connectivity_state, - NULL, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL, NULL, NULL); } void diff --git a/src/nm-dispatcher.h b/src/nm-dispatcher.h index 47cb648..919a92d 100644 --- a/src/nm-dispatcher.h +++ b/src/nm-dispatcher.h @@ -62,6 +62,7 @@ gboolean nm_dispatcher_call_vpn (DispatcherAction action, NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, + NMProxyConfig *vpn_proxy_config, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config, DispatcherFunc callback, @@ -73,6 +74,7 @@ gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action, NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, + NMProxyConfig *vpn_proxy_config, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config); diff --git a/src/nm-logging.c b/src/nm-logging.c index 8e5a44b..e777f6c 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -124,7 +124,7 @@ static struct { char *logging_domains_to_string; const LogLevelDesc level_desc[_LOGL_N]; -#define _DOMAIN_DESC_LEN 38 +#define _DOMAIN_DESC_LEN 39 /* Would be nice to use C99 flexible array member here, * but that feature doesn't seem well supported. */ const LogDesc domain_desc[_DOMAIN_DESC_LEN]; @@ -180,6 +180,7 @@ static struct { { LOGD_AUDIT, "AUDIT" }, { LOGD_SYSTEMD, "SYSTEMD" }, { LOGD_VPN_PLUGIN,"VPN_PLUGIN" }, + { LOGD_PROXY, "PROXY" }, { 0, NULL } /* keep _DOMAIN_DESC_LEN in sync */ }, diff --git a/src/nm-logging.h b/src/nm-logging.h index 9e2b010..9f85c16 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -66,6 +66,7 @@ typedef enum { /*< skip >*/ LOGD_AUDIT = (1LL << 34), LOGD_SYSTEMD = (1LL << 35), LOGD_VPN_PLUGIN = (1LL << 36), + LOGD_PROXY = (1LL << 37), __LOGD_MAX, LOGD_ALL = (((__LOGD_MAX - 1LL) << 1) - 1LL), diff --git a/src/nm-types.h b/src/nm-types.h index 1fbf043..4e80200 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -42,11 +42,13 @@ typedef struct _NMDefaultRouteManager NMDefaultRouteManager; typedef struct _NMDevice NMDevice; typedef struct _NMDhcp4Config NMDhcp4Config; typedef struct _NMDhcp6Config NMDhcp6Config; +typedef struct _NMProxyConfig NMProxyConfig; typedef struct _NMIP4Config NMIP4Config; typedef struct _NMIP6Config NMIP6Config; typedef struct _NMManager NMManager; typedef struct _NMPolicy NMPolicy; typedef struct _NMRfkillManager NMRfkillManager; +typedef struct _NMPacRunnerManager NMPacRunnerManager; typedef struct _NMRouteManager NMRouteManager; typedef struct _NMSessionMonitor NMSessionMonitor; typedef struct _NMSleepMonitor NMSleepMonitor; diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 529d758..60b48ae 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -57,6 +57,7 @@ #include "nm-setting-adsl.h" #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" +#include "nm-setting-proxy.h" #include "nm-setting-bond.h" #include "nm-utils.h" #include "nm-core-internal.h" diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index af5d291..9eb143d 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -48,6 +48,7 @@ #include "nm-setting-bridge.h" #include "nm-setting-bridge-port.h" #include "nm-setting-dcb.h" +#include "nm-setting-proxy.h" #include "nm-setting-generic.h" #include "nm-core-internal.h" #include "nm-utils.h" @@ -899,6 +900,176 @@ error: return success; } +static NMSetting * +make_proxy_setting (shvarFile *ifcfg, GError **error) +{ + NMSettingProxy *s_proxy = NULL; + char *value = NULL; + NMSettingProxyMethod method; + + value = svGetValue (ifcfg, "PROXY_METHOD", FALSE); + if (!value) + return NULL; + + if (!g_ascii_strcasecmp (value, "auto")) + method = NM_SETTING_PROXY_METHOD_AUTO; + else if (!g_ascii_strcasecmp (value, "manual")) + method = NM_SETTING_PROXY_METHOD_MANUAL; + else + method = NM_SETTING_PROXY_METHOD_NONE; + g_free (value); + + s_proxy = (NMSettingProxy *) nm_setting_proxy_new (); + + switch (method) { + case NM_SETTING_PROXY_METHOD_AUTO: + g_object_set (s_proxy, + NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_AUTO, + NULL); + + value = svGetValue (ifcfg, "PAC_URL", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_proxy, NM_SETTING_PROXY_PAC_URL, value, NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "PAC_SCRIPT", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_proxy, NM_SETTING_PROXY_PAC_SCRIPT, value, NULL); + g_free (value); + } + + break; + case NM_SETTING_PROXY_METHOD_MANUAL: + g_object_set (s_proxy, + NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_MANUAL, + NULL); + + value = svGetValue (ifcfg, "NO_PROXY_FOR", FALSE); + if (value) { + char **excludes = NULL; + + excludes = g_strsplit (value, " ", 0); + if (excludes) + g_object_set (s_proxy, + NM_SETTING_PROXY_NO_PROXY_FOR, excludes, + NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "HTTP_PROXY", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_proxy, NM_SETTING_PROXY_HTTP_PROXY, value, NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "HTTP_PORT", FALSE); + if (value) { + int port; + + port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1); + if (port > 0) + g_object_set (s_proxy, NM_SETTING_PROXY_HTTP_PORT, (guint) port, NULL); + else + PARSE_WARNING ("invalid PORT '%s'", value); + g_free (value); + } + + value = svGetValue (ifcfg, "HTTP_DEFAULT", FALSE); + if (value) { + if (!g_ascii_strcasecmp (value, "yes")) { + g_object_set (s_proxy, NM_SETTING_PROXY_HTTP_DEFAULT, TRUE, NULL); + g_free (value); + break; + } + } + + value = svGetValue (ifcfg, "SSL_PROXY", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_proxy, NM_SETTING_PROXY_SSL_PROXY, value, NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "SSL_PORT", FALSE); + if (value) { + int port; + + port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1); + if (port > 0) + g_object_set (s_proxy, NM_SETTING_PROXY_SSL_PORT, (guint) port, NULL); + else + PARSE_WARNING ("invalid PORT '%s'", value); + g_free (value); + } + + value = svGetValue (ifcfg, "FTP_PROXY", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_proxy, NM_SETTING_PROXY_FTP_PROXY, value, NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "FTP_PORT", FALSE); + if (value) { + int port; + + port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1); + if (port > 0) + g_object_set (s_proxy, NM_SETTING_PROXY_FTP_PORT, (guint) port, NULL); + else + PARSE_WARNING ("invalid PORT '%s'", value); + g_free (value); + } + + value = svGetValue (ifcfg, "SOCKS_PROXY", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_proxy, NM_SETTING_PROXY_SOCKS_PROXY, value, NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "SOCKS_PORT", FALSE); + if (value) { + int port; + + port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1); + if (port > 0) + g_object_set (s_proxy, NM_SETTING_PROXY_SOCKS_PORT, (guint) port, NULL); + else + PARSE_WARNING ("invalid PORT '%s'", value); + g_free (value); + } + + value = svGetValue (ifcfg, "SOCKS_VERSION_5", FALSE); + if (value) { + if (!g_ascii_strcasecmp (value, "yes")) { + g_object_set (s_proxy, NM_SETTING_PROXY_SOCKS_VERSION_5, TRUE, NULL); + g_free (value); + break; + } + } + + break; + case NM_SETTING_PROXY_METHOD_NONE: + g_object_set (s_proxy, + NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_NONE, + NULL); + } + + value = svGetValue (ifcfg, "BROWSER_ONLY", FALSE); + if (value) { + if (!g_ascii_strcasecmp (value, "yes")) { + g_object_set (s_proxy, NM_SETTING_PROXY_BROWSER_ONLY, TRUE, NULL); + g_free (value); + } + } + + return NM_SETTING (s_proxy); +} static NMSetting * make_ip4_setting (shvarFile *ifcfg, @@ -4959,7 +5130,7 @@ connection_from_file_full (const char *filename, shvarFile *parsed; gs_free char *type = NULL; char *devtype, *bootproto; - NMSetting *s_ip4, *s_ip6, *s_port, *s_dcb = NULL; + NMSetting *s_ip4, *s_ip6, *s_proxy, *s_port, *s_dcb = NULL; const char *ifcfg_name = NULL; g_return_val_if_fail (filename != NULL, NULL); @@ -5171,6 +5342,10 @@ connection_from_file_full (const char *filename, */ check_dns_search_domains (parsed, s_ip4, s_ip6); + s_proxy = make_proxy_setting (parsed, error); + if (s_proxy) + nm_connection_add_setting (connection, s_proxy); + /* Bridge port? */ s_port = make_bridge_port_setting (parsed); if (s_port) diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 3682640..77d869d 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -36,6 +36,7 @@ #include "nm-setting-wired.h" #include "nm-setting-wireless.h" #include "nm-setting-8021x.h" +#include "nm-setting-proxy.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-setting-pppoe.h" @@ -1984,6 +1985,147 @@ error: } static gboolean +write_proxy_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) +{ + NMSettingProxy *s_proxy; + NMSettingProxyMethod method; + char *tmp; + const char *pac_url, *pac_script; + const char *http_proxy, *ssl_proxy, *ftp_proxy, *socks_proxy; + guint32 http_port, ssl_port, ftp_port, socks_port; + gboolean http_default, socks_version_5, browser_only; + GString *no_proxy_for; + char **iter, **excludes = NULL; + + s_proxy = nm_connection_get_setting_proxy (connection); + if (!s_proxy) + return TRUE; + + svSetValue (ifcfg, "HTTP_PROXY", NULL, FALSE); + svSetValue (ifcfg, "HTTP_PORT", NULL, FALSE); + svSetValue (ifcfg, "HTTP_DEFAULT", NULL, FALSE); + svSetValue (ifcfg, "SSL_PROXY", NULL, FALSE); + svSetValue (ifcfg, "SSL_PORT", NULL, FALSE); + svSetValue (ifcfg, "FTP_PROXY", NULL, FALSE); + svSetValue (ifcfg, "FTP_PORT", NULL, FALSE); + svSetValue (ifcfg, "SOCKS_PROXY", NULL, FALSE); + svSetValue (ifcfg, "SOCKS_PORT", NULL, FALSE); + svSetValue (ifcfg, "SOCKS_VERSION_5", NULL, FALSE); + svSetValue (ifcfg, "NO_PROXY_FOR", NULL, FALSE); + svSetValue (ifcfg, "BROWSER_ONLY", NULL, FALSE); + svSetValue (ifcfg, "PAC_URL", NULL, FALSE); + svSetValue (ifcfg, "PAC_SCRIPT", NULL, FALSE); + + method = nm_setting_proxy_get_method (s_proxy); + switch (method) { + case NM_SETTING_PROXY_METHOD_AUTO: + svSetValue (ifcfg, "PROXY_METHOD", "auto", FALSE); + + pac_url = nm_setting_proxy_get_pac_url (s_proxy); + if (pac_url) + svSetValue (ifcfg, "PAC_URL", pac_url, FALSE); + + pac_script = nm_setting_proxy_get_pac_script (s_proxy); + if (pac_script) + svSetValue (ifcfg, "PAC_SCRIPT", pac_script, FALSE); + + break; + case NM_SETTING_PROXY_METHOD_MANUAL: + svSetValue (ifcfg, "PROXY_METHOD", "manual", FALSE); + + excludes = nm_setting_proxy_get_no_proxy_for (s_proxy); + if (excludes && g_strv_length (excludes)) { + int counter = 0; + + no_proxy_for = g_string_new (NULL); + for (iter = excludes; *iter; iter++) { + if (counter > 0) + g_string_append (no_proxy_for, " "); + counter++; + g_string_append (no_proxy_for, *iter); + } + + svSetValue (ifcfg, "NO_PROXY_FOR", no_proxy_for->str, FALSE); + g_string_free (no_proxy_for, TRUE); + } + + http_proxy = nm_setting_proxy_get_http_proxy (s_proxy); + if (http_proxy) + svSetValue (ifcfg, "HTTP_PROXY", http_proxy, FALSE); + + svSetValue (ifcfg, "HTTP_PORT", NULL, FALSE); + http_port = nm_setting_proxy_get_http_port (s_proxy); + if (http_port) { + tmp = g_strdup_printf ("%u", http_port); + svSetValue (ifcfg, "HTTP_PORT", tmp, FALSE); + g_free (tmp); + } + + http_default = nm_setting_proxy_get_http_default (s_proxy); + if (http_default) { + svSetValue (ifcfg, "HTTP_DEFAULT", "yes", FALSE); + break; + } else + svSetValue (ifcfg, "HTTP_DEFAULT", "no", FALSE); + + ssl_proxy = nm_setting_proxy_get_ssl_proxy (s_proxy); + if (ssl_proxy) + svSetValue (ifcfg, "SSL_PROXY", ssl_proxy, FALSE); + + svSetValue (ifcfg, "SSL_PORT", NULL, FALSE); + ssl_port = nm_setting_proxy_get_ssl_port (s_proxy); + if (ssl_port) { + tmp = g_strdup_printf ("%u", ssl_port); + svSetValue (ifcfg, "SSL_PORT", tmp, FALSE); + g_free (tmp); + } + + ftp_proxy = nm_setting_proxy_get_ftp_proxy (s_proxy); + if (ftp_proxy) + svSetValue (ifcfg, "FTP_PROXY", ftp_proxy, FALSE); + + svSetValue (ifcfg, "FTP_PORT", NULL, FALSE); + ftp_port = nm_setting_proxy_get_ftp_port (s_proxy); + if (ftp_port) { + tmp = g_strdup_printf ("%u", ftp_port); + svSetValue (ifcfg, "FTP_PORT", tmp, FALSE); + g_free (tmp); + } + + socks_proxy = nm_setting_proxy_get_socks_proxy (s_proxy); + if (socks_proxy) + svSetValue (ifcfg, "SOCKS_PROXY", socks_proxy, FALSE); + + svSetValue (ifcfg, "SOCKS_PORT", NULL, FALSE); + socks_port = nm_setting_proxy_get_socks_port (s_proxy); + if (socks_port) { + tmp = g_strdup_printf ("%u", socks_port); + svSetValue (ifcfg, "SOCKS_PORT", tmp, FALSE); + g_free (tmp); + } + + socks_version_5 = nm_setting_proxy_get_socks_version_5 (s_proxy); + if (socks_version_5) + svSetValue (ifcfg, "SOCKS_VERSION_5", "yes", FALSE); + else + svSetValue (ifcfg, "SOCKS_VERSION_5", "no", FALSE); + + break; + case NM_SETTING_PROXY_METHOD_NONE: + svSetValue (ifcfg, "PROXY_METHOD", "none", FALSE); + /* Write nothing more */ + } + + browser_only = nm_setting_proxy_get_browser_only (s_proxy); + if (browser_only) + svSetValue (ifcfg, "BROWSER_ONLY", "yes", FALSE); + else + svSetValue (ifcfg, "BROWSER_ONLY", "no", FALSE); + + return TRUE; +} + +static gboolean write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingIPConfig *s_ip4; @@ -2862,6 +3004,9 @@ write_connection (NMConnection *connection, if (!write_dcb_setting (connection, ifcfg, error)) goto out; + if (!write_proxy_setting (connection, ifcfg, error)) + goto out; + if (!utils_ignore_ip_config (connection)) { svSetValue (ifcfg, "DHCP_HOSTNAME", NULL, FALSE); svSetValue (ifcfg, "DHCP_FQDN", NULL, FALSE); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 5378909..c9651e6 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -31,6 +31,7 @@ #include <syslog.h> #include "nm-vpn-connection.h" +#include "nm-proxy-config.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" #include "nm-platform.h" @@ -40,6 +41,7 @@ #include "nm-dispatcher.h" #include "nm-agent-manager.h" #include "nm-core-internal.h" +#include "nm-pacrunner-manager.h" #include "nm-default-route-manager.h" #include "nm-route-manager.h" #include "nm-firewall-manager.h" @@ -107,6 +109,7 @@ typedef struct { GCancellable *cancellable; GVariant *connect_hash; guint connect_timeout; + NMProxyConfig *proxy_config; gboolean has_ip4; NMIP4Config *ip4_config; guint32 ip4_internal_gw; @@ -511,6 +514,7 @@ _set_vpn_state (NMVpnConnection *self, _get_applied_connection (self), parent_dev, priv->ip_iface, + priv->proxy_config, priv->ip4_config, priv->ip6_config, dispatcher_pre_up_done, @@ -530,11 +534,20 @@ _set_vpn_state (NMVpnConnection *self, _get_applied_connection (self), parent_dev, priv->ip_iface, + priv->proxy_config, priv->ip4_config, priv->ip6_config, NULL, NULL, NULL); + + /* Load PacRunner with VPN's config */ + if (!nm_pacrunner_manager_send (nm_pacrunner_manager_get (), + priv->ip_iface, + priv->proxy_config, + priv->ip4_config, + priv->ip6_config)) + _LOGI ("Couldn't update pacrunner for %s", priv->ip_iface); break; case STATE_DEACTIVATING: if (quitting) { @@ -543,6 +556,7 @@ _set_vpn_state (NMVpnConnection *self, _get_applied_connection (self), parent_dev, priv->ip_iface, + priv->proxy_config, priv->ip4_config, priv->ip6_config); } else { @@ -551,6 +565,7 @@ _set_vpn_state (NMVpnConnection *self, _get_applied_connection (self), parent_dev, priv->ip_iface, + priv->proxy_config, priv->ip4_config, priv->ip6_config, dispatcher_pre_down_done, @@ -560,6 +575,9 @@ _set_vpn_state (NMVpnConnection *self, dispatcher_pre_down_done (0, self); } } + + /* Remove config from PacRunner */ + nm_pacrunner_manager_remove (nm_pacrunner_manager_get(), priv->ip_iface); break; case STATE_FAILED: case STATE_DISCONNECTED: @@ -573,6 +591,7 @@ _set_vpn_state (NMVpnConnection *self, parent_dev, priv->ip_iface, NULL, + NULL, NULL); } else { nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_DOWN, @@ -584,6 +603,7 @@ _set_vpn_state (NMVpnConnection *self, NULL, NULL, NULL, + NULL, NULL); } } @@ -1251,6 +1271,20 @@ process_generic_config (NMVpnConnection *self, GVariant *dict) g_object_notify (G_OBJECT (self), NM_VPN_CONNECTION_BANNER); } + /* Proxy Config */ + g_clear_object (&priv->proxy_config); + priv->proxy_config = nm_proxy_config_new (); + + if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_PROXY_PAC, "&s", &str)) { + nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO); + nm_proxy_config_set_pac_url (priv->proxy_config, str); + } else + nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE); + + /* User overrides if any from the NMConnection's Proxy settings */ + nm_proxy_config_merge_setting (priv->proxy_config, + nm_connection_get_setting_proxy (_get_applied_connection (self))); + /* External world-visible address of the VPN server */ priv->ip4_external_gw = 0; g_clear_pointer (&priv->ip6_external_gw, g_free); @@ -2161,6 +2195,14 @@ nm_vpn_connection_get_banner (NMVpnConnection *self) return NM_VPN_CONNECTION_GET_PRIVATE (self)->banner; } +NMProxyConfig * +nm_vpn_connection_get_proxy_config (NMVpnConnection *self) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL); + + return NM_VPN_CONNECTION_GET_PRIVATE (self)->proxy_config; +} + NMIP4Config * nm_vpn_connection_get_ip4_config (NMVpnConnection *self) { @@ -2559,6 +2601,7 @@ dispose (GObject *object) g_cancellable_cancel (priv->cancellable); g_clear_object (&priv->cancellable); } + g_clear_object (&priv->proxy_config); nm_exported_object_clear_and_unexport (&priv->ip4_config); nm_exported_object_clear_and_unexport (&priv->ip6_config); g_clear_object (&priv->proxy); diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index 6837432..09a0379 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -89,6 +89,8 @@ void nm_vpn_connection_disconnect (NMVpnConnection *self, NMVpnConnectionStateReason reason, gboolean quitting); +NMProxyConfig * nm_vpn_connection_get_proxy_config (NMVpnConnection *self); + NMIP4Config * nm_vpn_connection_get_ip4_config (NMVpnConnection *self); NMIP6Config * nm_vpn_connection_get_ip6_config (NMVpnConnection *self); const char * nm_vpn_connection_get_ip_iface (NMVpnConnection *self, gboolean fallback_device); -- 2.5.5 _______________________________________________ networkmanager-list mailing list networkmanager-list@gnome.org https://mail.gnome.org/mailman/listinfo/networkmanager-list