Use TorControl to apply bridge relay configuration
authorPhilipp Zabel <philipp.zabel@gmail.com>
Fri, 26 Feb 2010 17:19:51 +0000 (18:19 +0100)
committerPhilipp Zabel <philipp.zabel@gmail.com>
Sun, 28 Feb 2010 18:33:59 +0000 (19:33 +0100)
src/status-area-applet-tor.vala

index fc39bad..8301f94 100644 (file)
@@ -73,6 +73,8 @@ class TorStatusMenuItem : HD.StatusMenuItem {
        Pid polipo_pid;
        ProxyBackup backup;
        string tor_log;
+       TorControl.Connection tor_control;
+       string password;
 
        /**
         * Update status area icon and status menu button value
@@ -143,6 +145,10 @@ class TorStatusMenuItem : HD.StatusMenuItem {
                                                proxy_setup ();
                                                update_status ();
                                        }
+                                       if ("Opening Control listener on 127.0.0.1:9051" in line) {
+                                               tor_control = new TorControl.Connection ();
+                                               tor_control_auth.begin ();
+                                       }
                                } else {
                                        // FIXME
                                        Hildon.Banner.show_information (null, null, "DEBUG: %s".printf (line));
@@ -159,13 +165,67 @@ class TorStatusMenuItem : HD.StatusMenuItem {
        }
 
        /**
+        * Authenticate with Tor on the control channel
+        */
+       private async void tor_control_auth () throws Error {
+               yield tor_control.authenticate_async (password);
+
+               var bridges = new SList<string> ();
+               try {
+                       bridges = gconf.get_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING);
+               } catch (Error e) {
+                       error ("Error loading bridges: %s", e.message);
+                       return;
+               }
+
+               if (bridges.length () <= 0)
+                       return;
+
+               // Enable bridge relays
+               tor_control.set_conf_list ("Bridge", bridges);
+               tor_control.set_conf_bool ("UseBridges", true);
+
+               bool use = yield tor_control.get_conf_bool_async ("UseBridges");
+               if (!use) {
+                       Hildon.Banner.show_information (null, null,
+                                                       "Failed to set up bridge relays");
+               }
+       }
+
+       /**
         * Start Tor and setup proxy settings
         */
        private void start_tor () {
                try {
                        if (tor_pid == (Pid) 0) {
+                               string[] tor_hash_argv = {
+                                       "/usr/sbin/tor",
+                                       "--hash-password", "",
+                                       null
+                               };
+                               var tv = TimeVal ();
+                               Random.set_seed ((uint32) tv.tv_usec);
+                               password = "tor-status-%8x".printf (Random.next_int ());
+                               tor_hash_argv[2] = password;
+                               string hash;
+                               Process.spawn_sync ("/tmp", tor_hash_argv, null, 0, null, out hash);
+                               hash = hash.str ("16:").replace ("\n", "");
+
+                               if (hash == null) {
+                                       Hildon.Banner.show_information (null, null,
+                                                                       "Failed to get hash");
+                                       return;
+                               }
+
+                               string[] tor_argv = {
+                                       "/usr/sbin/tor",
+                                       "--ControlPort", "9051",
+                                       "--HashedControlPassword", "",
+                                       null
+                               };
+                               tor_argv[4] = hash;
                                Process.spawn_async_with_pipes ("/tmp",
-                                                               { "/usr/sbin/tor" },
+                                                               tor_argv,
                                                                null,
                                                                SpawnFlags.SEARCH_PATH,
                                                                null,
@@ -301,7 +361,7 @@ class TorStatusMenuItem : HD.StatusMenuItem {
                try {
                        bridges = gconf.get_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING);
                } catch (Error e) {
-                       error ("Error loading bridges: %s", e.message);
+                       Hildon.Banner.show_information (null, null, "Error loading bridges: %s".printf (e.message));
                }
 
                var list_store = new Gtk.ListStore (1, typeof (string));
@@ -405,8 +465,14 @@ class TorStatusMenuItem : HD.StatusMenuItem {
                                                store.@get (iter, 0, out bridge);
                                                bridges.append (bridge);
                                        } while (store.iter_next (ref iter));
-                                       gconf.set_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING,
-                                                       bridges);
+                                       try {
+                                               gconf.set_list (GCONF_KEY_BRIDGES,
+                                                               GConf.ValueType.STRING,
+                                                               bridges);
+                                       } catch (Error e) {
+                                               Hildon.Banner.show_information (dialog, null,
+                                                                               "Failed to save bridge relay list: %s".printf (e.message));
+                                       }
                                }
                                dialog.destroy ();
                        }
@@ -426,8 +492,13 @@ class TorStatusMenuItem : HD.StatusMenuItem {
                                        store.append (out iter);
                                }
                                store.@set (iter, 0, "%s:%d".printf (ip_entry.get_text (), port));
-
-                               bridges = gconf.get_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING);
+                               try {
+                                       bridges = gconf.get_list (GCONF_KEY_BRIDGES,
+                                                                 GConf.ValueType.STRING);
+                               } catch (Error e) {
+                                       Hildon.Banner.show_information (null, null,
+                                                                       "Error loading bridges: %s".printf (e.message));
+                               }
                                if (path == null) {
                                        bridges.append ("%s:%d".printf (ip_entry.get_text (), port));
                                } else {
@@ -438,7 +509,14 @@ class TorStatusMenuItem : HD.StatusMenuItem {
                                                bridges.append (bridge);
                                        } while (store.iter_next (ref iter));
                                }
-                               gconf.set_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING, bridges);
+                               try {
+                                       gconf.set_list (GCONF_KEY_BRIDGES,
+                                                       GConf.ValueType.STRING,
+                                                       bridges);
+                               } catch (Error e) {
+                                               Hildon.Banner.show_information (dialog, null,
+                                                                               "Failed to save bridge relay list: %s".printf (e.message));
+                               }
 
                                dialog.destroy ();
                        }