[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