2015-04-10 04:58:31 +00:00
|
|
|
# Magic Wormhole
|
2015-09-28 23:23:19 +00:00
|
|
|
[![Build Status](https://travis-ci.org/warner/magic-wormhole.svg?branch=master)](https://travis-ci.org/warner/magic-wormhole)
|
2017-11-02 18:44:55 +00:00
|
|
|
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/mfnn5rsyfnrq576a/branch/master?svg=true)](https://ci.appveyor.com/project/warner/magic-wormhole)
|
2016-03-02 22:42:19 +00:00
|
|
|
[![codecov.io](https://codecov.io/github/warner/magic-wormhole/coverage.svg?branch=master)](https://codecov.io/github/warner/magic-wormhole?branch=master)
|
2015-03-24 06:38:47 +00:00
|
|
|
|
2015-04-10 04:58:31 +00:00
|
|
|
Get things from one computer to another, safely.
|
|
|
|
|
|
|
|
This package provides a library and a command-line tool named `wormhole`,
|
2017-06-24 14:59:48 +00:00
|
|
|
which makes it possible to get arbitrary-sized files and directories
|
2017-05-24 15:40:43 +00:00
|
|
|
(or short pieces of text) from one computer to another. The two endpoints are
|
2015-12-03 23:02:34 +00:00
|
|
|
identified by using identical "wormhole codes": in general, the sending
|
|
|
|
machine generates and displays the code, which must then be typed into the
|
|
|
|
receiving machine.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
The codes are short and human-pronounceable, using a phonetically-distinct
|
|
|
|
wordlist. The receiving side offers tab-completion on the codewords, so
|
|
|
|
usually only a few characters must be typed. Wormhole codes are single-use
|
|
|
|
and do not need to be memorized.
|
|
|
|
|
2016-10-23 18:48:27 +00:00
|
|
|
* PyCon 2016 presentation: [Slides](http://www.lothar.com/~warner/MagicWormhole-PyCon2016.pdf), [Video](https://youtu.be/oFrTqQw0_3c)
|
2016-06-01 00:43:49 +00:00
|
|
|
|
2016-07-27 23:51:01 +00:00
|
|
|
## Example
|
|
|
|
|
|
|
|
Sender:
|
|
|
|
|
|
|
|
```
|
|
|
|
% wormhole send README.md
|
|
|
|
Sending 7924 byte file named 'README.md'
|
|
|
|
On the other computer, please run: wormhole receive
|
|
|
|
Wormhole code is: 7-crossover-clockwork
|
|
|
|
|
|
|
|
Sending (<-10.0.1.43:58988)..
|
|
|
|
100%|=========================| 7.92K/7.92K [00:00<00:00, 6.02MB/s]
|
|
|
|
File sent.. waiting for confirmation
|
|
|
|
Confirmation received. Transfer complete.
|
|
|
|
```
|
|
|
|
|
|
|
|
Receiver:
|
|
|
|
|
|
|
|
```
|
|
|
|
% wormhole receive
|
|
|
|
Enter receive wormhole code: 7-crossover-clockwork
|
|
|
|
Receiving file (7924 bytes) into: README.md
|
|
|
|
ok? (y/n): y
|
|
|
|
Receiving (->tcp:10.0.1.43:58986)..
|
|
|
|
100%|===========================| 7.92K/7.92K [00:00<00:00, 120KB/s]
|
|
|
|
Received file written to README.md
|
|
|
|
```
|
|
|
|
|
|
|
|
|
2015-10-05 20:52:32 +00:00
|
|
|
## Installation
|
|
|
|
|
|
|
|
```$ pip install magic-wormhole```
|
|
|
|
|
2017-09-13 05:52:00 +00:00
|
|
|
You either want to do this into a "user" environment (putting the
|
|
|
|
``wormhole`` executable in ``~/.local/bin/wormhole``) like this:
|
|
|
|
|
|
|
|
```
|
|
|
|
pip install --user magic-wormhole
|
|
|
|
```
|
|
|
|
|
|
|
|
or put it into a virtualenv, to avoid modifying the system python's
|
|
|
|
libraries, like this:
|
|
|
|
|
|
|
|
```
|
|
|
|
virtualenv venv
|
|
|
|
source venv/bin/activate
|
|
|
|
pip install magic-wormhole
|
|
|
|
```
|
|
|
|
|
|
|
|
You probably *don't* want to use ``sudo`` when you run ``pip``.
|
2017-05-27 17:48:01 +00:00
|
|
|
|
2017-06-29 15:43:53 +00:00
|
|
|
### OS X
|
|
|
|
|
2017-06-29 22:49:34 +00:00
|
|
|
On OS X, you may need to install `pip` and run `$ xcode-select --install` to
|
|
|
|
get GCC.
|
2017-06-29 15:43:53 +00:00
|
|
|
|
|
|
|
Or with `homebrew`:
|
|
|
|
|
|
|
|
`$ brew install magic-wormhole`
|
|
|
|
|
|
|
|
### Linux
|
|
|
|
|
|
|
|
On Debian 9 and Ubuntu 17.04+ with `apt`:
|
|
|
|
|
2017-06-28 12:01:12 +00:00
|
|
|
```$ sudo apt install magic-wormhole```
|
|
|
|
|
2017-06-29 14:50:10 +00:00
|
|
|
On previous versions of the Debian/Ubuntu systems, or if you want to install
|
2017-06-29 15:43:53 +00:00
|
|
|
the latest version, you may first need:
|
|
|
|
|
2017-09-13 00:13:07 +00:00
|
|
|
`$ sudo apt-get install python-pip build-essential python-dev libffi-dev libssl-dev`
|
2017-06-29 15:43:53 +00:00
|
|
|
|
|
|
|
On Fedora:
|
|
|
|
|
2017-09-13 00:13:07 +00:00
|
|
|
`$ sudo dnf install python-pip python-devel libffi-devel openssl-devel gcc-c++
|
2017-06-29 15:43:53 +00:00
|
|
|
libtool redhat-rpm-config`.
|
|
|
|
|
2017-06-29 22:49:34 +00:00
|
|
|
Note: If you get errors like `fatal error: sodium.h: No such file or
|
|
|
|
directory` on Linux, either use `SODIUM_INSTALL=bundled pip install
|
|
|
|
magic-wormhole`, or try installing the `libsodium-dev` / `libsodium-devel`
|
|
|
|
package. These work around a bug in pynacl which gets confused when the
|
|
|
|
libsodium runtime is installed (e.g. `libsodium13`) but not the development
|
|
|
|
package.
|
README: mention libsodium-dev package
pynacl-1.0.1 has a bug, on systems which have the sodium runtime library
installed (/usr/lib/libsodium.so, as provided by a package like
"libsodium13"), but not the development headers (/usr/include/sodium.h,
as provided by "libsodium-dev"). The pynacl setup.py tries to detect
whether a system libsodium can be used (instead of the bundled copy), by
using cffi to load libsodium.so and check the version strings. However
this test doesn't check that sodium.h is available, which is needed to
build the glue code.
The long-term fix is to change pynacl, either to improve the test (to
look for a header file, which sounds tricky), or to always use the
bundled sodium unless explicitly told otherwise (removing the test
altogether). The short term fix is to tell magic-wormhole builders to
install libsodium-dev if they run into this error, or use the
environment-variable override when installing.
closes #10
refs https://github.com/pyca/pynacl/issues/184
2016-06-23 18:23:27 +00:00
|
|
|
|
2017-06-29 15:43:53 +00:00
|
|
|
### Windows
|
|
|
|
|
2017-06-29 22:49:34 +00:00
|
|
|
On Windows, python2 may work better than python3. On older systems, `$ pip
|
|
|
|
install --upgrade pip` may be necessary to get a version that can compile all
|
2017-09-03 21:10:08 +00:00
|
|
|
the dependencies. Most of the dependencies are published as binary wheels,
|
|
|
|
but in case your system is unable to find these, it will have to compile
|
|
|
|
them, for which Microsoft Visual C++ 9.0 may be required. Get it from
|
|
|
|
http://aka.ms/vcpython27 .
|
2016-02-27 22:39:56 +00:00
|
|
|
|
2015-04-10 04:58:31 +00:00
|
|
|
## Motivation
|
|
|
|
|
|
|
|
* Moving a file to a friend's machine, when the humans can speak to each
|
2016-01-12 23:03:55 +00:00
|
|
|
other (directly) but the computers cannot
|
2015-04-10 04:58:31 +00:00
|
|
|
* Delivering a properly-random password to a new user via the phone
|
|
|
|
* Supplying an SSH public key for future login use
|
|
|
|
|
|
|
|
Copying files onto a USB stick requires physical proximity, and is
|
2015-10-08 00:10:33 +00:00
|
|
|
uncomfortable for transferring long-term secrets because flash memory is hard
|
|
|
|
to erase. Copying files with ssh/scp is fine, but requires previous
|
|
|
|
arrangements and an account on the target machine, and how do you bootstrap
|
|
|
|
the account? Copying files through email first requires transcribing an email
|
|
|
|
address in the opposite direction, and is even worse for secrets, because
|
|
|
|
email is unencrypted. Copying files through encrypted email requires
|
|
|
|
bootstrapping a GPG key as well as an email address. Copying files through
|
|
|
|
Dropbox is not secure against the Dropbox server and results in a large URL
|
2016-01-12 23:03:55 +00:00
|
|
|
that must be transcribed. Using a URL shortener adds an extra step, reveals
|
|
|
|
the full URL to the shortening service, and leaves a short URL that can be
|
|
|
|
guessed by outsiders.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
Many common use cases start with a human-mediated communication channel, such
|
2015-10-08 00:10:33 +00:00
|
|
|
as IRC, IM, email, a phone call, or a face-to-face conversation. Some of
|
|
|
|
these are basically secret, or are "secret enough" to last until the code is
|
2015-04-10 04:58:31 +00:00
|
|
|
delivered and used. If this does not feel strong enough, users can turn on
|
|
|
|
additional verification that doesn't depend upon the secrecy of the channel.
|
|
|
|
|
|
|
|
The notion of a "magic wormhole" comes from the image of two distant wizards
|
2016-05-26 03:58:53 +00:00
|
|
|
speaking the same enchanted phrase at the same time, and causing a mystical
|
|
|
|
connection to pop into existence between them. The wizards then throw books
|
|
|
|
into the wormhole and they fall out the other side. Transferring files
|
|
|
|
securely should be that easy.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
## Design
|
|
|
|
|
|
|
|
The `wormhole` tool uses PAKE "Password-Authenticated Key Exchange", a family
|
|
|
|
of cryptographic algorithms that uses a short low-entropy password to
|
|
|
|
establish a strong high-entropy shared key. This key can then be used to
|
|
|
|
encrypt data. `wormhole` uses the SPAKE2 algorithm, due to Abdalla and
|
|
|
|
Pointcheval[1].
|
|
|
|
|
|
|
|
PAKE effectively trades off interaction against offline attacks. The only way
|
|
|
|
for a network attacker to learn the shared key is to perform a
|
|
|
|
man-in-the-middle attack during the initial connection attempt, and to
|
|
|
|
correctly guess the code being used by both sides. Their chance of doing this
|
2016-01-12 23:03:55 +00:00
|
|
|
is inversely proportional to the entropy of the wormhole code. The default is
|
|
|
|
to use a 16-bit code (use --code-length= to change this), so for each use of
|
|
|
|
the tool, an attacker gets a 1-in-65536 chance of success. As such, users can
|
|
|
|
expect to see many error messages before the attacker has a reasonable chance
|
|
|
|
of success.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
## Timing
|
|
|
|
|
2016-05-26 03:58:53 +00:00
|
|
|
The program does not have any built-in timeouts, however it is expected that
|
|
|
|
both clients will be run within an hour or so of each other. This makes the
|
|
|
|
tool most useful for people who are having a real-time conversation already,
|
|
|
|
and want to graduate to a secure connection. Both clients must be left
|
|
|
|
running until the transfer has finished.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
## Relays
|
|
|
|
|
2016-05-26 03:58:53 +00:00
|
|
|
The wormhole library requires a "Rendezvous Server": a simple WebSocket-based
|
|
|
|
relay that delivers messages from one client to another. This allows the
|
|
|
|
wormhole codes to omit IP addresses and port numbers. The URL of a public
|
|
|
|
server is baked into the library for use as a default, and will be freely
|
|
|
|
available until volume or abuse makes it infeasible to support. Applications
|
|
|
|
which desire more reliability can easily run their own relay and configure
|
|
|
|
their clients to use it instead. Code for the Rendezvous Server is included
|
|
|
|
in the library.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
The file-transfer commands also use a "Transit Relay", which is another
|
|
|
|
simple server that glues together two inbound TCP connections and transfers
|
2015-10-08 00:10:33 +00:00
|
|
|
data on each to the other. The `wormhole send` file mode shares the IP
|
2015-04-10 04:58:31 +00:00
|
|
|
addresses of each client with the other (inside the encrypted message), and
|
|
|
|
both clients first attempt to connect directly. If this fails, they fall back
|
|
|
|
to using the transit relay. As before, the host/port of a public server is
|
|
|
|
baked into the library, and should be sufficient to handle moderate traffic.
|
|
|
|
|
|
|
|
The protocol includes provisions to deliver notices and error messages to
|
|
|
|
clients: if either relay must be shut down, these channels will be used to
|
|
|
|
provide information about alternatives.
|
|
|
|
|
|
|
|
## CLI tool
|
|
|
|
|
2016-07-28 00:52:21 +00:00
|
|
|
* `wormhole send [args] --text TEXT`
|
|
|
|
* `wormhole send [args] FILENAME`
|
|
|
|
* `wormhole send [args] DIRNAME`
|
|
|
|
* `wormhole receive [args]`
|
2015-04-10 04:58:31 +00:00
|
|
|
|
2016-07-28 00:52:21 +00:00
|
|
|
Both commands accept additional arguments to influence their behavior:
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
* `--code-length WORDS`: use more or fewer than 2 words for the code
|
2015-11-24 01:13:13 +00:00
|
|
|
* `--verify` : print (and ask user to compare) extra verification string
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
## Library
|
|
|
|
|
|
|
|
The `wormhole` module makes it possible for other applications to use these
|
2016-05-26 03:58:53 +00:00
|
|
|
code-protected channels. This includes Twisted support, and (in the future)
|
|
|
|
will include blocking/synchronous support too. See docs/api.md for details.
|
|
|
|
|
|
|
|
The file-transfer tools use a second module named `wormhole.transit`, which
|
|
|
|
provides an encrypted record-pipe. It knows how to use the Transit Relay as
|
|
|
|
well as direct connections, and attempts them all in parallel.
|
|
|
|
`TransitSender` and `TransitReceiver` are distinct, although once the
|
|
|
|
connection is established, data can flow in either direction. All data is
|
|
|
|
encrypted (using nacl/libsodium "secretbox") using a key derived from the
|
|
|
|
PAKE phase. See `src/wormhole/cli/cmd_send.py` for examples.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
2017-05-23 23:43:18 +00:00
|
|
|
## Development
|
|
|
|
|
2017-08-11 21:31:28 +00:00
|
|
|
* Bugs and Patches: https://github.com/warner/magic-wormhole
|
|
|
|
* Chat: #magic-wormhole on irc.freenode.net
|
|
|
|
|
2017-05-23 23:43:18 +00:00
|
|
|
To set up Magic Wormhole for development, you will first need to
|
|
|
|
install [virtualenv][].
|
|
|
|
|
2017-09-13 05:52:00 +00:00
|
|
|
Once you've done that, ``git clone`` the repo, ``cd`` into the root of the
|
|
|
|
repository, and run:
|
2017-05-23 23:43:18 +00:00
|
|
|
|
|
|
|
```
|
|
|
|
virtualenv venv
|
|
|
|
source venv/bin/activate
|
|
|
|
pip install --upgrade pip setuptools
|
|
|
|
```
|
|
|
|
|
|
|
|
Now your virtualenv has been activated. You'll want to re-run
|
|
|
|
`source venv/bin/activate` for every new terminal session you open.
|
|
|
|
|
|
|
|
To install Magic Wormhole and its development dependencies into your
|
|
|
|
virtualenv, run:
|
|
|
|
|
|
|
|
```
|
|
|
|
pip install -e .[dev]
|
|
|
|
```
|
|
|
|
|
2017-09-13 05:52:00 +00:00
|
|
|
While the virtualenv is active, running ``wormhole`` will get you the
|
|
|
|
development version.
|
|
|
|
|
2017-05-23 23:43:18 +00:00
|
|
|
### Running Tests
|
|
|
|
|
2017-06-29 22:49:34 +00:00
|
|
|
|
2017-05-23 23:43:18 +00:00
|
|
|
Within your virtualenv, the command-line program `trial` will
|
|
|
|
run the test suite:
|
|
|
|
|
|
|
|
```
|
|
|
|
trial wormhole
|
|
|
|
```
|
|
|
|
|
|
|
|
This tests the entire `wormhole` package. If you want to run
|
|
|
|
only the tests for a specific module, or even just a specific test,
|
|
|
|
you can specify it instead via Python's standard dotted
|
|
|
|
import notation, e.g.:
|
|
|
|
|
|
|
|
```
|
|
|
|
trial wormhole.test.test_cli.PregeneratedCode.test_file_tor
|
|
|
|
```
|
|
|
|
|
2017-06-29 22:49:34 +00:00
|
|
|
Developers can also just clone the source tree and run `tox` to run the unit
|
|
|
|
tests on all supported (and installed) versions of python: 2.7, 3.4, 3.5, and
|
|
|
|
3.6.
|
|
|
|
|
2017-05-23 23:43:18 +00:00
|
|
|
### Troubleshooting
|
|
|
|
|
|
|
|
Every so often, you might get a traceback with the following
|
|
|
|
kind of error:
|
|
|
|
|
|
|
|
```
|
|
|
|
pkg_resources.DistributionNotFound: The 'magic-wormhole==0.9.1-268.g66e0d86.dirty' distribution was not found and is required by the application
|
|
|
|
```
|
|
|
|
|
|
|
|
If this happens, run `pip install -e .[dev]` again.
|
|
|
|
|
|
|
|
[virtualenv]: http://python-guide-pt-br.readthedocs.io/en/latest/dev/virtualenvs/
|
|
|
|
|
2017-06-28 18:47:20 +00:00
|
|
|
### Other
|
|
|
|
|
2017-06-30 18:51:28 +00:00
|
|
|
Relevant [xkcd](https://xkcd.com/949/) :-)
|
2017-06-28 18:47:20 +00:00
|
|
|
|
2015-04-10 04:58:31 +00:00
|
|
|
## License, Compatibility
|
|
|
|
|
|
|
|
This library is released under the MIT license, see LICENSE for details.
|
|
|
|
|
2017-05-25 00:11:25 +00:00
|
|
|
This library is compatible with python2.7, 3.4, 3.5, and 3.6 . It is
|
|
|
|
probably compatible with py2.6, but the latest Twisted (>=15.5.0) is
|
2016-12-29 18:51:40 +00:00
|
|
|
not.
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
|
2017-01-04 23:58:58 +00:00
|
|
|
<!-- footnotes -->
|
2015-04-10 04:58:31 +00:00
|
|
|
|
|
|
|
[1]: http://www.di.ens.fr/~pointche/Documents/Papers/2005_rsa.pdf "RSA 2005"
|