switch most everything to use new utility functions

This commit is contained in:
Brian Warner 2016-05-28 18:19:45 -07:00
parent 3850c164f7
commit 6a108f93e6
4 changed files with 30 additions and 29 deletions

View File

@ -1,5 +1,5 @@
from __future__ import print_function from __future__ import print_function
import os, sys, json, binascii, six, tempfile, zipfile, hashlib import os, sys, six, tempfile, zipfile, hashlib
from tqdm import tqdm from tqdm import tqdm
from twisted.internet import reactor from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks, returnValue from twisted.internet.defer import inlineCallbacks, returnValue
@ -7,6 +7,7 @@ from twisted.python import log
from ..wormhole import wormhole from ..wormhole import wormhole
from ..transit import TransitReceiver from ..transit import TransitReceiver
from ..errors import TransferError, WormholeClosedError from ..errors import TransferError, WormholeClosedError
from ..util import dict_to_bytes, bytes_to_dict, bytes_to_hexstr
APPID = u"lothar.com/wormhole/text-or-file-xfer" APPID = u"lothar.com/wormhole/text-or-file-xfer"
@ -100,14 +101,14 @@ class TwistedReceiver:
log.msg("unrecognized message %r" % (them_d,)) log.msg("unrecognized message %r" % (them_d,))
def _send_data(self, data, w): def _send_data(self, data, w):
data_bytes = json.dumps(data).encode("utf-8") data_bytes = dict_to_bytes(data)
w.send(data_bytes) w.send(data_bytes)
@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.get()
them_d = json.loads(them_bytes.decode("utf-8")) 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"])
returnValue(them_d) returnValue(them_d)
@ -125,7 +126,7 @@ class TwistedReceiver:
self.args.code_length) self.args.code_length)
def _show_verifier(self, verifier): def _show_verifier(self, verifier):
verifier_hex = binascii.hexlify(verifier).decode("ascii") verifier_hex = bytes_to_hexstr(verifier)
if self.args.verify: if self.args.verify:
self._msg(u"Verifier %s." % verifier_hex) self._msg(u"Verifier %s." % verifier_hex)
@ -298,9 +299,9 @@ class TwistedReceiver:
@inlineCallbacks @inlineCallbacks
def _close_transit(self, record_pipe, datahash): def _close_transit(self, record_pipe, datahash):
datahash_hex = binascii.hexlify(datahash).decode("ascii") datahash_hex = bytes_to_hexstr(datahash)
ack = {u"ack": u"ok", u"sha256": datahash_hex} ack = {u"ack": u"ok", u"sha256": datahash_hex}
ack_bytes = json.dumps(ack).encode("utf-8") ack_bytes = dict_to_bytes(ack)
with self.args.timing.add("send ack"): with self.args.timing.add("send ack"):
yield record_pipe.send_record(ack_bytes) yield record_pipe.send_record(ack_bytes)
yield record_pipe.close() yield record_pipe.close()

View File

