From b72c423a344f2e455c17978bab76eb29912d0b5b Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <chingpang@gmail.com>
Date: Tue, 14 Feb 2012 18:41:51 +0800
Subject: [PATCH] network: create private connections if the user if not
 authorized

This commit checks whether the polkit policy allows the user to
create a system connection without authentication. If not, create
private connections.

https://bugzilla.gnome.org/show_bug.cgi?id=646187
---
diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c
index 8fbb048..af674a8 100644
--- a/panels/network/cc-network-panel.c
+++ b/panels/network/cc-network-panel.c
@@ -23,6 +23,8 @@
 #include <glib/gi18n.h>
 #include <stdlib.h>
 
+#include <polkit/polkit.h>
+
 #include "cc-network-panel.h"
 #include "cc-network-resources.h"
 
@@ -84,6 +86,9 @@ struct _CcNetworkPanelPrivate
         gchar            *arg_device;
         gchar            *arg_access_point;
         gboolean          operation_done;
+
+        /* polkit authentication check */
+        gboolean          default_private;
 };
 
 enum {
@@ -576,13 +581,13 @@ handle_argv_for_device (CcNetworkPanel *panel,
                 return TRUE;
         } else if (g_strcmp0 (nm_object_get_path (NM_OBJECT (device)), priv->arg_device) == 0) {
                 if (priv->arg_operation == OPERATION_CONNECT_MOBILE) {
-                        cc_network_panel_connect_to_3g_network (toplevel, priv->client, priv->remote_settings, device);
+                        cc_network_panel_connect_to_3g_network (toplevel, priv->client, priv->remote_settings, device, priv->default_private);
 
                         reset_command_line_args (panel); /* done */
                         select_tree_iter (panel, iter);
                         return TRUE;
                 } else if (priv->arg_operation == OPERATION_CONNECT_8021X) {
-                        cc_network_panel_connect_to_8021x_network (toplevel, priv->client, priv->remote_settings, device, priv->arg_access_point);
+                        cc_network_panel_connect_to_8021x_network (toplevel, priv->client, priv->remote_settings, device, priv->arg_access_point, priv->default_private);
                         reset_command_line_args (panel); /* done */
                         select_tree_iter (panel, iter);
                         return TRUE;
@@ -1400,6 +1405,9 @@ cc_network_panel_init (CcNetworkPanel *panel)
         GtkWidget *toplevel;
         GDBusConnection *system_bus;
         GtkCssProvider *provider;
+	PolkitSubject    *subject;
+	PolkitAuthority  *authority;
+	PolkitAuthorizationResult *result;
 
         panel->priv = NETWORK_PANEL_PRIVATE (panel);
         g_resources_register (cc_network_get_resource ());
@@ -1511,4 +1519,32 @@ cc_network_panel_init (CcNetworkPanel *panel)
                                                    GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
         g_object_unref (provider);
 
+	/* check the polkit authentication */
+	panel->priv->default_private = TRUE;
+	authority = polkit_authority_get_sync (NULL, NULL);
+	subject = polkit_unix_process_new_for_owner (getpid (), 0, -1);
+	result = polkit_authority_check_authorization_sync (authority,
+                                                            subject,
+                                                            "org.freedesktop.NetworkManager.settings.modify.system",
+							    NULL,
+                                                            POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+                                                            NULL,
+                                                            &error);
+
+	if (error || !result) {
+		g_warning ("Failed to check polkit authorization! %s",
+				error->message);
+		g_clear_error (&error);
+	} else if (polkit_authorization_result_get_is_authorized (result)) {
+		panel->priv->default_private = FALSE;
+	}
+	g_object_unref (result);
+	g_object_unref (authority);
+	g_object_unref (subject);
+}
+
+gboolean
+cc_network_panel_get_default_private (CcNetworkPanel *panel)
+{
+        return panel->priv->default_private;
 }
diff --git a/panels/network/cc-network-panel.h b/panels/network/cc-network-panel.h
index b8957b2..e839f92 100644
--- a/panels/network/cc-network-panel.h
+++ b/panels/network/cc-network-panel.h
@@ -66,6 +66,8 @@ GType cc_network_panel_get_type (void) G_GNUC_CONST;
 
 GPtrArray *cc_network_panel_get_devices (CcNetworkPanel *panel);
 
+gboolean cc_network_panel_get_default_private (CcNetworkPanel *panel);
+
 G_END_DECLS
 
 #endif /* _CC_NETWORK_PANEL_H */
diff --git a/panels/network/net-device-mobile.c b/panels/network/net-device-mobile.c
index 71379f9..fc3c57f 100644
--- a/panels/network/net-device-mobile.c
+++ b/panels/network/net-device-mobile.c
@@ -141,12 +141,15 @@ mobile_connection_changed_cb (GtkComboBox *combo_box, NetDeviceMobile *device_mo
                             COLUMN_ID, &object_path,
                             -1);
         if (g_strcmp0 (object_path, NULL) == 0) {
+                gboolean default_private;
                 panel = net_object_get_panel (NET_OBJECT (device_mobile));
                 toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)));
