2016-08-14 23:14:29 +00:00
|
|
|
import json
|
|
|
|
from twisted.internet.defer import inlineCallbacks, returnValue
|
|
|
|
|
|
|
|
from .wormhole import wormhole
|
rewrite Tor support (py2 only)
The new TorManager adds --launch-tor and --tor-control-port= arguments
(requiring the user to explicitly request a new Tor process, if that's what
they want). The default (when --tor is enabled) looks for a control port in
the usual places (/var/run/tor/control, localhost:9051, localhost:9151), then
falls back to hoping there's a SOCKS port in the usual
place (localhost:9050). (closes #64)
The ssh utilities should now accept the same tor arguments as ordinary
send/receive commands. There are now full tests for TorManager, and basic
tests for how send/receive use it. (closes #97)
Note that Tor is only supported on python2.7 for now, since txsocksx (and
therefore txtorcon) doesn't work on py3. You need to do "pip install
magic-wormhole[tor]" to get Tor support, and that will get you an inscrutable
error on py3 (referencing vcversioner, "install_requires must be a string or
list of strings", and "int object not iterable").
To run tests, you must install with the [dev] extra (to get "mock" and other
libraries). Our setup.py only includes "txtorcon" in the [dev] extra when on
py2, not on py3. Unit tests tolerate the lack of txtorcon (they mock out
everything txtorcon would provide), so they should provide the same coverage
on both py2 and py3.
2017-01-16 03:24:23 +00:00
|
|
|
from .tor_manager import TorManager
|
|
|
|
from .errors import NoTorError
|
2016-08-14 23:14:29 +00:00
|
|
|
|
|
|
|
@inlineCallbacks
|
rewrite Tor support (py2 only)
The new TorManager adds --launch-tor and --tor-control-port= arguments
(requiring the user to explicitly request a new Tor process, if that's what
they want). The default (when --tor is enabled) looks for a control port in
the usual places (/var/run/tor/control, localhost:9051, localhost:9151), then
falls back to hoping there's a SOCKS port in the usual
place (localhost:9050). (closes #64)
The ssh utilities should now accept the same tor arguments as ordinary
send/receive commands. There are now full tests for TorManager, and basic
tests for how send/receive use it. (closes #97)
Note that Tor is only supported on python2.7 for now, since txsocksx (and
therefore txtorcon) doesn't work on py3. You need to do "pip install
magic-wormhole[tor]" to get Tor support, and that will get you an inscrutable
error on py3 (referencing vcversioner, "install_requires must be a string or
list of strings", and "int object not iterable").
To run tests, you must install with the [dev] extra (to get "mock" and other
libraries). Our setup.py only includes "txtorcon" in the [dev] extra when on
py2, not on py3. Unit tests tolerate the lack of txtorcon (they mock out
everything txtorcon would provide), so they should provide the same coverage
on both py2 and py3.
2017-01-16 03:24:23 +00:00
|
|
|
def receive(reactor, appid, relay_url, code,
|
|
|
|
use_tor=False, launch_tor=False, tor_control_port=None,
|
|
|
|
on_code=None):
|
2016-08-14 23:14:29 +00:00
|
|
|
"""
|
|
|
|
This is a convenience API which returns a Deferred that callbacks
|
|
|
|
with a single chunk of data from another wormhole (and then closes
|
|
|
|
the wormhole). Under the hood, it's just using an instance
|
|
|
|
returned from :func:`wormhole.wormhole`. This is similar to the
|
|
|
|
`wormhole receive` command.
|
|
|
|
|
|
|
|
:param unicode appid: our application ID
|
|
|
|
|
|
|
|
:param unicode relay_url: the relay URL to use
|
|
|
|
|
|
|
|
:param unicode code: a pre-existing code to use, or None
|
|
|
|
|
|
|
|
:param bool use_tor: True if we should use Tor, False to not use it (None for default)
|
|
|
|
|
|
|
|
:param on_code: if not None, this is called when we have a code (even if you passed in one explicitly)
|
|
|
|
:type on_code: single-argument callable
|
|
|
|
"""
|
rewrite Tor support (py2 only)
The new TorManager adds --launch-tor and --tor-control-port= arguments
(requiring the user to explicitly request a new Tor process, if that's what
they want). The default (when --tor is enabled) looks for a control port in
the usual places (/var/run/tor/control, localhost:9051, localhost:9151), then
falls back to hoping there's a SOCKS port in the usual
place (localhost:9050). (closes #64)
The ssh utilities should now accept the same tor arguments as ordinary
send/receive commands. There are now full tests for TorManager, and basic
tests for how send/receive use it. (closes #97)
Note that Tor is only supported on python2.7 for now, since txsocksx (and
therefore txtorcon) doesn't work on py3. You need to do "pip install
magic-wormhole[tor]" to get Tor support, and that will get you an inscrutable
error on py3 (referencing vcversioner, "install_requires must be a string or
list of strings", and "int object not iterable").
To run tests, you must install with the [dev] extra (to get "mock" and other
libraries). Our setup.py only includes "txtorcon" in the [dev] extra when on
py2, not on py3. Unit tests tolerate the lack of txtorcon (they mock out
everything txtorcon would provide), so they should provide the same coverage
on both py2 and py3.
2017-01-16 03:24:23 +00:00
|
|
|
tm = None
|
|
|
|
if use_tor:
|
|
|
|
tm = TorManager(reactor, launch_tor, tor_control_port)
|
|
|
|
# For now, block everything until Tor has started. Soon: launch
|
|
|
|
# tor in parallel with everything else, make sure the TorManager
|
|
|
|
# can lazy-provide an endpoint, and overlap the startup process
|
|
|
|
# with the user handing off the wormhole code
|
|
|
|
if not tm.tor_available():
|
|
|
|
raise NoTorError()
|
|
|
|
yield tm.start()
|
|
|
|
|
|
|
|
wh = wormhole(appid, relay_url, reactor, tor_manager=tm)
|
2016-08-14 23:14:29 +00:00
|
|
|
if code is None:
|
|
|
|
code = yield wh.get_code()
|
|
|
|
else:
|
|
|
|
wh.set_code(code)
|
|
|
|
# we'll call this no matter what, even if you passed in a code --
|
|
|
|
# maybe it should be only in the 'if' block above?
|
|
|
|
if on_code:
|
|
|
|
on_code(code)
|
|
|
|
data = yield wh.get()
|
2016-08-16 00:34:33 +00:00
|
|
|
data = json.loads(data.decode("utf-8"))
|
2016-08-14 23:14:29 +00:00
|
|
|
offer = data.get('offer', None)
|
|
|
|
if not offer:
|
|
|
|
raise Exception(
|
|
|
|
"Do not understand response: {}".format(data)
|
|
|
|
)
|
|
|
|
msg = None
|
|
|
|
if 'message' in offer:
|
|
|
|
msg = offer['message']
|
2016-08-16 00:34:33 +00:00
|
|
|
wh.send(json.dumps({"answer": {"message_ack": "ok"}}).encode("utf-8"))
|
2016-08-14 23:14:29 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
raise Exception(
|
|
|
|
"Unknown offer type: {}".format(offer.keys())
|
|
|
|
)
|
|
|
|
|
|
|
|
yield wh.close()
|
|
|
|
returnValue(msg)
|
|
|
|
|
|
|
|
|
|
|
|
@inlineCallbacks
|
rewrite Tor support (py2 only)
The new TorManager adds --launch-tor and --tor-control-port= arguments
(requiring the user to explicitly request a new Tor process, if that's what
they want). The default (when --tor is enabled) looks for a control port in
the usual places (/var/run/tor/control, localhost:9051, localhost:9151), then
falls back to hoping there's a SOCKS port in the usual
place (localhost:9050). (closes #64)
The ssh utilities should now accept the same tor arguments as ordinary
send/receive commands. There are now full tests for TorManager, and basic
tests for how send/receive use it. (closes #97)
Note that Tor is only supported on python2.7 for now, since txsocksx (and
therefore txtorcon) doesn't work on py3. You need to do "pip install
magic-wormhole[tor]" to get Tor support, and that will get you an inscrutable
error on py3 (referencing vcversioner, "install_requires must be a string or
list of strings", and "int object not iterable").
To run tests, you must install with the [dev] extra (to get "mock" and other
libraries). Our setup.py only includes "txtorcon" in the [dev] extra when on
py2, not on py3. Unit tests tolerate the lack of txtorcon (they mock out
everything txtorcon would provide), so they should provide the same coverage
on both py2 and py3.
2017-01-16 03:24:23 +00:00
|
|
|
def send(reactor, appid, relay_url, data, code,
|
|
|
|
use_tor=False, launch_tor=False, tor_control_port=None,
|
|
|
|
on_code=None):
|
2016-08-14 23:14:29 +00:00
|
|
|
"""
|
|
|
|
This is a convenience API which returns a Deferred that callbacks
|
|
|
|
after a single chunk of data has been sent to another
|
|
|
|
wormhole. Under the hood, it's just using an instance returned
|
|
|
|
from :func:`wormhole.wormhole`. This is similar to the `wormhole
|
|
|
|
send` command.
|
|
|
|
|
|
|
|
:param unicode appid: the application ID
|
|
|
|
|
|
|
|
:param unicode relay_url: the relay URL to use
|
|
|
|
|
|
|
|
:param unicode code: a pre-existing code to use, or None
|
|
|
|
|
|
|
|
:param bool use_tor: True if we should use Tor, False to not use it (None for default)
|
|
|
|
|
|
|
|
:param on_code: if not None, this is called when we have a code (even if you passed in one explicitly)
|
|
|
|
:type on_code: single-argument callable
|
|
|
|
"""
|
rewrite Tor support (py2 only)
The new TorManager adds --launch-tor and --tor-control-port= arguments
(requiring the user to explicitly request a new Tor process, if that's what
they want). The default (when --tor is enabled) looks for a control port in
the usual places (/var/run/tor/control, localhost:9051, localhost:9151), then
falls back to hoping there's a SOCKS port in the usual
place (localhost:9050). (closes #64)
The ssh utilities should now accept the same tor arguments as ordinary
send/receive commands. There are now full tests for TorManager, and basic
tests for how send/receive use it. (closes #97)
Note that Tor is only supported on python2.7 for now, since txsocksx (and
therefore txtorcon) doesn't work on py3. You need to do "pip install
magic-wormhole[tor]" to get Tor support, and that will get you an inscrutable
error on py3 (referencing vcversioner, "install_requires must be a string or
list of strings", and "int object not iterable").
To run tests, you must install with the [dev] extra (to get "mock" and other
libraries). Our setup.py only includes "txtorcon" in the [dev] extra when on
py2, not on py3. Unit tests tolerate the lack of txtorcon (they mock out
everything txtorcon would provide), so they should provide the same coverage
on both py2 and py3.
2017-01-16 03:24:23 +00:00
|
|
|
tm = None
|
|
|
|
if use_tor:
|
|
|
|
tm = TorManager(reactor, launch_tor, tor_control_port)
|
|
|
|
# For now, block everything until Tor has started. Soon: launch
|
|
|
|
# tor in parallel with everything else, make sure the TorManager
|
|
|
|
# can lazy-provide an endpoint, and overlap the startup process
|
|
|
|
# with the user handing off the wormhole code
|
|
|
|
if not tm.tor_available():
|
|
|
|
raise NoTorError()
|
|
|
|
yield tm.start()
|
|
|
|
wh = wormhole(appid, relay_url, reactor, tor_manager=tm)
|
2016-08-14 23:14:29 +00:00
|
|
|
if code is None:
|
|
|
|
code = yield wh.get_code()
|
|
|
|
else:
|
|
|
|
wh.set_code(code)
|
|
|
|
if on_code:
|
|
|
|
on_code(code)
|
|
|
|
|
|
|
|
wh.send(
|
|
|
|
json.dumps({
|
|
|
|
"offer": {
|
|
|
|
"message": data
|
|
|
|
}
|
2016-08-16 00:34:33 +00:00
|
|
|
}).encode("utf-8")
|
2016-08-14 23:14:29 +00:00
|
|
|
)
|
|
|
|
data = yield wh.get()
|
2016-08-16 00:34:33 +00:00
|
|
|
data = json.loads(data.decode("utf-8"))
|
2016-08-14 23:14:29 +00:00
|
|
|
answer = data.get('answer', None)
|
|
|
|
yield wh.close()
|
|
|
|
if answer:
|
|
|
|
returnValue(None)
|
|
|
|
else:
|
|
|
|
raise Exception(
|
|
|
|
"Unknown answer: {}".format(data)
|
|
|
|
)
|