Opened 6 years ago

Closed 5 years ago

Last modified 5 years ago

#11345 closed enhancement (fixed)

BridgeDB should have QR codes for bridge lines

Reported by: isis Owned by: isis
Priority: Low Milestone:
Component: Circumvention/BridgeDB Version:
Severity: Keywords: bridgedb-ui, bridgedb-https, bridgedb-0.2.4, isis2014Q3Q4, bridgedb-0.3.0
Cc: isis, sysrqb, n8fr8 Actual Points:
Parent ID: Points:
Reviewer: Sponsor:


Perhaps this will make entering fingerprints easier for some people. Perhaps someday Orbot will support scanning them. Users have been reporting a lot of problems when they have to type in fingerprints by hand.

It's two lines of python:

import qrencode
qrcode = qrencode.encode('86e78dd3720c78da8683182ef96c64b162cd660c').resize([150,150])

Child Tickets

Attachments (2)

2015-01-22-230138_1223x698_scrot.png (132.4 KB) - added by isis 5 years ago.
2015-01-22-230207_1205x695_scrot.png (237.9 KB) - added by isis 5 years ago.

Download all attachments as: .zip

Change History (20)

comment:1 Changed 6 years ago by rransom

See also #5096.

comment:2 Changed 6 years ago by isis

Priority: normalminor

comment:3 Changed 6 years ago by isis

Keywords: bridgedb-https added
Status: newneeds_information
Type: defectenhancement

I want some sort of feedback that this is a useful thing to add, and that there is currently a known use-case where displaying these is going to make sense to a user, before I add a new library requirement to BridgeDB.

comment:4 Changed 6 years ago by isis

Keywords: bridgedb-ui added; bridgedb-dist removed

Ticket #12639 was a duplicate of this one and perhaps contains a bit of relevant information. This ticket should be considered the canonical bug for this feature request, however.

comment:5 Changed 6 years ago by chingucha

Priority: minornormal
Status: needs_informationnew

Increasing priority, now that Orbot supports QR codes -

comment:6 Changed 6 years ago by isis

Priority: normalminor
Status: newneeds_information

comment:7 Changed 6 years ago by n8fr8

Anything I can help with?

Changed 5 years ago by isis

Changed 5 years ago by isis

comment:8 Changed 5 years ago by isis

Status: needs_informationneeds_review

So… here is what the new BridgeDB API for this currently looks like, after you've clicked a little Show QRCode button (if you have JS enabled):

(It's prettier with JS enabled, as you get the little popuppish modal thing. If JS is disabled, it's still functional, of course, you just get a data: URI which just shows the QR code. No screenshot for that one.)

This is what is looks like before clicking the button:


I looked at Orbot's code, and it seems like, for some reason, it's not registering the intent.ACTION_VIEW mentioned on L590 of in the current master branch (09bdd8fd29a7c4086f9f95ab214e0bc77166a6f7):

        else if (action.equals(Intent.ACTION_VIEW))
            String urlString = intent.getDataString();

            if (urlString != null)

                if (urlString.toLowerCase().startsWith("bridge://"))

                    String newBridgeValue = urlString.substring(9); //remove the bridge protocol piece                                                                                                              
                    newBridgeValue = URLDecoder.decode(newBridgeValue); //decode the value here                                                                                                                     

                    showAlert("Bridges Updated","Restart Orbot to use this bridge: " + newBridgeValue,false);

So Problem #1 is that the above code doesn't work for some reason. I had three friends with Android devices (though I believe they all had the same QRCode reader app) test the above QRCode, and Orbot never picked up on the intent.

FWIW, the QRCode above contains the following:


which is just

bridge://scramblesuit a93fb6cf0709b8e732f300ff237f8cd51e5b6a7f password=ABCDEFGHIJKLMNOPQRSTUVWXYZ234567
bridge://scramblesuit eedc85ac9c946f1fda61bc9d99ee6f8a39df4fb9 password=ABCDEFGHIJKLMNOPQRSTUVWXYZ234567
bridge://scramblesuit ae6d596901e49324317d48b21dfbc51cb7b4bd40 password=ABCDEFGHIJKLMNOPQRSTUVWXYZ234567

in URL-encoded form.

The other thing I tried was to just encode the plain bridge lines into a QRCode (i.e. without the 'bridge://' scheme), and ask them to copy+paste it. This worked, but was obviously very painful because it took like 10 rather complicated UI steps (and is probably different for each QRCode app).

Another problem is that I'm not sure how Orbot intends to receive multiple bridge lines, because the above code doesn't handle that case.

