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_stringlibrary, 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
TorBootstrapthreads from being garbage collected while they are still running. This should likely be implemented by creating a global set that storesTorBootstrapthread objects, then using a signal handler to remove each thread from that set when it terminates. The existingtor_bootstrapvariable 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.