Tor controller GUI (tor-control-panel)

Patrick and I discussed the merged Tor Control Panel and Anon Connection Wizard recently. Ultimately while this code is messier than I would like, and the vast majority of the TODOs from my original review have not been dealt with, we think it’s best to merge this. It’s better than what was there before, it does work (I tested it pretty thoroughly on Qubes OS, no issues there, and Qubes and non-Qubes don’t differ enough in this area for issues on other virtualizers to be likely), and it doesn’t look like it introduces any security issues.

Some testing notes, bugs found, and TODOs from my last review are below.


Test plan for Tor Control Panel:

  • Open Tor Control Panel.

  • Three tabs are shown, “Control”, “Utilities”, and “Logs”?

  • “Control” is selected by default?

  • Ensure Tor is running. Tor status shows as “Tor status: Connected to the Tor network!”?

  • User configuration shows “Bridges type: None” and “Proxy type: None”?

  • Control shows “Restart Tor”, “Stop Tor”, and “Configure”?

  • “Exit” button is shown in lower-right corner?

  • Click “Restart Tor”. Tor status morphs and goes through the following states:

    • Constructing tor controller…
    • Connected to a relay…
    • Connected to a relay…
    • Handshaking…
    • Establishing a Tor circuit…
    • Connected to the Tor network!
  • Click “Stop Tor”. Tor status morphs to “Tor is not running”?

  • Click “Restart Tor”. Above states are shown again?

  • Click “Configure”. “Bridges type:” and “Proxy type:” become editable?

  • Help buttons appear next to each?

  • “Configure” button morphs into “Accept”?

  • Help buttons, when clicked, display useful help information in dialog boxes?

  • Change both “Bridges type” and “Proxy type”, then click the back button in the lower-right corner of the box. Changes are reverted?

  • Click “Configure” again, then change “Bridges type” to “obfs4” and click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!”, but mentions a pluggable transport near the beginning?

  • Click “Configure”, change “Bridges type” to “Snowflake”, and click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!”, but does so rather slowly?

  • Tor log mentions “snowflake-client” near the end?

  • Click “Configure”, change “Bridges type:” to “meek”, and click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!”, but does so rather slowly?

  • Tor log mentions “meek_lite” near the end?

  • Click “Configure”, change “Bridges type:” to “Disable network”, and click “Accept”. Stops Tor and says “The network is disabled.”, and prevents restarting Tor?

  • Click “Configure”, change “Bridges type:” to “Enable network”, and click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!”, but does so rather slowly?

  • Tor log mentions “meek_lite” near the end?

  • Click “Configure”, change “Bridges type:” to “None”, and click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!” rather quickly?

  • Click “Configure”, change “Proxy type” to SOCKS5, and set one of the proxies from the proxifly free proxy list. Then click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!” rather quickly?

  • Repeat the above but with a SOCKS4 proxy. Same result?

    • Note that HTTP proxies are notoriously unreliable, don’t bother with those
  • Click “Configure”, change “Proxy type” to None, then click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!” rather quickly?

  • Click “Configure”, change “Bridges type” to “Custom bridges”, then click “Accept”. Custom bridge configuration screen appears?

  • Click “Cancel”. Goes back to “Control” screen?

  • Click “Configure”, change “Bridges type” to “Custom bridges”, then click “Accept”. Custom bridge configuration screen appears?

  • Get bridges from Tor’s BridgesDB, plug them into the bridge list, and click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!”, but mentions a pluggable transport near the beginning?

  • Click “Configure”, change “Bridges type:” to “None”, and click “Accept”. Tor status morphs and goes through a number of states terminating in “Connected to the Tor network!” rather quickly?

  • Click the “Utilities” tab. Shows “Onion Circuits” and “Request new Tor circuit” buttons with useful text underneath each?

  • Click “Onion Circuits”. Displays details about the circuits you are currently using?

  • Close the “Onion Circuits” app.

  • Click “Request new Tor circuit”, then immediately look at the “Control” tab. Did Tor restart?

  • Click the “Logs” tab. Shows “torrc”, “Tor log”, and “systemd journal” options in the upper-left corner, “Refresh” in the upper-right corner, and a log view below?

  • Click on each of the viewing options. Switches the log view to display the appropriate content with each click?

  • Click on the “Tor log” option.

  • Do something to cause Tor to generate new log lines (perhaps launch Nyx and close it).

  • Click “Refresh”. Logs are refreshed?

  • Click “Exit”. Application exits normally?