+                default_private = cc_network_panel_get_default_private (panel);
                 cc_network_panel_connect_to_3g_network (toplevel,
                                                         client,
                                                         remote_settings,
-                                                        device);
+                                                        device,
+                                                        default_private);
                 goto out;
         }
 
diff --git a/panels/network/net-device-wifi.c b/panels/network/net-device-wifi.c
index ca55d94..05972cd 100644
--- a/panels/network/net-device-wifi.c
+++ b/panels/network/net-device-wifi.c
@@ -714,6 +714,9 @@ wireless_try_to_connect (NetDeviceWifi *device_wifi,
         NMDevice *device;
         NMSettingWireless *setting_wireless;
         NMClient *client;
+        CcNetworkPanel *panel;
+        NMConnection *partial = NULL;
+        NMSettingConnection *setting_con;
 
         if (device_wifi->priv->updating_device)
                 goto out;
@@ -777,7 +780,7 @@ wireless_try_to_connect (NetDeviceWifi *device_wifi,
                         g_object_unref (permission);
                 }
 
-                if (!allowed_to_share) {
+                if (!allowed_to_share || cc_network_panel_get_default_private (device_wifi)) {
                         NMSettingConnection *s_con;
 
                         s_con = (NMSettingConnection *)nm_setting_connection_new ();
@@ -1030,6 +1033,7 @@ start_shared_connection (NetDeviceWifi *device_wifi)
         NMClient *client;
         const char *mode;
         NMDeviceWifiCapabilities caps;
+        CcNetworkPanel *panel;
 
         device = net_device_get_nm_device (NET_DEVICE (device_wifi));
         g_assert (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI);
@@ -1066,6 +1070,14 @@ start_shared_connection (NetDeviceWifi *device_wifi)
                       "id", "Hotspot",
                       "autoconnect", FALSE,
                       NULL);
+
+        panel = net_object_get_panel (NET_OBJECT (device_wifi));
+        if (cc_network_panel_get_default_private (panel))
+                nm_setting_connection_add_permission (sc,
+                                                      "user",
+                                                      g_get_user_name(),
+                                                      NULL);
+
         nm_connection_add_setting (c, (NMSetting *)sc);
 
         sw = (NMSettingWireless *)nm_setting_wireless_new ();
diff --git a/panels/network/network-dialogs.c b/panels/network/network-dialogs.c
index 7e7035c..8bd17bf 100644
--- a/panels/network/network-dialogs.c
+++ b/panels/network/network-dialogs.c
@@ -41,6 +41,7 @@ typedef struct {
         NMClient *client;
         NMRemoteSettings *settings;
         NMDevice *device;
+        gboolean default_private;
 } MobileDialogClosure;
 
 static void
@@ -267,7 +268,8 @@ cc_network_panel_connect_to_8021x_network (GtkWidget        *toplevel,
                                            NMClient         *client,
                                            NMRemoteSettings *settings,
                                            NMDevice         *device,
-                                           const gchar      *arg_access_point)
+                                           const gchar      *arg_access_point,
+                                           gboolean          default_private)
 {
 	NMConnection *connection;
 	NMSettingConnection *s_con;
@@ -305,6 +307,8 @@ cc_network_panel_connect_to_8021x_network (GtkWidget        *toplevel,
         uuid = nm_utils_uuid_generate ();
         g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL);
         g_free (uuid);
+        if (default_private)
+                nm_setting_connection_add_permission (s_con, "user", g_get_user_name(), NULL);
         nm_connection_add_setting (connection, NM_SETTING (s_con));
 
         s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
@@ -362,6 +366,7 @@ cdma_mobile_wizard_done (NMAMobileWizard *wizard,
 	if (!canceled && method) {
 		NMSetting *setting;
 		char *uuid, *id;
+		MobileDialogClosure *closure = user_data;
 
 		if (method->devtype != NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
 			g_warning ("Unexpected device type (not CDMA).");
@@ -405,6 +410,11 @@ cdma_mobile_wizard_done (NMAMobileWizard *wizard,
 		              NULL);
 		g_free (uuid);
 		g_free (id);
+		if (closure->default_private)
+			nm_setting_connection_add_permission ((NMSettingConnection *)setting,
+			                                      "user",
+                                                              g_get_user_name(),
+			                                      NULL);
 		nm_connection_add_setting (connection, setting);
 	}
 
@@ -424,6 +434,7 @@ gsm_mobile_wizard_done (NMAMobileWizard *wizard,
 	if (!canceled && method) {
 		NMSetting *setting;
 		char *uuid, *id;
+		MobileDialogClosure *closure = user_data;
 
 		if (method->devtype != NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
 			g_warning ("Unexpected device type (not GSM).");
@@ -468,6 +479,11 @@ gsm_mobile_wizard_done (NMAMobileWizard *wizard,
 		              NULL);
 		g_free (uuid);
 		g_free (id);
+		if (closure->default_private)
+			nm_setting_connection_add_permission ((NMSettingConnection *)setting,
+			                                      "user",
+                                                              g_get_user_name(),
+			                                      NULL);
 		nm_connection_add_setting (connection, setting);
 	}
 
@@ -499,7 +515,8 @@ void
 cc_network_panel_connect_to_3g_network (GtkWidget        *toplevel,
                                         NMClient         *client,
                                         NMRemoteSettings *settings,
-                                        NMDevice         *device)
+                                        NMDevice         *device,
+                                        gboolean          default_private)
 {
         MobileDialogClosure *closure;
         NMAMobileWizard *wizard;
@@ -517,6 +534,7 @@ cc_network_panel_connect_to_3g_network (GtkWidget        *toplevel,
         closure->client = g_object_ref (client);
         closure->settings = g_object_ref (settings);
         closure->device = g_object_ref (device);
+        closure->default_private = default_private;
 
 	caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
 	if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
diff --git a/panels/network/network-dialogs.h b/panels/network/network-dialogs.h
index ddbf392..953fc2b 100644
--- a/panels/network/network-dialogs.h
+++ b/panels/network/network-dialogs.h
@@ -38,11 +38,13 @@ void cc_network_panel_connect_to_8021x_network (GtkWidget        *toplevel,
                                                 NMClient         *client,
                                                 NMRemoteSettings *settings,
                                                 NMDevice         *device,
-                                                const gchar      *arg_access_point);
+                                                const gchar      *arg_access_point,
+                                                gboolean          default_private);
 
 void cc_network_panel_connect_to_3g_network (GtkWidget        *toplevel,
                                              NMClient         *client,
                                              NMRemoteSettings *settings,
-                                             NMDevice         *device);
+                                             NMDevice         *device,
+                                             gboolean          default_private);
 
 #endif /* _NETWORK_DIALOGS_H */
