change API (wormhole.create), start on serialization
This commit is contained in:
parent
b7b8df17be
commit
c499fce9f5
|
@ -80,6 +80,9 @@ class Boss(object):
|
||||||
old_state, input, new_state))
|
old_state, input, new_state))
|
||||||
names[machine].set_trace(tracer)
|
names[machine].set_trace(tracer)
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
# and these are the state-machine transition functions, which don't take
|
# and these are the state-machine transition functions, which don't take
|
||||||
# args
|
# args
|
||||||
@m.state(initial=True)
|
@m.state(initial=True)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from humanize import naturalsize
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet.defer import inlineCallbacks, returnValue
|
from twisted.internet.defer import inlineCallbacks, returnValue
|
||||||
from twisted.python import log
|
from twisted.python import log
|
||||||
from ..wormhole import wormhole
|
from .. import wormhole
|
||||||
from ..transit import TransitReceiver
|
from ..transit import TransitReceiver
|
||||||
from ..errors import TransferError, WormholeClosedError, NoTorError
|
from ..errors import TransferError, WormholeClosedError, NoTorError
|
||||||
from ..util import (dict_to_bytes, bytes_to_dict, bytes_to_hexstr,
|
from ..util import (dict_to_bytes, bytes_to_dict, bytes_to_hexstr,
|
||||||
|
@ -61,8 +61,10 @@ class TwistedReceiver:
|
||||||
# with the user handing off the wormhole code
|
# with the user handing off the wormhole code
|
||||||
yield self._tor_manager.start()
|
yield self._tor_manager.start()
|
||||||
|
|
||||||
w = wormhole(self.args.appid or APPID, self.args.relay_url,
|
w = wormhole.create(self.args.appid or APPID, self.args.relay_url,
|
||||||
self._reactor, self._tor_manager, timing=self.args.timing)
|
self._reactor,
|
||||||
|
tor_manager=self._tor_manager,
|
||||||
|
timing=self.args.timing)
|
||||||
# I wanted to do this instead:
|
# I wanted to do this instead:
|
||||||
#
|
#
|
||||||
# try:
|
# try:
|
||||||
|
@ -80,13 +82,12 @@ class TwistedReceiver:
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def _go(self, w):
|
def _go(self, w):
|
||||||
yield self._handle_code(w)
|
yield self._handle_code(w)
|
||||||
yield w.establish_key()
|
|
||||||
def on_slow_connection():
|
def on_slow_connection():
|
||||||
print(u"Key established, waiting for confirmation...",
|
print(u"Key established, waiting for confirmation...",
|
||||||
file=self.args.stderr)
|
file=self.args.stderr)
|
||||||
notify = self._reactor.callLater(VERIFY_TIMER, on_slow_connection)
|
notify = self._reactor.callLater(VERIFY_TIMER, on_slow_connection)
|
||||||
try:
|
try:
|
||||||
verifier = yield w.verify()
|
verifier = yield w.when_verifier()
|
||||||
finally:
|
finally:
|
||||||
if not notify.called:
|
if not notify.called:
|
||||||
notify.cancel()
|
notify.cancel()
|
||||||
|
@ -127,7 +128,7 @@ class TwistedReceiver:
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def _get_data(self, w):
|
def _get_data(self, w):
|
||||||
# this may raise WrongPasswordError
|
# this may raise WrongPasswordError
|
||||||
them_bytes = yield w.get()
|
them_bytes = yield w.when_received()
|
||||||
them_d = bytes_to_dict(them_bytes)
|
them_d = bytes_to_dict(them_bytes)
|
||||||
if "error" in them_d:
|
if "error" in them_d:
|
||||||
raise TransferError(them_d["error"])
|
raise TransferError(them_d["error"])
|
||||||
|
@ -142,7 +143,7 @@ class TwistedReceiver:
|
||||||
if code:
|
if code:
|
||||||
w.set_code(code)
|
w.set_code(code)
|
||||||
else:
|
else:
|
||||||
yield w.input_code("Enter receive wormhole code: ",
|
yield w.input_code("Enter receive wormhole code: ", # TODO
|
||||||
self.args.code_length)
|
self.args.code_length)
|
||||||
|
|
||||||
def _show_verifier(self, verifier):
|
def _show_verifier(self, verifier):
|
||||||
|
|
|
@ -7,7 +7,7 @@ from twisted.protocols import basic
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet.defer import inlineCallbacks, returnValue
|
from twisted.internet.defer import inlineCallbacks, returnValue
|
||||||
from ..errors import TransferError, WormholeClosedError, NoTorError
|
from ..errors import TransferError, WormholeClosedError, NoTorError
|
||||||
from ..wormhole import wormhole
|
from .. import wormhole
|
||||||
from ..transit import TransitSender
|
from ..transit import TransitSender
|
||||||
from ..util import dict_to_bytes, bytes_to_dict, bytes_to_hexstr
|
from ..util import dict_to_bytes, bytes_to_dict, bytes_to_hexstr
|
||||||
|
|
||||||
|
@ -52,8 +52,9 @@ class Sender:
|
||||||
# with the user handing off the wormhole code
|
# with the user handing off the wormhole code
|
||||||
yield self._tor_manager.start()
|
yield self._tor_manager.start()
|
||||||
|
|
||||||
w = wormhole(self._args.appid or APPID, self._args.relay_url,
|
w = wormhole.create(self._args.appid or APPID, self._args.relay_url,
|
||||||
self._reactor, self._tor_manager,
|
self._reactor,
|
||||||
|
tor_manager=self._tor_manager,
|
||||||
timing=self._timing)
|
timing=self._timing)
|
||||||
d = self._go(w)
|
d = self._go(w)
|
||||||
d.addBoth(w.close) # must wait for ack from close()
|
d.addBoth(w.close) # must wait for ack from close()
|
||||||
|
@ -83,25 +84,25 @@ class Sender:
|
||||||
|
|
||||||
if args.code:
|
if args.code:
|
||||||
w.set_code(args.code)
|
w.set_code(args.code)
|
||||||
code = args.code
|
|
||||||
else:
|
else:
|
||||||
code = yield w.get_code(args.code_length)
|
w.allocate_code(args.code_length)
|
||||||
|
|
||||||
|
code = yield w.when_code()
|
||||||
if not args.zeromode:
|
if not args.zeromode:
|
||||||
print(u"Wormhole code is: %s" % code, file=args.stderr)
|
print(u"Wormhole code is: %s" % code, file=args.stderr)
|
||||||
# flush stderr so the code is displayed immediately
|
# flush stderr so the code is displayed immediately
|
||||||
args.stderr.flush()
|
args.stderr.flush()
|
||||||
print(u"", file=args.stderr)
|
print(u"", file=args.stderr)
|
||||||
|
|
||||||
yield w.establish_key()
|
|
||||||
def on_slow_connection():
|
def on_slow_connection():
|
||||||
print(u"Key established, waiting for confirmation...",
|
print(u"Key established, waiting for confirmation...",
|
||||||
file=args.stderr)
|
file=args.stderr)
|
||||||
notify = self._reactor.callLater(VERIFY_TIMER, on_slow_connection)
|
notify = self._reactor.callLater(VERIFY_TIMER, on_slow_connection)
|
||||||
|
|
||||||
# TODO: don't stall on w.verify() unless they want it
|
# TODO: maybe don't stall on verifier unless they want it
|
||||||
try:
|
try:
|
||||||
verifier_bytes = yield w.verify() # this may raise WrongPasswordError
|
# this may raise WrongPasswordError
|
||||||
|
verifier_bytes = yield w.when_verifier()
|
||||||
finally:
|
finally:
|
||||||
if not notify.called:
|
if not notify.called:
|
||||||
notify.cancel()
|
notify.cancel()
|
||||||
|
@ -146,12 +147,13 @@ class Sender:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
them_d_bytes = yield w.get()
|
them_d_bytes = yield w.when_received()
|
||||||
except WormholeClosedError:
|
except WormholeClosedError:
|
||||||
if done:
|
if done:
|
||||||
returnValue(None)
|
returnValue(None)
|
||||||
raise TransferError("unexpected close")
|
raise TransferError("unexpected close")
|
||||||
# TODO: get() fired, so now it's safe to use w.derive_key()
|
# TODO: when_received() fired, so now it's safe to use
|
||||||
|
# w.derive_key()
|
||||||
them_d = bytes_to_dict(them_d_bytes)
|
them_d = bytes_to_dict(them_d_bytes)
|
||||||
#print("GOT", them_d)
|
#print("GOT", them_d)
|
||||||
recognized = False
|
recognized = False
|
||||||
|
|
|
@ -51,6 +51,12 @@ class _DelegatedWormhole(object):
|
||||||
def set_code(self, code):
|
def set_code(self, code):
|
||||||
self._boss.set_code(code)
|
self._boss.set_code(code)
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
s = {"serialized_wormhole_version": 1,
|
||||||
|
"boss": self._boss.serialize(),
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
|
||||||
def send(self, plaintext):
|
def send(self, plaintext):
|
||||||
self._boss.send(plaintext)
|
self._boss.send(plaintext)
|
||||||
def close(self):
|
def close(self):
|
||||||
|
@ -116,6 +122,7 @@ class _DeferredWormhole(object):
|
||||||
def set_code(self, code):
|
def set_code(self, code):
|
||||||
self._boss.set_code(code)
|
self._boss.set_code(code)
|
||||||
|
|
||||||
|
# no .serialize in Deferred-mode
|
||||||
def send(self, plaintext):
|
def send(self, plaintext):
|
||||||
self._boss.send(plaintext)
|
self._boss.send(plaintext)
|
||||||
def close(self):
|
def close(self):
|
||||||
|
@ -165,11 +172,8 @@ class _DeferredWormhole(object):
|
||||||
for d in self._closed_observers:
|
for d in self._closed_observers:
|
||||||
d.callback(close_result)
|
d.callback(close_result)
|
||||||
|
|
||||||
def _wormhole(appid, relay_url, reactor, delegate=None,
|
def create(appid, relay_url, reactor, delegate=None, journal=None,
|
||||||
tor_manager=None, timing=None,
|
tor_manager=None, timing=None, stderr=sys.stderr):
|
||||||
journal=None,
|
|
||||||
stderr=sys.stderr,
|
|
||||||
):
|
|
||||||
timing = timing or DebugTiming()
|
timing = timing or DebugTiming()
|
||||||
side = bytes_to_hexstr(os.urandom(5))
|
side = bytes_to_hexstr(os.urandom(5))
|
||||||
journal = journal or ImmediateJournal()
|
journal = journal or ImmediateJournal()
|
||||||
|
@ -179,23 +183,30 @@ def _wormhole(appid, relay_url, reactor, delegate=None,
|
||||||
w = _DeferredWormhole()
|
w = _DeferredWormhole()
|
||||||
b = Boss(w, side, relay_url, appid, reactor, journal, timing)
|
b = Boss(w, side, relay_url, appid, reactor, journal, timing)
|
||||||
w._set_boss(b)
|
w._set_boss(b)
|
||||||
# force allocate for now
|
|
||||||
b.start()
|
b.start()
|
||||||
return w
|
return w
|
||||||
|
|
||||||
def delegated_wormhole(appid, relay_url, reactor, delegate,
|
def from_serialized(serialized, reactor, delegate,
|
||||||
tor_manager=None, timing=None,
|
journal=None, tor_manager=None,
|
||||||
journal=None,
|
timing=None, stderr=sys.stderr):
|
||||||
stderr=sys.stderr,
|
assert serialized["serialized_wormhole_version"] == 1
|
||||||
):
|
timing = timing or DebugTiming()
|
||||||
assert delegate
|
w = _DelegatedWormhole(delegate)
|
||||||
return _wormhole(appid, relay_url, reactor, delegate,
|
# now unpack state machines, including the SPAKE2 in Key
|
||||||
tor_manager, timing, journal, stderr)
|
b = Boss.from_serialized(w, serialized["boss"], reactor, journal, timing)
|
||||||
|
w._set_boss(b)
|
||||||
|
b.start() # ??
|
||||||
|
raise NotImplemented
|
||||||
|
# should the new Wormhole call got_code? only if it wasn't called before.
|
||||||
|
|
||||||
|
# after creating the wormhole object, app must call exactly one of:
|
||||||
|
# set_code(code), generate_code(), helper=type_code(), and then (if they need
|
||||||
|
# to know the code) wait for delegate.got_code() or d=w.when_code()
|
||||||
|
|
||||||
|
# the helper for type_code() can be asked for completions:
|
||||||
|
# d=helper.get_completions(text_so_far), which will fire with a list of
|
||||||
|
# strings that could usefully be appended to text_so_far.
|
||||||
|
|
||||||
|
# wormhole.type_code_readline(w) is a wrapper that knows how to use
|
||||||
|
# w.type_code() to drive rlcompleter
|
||||||
|
|
||||||
def deferred_wormhole(appid, relay_url, reactor,
|
|
||||||
tor_manager=None, timing=None,
|
|
||||||
journal=None,
|
|
||||||
stderr=sys.stderr,
|
|
||||||
):
|
|
||||||
return _wormhole(appid, relay_url, reactor, None,
|
|
||||||
tor_manager, timing, journal, stderr)
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user