Test plan for Anon Connection Wizard:

  • Open Anon Connection Wizard.
  • First page offers three options, “Connect”, “Configure”, and “Disable Tor”?
  • “Next”, “Back”, and “Cancel” buttons are displayed at the bottom of the screen?
  • Ensure “Connect” is selected, then click “Next”. Displays a summary stating that “Tor will be enabled”, “Bridges: None Selected”, “Proxy: None Selected”, and has a “Show torrc” button?
  • Click “Back”. Returns to the first page?
  • Click “Next” again. Shows the summary page again?
  • Click “Details”. Button morphs to “Hide”, and a Tor configuration file with a single “DisableNetwork 0” line is displayed?
  • Click “Hide”. Button morphs to “Show torrc”, configuration details vanish?
  • Click “Next”. Displays “Bootstrapping tor”, which eventually morphs to “Tor bootstrapping done”?
  • Click “Finish”.
  • Re-open Anon Connection Wizard.
  • On the first page, click “Disable Tor”, then click “Next”. Displays a “Tor is disabled” screen?
  • sdwdate-gui icon has morphed to an “X”?
  • Click “Finish”.
  • Re-open Anon Connection Wizard.
  • Click “Disable Tor” again, then click “Next” again.
  • On the 'Tor is disabled" screen, click “Back”.
  • On the first page, click “Configure”, then “Next”. Displays a “Tor Bridges Configuration” page with a checkbox “I need bridges to bypass censorship”, and a “Help ?” button?
  • Click “Help ?”. Displays a help window?
  • Dismiss the help window by clicking “OK”.
  • Click “Next”. Displays a “Local Proxy Configuration” screen with a checkbox “Use proxy before connecting to the Tor network”?
  • Click “Next”. Displays the same summary screen that would be displayed if you had used “Connect”?
  • Click “Next”. Displays “Bootstrapping tor”, which eventually morphs to “Tor bootstrapping done”?
  • Click “Back”. Goes back to the summary screen?
  • Click “Back”. Goes back to the “Local Proxy Configuration” screen?
  • Click “Back”. Goes back to the “Tor Bridges Configuration” screen?
  • Check “I need bridges…”. Displays a combo box “Select a bridge type” offering obfs4, snowflake, meek, and custom bridges?
  • Ensure a transport type of “obfs4” is selected, then click “Next” repeatedly until the last screen is displayed. Displays “Bootstrapping tor”, says something about a pluggable transport, and eventually gets to “Connected to the Tor network!”?
  • Click “Back” until you are back to the “Tor Bridges Configuration” screen.
  • Select a bridge type of “meek”, then click “Next” repeatedly until the last screen is displayed. Displays “Bootstrapping tor”, and eventually gets to “Connected to the Tor network!”, but slowly?
  • Click “Back” until you are back to the “Tor Bridges Configuration” screen.
  • Select a bridge type of “snowflake”, then click “Next” repeatedly until the last screen is displayed. Displays “Bootstrapping tor”, and eventually gets to “Connected to the Tor network!”, but slowly?
  • Click “Back” until you are back to the “Tor Bridges Configuration” screen.
  • Select “Custom bridges”. Bridge input field appears, and a “How to get Bridges?” button appears?
  • Click “How to get Bridges?”. Displays a help dialog?
  • Dismiss the help dialog with “OK”.
  • Paste bridge lines into the custom bridges field, then click “Next” repeatedly until the last screen is displayed. Displays “Bootstrapping tor”, mentions something about a pluggable transport, and eventually gets to “Connected to the Tor network!”?
  • Click “Back” until you are back to the “Tor Bridges Configuration” screen.
  • Uncheck “I need bridges…”, then click “Next”.
  • On the “Local Proxy Configuration” screen, check “Use proxy before connecting to the Tor network”. Displays a proxy configuration UI, with a “Help ?” button?
  • Click “Help ?”. Displays a help dialog?
  • Dismiss the help dialog with “OK”.
  • Select a proxy type of “SOCKS5”, then plug in a SOCKS5 proxy and click “Next” repeatedly until the last screen is displayed. Displays “Bootstrapping tor”, and eventually gets to “Connected to the Tor network!”?
  • Minor bug: “Unknown Bootstrap TAG” message appears on the “Bootstrapping Tor” screen when connecting via a proxy.
  • Click “Back” until you are back to the “Local Proxy Configuration” screen.
  • Select a proxy type of “SOCKS4”, then plug in a SOCKS4 proxy and click “Next” repeatedly until the last screen is displayed. Displays “Bootstrapping tor”, and eventually gets to “Connected to the Tor network!”?
  • Click “Back” until you are back to the “Local Proxy Configuration” screen.
  • Uncheck “Use proxy before connecting to the Tor network”, then click “Next”. Summary indicates that no bridges will be used?
  • Click “Cancel”. Closes Anon Connection Wizard?
  • Re-open Anon Connection Wizard.
  • Ensure “Connect” is selected, then click “Next” repeatedly until Tor connects. Connection is successful?
  • Click “Finish”. Closes Anon Connection Wizard?

