changeset 6:2477a6151087

Make PackagKit use the user's network proxies Pick up network proxies from the user's environment and make PackagKit use them. Setting network proxies is a privileged operation, so it is only attempted if the user is allowed to use the polkit action org.freedesktop.packagekit.system-network-proxy-configure without authentication.
author Guido Berhoerster <guido+pui@berhoerster.name>
date Tue, 19 Jun 2018 15:44:36 +0200
parents a4020e99e550
children 9d961e513af0
files Makefile README package-update-indicator.1.xml pui-application.c pui-backend.c pui-backend.h
diffstat 6 files changed, 157 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sun Jun 17 17:05:16 2018 +0200
+++ b/Makefile	Tue Jun 19 15:44:36 2018 +0200
@@ -143,9 +143,11 @@
 			-DSETTINGS_SCHEMA_ID=\"$(APPLICATION_ID)\" \
 			-DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
 $(PACKAGE): XCFLAGS =	$(shell pkg-config --cflags gtk+-3.0 \
-			    appindicator3-0.1 packagekit-glib2 upower-glib)
+			    appindicator3-0.1 packagekit-glib2 \
+			    polkit-gobject-1 upower-glib)
 $(PACKAGE): LDLIBS =	$(shell pkg-config --libs gtk+-3.0 \
-			    appindicator3-0.1 packagekit-glib2 upower-glib)
+			    appindicator3-0.1 packagekit-glib2 \
+			    polkit-gobject-1 upower-glib)
 
 $(PACKAGE)-prefs: XCPPFLAGS = -DPACKAGE=\"$(PACKAGE)\" \
 			-DAPPLICATION_ID=\"$(PREFS_APPLICATION_ID)\" \
--- a/README	Sun Jun 17 17:05:16 2018 +0200
+++ b/README	Tue Jun 19 15:44:36 2018 +0200
@@ -24,6 +24,7 @@
 - libappindicator 12.10.0 or later
 - PackageKit-glib2 0.8.17 or later
 - upower-glib 0.99.0 or later
+- polkit 0.105 or later
 - the xsltproc tool from libxml2
 
 Before building package-update-indicator check the commented macros in the
--- a/package-update-indicator.1.xml	Sun Jun 17 17:05:16 2018 +0200
+++ b/package-update-indicator.1.xml	Tue Jun 19 15:44:36 2018 +0200
@@ -33,7 +33,7 @@
       <email>guido+pui@berhoerster.name</email>
       <personblurb/>
     </author>
-    <date>5 June, 2018</date>
+    <date>19 June, 2018</date>
   </info>
   <refmeta>
     <refentrytitle>package-update-indicator</refentrytitle>
@@ -73,6 +73,11 @@
     checks for software updates and notifies the user about available updates
     using desktop notifications and either a status notifier icon or a system
     tray icon.</para>
+    <para>Protocol-specific proxies specified through the corresponding
+    environment variables will be used by PackagKit when refreshing metadata if
+    the user is allowed to use the polkit action
+    <literal>org.freedesktop.packagekit.system-network-proxy-configure</literal>
+    without authentication.</para>
   </refsect1>
   <refsect1>
     <title>Options</title>
@@ -104,6 +109,42 @@
     </variablelist>
   </refsect1>
   <refsect1>
+    <title>Environment Variables</title>
+    <variablelist>
+      <varlistentry>
+        <term>http_proxy</term>
+        <listitem>
+          <para>Network proxy using the HTTP protcol.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>https_proxy</term>
+        <listitem>
+          <para>Network proxy using the HTTPS protcol.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>ftp_proxy</term>
+        <listitem>
+          <para>Network proxy using the FTP protcol.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>socks_proxy</term>
+        <listitem>
+          <para>Network proxy using the SOCKS protcol.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>no_proxy</term>
+        <listitem>
+          <para>Comma-separated list of host for which no proxy should be
+            used.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+  <refsect1>
     <title>Exit Status</title>
     <para>The following exit values are returned:</para>
     <variablelist>
@@ -131,6 +172,8 @@
     <title>See Also</title>
     <para><citerefentry>
       <refentrytitle>package-update-indicator-prefs</refentrytitle>
-      <manvolnum>1</manvolnum></citerefentry></para>
+      <manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>polkit</refentrytitle>
+      <manvolnum>8</manvolnum></citerefentry></para>
   </refsect1>
 </refentry>
--- a/pui-application.c	Sun Jun 17 17:05:16 2018 +0200
+++ b/pui-application.c	Tue Jun 19 15:44:36 2018 +0200
@@ -406,6 +406,10 @@
 		return;
 	}
 
+	pui_backend_set_proxy(self->backend, g_getenv("http_proxy"),
+	    g_getenv("https_proxy"), g_getenv("ftp_proxy"),
+	    g_getenv("socks_proxy"), g_getenv("no_proxy"), NULL);
+
 	g_settings_bind(self->settings, "refresh-interval", self->backend,
 	    "refresh-interval", G_SETTINGS_BIND_GET);
 	g_settings_bind(self->settings, "use-mobile-connection", self->backend,
--- a/pui-backend.c	Sun Jun 17 17:05:16 2018 +0200
+++ b/pui-backend.c	Tue Jun 19 15:44:36 2018 +0200
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <packagekit-glib2/packagekit.h>
+#include <polkit/polkit.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -42,6 +43,12 @@
 	GCancellable	*cancellable;
 	UpClient	*up_client;
 	UpDevice	*up_device;
+	gchar		*proxy_http;
+	gchar		*proxy_https;
+	gchar		*proxy_ftp;
+	gchar		*proxy_socks;
+	gchar		*no_proxy;
+	gchar		*pac;
 	gint64		last_check;
 	PkNetworkEnum	network_state;
 	gboolean	inhibited;
@@ -312,6 +319,21 @@
 }
 
 static void