@ -1,5 +1,5 @@
from __future__ import print_function from __future__ import print_function
import os, sys, json, binascii, six, tempfile, zipfile, hashlib import os, sys, six, tempfile, zipfile, hashlib
from tqdm import tqdm from tqdm import tqdm
from twisted.python import log from twisted.python import log
from twisted.protocols import basic from twisted.protocols import basic
@ -8,6 +8,7 @@ from twisted.internet.defer import inlineCallbacks, returnValue
from ..errors import TransferError, WormholeClosedError from ..errors import TransferError, WormholeClosedError
from ..wormhole import wormhole from ..wormhole import wormhole
from ..transit import TransitSender from ..transit import TransitSender
from ..util import dict_to_bytes, bytes_to_dict, bytes_to_hexstr
APPID = u"lothar.com/wormhole/text-or-file-xfer" APPID = u"lothar.com/wormhole/text-or-file-xfer"
@ -52,7 +53,7 @@ class Sender:
yield d yield d
def _send_data(self, data, w): def _send_data(self, data, w):
data_bytes = json.dumps(data).encode("utf-8") data_bytes = dict_to_bytes(data)
w.send(data_bytes) w.send(data_bytes)
@inlineCallbacks @inlineCallbacks
@ -86,14 +87,14 @@ class Sender:
# TODO: don't stall on w.verify() unless they want it # TODO: don't stall on w.verify() unless they want it
verifier_bytes = yield w.verify() # this may raise WrongPasswordError verifier_bytes = yield w.verify() # this may raise WrongPasswordError
if args.verify: if args.verify:
verifier = binascii.hexlify(verifier_bytes).decode("ascii") verifier = bytes_to_hexstr(verifier_bytes)
while True: while True:
ok = six.moves.input("Verifier %s. ok? (yes/no): " % verifier) ok = six.moves.input("Verifier %s. ok? (yes/no): " % verifier)
if ok.lower() == "yes": if ok.lower() == "yes":
break break
if ok.lower() == "no": if ok.lower() == "no":
err = "sender rejected verification check, abandoned transfer" err = "sender rejected verification check, abandoned transfer"
reject_data = json.dumps({"error": err}).encode("utf-8") reject_data = dict_to_bytes({"error": err})
w.send(reject_data) w.send(reject_data)
raise TransferError(err) raise TransferError(err)
@ -131,7 +132,7 @@ class Sender:
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: get() fired, so now it's safe to use w.derive_key()
them_d = json.loads(them_d_bytes.decode("utf-8")) them_d = bytes_to_dict(them_d_bytes)
#print("GOT", them_d) #print("GOT", them_d)
recognized = False recognized = False
if u"error" in them_d: if u"error" in them_d:
@ -273,12 +274,12 @@ class Sender:
transform=_count_and_hash) transform=_count_and_hash)
expected_hash = hasher.digest() expected_hash = hasher.digest()
expected_hex = binascii.hexlify(expected_hash).decode("ascii") expected_hex = bytes_to_hexstr(expected_hash)
print(u"File sent.. waiting for confirmation", file=stdout) print(u"File sent.. waiting for confirmation", file=stdout)
with self._timing.add("get ack") as t: with self._timing.add("get ack") as t:
ack_bytes = yield record_pipe.receive_record() ack_bytes = yield record_pipe.receive_record()
record_pipe.close() record_pipe.close()
ack = json.loads(ack_bytes.decode("utf-8")) ack = bytes_to_dict(ack_bytes)
ok = ack.get(u"ack", u"") ok = ack.get(u"ack", u"")
if ok != u"ok": if ok != u"ok":
t.detail(ack="failed") t.detail(ack="failed")

View File

@ -1,8 +1,9 @@
import json, time import time
from twisted.internet import reactor from twisted.internet import reactor
from twisted.python import log from twisted.python import log
from autobahn.twisted import websocket from autobahn.twisted import websocket
from .rendezvous import CrowdedError, SidedMessage from .rendezvous import CrowdedError, SidedMessage
from ..util import dict_to_bytes, bytes_to_dict
# The WebSocket allows the client to send "commands" to the server, and the # The WebSocket allows the client to send "commands" to the server, and the
# server to send "responses" to the client. Note that commands and responses # server to send "responses" to the client. Note that commands and responses
@ -101,7 +102,7 @@ class WebSocketRendezvous(websocket.WebSocketServerProtocol):
def onMessage(self, payload, isBinary): def onMessage(self, payload, isBinary):
server_rx = time.time() server_rx = time.time()
msg = json.loads(payload.decode("utf-8")) msg = bytes_to_dict(payload)
try: try:
if "type" not in msg: if "type" not in msg:
raise Error("missing 'type'") raise Error("missing 'type'")
@ -227,7 +228,7 @@ class WebSocketRendezvous(websocket.WebSocketServerProtocol):
def send(self, mtype, **kwargs): def send(self, mtype, **kwargs):
kwargs["type"] = mtype kwargs["type"] = mtype
kwargs["server_tx"] = time.time() kwargs["server_tx"] = time.time()
payload = json.dumps(kwargs).encode("utf-8") payload = dict_to_bytes(kwargs)
self.sendMessage(payload, False) self.sendMessage(payload, False)
def onClose(self, wasClean, code, reason): def onClose(self, wasClean, code, reason):

View File

