[tor-bugs] #29347 [Obfuscation/meek]: Rewrite meek-http-helper as a WebExtension

Tor Bug Tracker & Wiki blackhole at torproject.org
Thu Feb 14 05:53:06 UTC 2019


#29347: Rewrite meek-http-helper as a WebExtension
------------------------------+--------------------------
 Reporter:  dcf               |          Owner:  dcf
     Type:  enhancement       |         Status:  assigned
 Priority:  Medium            |      Milestone:
Component:  Obfuscation/meek  |        Version:
 Severity:  Normal            |     Resolution:
 Keywords:  webextension      |  Actual Points:
Parent ID:                    |         Points:
 Reviewer:                    |        Sponsor:
------------------------------+--------------------------

Comment (by dcf):

 Here is a first version, using the scheme I described in comment:5. It
 doesn't support domain fronting or a proxy yet, but it is enough to
 bootstrap 100% with `meek-client --helper`.
  * [https://gitweb.torproject.org/pluggable-
 transports/meek.git/log/?h=webextension&id=0245c8e73900eb8f90775d9206610547b9f1f216
 webextension branch]
  * [https://gitweb.torproject.org/pluggable-
 transports/meek.git/diff/?h=webextension&id=0245c8e73900eb8f90775d9206610547b9f1f216&id2=bbe789add5ece1d493f065ff0d0b125b0c2a6c78
 diff]

 Next I'm going to add domain fronting and proxy support, but feedback is
 welcome in the meantime.

 === Setup instructions ===

 I used Firefox 65.

 1. Compile the native application.
    {{{
 cd webextension/native && go build
    }}}
 2. Edit meek.http.helper.json and set the `"path"` field to the path to
 the native application.
    {{{
 "path": "/path/to/webextension/native/native",
    }}}
 3. Copy the edited meek.http.helper.json file to the
 [https://developer.mozilla.org/en-US/docs/Mozilla/Add-
 ons/WebExtensions/Native_manifests#Manifest_location OS-appropriate
 location]. The meek.http.helper.json file is called the "host manifest" or
 "app manifest" and it tells the browser where to find the native part of
 the WebExtension.
    * macOS
      {{{
 mkdir -p ~/"Library/Application Support/Mozilla/NativeMessagingHosts/"
 cp meek.http.helper.json ~/"Library/Application
 Support/Mozilla/NativeMessagingHosts/"
      }}}
    * other Unix
      {{{
 mkdir -p ~/.mozilla/native-messaging-hosts/
 cp meek.http.helper.json ~/.mozilla/native-messaging-hosts/
      }}}
    * no Windows yet, see below
 4. Run Firefox in a terminal so you can see its stdout. In Firefox, go to
 about:config and set
    {{{
 browser.dom.window.dump.enabled=true
    }}}
    This enables the extension to write to stdout.
 5. In Firefox, go to about:debugging and click
 [https://developer.mozilla.org/en-US/docs/Tools/about:debugging
 #Loading_a_temporary_add-on "Load Temporary Add-on..."]. Find
 webextension/manifest.json and click Open. In the terminal, you should see
 a line like this, with a random port number in place of ''XXXX'':
    {{{
 meek-http-helper: listen 127.0.0.1:XXXX
    }}}

 Test it out with this torrc (you need to replace ''XXXX''):
 {{{
 UseBridges 1
 ClientTransportPlugin meek exec ./meek-client --helper 127.0.0.1:XXXX
 --log meek-client.log
 Bridge meek 0.0.2.0:1 url=https://meek.bamsoftware.com/
 }}}

 In the browser, open the browser console with Ctrl+Shift+J and you will
 see the requests being made.

 === Notes ===

 The WebExtension is made of two parts: the extension and the native
 application. The extension itself is JavaScript, runs in the browser, and
 is responsible for making HTTP requests as instructed. The native
 application runs as a subprocess of the browser; its job is to open a
 localhost socket and act as an intermediary between the extension and
 meek-client, because the extension cannot open a socket by itself.

 The in-browser part of the WebExtension is actually really really simple
 now. Most of the XPCOM extension was concerned with IPC, but now native
 messaging takes care of that. It will get a little more complicated once I
 add the ability to override the Host header and use a proxy.

 The main complication in the native part of the WebExtension is that we
 have to share the [https://developer.mozilla.org/en-US/docs/Mozilla/Add-
 ons/WebExtensions/Native_messaging#App_side stdio channel] to the browser
 among many request–response pairs. Formerly, the XPCOM extension opened a
 server socket and did one request–response exchange for each new TCP
 connection. The TCP connection provided a natural binding between a
 request and its corresponding response. But now, every request and
 response must use the permanent stdio–stdout channel. To make this work, I
 had the native part of the extension tag every request with a random ID
 before sending it to the browser. When the browser sends back a response,
 it also tags the response with the same ID. That way, the native part can
 match them up and continue to provide the same old old-connection-per-
 roundtrip interface to meek-client.

 Another slight complication is that meek-client needs to know the
 listening port of the native part, which is two levels down in the process
 hierarchy. To make this work, I added a `"report-address"` command that
 the native part can send to the in-browser part to inform it of its
 address. Then the in-browser part can write it to stdout as before.

 Coincidentally, the WebExtension stdio protocol for transmitting JSON
 objects is almost exactly the same as the one I invented for `meek-client
 --helper`. The only difference is that meek-client uses a big-endian
 length prefix and WebExtension uses native-endian.

 The need to install a host manifest (meek.http.helper.json) is a bit of a
 bummer, as is the requirement that it contain
 [https://developer.mozilla.org/en-US/docs/Mozilla/Add-
 ons/WebExtensions/Native_manifests#Manifest_location an absolute path] to
 the native app. But I presume we can work around these by setting `$HOME`
 to be within the browser bundle, and perhaps rewrite some paths on first
 run. But the really awkward thing is that on Windows, there is no fixed
 location for the host manifest; you have to set a
 [https://developer.mozilla.org/en-US/docs/Mozilla/Add-
 ons/WebExtensions/Native_manifests#Windows registry key] pointing to it,
 one of:
 {{{
 HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\NativeMessagingHosts\meek.http.helper
 HKEY_CURRENT_USER\SOFTWARE\Mozilla\NativeMessagingHosts\meek.http.helper
 }}}
 I'm pretty sure it's off-limits for Tor Browser to make such a persistent,
 global change as setting a registry key. I found the code responsible for
 doing the lookup. Maybe it's something we can patch.
 * https://dxr.mozilla.org/mozilla-
 central/rev/c2593a3058afdfeaac5c990e18794ee8257afe99/toolkit/components/extensions/NativeManifests.jsm#40

--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/29347#comment:9>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list