From af1e3c51ecedd9a1190ce90b22117071a2b59941 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Mon, 23 Mar 2015 23:53:28 -0700 Subject: [PATCH] add --code-length, to configure the size of the PAKE code (in bytes/words) --- src/wormhole/blocking/transcribe.py | 9 ++++---- src/wormhole/codes.py | 26 +++++++++++++++--------- src/wormhole/scripts/cmd_receive_file.py | 3 ++- src/wormhole/scripts/cmd_receive_text.py | 3 ++- src/wormhole/scripts/cmd_send_file.py | 2 +- src/wormhole/scripts/cmd_send_text.py | 2 +- src/wormhole/scripts/runner.py | 2 ++ 7 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/wormhole/blocking/transcribe.py b/src/wormhole/blocking/transcribe.py index ceaf374..e0fa524 100644 --- a/src/wormhole/blocking/transcribe.py +++ b/src/wormhole/blocking/transcribe.py @@ -177,9 +177,9 @@ class Initiator(Common): self.timeout = 3*MINUTE self.side = "initiator" - def get_code(self): + def get_code(self, code_length=2): self.channel_id = self._allocate() # allocate channel - self.code = codes.make_code(self.channel_id) + self.code = codes.make_code(self.channel_id, code_length) self.sp = SPAKE2_A(self.code.encode("ascii"), idA=self.appid+":Initiator", idB=self.appid+":Receiver") @@ -225,8 +225,9 @@ class Receiver(Common): channel_ids = r.json()["channel-ids"] return channel_ids - def input_code(self, prompt="Enter wormhole code: "): - code = codes.input_code_with_completion(prompt, self.list_channels) + def input_code(self, prompt="Enter wormhole code: ", code_length=2): + code = codes.input_code_with_completion(prompt, self.list_channels, + code_length) return code def set_code(self, code): diff --git a/src/wormhole/codes.py b/src/wormhole/codes.py index 59388a4..966b262 100644 --- a/src/wormhole/codes.py +++ b/src/wormhole/codes.py @@ -3,10 +3,15 @@ import os from .wordlist import (byte_to_even_word, byte_to_odd_word, even_words_lowercase, odd_words_lowercase) -def make_code(channel_id): - odd_word = byte_to_odd_word[os.urandom(1)] - even_word = byte_to_even_word[os.urandom(1)] - return "%d-%s-%s" % (channel_id, odd_word.lower(), even_word.lower()) +def make_code(channel_id, code_length): + words = [] + for i in range(code_length): + # we start with an "odd word" + if i % 2 == 0: + words.append(byte_to_odd_word[os.urandom(1)].lower()) + else: + words.append(byte_to_even_word[os.urandom(1)].lower()) + return str(channel_id) + "-" + "-".join(words) def extract_channel_id(code): channel_id = int(code.split("-")[0]) @@ -16,8 +21,9 @@ import readline #import sys class CodeInputter: - def __init__(self, get_channel_ids): + def __init__(self, get_channel_ids, code_length): self.get_channel_ids = get_channel_ids + self.code_length = code_length self.last_text = None # memoize for a speedup self.last_matches = None @@ -45,7 +51,7 @@ class CodeInputter: matches = self.last_matches #print(" old matches", len(matches), file=sys.stderr) else: - if len(pieces) < 2: + if len(pieces) <= 1: channel_ids = self.get_channel_ids() matches = [str(channel_id) for channel_id in channel_ids if str(channel_id).startswith(last)] @@ -63,15 +69,15 @@ class CodeInputter: if state >= len(matches): return None match = matches[state] - if len(pieces) < 3: + if len(pieces) < 1+self.code_length: match += "-" #print(" match: '%s'" % match, file=sys.stderr) #sys.stderr.flush() return match -def input_code_with_completion(prompt, get_channel_ids): - c = CodeInputter(get_channel_ids) +def input_code_with_completion(prompt, get_channel_ids, code_length): + c = CodeInputter(get_channel_ids, code_length) readline.parse_and_bind("tab: complete") readline.set_completer(c.wrap_completer) readline.set_completer_delims("") @@ -79,5 +85,5 @@ def input_code_with_completion(prompt, get_channel_ids): return code if __name__ == "__main__": - code = input_code_with_completion("Enter wormhole code: ", lambda: []) + code = input_code_with_completion("Enter wormhole code: ", lambda: [], 2) print("code is:", code) diff --git a/src/wormhole/scripts/cmd_receive_file.py b/src/wormhole/scripts/cmd_receive_file.py index f5d4a3c..23271e2 100644 --- a/src/wormhole/scripts/cmd_receive_file.py +++ b/src/wormhole/scripts/cmd_receive_file.py @@ -19,7 +19,8 @@ def receive_file(args): r = Receiver(APPID, mydata, args.relay_url) code = args.code if not code: - code = r.input_code("Enter receive-file wormhole code: ") + code = r.input_code("Enter receive-file wormhole code: ", + args.code_length) r.set_code(code) try: diff --git a/src/wormhole/scripts/cmd_receive_text.py b/src/wormhole/scripts/cmd_receive_text.py index c338b64..f9ad196 100644 --- a/src/wormhole/scripts/cmd_receive_text.py +++ b/src/wormhole/scripts/cmd_receive_text.py @@ -10,7 +10,8 @@ def receive_text(args): r = Receiver(APPID, data, args.relay_url) code = args.code if not code: - code = r.input_code("Enter receive-text wormhole code: ") + code = r.input_code("Enter receive-text wormhole code: ", + args.code_length) r.set_code(code) try: them_bytes = r.get_data() diff --git a/src/wormhole/scripts/cmd_send_file.py b/src/wormhole/scripts/cmd_send_file.py index 33e714f..8bab63f 100644 --- a/src/wormhole/scripts/cmd_send_file.py +++ b/src/wormhole/scripts/cmd_send_file.py @@ -25,7 +25,7 @@ def send_file(args): }).encode("utf-8") i = Initiator(APPID, data, args.relay_url) - code = i.get_code() + code = i.get_code(args.code_length) print("On the other computer, please run: wormhole receive-file") print("Wormhole code is '%s'" % code) print() diff --git a/src/wormhole/scripts/cmd_send_text.py b/src/wormhole/scripts/cmd_send_text.py index 2822400..0d106b5 100644 --- a/src/wormhole/scripts/cmd_send_text.py +++ b/src/wormhole/scripts/cmd_send_text.py @@ -10,7 +10,7 @@ def send_text(args): data = json.dumps({"message": message, }).encode("utf-8") i = Initiator(APPID, data, args.relay_url) - code = i.get_code() + code = i.get_code(args.code_length) print("On the other computer, please run: wormhole receive-text") print("Wormhole code is: %s" % code) print("") diff --git a/src/wormhole/scripts/runner.py b/src/wormhole/scripts/runner.py index 5f10d86..1ce7f57 100644 --- a/src/wormhole/scripts/runner.py +++ b/src/wormhole/scripts/runner.py @@ -18,6 +18,8 @@ g.add_argument("--relay-url", default=public_relay.RENDEZVOUS_RELAY, metavar="URL", help="rendezvous relay to use") g.add_argument("--transit-helper", default=public_relay.TRANSIT_RELAY, metavar="tcp:HOST:PORT", help="transit relay to use") +g.add_argument("-c", "--code-length", type=int, default=2, + metavar="WORDS", help="length of code (in bytes/words)") subparsers = parser.add_subparsers(title="subcommands", dest="subcommand")