@ -1,7 +1,6 @@
from __future__ import print_function, absolute_import from __future__ import print_function, absolute_import
import os, sys, json, re import os, sys, re
from six.moves.urllib_parse import urlparse from six.moves.urllib_parse import urlparse
from binascii import hexlify, unhexlify
from twisted.internet import defer, endpoints, error from twisted.internet import defer, endpoints, error
from twisted.internet.threads import deferToThread, blockingCallFromThread from twisted.internet.threads import deferToThread, blockingCallFromThread
from twisted.internet.defer import inlineCallbacks, returnValue from twisted.internet.defer import inlineCallbacks, returnValue
@ -18,7 +17,8 @@ from . import codes
from .errors import (WrongPasswordError, UsageError, WelcomeError, from .errors import (WrongPasswordError, UsageError, WelcomeError,
WormholeClosedError) WormholeClosedError)
from .timing import DebugTiming from .timing import DebugTiming
from .util import to_bytes from .util import (to_bytes, bytes_to_hexstr, hexstr_to_bytes,
dict_to_bytes, bytes_to_dict)
from hkdf import Hkdf from hkdf import Hkdf
def HKDF(skm, outlen, salt=None, CTXinfo=b""): def HKDF(skm, outlen, salt=None, CTXinfo=b""):
@ -223,7 +223,7 @@ class _Wormhole:
self._welcomer = _WelcomeHandler(self._ws_url, __version__, self._welcomer = _WelcomeHandler(self._ws_url, __version__,
self._signal_error) self._signal_error)
self._side = hexlify(os.urandom(5)).decode("ascii") self._side = bytes_to_hexstr(os.urandom(5))
self._connection_state = CLOSED self._connection_state = CLOSED
self._connection_waiters = [] self._connection_waiters = []
self._started_get_code = False self._started_get_code = False
@ -398,14 +398,14 @@ class _Wormhole:
# ACKs we get back from the server (which we otherwise ignore). There # ACKs we get back from the server (which we otherwise ignore). There
# are so few messages, 16 bits is enough to be mostly-unique. # are so few messages, 16 bits is enough to be mostly-unique.
if self.DEBUG: print("SEND", mtype) if self.DEBUG: print("SEND", mtype)
kwargs["id"] = hexlify(os.urandom(2)).decode("ascii") kwargs["id"] = bytes_to_hexstr(os.urandom(2))
kwargs["type"] = mtype kwargs["type"] = mtype
payload = json.dumps(kwargs).encode("utf-8") payload = dict_to_bytes(kwargs)
self._timing.add("ws_send", _side=self._side, **kwargs) self._timing.add("ws_send", _side=self._side, **kwargs)
self._ws.sendMessage(payload, False) self._ws.sendMessage(payload, False)
def _ws_dispatch_response(self, payload): def _ws_dispatch_response(self, payload):
msg = json.loads(payload.decode("utf-8")) msg = bytes_to_dict(payload)
if self.DEBUG and msg["type"]!="ack": print("DIS", msg["type"], msg) if self.DEBUG and msg["type"]!="ack": print("DIS", msg["type"], msg)
self._timing.add("ws_receive", _side=self._side, message=msg) self._timing.add("ws_receive", _side=self._side, message=msg)
mtype = msg["type"] mtype = msg["type"]
@ -562,7 +562,7 @@ class _Wormhole:
# this is encrypted like a normal phase message, and includes a # this is encrypted like a normal phase message, and includes a
# dictionary of version flags to let the other Wormhole know what # dictionary of version flags to let the other Wormhole know what
# we're capable of (for future expansion) # we're capable of (for future expansion)
plaintext = json.dumps(self._my_versions).encode("utf-8") plaintext = dict_to_bytes(self._my_versions)
phase = u"version" phase = u"version"
data_key = self._derive_phase_key(self._side, phase) data_key = self._derive_phase_key(self._side, phase)
encrypted = self._encrypt_data(data_key, plaintext) encrypted = self._encrypt_data(data_key, plaintext)
@ -616,7 +616,7 @@ class _Wormhole:
if self.DEBUG: print("CONFIRM FAILED") if self.DEBUG: print("CONFIRM FAILED")
self._signal_error(WrongPasswordError(), u"scary") self._signal_error(WrongPasswordError(), u"scary")
return return
msg = json.loads(plaintext.decode("utf-8")) msg = bytes_to_dict(plaintext)
self._version_received(msg) self._version_received(msg)
self._maybe_notify_verify() self._maybe_notify_verify()
@ -681,9 +681,7 @@ class _Wormhole:
# TODO: retry on failure, with exponential backoff. We're guarding # TODO: retry on failure, with exponential backoff. We're guarding
# against the rendezvous server being temporarily offline. # against the rendezvous server being temporarily offline.
self._timing.add("add", phase=phase) self._timing.add("add", phase=phase)
self._ws_send_command(u"add", phase=phase, self._ws_send_command(u"add", phase=phase, body=bytes_to_hexstr(body))
body=hexlify(body).decode("ascii"))
def _event_mailbox_used(self): def _event_mailbox_used(self):
if self.DEBUG: print("_event_mailbox_used") if self.DEBUG: print("_event_mailbox_used")
@ -708,7 +706,7 @@ class _Wormhole:
side = msg["side"] side = msg["side"]
phase = msg["phase"] phase = msg["phase"]
assert isinstance(phase, type(u"")), type(phase) assert isinstance(phase, type(u"")), type(phase)
body = unhexlify(msg["body"].encode("ascii")) body = hexstr_to_bytes(msg["body"])
if side == self._side: if side == self._side:
return return
self._event_received_peer_message(side, phase, body) self._event_received_peer_message(side, phase, body)