+pui_backend_finalize(GObject *object)
+{
+	PuiBackend	*self = PUI_BACKEND(object);
+
+	g_free(self->proxy_http);
+	g_free(self->proxy_https);
+	g_free(self->proxy_ftp);
+	g_free(self->proxy_socks);
+	g_free(self->no_proxy);
+	g_free(self->pac);
+
+	G_OBJECT_CLASS(pui_backend_parent_class)->finalize(object);
+}
+
+static void
 pui_backend_class_init(PuiBackendClass *klass)
 {
 	GObjectClass	*object_class = G_OBJECT_CLASS(klass);
@@ -319,6 +341,7 @@
 	object_class->set_property = pui_backend_set_property;
 	object_class->get_property = pui_backend_get_property;
 	object_class->dispose = pui_backend_dispose;
+	object_class->finalize = pui_backend_finalize;
 
 	properties[PROP_IMPORTANT_UPDATES] =
 	    g_param_spec_uint("important-updates", "Important updates",
@@ -559,3 +582,81 @@
 
 	return ((object != NULL) ? PUI_BACKEND(object) : NULL);
 }
+
+static void
+on_set_proxy_finished(GObject *source_object, GAsyncResult *result,
+    gpointer user_data)
+{
+	PuiBackend	*self = user_data;
+	GError		*error = NULL;
+
+	if (!pk_control_set_proxy_finish(self->pk_control, result, &error)) {
+		g_warning("failed to set proxies: %s", error->message);
+		g_error_free(error);
+	}
+}
+
+static void
+on_polkit_permission_finished(GObject *source_object, GAsyncResult *result,
+    gpointer user_data)
+{
+	PuiBackend	*self = user_data;
+	GPermission	*permission;
+	GError		*error = NULL;
+
+	permission = polkit_permission_new_finish(result, &error);
+	if (permission == NULL) {
+		g_warning("failed to create PolKit permission for setting the "
+		    "network proxies: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	if (!g_permission_get_allowed(permission)) {
+		/* setting the proxy requires authentication or is disallowed */
+		g_debug("setting the network proxy is not allowed");
+		return;
+	}
+
+	g_debug("setting HTTP proxy to \"%s\"", (self->proxy_http != NULL) ?
+	    self->proxy_http : "(null)");
+	g_debug("setting HTTPS proxy to \"%s\"", (self->proxy_https != NULL) ?
+	    self->proxy_https : "(null)");
+	g_debug("setting FTP proxy to \"%s\"", (self->proxy_ftp != NULL) ?
+	    self->proxy_ftp : "(null)");
+	g_debug("setting SOCKS proxy to \"%s\"", (self->proxy_socks != NULL) ?
+	    self->proxy_socks : "(null)");
+	g_debug("setting the list of download IPs which should not go through "
+	    "a proxy to \"%s\"", (self->no_proxy != NULL) ? self->no_proxy :
+	    "(null)");
+	g_debug("setting the PAC string to \"%s\"", (self->pac != NULL) ?
+	    self->pac : "(null)");
+	pk_control_set_proxy2_async(self->pk_control, self->proxy_http,
+	    self->proxy_https, self->proxy_ftp, self->proxy_socks,
+	    self->no_proxy, self->pac, NULL, on_set_proxy_finished, self);
+}
+
+void
+pui_backend_set_proxy(PuiBackend *self, const gchar *proxy_http,
+    const gchar *proxy_https, const gchar *proxy_ftp, const gchar *proxy_socks,
+    const gchar *no_proxy, const gchar *pac)
+{
+	g_free(self->proxy_http);
+	self->proxy_http = (proxy_http != NULL) ? g_strdup(proxy_http) : NULL;
+	g_free(self->proxy_https);
+	self->proxy_https = (proxy_https != NULL) ? g_strdup(proxy_https) :
+	    NULL;
+	g_free(self->proxy_ftp);
+	self->proxy_ftp = (proxy_ftp != NULL) ? g_strdup(proxy_ftp) : NULL;
+	g_free(self->proxy_socks);
+	self->proxy_socks = (proxy_socks != NULL) ? g_strdup(proxy_socks) :
+	    NULL;
+	g_free(self->no_proxy);
+	self->no_proxy = (no_proxy != NULL) ? g_strdup(no_proxy) : NULL;
+	g_free(self->pac);
+	self->pac = (pac != NULL) ? g_strdup(pac) : NULL;
+
+	polkit_permission_new("org.freedesktop.packagekit."
+	    "system-network-proxy-configure", NULL, NULL,
+	    on_polkit_permission_finished, self);
+}
--- a/pui-backend.h	Sun Jun 17 17:05:16 2018 +0200
+++ b/pui-backend.h	Tue Jun 19 15:44:36 2018 +0200
@@ -43,6 +43,8 @@
 void		pui_backend_new_async(GCancellable *, GAsyncReadyCallback,
     gpointer);
 PuiBackend *	pui_backend_new_finish(GAsyncResult *, GError **);
+void		pui_backend_set_proxy(PuiBackend *, const gchar *,
+    const gchar *, const gchar *, const gchar *, const gchar *, const gchar *);
 
 G_END_DECLS