comment:9 Changed 5 years ago by isis


Perhaps I should make the modal movable/draggable, so that users can print their textual bridge lines and the QR without wasting an extra sheet of paper.

comment:10 Changed 5 years ago by isis

Resolution: fixed
Status: needs_reviewclosed

Okay, this is merged to develop for 0.2.4. The code lives in my fix/11345-qrcodes_r2 branch. Currently, there is a boolean flag to pass to the bridgedb.qrcodes.generateQR() function which will decide whether or not to make "Orbot-style" QRCodes which have the "bridge://" schema prefix:

diff --git a/lib/bridgedb/ b/lib/bridgedb/
index a76cf8f..8016262 100644
--- a/lib/bridgedb/
+++ b/lib/bridgedb/
@@ -25,13 +25,15 @@ except ImportError:
                    "work. On Debian-based systems, this should be in the "
                    "python-qrcode package."))
-def generateQR(bridgelines, imageFormat=u'JPEG'):
+def generateQR(bridgelines, imageFormat=u'JPEG', bridgeSchema=False):
     """Generate a QRCode for the client's bridge lines.
     :param str bridgelines: The Bridge Lines which we are distributing to the
+    :param bool bridgeSchema: If ``True``, prepend ``'bridge://'`` to the
+        beginning of each bridge line before QR encoding.
     :rtype: str or ``None``
     :returns: The generated QRCode, as a string.
     logging.debug("Attempting to encode bridge lines into a QRCode...")
@@ -43,16 +45,26 @@ def generateQR(bridgelines, imageFormat=u'JPEG'):"Not creating QRCode for bridgelines; no qrcode module.")
+        if bridgeSchema:
+            # See for why bridge:// is used.
+            # (Hopefully, Orbot will pick up the ACTION_VIEW intent.)
+            schema = 'bridge://'
+            prefixed = []
+            for line in bridgelines.strip().split('\n'):
+                prefixed.append(schema + line)
+            bridgelines = '\n'.join(prefixed)
+        logging.debug("QR encoding bridge lines: %s" % bridgelines)
         qr = qrcode.QRCode()

(See commit 66ef631c51176777da212ab02f7a0d47dff00579.) However, the current default is to not add the prefix because it doesn't seem to help Orbot pick up the intent.ACTION_VIEW, and it definitely makes copy+pasting the text from the QRCode much harder to do manually. Also, having the schema prefix would mean that TorLauncher in Tails would have to do extra processing to get rid of it (if, in the future, we were to support holding up QRCodes to the webcam for TorLauncher to extract bridge lines).

comment:11 Changed 5 years ago by isis

Keywords: bridgedb-0.2.4 added

comment:12 Changed 5 years ago by isis

Keywords: Isis2014Q3Q4 added

comment:13 Changed 5 years ago by isis

Keywords: isis2014Q3Q4 added; Isis2014Q3Q4 removed

comment:14 Changed 5 years ago by isis

Keywords: bridgedb-0.2.5 added

I just merged fix/11345-qrcodes_r2 again, with two very minor fixes for a typo and to more efficiently return after a certain error is hit (neither of these change functionality) (see 6293394fba0f6dbf00223435d15b301cd7fb712b and 99f3b3f978dbacdfdf45bca8d7a6339e03d94af1) and a commit for unittests (129dc997439dfb4c218c482b1838078c51e41f00).

Last edited 5 years ago by isis (previous) (diff)

comment:15 Changed 5 years ago by n8fr8

Glad to see this was implemented and release. I know it was a lot of work!

Orbot does indeed support ACTION_VIEW and bridge:// encoded URLs. I am not sure why it wasn't working for you. Perhaps because you are generating three bridge:// lines and not just one long link? Android only except one URI in a QRCode.

If you encode the bridge lines with the \n as a whole URL encoded string, Orbot will decode that properly:

comment:16 Changed 5 years ago by n8fr8

Looking at the code above, it looks like you are encoding the bridge:// into bridge%3A which isn't correct.

It should be:


comment:17 Changed 5 years ago by isis

Keywords: bridgedb-0.3.0 added; bridgedb-0.2.5 removed

comment:18 Changed 5 years ago by eighthave

I think the bridge: URI will work a lot better if it fits into the standard definitions of the bits of a "hierarchical URI", i.e.


Most systems provide parsers that make it trivial to get the pieces of URI, for example or So maybe for bridges it would be something like:


So user is user, password is password, host is the IP addres, port is the port, path is the bridge type, and everything else is in the query string as key/value pairs.

Note: See TracTickets for help on using tickets.