Skip to content

Improve support for Pluggable Transports in Tails

Where to find the team

tails-dev XMPP channel (https://tails.boum.org/contribute/chat/):

protocol: XMPP

server: chat.disroot.org

channel: tails-dev

Use TLS/SSL to connect!

XMPP causes trouble so we'll instead use #tails-hackweek on OFTC, hoping it excludes fewer people.

When

Tails developers will be around on Monday-Thursday, 07:00-15:00 UTC, with a long lunch break in the middle.

Team

intrigeri (coordinator)

boyska (Tails developer)

PieroV (one of Tor Browser developers)

Scope: Improve support for Pluggable Transports in Tails

Users who need to use Pluggable Transports in Tails face a chicken-and-egg situation: they need a way to get bridges outside of Tails and then to configure their bridges in Tails, which means typing a looong string. Let's improve this!

Project A: Help Tails users use the QR code from emails from bridges@torproject.org

We will evaluate applications that Tails users could use, inside Tails, to scan with their webcam the QR code from an email from bridges@torproject.org displayed on another device. Once we suitable tools, we will report our findings in the form of draft documentation.

On top of this, if time allows and Python+GTK software developers show up, we will also:

  • Integrate UI into the Tor Connection assistant to start the camera & QR code scanning application
  • Teach Tor Connection to notice bridges addresses in the clipboard, convert them from JSON, and offer the user to use them

Tracking issue: https://gitlab.tails.boum.org/tails/tails/-/issues/18219

  • scan QR code with camera → JSON
  • zbarcam --oneshot
    • conclusion: seems great for integration into Tor Connection, not good enough for the purely-doc MVP unless we write a wrapper
    • extremely simple GUI: only the video capture, no way to choose the webcam, which is OK in most cases
    • waits until it detects a QR code, and once done, it writes decoded text to stdout and exits
    • does not share QR code over D-Bus on sid, whiele the code is supposed to do it (and the binary is linked against libdbus); but really stdout is fine for integration into Tor Connection
    • same concerns with upstream project as zbarcam-gtk, see below
  • qtqr:
    • conclusion: decent option for the doc-only MVP
    • camera selection with usable name
    • more features than we need ⇒ cluttered GUI
    • the QR code is displayed in a label in a dialog; can be selected and copied
  • zbarcam-qt
    • conclusion: decent option for the doc-only MVP, and could also work for integration into Tor Connection if we fix the D-Bus support
    • GUI is cluttered by default, but we can hide controls and options via config file
    • low-level webcam name
    • in theory, can send the decoded text via D-Bus… but on sid it does not, despite the binary being linked against libdbus
    • displays decoded text in a dedicated text area
  • zbarcam-gtk
    • conclusion: no, more cons than pros vs. the other options
    • poor UX:
    • displays low-level names for cameras
    • window width expands to fit the full text extracted from the QR code, which is 1 very long line
    • window title is "test_gtk", does not look very polished
    • does not ship a .desktop file ⇒ not listed in GNOME
    • on Wayland, need to set GDK_BACKEND=x11 (fixed upstream, not released yet)
    • at least with zbarimg (CLI), an app can monitor a D-Bus service to get the extract text ⇒ can help with integration
    • last release in Feb 2021, but active dev
  • Cheese
    • conclusion: no, does not extract QR code, feature request has little traction upstream: https://gitlab.gnome.org/GNOME/cheese/-/issues/68
    • displays usable webcam names in Preferences
  • megapixels: apparently needs a config file to tell which camera should be used
  • ACTION: look for better options

  • Figure out how to integrate QR code scanning directly in Tor Connection

  • zbarcam --oneshot

    • I (PieroV) have a working proof of concept, but it uses OpenCV

    • Now I am looking for other libraries, that uses less space

    • pygame also supports webcams, but does not have a nice API (it's also marked as experimental), can enumerate webcams, but not tell their name

    • v4l2-python3 is very light (22k)

    • but it's very low-level (ioctl, and similar stuff)

    • not available on APT, but only on PyPI

    • very young, so we don't know how long it will be updated, but it seems to be Raspberry's foundation

    Example to hack: https://gist.github.com/fernandoremor/8d9efb81e25360ab38245c8e96d870c8

    • another alternative: use ffmpeg with some pipe (Tails seems to bundle it)

    • we'd need some alternative way to get webcam name

    • also, too much involved

Conclusions:

  • For a MVP this week, the fully DIY approach (v4l+zbar etc.) requires too much work.
  • The doc-based MVP may not save us that much coding and gives a worse UX.

Next steps:

  • Add support to tca-portal to run zbarcam --oneshot and collect its STDOUT (boyska)

  • Add a button in Tor Connection to get bridges JSON from QR code, using tca-portal (intrigeri)

  • step_bridge_box
  • step_error_box
  • Polish spacing & white space

  • Extract & validate bridge info from data extracted from QR code: JSON (bridges@torproject.org) or bridge line (Tor Browser >=11.5) (PieroV)

    • Current status: the code is ready (if it is being called with a string, otherwise I need to add a .decode('utf-8').

    It raises a ValueError when it believes the lines are in current format, but they cannot be parsed as JSON.

    The current format is similar to JSON, but it's actually the Python representation of the list. So it's ['line1', 'line2', ...].

    If you change single quotes with double quotes it becomes JSON... unless the string contains some illegal character (including an unescaped "). However, right now no bridge line contains neither " nor ', so the replace should just work, and any JSON decoding error just means the QR code was not valid from the beginning.

    How do you want me to merge it? With a MR on your GitLab?

  • ACTION: write Python function input=JSON output=text (or raise Exception) format that Tor Connection supports (bridge line like in torrc, without the Bridge prefix?)

    • Seems like it isn't a JSON, but it's a str([... lines ...]). I think it was meant to be '\n'.join([... lines ...]). I'm contacting the anticensorhip team to ask them

    • It seems it may be. Meskio didn't know if there is any consumer of those codes, and they may change them. The new format will be either bridge lines separated by '\n' (basically the same as Tor Browser, which write only one bridge per QR code), but it could also be the bridge:// URIs.

    • FWIW, JSON would make it easier for various consumers to share validation via a JSON schema, which is programming-language-agnostic as long as the JSON library you use supports schemas.

    • I agree, I think it was some error that was never catched, because the library that generates the QR codes must have either a str(...) or bytes(...) inside.

    For the schema, PTs can have custom parameters, Tor only says that the line must be like this: [transport] IP:ORPort [fingerprint], but after the fingerprint it can have any other additional parameter for the PT executable.

    • Bridge strings do not contain ' and " at the moment, so we could replace ' with ", and parse it as a JSON anyway; if it gives any errors, the input JSON was not valid. It's a hack, but better than evaluating the code, and is the easiest and fastest thing to do. The new format won't begin/end with [/].

    • The QR code you get from https://bridges.torproject.org are the same you'd get by email

  • Consider supporting multiple bridges in Tor Connection again (intrigeri)

  • issue: https://gitlab.tails.boum.org/tails/tails/-/issues/18981
  • It has pros and cons, it's needs UX decision that won't happen this week ⇒ we should pick only 1 bridge from the QR code for the 1st iteration.

  • Fill (replace) the bridge input widget with 1 of the bridges we got from QR code (boyska)

  • step_bridge
  • step_error

  • Robustness: what happens if user: [boyska!]

  • clicks on "scan QR code"

  • ignores the zbarcam window and fills data manually
  • you click "Connect to Tor" (or, "Back")
  • then, scans a QR code

Implemented solution: check if the results from call_async("scan-qrcode") arrives at the right step; if not, make it a no-op. ie: the value of self.state['step'] must not have changed

  • Explain sajolida which failure mode we're in, every time we ask him to write error messages

  • if not res or res.get("returncode", 1) != 0:

    zbarcam aborted before ever displaying anything to the user, most likely because there's no supported webcam.

  • if not raw_content:

    • The user manually closed the zbarcam window, likely because zbarcam did not manage to find a QR code. We could suggest they retry with another webcam.
  • TorConnectionConfig.parse_qr_content(raw_content) raises exception

    • invalid QR code e.g. I've scanned my boarding pass :P
  • differentiate these failure modes in the code so we can give different error messages.

Bonus:

  • automated tests
    • ship the v4l2loopback kernel module in Tails [intrigeri]
    • emulate a webcam at runtime [pierov]
    • see discussion on the MR, I think I put the right ffmpeg command there but did not test it with v4l2
    • figure out how to generate the QR code image on the fly when we run the test suite (we use Chutney so bridges addresses & ports are not known in advance)
    • Here is how bridges@torproject.org generates QR codes: https://gitlab.torproject.org/tpo/anti-censorship/bridgedb/-/blob/main/bridgedb/qrcodes.py tl;dr: uses the Python qrcode module, asks for a 350×350 px image in JPEG format
    • write automated test [intrigeri]
    • capture video of the test suite for the Friday presentation

Project B: Experiment with Snowflake bridges in Tails

We, the Tails developers, don't know how much work it would take to add support for Snowflake bridges in Tails. If time allows, we will experiment, discover problems, and think about solutions.

Tracking issue: https://gitlab.tails.boum.org/tails/tails/-/issues/5494

Pre-requisites

To join this project:

  • You are familiar with a Debian-based operating system.
  • You have prepared yourself:
  • Learn how to install and start Tails: https://tails.boum.org/install/.
  • Learn what are Tor bridges are and get familiar with how you can use them in Tails.

Bonus points if you have experience in software development with Python + GTK.