X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fstatus-area-applet-tor.vala;h=8bb41fa81bdab38292d15bbacbeb06a4711df42c;hb=579a260bd3cc8a6bcaadb6e44317a65ff14b03a9;hp=dc7e35ef534f49eaff66bd97d69cdde2c889618b;hpb=164dbb8b6045ba1664a08ccd45b1e68570a3efa7;p=tor-status diff --git a/src/status-area-applet-tor.vala b/src/status-area-applet-tor.vala index dc7e35e..8bb41fa 100644 --- a/src/status-area-applet-tor.vala +++ b/src/status-area-applet-tor.vala @@ -37,6 +37,7 @@ class TorStatusMenuItem : HD.StatusMenuItem { private const string GCONF_DIR_TOR = "/apps/maemo/tor"; private const string GCONF_KEY_TOR_ENABLED = GCONF_DIR_TOR + "/enabled"; private const string GCONF_KEY_BRIDGES = GCONF_DIR_TOR + "/bridges"; + private const string GCONF_KEY_EXITNODES = GCONF_DIR_TOR + "/exit_nodes"; private const string GCONF_DIR_PROXY_HTTP = "/system/http_proxy"; private const string GCONF_KEY_PROXY_HTTP_ENABLED = GCONF_DIR_PROXY_HTTP + "/use_http_proxy"; @@ -52,6 +53,7 @@ class TorStatusMenuItem : HD.StatusMenuItem { // Widgets Hildon.Button button; + Gtk.Label log_label; // Icons Gdk.Pixbuf icon_connecting; @@ -79,42 +81,42 @@ class TorStatusMenuItem : HD.StatusMenuItem { /** * Update status area icon and status menu button value */ - private void update_status () { - if (tor_enabled && tor_connected && icon_connected == null) try { - var icon_theme = Gtk.IconTheme.get_default (); - var pixbuf = icon_theme.load_icon ("statusarea_tor_connected", - STATUS_AREA_ICON_SIZE, - Gtk.IconLookupFlags.NO_SVG); - icon_connected = pixbuf; + private bool update_status () { + try { + if (tor_enabled && tor_connected && icon_connected == null) { + var icon_theme = Gtk.IconTheme.get_default (); + var pixbuf = icon_theme.load_icon ("statusarea_tor_connected", + STATUS_AREA_ICON_SIZE, + Gtk.IconLookupFlags.NO_SVG); + icon_connected = pixbuf; + } + if (tor_enabled && !tor_connected && icon_connecting == null) { + var icon_theme = Gtk.IconTheme.get_default (); + var pixbuf = icon_theme.load_icon ("statusarea_tor_connecting", + STATUS_AREA_ICON_SIZE, + Gtk.IconLookupFlags.NO_SVG); + icon_connecting = pixbuf; + } + if (tor_enabled && icon_enabled == null) { + var icon_theme = Gtk.IconTheme.get_default(); + var pixbuf = icon_theme.load_icon ("statusarea_tor_enabled", + STATUS_MENU_ICON_SIZE, + Gtk.IconLookupFlags.NO_SVG); + icon_enabled = new Gtk.Image.from_pixbuf (pixbuf); + } + if (!tor_enabled && icon_disabled == null) { + var icon_theme = Gtk.IconTheme.get_default(); + var pixbuf = icon_theme.load_icon ("statusarea_tor_disabled", + STATUS_MENU_ICON_SIZE, + Gtk.IconLookupFlags.NO_SVG); + icon_disabled = new Gtk.Image.from_pixbuf (pixbuf); + } } catch (Error e) { - error (e.message); - } - if (tor_enabled && !tor_connected && icon_connecting == null) try { + critical (e.message); var icon_theme = Gtk.IconTheme.get_default (); - var pixbuf = icon_theme.load_icon ("statusarea_tor_connecting", - STATUS_AREA_ICON_SIZE, - Gtk.IconLookupFlags.NO_SVG); - icon_connecting = pixbuf; - } catch (Error e) { - error (e.message); - } - if (tor_enabled && icon_enabled == null) try { - var icon_theme = Gtk.IconTheme.get_default(); - var pixbuf = icon_theme.load_icon ("statusarea_tor_enabled", - STATUS_MENU_ICON_SIZE, - Gtk.IconLookupFlags.NO_SVG); - icon_enabled = new Gtk.Image.from_pixbuf (pixbuf); - } catch (Error e) { - error (e.message); - } - if (!tor_enabled && icon_disabled == null) try { - var icon_theme = Gtk.IconTheme.get_default(); - var pixbuf = icon_theme.load_icon ("statusarea_tor_disabled", - STATUS_MENU_ICON_SIZE, - Gtk.IconLookupFlags.NO_SVG); - icon_disabled = new Gtk.Image.from_pixbuf (pixbuf); - } catch (Error e) { - error (e.message); + icon_theme.rescan_if_needed (); + Timeout.add_seconds (1, update_status); + return false; } if (conic_connected && tor_enabled) { @@ -125,6 +127,8 @@ class TorStatusMenuItem : HD.StatusMenuItem { button.set_value (tor_enabled ? _("Disconnected") : _("Disabled")); } button.set_image (tor_enabled ? icon_enabled : icon_disabled); + + return false; } /** @@ -139,6 +143,9 @@ class TorStatusMenuItem : HD.StatusMenuItem { /* var status = */ source.read_line (out line, out length, null); tor_log += line; + if (log_label != null) + log_label.label = tor_log; + if ("[notice]" in line) { if ("Bootstrapped 100%" in line) { tor_connected = true; @@ -170,25 +177,32 @@ class TorStatusMenuItem : HD.StatusMenuItem { private async void tor_control_auth () throws Error { yield tor_control.authenticate_async (password); - var bridges = new SList (); - try { - bridges = gconf.get_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING); - } catch (Error e) { - error ("Error loading bridges: %s", e.message); - return; + var bridges = gconf.get_list (GCONF_KEY_BRIDGES, GConf.ValueType.STRING); + + if (bridges.length () > 0) { + // 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"); + } } - if (bridges.length () <= 0) - return; + var exits = gconf.get_list (GCONF_KEY_EXITNODES, GConf.ValueType.STRING); - // Enable bridge relays - tor_control.set_conf_list ("Bridge", bridges); - tor_control.set_conf_bool ("UseBridges", true); + if (exits.length () > 0) { + // Enable strict exit nodes + tor_control.set_conf_list ("ExitNodes", exits); + tor_control.set_conf_bool ("StrictExitNodes", 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"); + bool strict = yield tor_control.get_conf_bool_async ("StrictExitNodes"); + if (!strict) { + Hildon.Banner.show_information (null, null, + "Failed to set up strict exit nodes"); + } } } @@ -209,7 +223,7 @@ class TorStatusMenuItem : HD.StatusMenuItem { 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", ""); + hash = hash.str ("\n16:").offset (1).replace ("\n", ""); if (hash == null) { Hildon.Banner.show_information (null, null, @@ -254,6 +268,8 @@ class TorStatusMenuItem : HD.StatusMenuItem { } tor_log = ""; + if (log_label != null) + log_label.label = tor_log; update_status (); } @@ -294,7 +310,7 @@ class TorStatusMenuItem : HD.StatusMenuItem { backup.mode = gconf.get_string (GCONF_KEY_PROXY_MODE); } catch (Error e) { - error ("Error saving proxy settings: %s", e.message); + critical ("Error saving proxy settings: %s", e.message); backup = new ProxyBackup (); backup.use_http_proxy = false; @@ -320,7 +336,7 @@ class TorStatusMenuItem : HD.StatusMenuItem { gconf.set_string (GCONF_KEY_PROXY_MODE, "manual"); } catch (Error e) { - error ("Error changing proxy settings: %s", e.message); + critical ("Error changing proxy settings: %s", e.message); } } @@ -342,187 +358,24 @@ class TorStatusMenuItem : HD.StatusMenuItem { gconf.set_string (GCONF_KEY_PROXY_MODE, backup.mode); backup = null; } catch (Error e) { - error ("Error restoring proxy: %s", e.message); + critical ("Error restoring proxy: %s", e.message); } } /** * Show the bridge relay configuration dialog */ - private const int RESPONSE_NEW = 1; private void bridges_clicked_cb () { - var dialog = new Gtk.Dialog (); - var content = (Gtk.VBox) dialog.get_content_area (); - content.set_size_request (-1, 5*70); - - dialog.set_title (_("Bridge relays")); - - var bridges = new SList (); - 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)); - } - - var list_store = new Gtk.ListStore (1, typeof (string)); - Gtk.TreeIter iter; - foreach (string bridge in bridges) { - list_store.append (out iter); - list_store.@set (iter, 0, bridge); - } - - var pannable_area = new Hildon.PannableArea (); - var tree_view = new Gtk.TreeView.with_model (list_store); - var renderer = new Gtk.CellRendererText (); - var column = new Gtk.TreeViewColumn.with_attributes ("IP", renderer, "text", 0); - tree_view.append_column (column); - pannable_area.add (tree_view); - content.pack_start (pannable_area, true, true, 0); - - tree_view.row_activated.connect ((path, column) => { - bridge_edit_dialog (list_store, path); - }); - - dialog.add_button (_("New"), RESPONSE_NEW); - dialog.response.connect ((response_id) => { - if (response_id == RESPONSE_NEW) { - bridge_edit_dialog (list_store, null); - } - }); - - dialog.show_all (); + var dialog = new BridgeDialog (); + dialog.show (); } /** - * Show the bridge relay edit dialog + * Show the exit node configuration dialog */ - private const int RESPONSE_DELETE = 1; - private void bridge_edit_dialog (Gtk.ListStore store, Gtk.TreePath? path) { - var dialog = new Gtk.Dialog (); - var content = (Gtk.VBox) dialog.get_content_area (); - - if (path == null) - dialog.set_title (_("New bridge relay")); - else - dialog.set_title (_("Edit bridge relay")); - - var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); - - var hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE); - var label = new Gtk.Label (_("IP address")); - label.set_alignment (0, 0.5f); - size_group.add_widget (label); - hbox.pack_start (label, false, false, 0); - var ip_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT); - ip_entry.set ("hildon-input-mode", Hildon.GtkInputMode.NUMERIC | - Hildon.GtkInputMode.SPECIAL); - hbox.pack_start (ip_entry, true, true, 0); - content.pack_start (hbox, false, false, 0); - - hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE); - label = new Gtk.Label (_("Port")); - label.set_alignment (0, 0.5f); - size_group.add_widget (label); - hbox.pack_start (label, false, false, 0); - var port_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT); - port_entry.set ("hildon-input-mode", Hildon.GtkInputMode.NUMERIC); - hbox.pack_start (port_entry, true, true, 0); - content.pack_start (hbox, true, true, 0); - - hbox = new Gtk.HBox (false, Hildon.MARGIN_DOUBLE); - label = new Gtk.Label (_("Fingerprint")); - label.set_alignment (0, 0.5f); - size_group.add_widget (label); - hbox.pack_start (label, false, false, 0); - var fingerprint_entry = new Hildon.Entry (Hildon.SizeType.FINGER_HEIGHT); - fingerprint_entry.set ("hildon-input-mode", Hildon.GtkInputMode.HEXA); - hbox.pack_start (fingerprint_entry, true, true, 0); - content.pack_start (hbox, true, true, 0); - - var iter = Gtk.TreeIter (); - if (path == null) { - port_entry.set_text ("443"); - } else if (store.get_iter (out iter, path)) { - string tmp; - store.@get (iter, 0, out tmp); - string[] ip_port = tmp.split (":"); - if (ip_port.length == 2) { - ip_entry.set_text (ip_port[0]); - port_entry.set_text (ip_port[1]); - } - - dialog.add_button (_("Delete"), RESPONSE_DELETE); - } - dialog.add_button (_("Save"), Gtk.ResponseType.OK); - dialog.response.connect ((response_id) => { - var bridges = new SList (); - - if (response_id == RESPONSE_DELETE) { - if (path != null) { - store.remove (iter); - string bridge; - if (store.get_iter_first (out iter)) do { - store.@get (iter, 0, out bridge); - bridges.append (bridge); - } while (store.iter_next (ref iter)); - 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 (); - } - if (response_id == Gtk.ResponseType.OK) { - if (!is_valid_ip_address (ip_entry.get_text ())) { - Hildon.Banner.show_information (dialog, null, - _("Invalid IP address")); - return; - } - int port = port_entry.get_text ().to_int (); - if (port < 0 || port > 65565) { - Hildon.Banner.show_information (dialog, null, - _("Invalid port number")); - return; - } - if (path == null) { - store.append (out iter); - } - store.@set (iter, 0, "%s:%d".printf (ip_entry.get_text (), port)); - 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 { - bridges = null; - string bridge; - if (store.get_iter_first (out iter)) do { - store.@get (iter, 0, out bridge); - bridges.append (bridge); - } while (store.iter_next (ref iter)); - } - 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 (); - } - }); - - dialog.show_all (); + private void exit_nodes_clicked_cb () { + var dialog = new ExitNodeDialog (tor_control); + dialog.show (); } /** @@ -555,10 +408,15 @@ class TorStatusMenuItem : HD.StatusMenuItem { var pannable = new Hildon.PannableArea (); pannable.mov_mode = Hildon.MovementMode.BOTH; - var label = new Gtk.Label (tor_log); - pannable.add_with_viewport (label); + log_label = new Gtk.Label (tor_log); + log_label.set_alignment (0, 0); + pannable.add_with_viewport (log_label); content.pack_start (pannable, true, true, 0); + dialog.response.connect (() => { + log_label = null; + }); + dialog.show_all (); } @@ -569,7 +427,7 @@ class TorStatusMenuItem : HD.StatusMenuItem { private void button_clicked_cb () { var dialog = new Gtk.Dialog (); var content = (Gtk.VBox) dialog.get_content_area (); - content.set_size_request (-1, 2*70); + content.set_size_request (-1, 3*70); dialog.set_title (_("Tor: anonymity online")); @@ -587,6 +445,15 @@ class TorStatusMenuItem : HD.StatusMenuItem { button.clicked.connect (bridges_clicked_cb); content.pack_start (button, true, true, 0); + button = new Hildon.Button.with_text (Hildon.SizeType.FINGER_HEIGHT, + Hildon.ButtonArrangement.VERTICAL, + _("Restrict exit nodes"), + get_exit_node_list ()); + button.set_style (Hildon.ButtonStyle.PICKER); + button.set_alignment (0, 0.5f, 0, 0.5f); + button.clicked.connect (exit_nodes_clicked_cb); + content.pack_start (button, true, true, 0); + dialog.add_button (_("Log"), RESPONSE_LOG); dialog.add_button (_("Save"), Gtk.ResponseType.ACCEPT); @@ -624,7 +491,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); + critical ("Error loading bridges: %s", e.message); } foreach (string bridge in bridges) { if (list == null) @@ -638,6 +505,26 @@ class TorStatusMenuItem : HD.StatusMenuItem { return list; } + private string get_exit_node_list () { + string list = null; + var exits = new SList (); + try { + exits = gconf.get_list (GCONF_KEY_EXITNODES, GConf.ValueType.STRING); + } catch (Error e) { + error ("Error loading exit nodes: %s", e.message); + } + foreach (string exit in exits) { + if (list == null) + list = exit; + else + list += ", " + exit; + } + if (list == null) + list = _("None"); + + return list; + } + /** * Callback for the ConIc connection-event signal */ @@ -689,6 +576,8 @@ class TorStatusMenuItem : HD.StatusMenuItem { add (button); + log_label = null; + // Status area icon update_status (); @@ -706,7 +595,7 @@ class TorStatusMenuItem : HD.StatusMenuItem { try { tor_enabled = gconf.get_bool (GCONF_KEY_TOR_ENABLED); } catch (Error e) { - error ("Failed to get GConf setting: %s", e.message); + critical ("Failed to get GConf setting: %s", e.message); } tor_connected = false;