[PATCH] Improve WPAD proxy handling



We already request WPAD information from the DHCP server (bug 368423)
but we don't do anything useful with it at all.

The same information can also come from a VPN server, but we don't even
*collect* that.

This patch fixes the latter, and exposes the information in a coherent
fashion. There's no need at this point to overcomplicate matters by
pretending to support complicated manual proxy setups (as discussed in
TODO); this is just for what we can glean automatically, which is *only*
PAC files.

Tested with a local DHCP server that tells me where the proxy is, and
with a slightly modified nm-openconnect-service-openconnect-helper[sic].

This is based largely on the existing handling of NIS domainname.

I see that it's considered acceptable to (ab)use nm-dns-manager to
configure the NIS domain. I'll look at making it prod the PacRunner
dæmon with proxy information too, but this part stands alone.

diff --git a/include/NetworkManagerVPN.h b/include/NetworkManagerVPN.h
index 6e654b3..9b6e5f7 100644
--- a/include/NetworkManagerVPN.h
+++ b/include/NetworkManagerVPN.h
@@ -176,6 +176,9 @@ typedef enum {
 /* boolean: prevent this VPN connection from ever getting the default route */
 #define NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT "never-default"
 
+/* string: Location of PAC file for HTTP proxy */
+#define NM_VPN_PLUGIN_IP4_CONFIG_PROXY_PAC   "proxy-pac"
+
 /* Deprecated */
 #define NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY   NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY
 
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
index f4e94a6..ebe9a69 100644
--- a/src/dhcp-manager/nm-dhcp-client.c
+++ b/src/dhcp-manager/nm-dhcp-client.c
@@ -1292,6 +1292,12 @@ ip4_options_to_config (NMDHCPClient *self)
                nm_ip4_config_set_nis_domain (ip4_config, str);
        }
 
+       str = g_hash_table_lookup (priv->options, "new_wpad");
+       if (str) {
+               nm_log_info (LOGD_DHCP4, "  Proxy PAC '%s'", str);
+               nm_ip4_config_set_proxy_pac (ip4_config, str);
+       }
+
        str = g_hash_table_lookup (priv->options, "new_nis_servers");
        if (str) {
                char **searches = g_strsplit (str, " ", 0);
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 0722981..8f86996 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -59,6 +59,8 @@ typedef struct {
        GArray *nis;
        char * nis_domain;
 
+       char * proxy_pac;
+
        GSList *routes;
 
        gboolean never_default;
@@ -569,6 +571,26 @@ nm_ip4_config_get_nis_domain (NMIP4Config *config)
        return NM_IP4_CONFIG_GET_PRIVATE (config)->nis_domain;
 }
 
+void
+nm_ip4_config_set_proxy_pac (NMIP4Config *config, const char *uri)
+{
+       NMIP4ConfigPrivate *priv;
+
+       g_return_if_fail (NM_IS_IP4_CONFIG (config));
+
+       priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+       g_free (priv->proxy_pac);
+       priv->proxy_pac = g_strdup (uri);
+}
+
+const char *
+nm_ip4_config_get_proxy_pac (NMIP4Config *config)
+{
+       g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
+
+       return NM_IP4_CONFIG_GET_PRIVATE (config)->proxy_pac;
+}
+
 /* libnl convenience/conversion functions */
 
 static int ip4_addr_to_rtnl_local (guint32 ip4_address, struct rtnl_addr *addr)
@@ -790,6 +812,10 @@ nm_ip4_config_diff (NMIP4Config *a, NMIP4Config *b)
                && (g_strcmp0 (a_priv->nis_domain, b_priv->nis_domain) != 0))
                flags |= NM_IP4_COMPARE_FLAG_NIS_DOMAIN;
 
+       if (   (a_priv->proxy_pac || b_priv->proxy_pac)
+               && (g_strcmp0 (a_priv->proxy_pac, b_priv->proxy_pac) != 0))
+               flags |= NM_IP4_COMPARE_FLAG_PROXY_PAC;
+
        if (   !route_slist_compare (a_priv->routes, b_priv->routes)
            || !route_slist_compare (b_priv->routes, a_priv->routes))
                flags |= NM_IP4_COMPARE_FLAG_ROUTES;