Test plan for restart-tor-gui:

  • Run /usr/bin/restart-tor-gui. Displays a popup showing progress connecting to the Tor network, which eventually disappears of its own accord?

Bugs found during testing:

  • tor-control-panel: If, on the “Control” tab, you first click “Restart Tor”, then click “Configure”, then open up the “Bridges type” selector, there will be two “Disable network” entries at the bottom of the selector.
  • tor-control-panel: If one configures custom bridges, clicks “Accept”, then configures a proxy, and clicks “Accept” again, the custom bridges are removed from the torrc file and are replaced with the default obfs4 bridges.
  • anon-connection-wizard: If you check “I need bridges to bypass censorship”, set a bridge type of “Custom bridges”, click “Next”, then click “Back”, then uncheck “I need bridges to bypass censorship”, the layout breaks slightly. “I need bridges to bypass censorship” ends up near the middle of the window.
  • anon-connection-wizard: When closing with the “Cancel” button, the wizard crashes:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/tor_control_panel/anon_connection_wizard.py", line 912, in cancel_button_clicked
    if self.bootstrap_thread:
       ^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'AnonConnectionWizard' object has no attribute 'bootstrap_thread'. Did you mean: 'bootstrap_done'?
zsh: IOT instruction (core dumped)  anon-connection-wizard

TODOs:

  • Add string sanitization for untrusted input. This should be a matter of using helper-scripts’ sanitize_string library, and calling it every time any data is read from Tor or the system journal. We may need to vendor a copy of this library in tor-control-panel so that it’s easier to make it usable on systems other than Whonix in the future.
  • Prevent TorBootstrap threads from being garbage collected while they are still running. This should likely be implemented by creating a global set that stores TorBootstrap thread objects, then using a signal handler to remove each thread from that set when it terminates. The existing tor_bootstrap variable should remain in place so that functions can access the “active” thread.
  • Verify that no other issues exist that could result in a QObject-derived object being freed while it is still in use. (I didn’t catch any other issues in a brief manual review, and the QThread issue was noticed by ChatGPT, so there probably aren’t a lot more of these issues, if any.)
  • Fix the bugs noted above.
  • Long-term, clean up the code substantially so that it is less fragile and easier to understand and develop. This is low-priority.
2 Likes

Plan…

I’ll fix list of issues / todo using claude code. Surgical fixes.

Assign initial review/testing to @troubadour and final review/testing to @arraybolt3.

Input strings from Tor should be considered untrusted and hardening is required in the age of AI.

Therefore I suggest not doing major change until this is completed.

2 Likes

UI is the biggest make or break change to the user experience, defer it until the last batch and assign higher priority values for the remaining issues.

Good news to have some news!

Lately, I have been working exclusively on TCP for Debian. It looks quite promising. Stuck with one minor weird issue and a configure script (perhaps a wizard since my tests are done with a manual configuration). Once completed, it will probably deserve a new thread.

I thought I had addressed most of the TODOs, so most likely not.

I will try to reply to some of your remarks.

The connections steps are outdated. Checked with TBB. We’ll have to update tor_bootstarp.py.

The text in the dialog boxes might be updated.

It’s even slower with TBB in Debian, be it obsf4 (if it manages to connect), snowflake or meek. The same applies to custom bridges, both in TBB or with TCP Debian. Still have to test in Qubes

It can be worse. If you select “Disable network”, it works instantly. Now, select “Enable network” without closing TCP firstly. Most of the time, TCP hangs up or the window vanished. Looking into that. Remark: tor_status.py was completely rewritten.

Seems normal, since we don’t use a pluggable transport.

Yes, and you can check your exit relay in Check your connection or so in the default torbrowser page (new tab after the Whonix local page). Most of the time,it changes after “Request new Tor circuit”.

This a very early bug that I have to attend. Also, after selecting “Disable network”, the configure command shows both “Disable network” and “Enable network”, which should not.

Test plan for restart-tor-gui:

Yes, this is intentional. Now, I’m wondering about the pertinence of keeping restart-tor-gui. In my opinion, it its redundant because we have restart tor in TCP

Regarding Anon Connection Wizard, I’m redacting this post in plain Debian. I’ll have to switch to Qubes, and look at it when TCP is merged.BTW, ACW and restart-tor-gui are removed in the Debian version.

Since you and @arraybolt3 agree that the latest TCP can be merged, can you let me know when it’s done.

1 Like

For the test plan stuff, the points in the plan weren’t criticisms of how the app behaved, they were notes on how the pre-merge app behaved, that I verified the new app continues to behave that way. All of those things (including connecting rather slowly) are good things (slower connectivity is part of how I know Tor is actually going through a bridge).

