diff pui-backend.c @ 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 adba37525ee5
line wrap: on
line diff
--- 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);
+}