@@ -856,6 +882,10 @@ nm_ip4_config_hash (NMIP4Config *config, GChecksum *sum, gboolean dns_only)
                s = nm_ip4_config_get_nis_domain (config);
                if (s)
                        g_checksum_update (sum, (const guint8 *) s, strlen (s));
+
+               s = nm_ip4_config_get_proxy_pac (config);
+               if (s)
+                       g_checksum_update (sum, (const guint8 *) s, strlen (s));
        }
 
        for (i = 0; i < nm_ip4_config_get_num_nameservers (config); i++)
@@ -900,6 +930,7 @@ finalize (GObject *object)
        g_ptr_array_free (priv->searches, TRUE);
        g_array_free (priv->nis, TRUE);
        g_free (priv->nis_domain);
+       g_free (priv->proxy_pac);
 
        G_OBJECT_CLASS (nm_ip4_config_parent_class)->finalize (object);
 }
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index 5433768..c66aece 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -107,6 +107,9 @@ void          nm_ip4_config_reset_nis_servers   (NMIP4Config *config);
 void          nm_ip4_config_set_nis_domain      (NMIP4Config *config, const char *domain);
 const char *  nm_ip4_config_get_nis_domain      (NMIP4Config *config);
 
+void          nm_ip4_config_set_proxy_pac       (NMIP4Config *config, const char *uri);
+const char *  nm_ip4_config_get_proxy_pac       (NMIP4Config *config);
+
 
 /* Flags for nm_ip4_config_to_rtnl_addr() */
 #define NM_RTNL_ADDR_NONE              0x0000
@@ -133,6 +136,7 @@ typedef enum {
        NM_IP4_COMPARE_FLAG_WINS_SERVERS= 0x00000100,
        NM_IP4_COMPARE_FLAG_NIS_SERVERS = 0x00000200,
        NM_IP4_COMPARE_FLAG_NIS_DOMAIN  = 0x00000400,
+       NM_IP4_COMPARE_FLAG_PROXY_PAC   = 0x00000800,
        NM_IP4_COMPARE_FLAG_ALL         = 0xFFFFFFFF   /* match everything */
 } NMIP4ConfigCompareFlags;
 
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index f2e31a8..bb9c710 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -493,6 +493,7 @@ print_vpn_config (NMVPNConnection *connection)
        NMIP4Address *addr;
        NMIP6Address *addr6;
        char *dns_domain = NULL;
+       const char *proxy_pac = NULL;
        guint32 num, i;
 
        if (priv->ip4_external_gw) {
@@ -542,6 +543,10 @@ print_vpn_config (NMVPNConnection *connection)
                        dns_domain = (char *) nm_ip4_config_get_domain (priv->ip4_config, 0);
 
                nm_log_info (LOGD_VPN, "  DNS Domain: '%s'", dns_domain ? dns_domain : "(none)");
+
+               proxy_pac = nm_ip4_config_get_proxy_pac (priv->ip4_config);
+               if (proxy_pac)
+                       nm_log_info (LOGD_VPN, "  Proxy PAC: '%s'", proxy_pac);
        } else
                nm_log_info (LOGD_VPN, "No IPv4 configuration");
 
@@ -898,6 +903,10 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
        if (val && G_VALUE_HOLDS_BOOLEAN (val))
                nm_ip4_config_set_never_default (config, g_value_get_boolean (val));
 
+       val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_PROXY_PAC);
+       if (val)
+               nm_ip4_config_set_proxy_pac (config, g_value_get_string (val));
+
        /* Merge in user overrides from the NMConnection's IPv4 setting */
        s_ip4 = nm_connection_get_setting_ip4_config (priv->connection);
        nm_utils_merge_ip4_config (config, s_ip4);



-- 
dwmw2

Attachment: smime.p7s
Description: S/MIME cryptographic signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]