It’s possible some code wasn’t pushed? Not sure. I used Meld to compare my merged-tcp-review repo with the latest code from your tor-control-panel repo, and while some of the TODOs were handled, most of them (mostly related to how the UI layout was built) had no code changes surrounding them, indicating that they weren’t dealt with yet. That’s not a problem though, if the app functionally works and isn’t a security hazard, it’s good enough. The other stuff can be dealt with some other time.

1 Like

Pretty much all issues / style / features should be implemented now. Please let me know if anything is missing. Fuzzing, CodeQL, coverity, bandit was also added.

tor-control-panel (TCP) standalone for Debian without dependency on privleap and/or helper-scripts may not worthwhile. The pull request below supports privleap as optional dependency with fallback to pkexec or passwordless sudo. But not sure that should be removed. Privleap is fine as is.

helper-scripts includes sanitize-string. Essential for security. TCP is now using it.

Getting sanitize-string right wasn’t easy at all.
Vendoring in sanitize-string in TCP seems wrong.

Dependency on anon-gw-anonymizer-config has been removed.

Debian support seems doable if maintained by @troubadour.

Maximum simplicity for packages.debian.org seems too much effort while no Debian Developer (DD) expressed interest in uploading to packages.debian.org.

Typically packages uploaded to packages.debian.org first gain users, traction by themselves before any DD gets interested. If a DD gets interested, they can post wishlist requests and I’ll likely support it (by polishing helper-scripts to make it suitable). Until that happens, this seems unnecessary effort.

Keep restart-tor-gui. Has start menu entry. Easy to maintain. Not a big deal.

Surgical edits only wasn’t possible because the whole laundry list of issues, style and feature requests as been implemented.

Ready for review (and merge, if useful). @troubadour

  • Folder ‎.clusterfuzzlite does not need a deep review. A non-malicious review would suffice. That code runs only on untrusted CI.
  • The same goes for the .github folder.
  • Also appliable to the fuzz folder.

There is also a large number of tests in dist-ai/usr/share/tor-control-panel-tests at master · org-ai-assisted/dist-ai · GitHub but these are probably too much for human review. These tests should only be run on untrusted CI.

Just noticed the history of GitHub - troubadoour/tor-control-panel · GitHub is shorter than and unrelated to GitHub - Kicksecure/tor-control-panel: Tor controller graphical control panel · GitHub. We cannot discard the history for no previously discussed reason. That causes confusion and merge conflicts. So any future work of tor-control-panel should be branched off Kicksecure/tor-control-panel (or org-ai-assisted/tor-control-panel - in case that is useful).

Step by step.

Fixed the annoying double Disable network.

Note that in tor_status.py, stop tor is replaced by restart tor int the set_disabled function, setting tor status to “disabled-running”. It seems to make sense, because tor should not be stopped at this stage. We only write DisableNetwork 1 in torrc.

1 Like

@arraybolt3 The problem with the change in tor_status.py(if it’s accepted) is that it’s a status not taken into account by sdwdate-gui to modify the systray icon. However, when the network is disabled, Show Tor status displays the right info (Tor is running but disabled…)

1 Like

I had a quick look at github list Refurbish tor-control-panel. Except for a few items taken randomly, this is way beyond my capacities .

So, I’m on a fork of org-ai-assisted / **tor-control-pane**l, trying to fix the most obvious bugs.

The first one fixes the double Disable network issue as per my previous commit in the original tor-control-panel. Please note that tor_status.py is not modified, but I maintain that in set_diabled, Tor should be restarted instead of being stopped, to reflect the true tor status. It would be a matter of adding an icon in sdwdate-gui.Easier said than done.

Then, in anon_connection_wizard, the Cancel and Finish behave as expected. It’s a TODO removed. While debugging, it looks like there is still some refactoring, regardless of the huge list in github.

2 Likes

A bit lost here and now.

Review bug fixes (arraybolt3 / adrelanos, post #161 + inline)

  • ACW Cancel crash: self.bootstrap_thread was never initialised → AttributeError core dump on cancel. Initialised to None.

  • Duplicate network toggle: hard-coded removeItem(8) (entry is index 7) appended a second Enable/Disable entry. Replaced with a text-based toggle helper.

Do you mean that those bugs were fixed, or is that it’s only a review? I could not see any change after the last upgrade.

So I reinstalled tor-control-panel from my repository, and the bugs are fixed with the last commits.

Is there a blocker to merge them in org-ai-assisted/tor-control-panel:master ?

1 Like

We don’t necessarily need bug fixes. Only bug reports. Claude can fix the code.

Unfortunately, was unavoidable versus the goal of removing code duplication.

The org-ai-assisted / **tor-control-pane should have all bugs fixed.

It’s not merged.

Yeah.

  1. Functionality review.
  2. Non-malicious review. (That can be assigned to @arraybolt3.)

So if you could help with the functionality review, that would be useful. @troubadour