2015-02-11 09:18:31 +00:00
|
|
|
from __future__ import print_function
|
2015-02-11 00:50:32 +00:00
|
|
|
import os, sys, json
|
|
|
|
from nacl.secret import SecretBox
|
2015-02-15 17:53:59 +00:00
|
|
|
from wormhole.blocking.transcribe import Initiator
|
|
|
|
from wormhole.blocking.transit import TransitSender
|
2015-02-11 00:50:32 +00:00
|
|
|
|
|
|
|
APPID = "lothar.com/wormhole/file-xfer"
|
|
|
|
|
|
|
|
# we're sending
|
|
|
|
filename = sys.argv[1]
|
|
|
|
assert os.path.isfile(filename)
|
2015-02-15 17:53:59 +00:00
|
|
|
transit_sender = TransitSender()
|
|
|
|
direct_hints = transit_sender.get_direct_hints()
|
|
|
|
relay_hints = transit_sender.get_relay_hints()
|
|
|
|
|
2015-02-20 00:30:24 +00:00
|
|
|
filesize = os.stat(filename).st_size
|
2015-02-15 22:42:59 +00:00
|
|
|
data = json.dumps({
|
|
|
|
"file": {
|
|
|
|
"filename": os.path.basename(filename),
|
2015-02-20 00:30:24 +00:00
|
|
|
"filesize": filesize,
|
2015-02-15 22:42:59 +00:00
|
|
|
},
|
|
|
|
"transit": {
|
|
|
|
"direct_connection_hints": direct_hints,
|
|
|
|
"relay_connection_hints": relay_hints,
|
|
|
|
},
|
|
|
|
}).encode("utf-8")
|
2015-02-15 17:53:59 +00:00
|
|
|
|
|
|
|
i = Initiator(APPID, data)
|
2015-02-11 02:34:13 +00:00
|
|
|
code = i.get_code()
|
2015-02-15 17:53:59 +00:00
|
|
|
print("On the other computer, please run: receive_file")
|
2015-02-11 00:50:32 +00:00
|
|
|
print("Wormhole code is '%s'" % code)
|
2015-02-15 17:53:59 +00:00
|
|
|
print("")
|
2015-02-11 02:34:13 +00:00
|
|
|
them_bytes = i.get_data()
|
2015-02-11 00:50:32 +00:00
|
|
|
them_d = json.loads(them_bytes.decode("utf-8"))
|
2015-02-20 00:30:24 +00:00
|
|
|
#print("them: %r" % (them_d,))
|
2015-02-20 01:16:43 +00:00
|
|
|
xfer_key = i.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE)
|
2015-02-11 00:50:32 +00:00
|
|
|
|
2015-02-11 01:04:28 +00:00
|
|
|
box = SecretBox(xfer_key)
|
|
|
|
with open(filename, "rb") as f:
|
|
|
|
plaintext = f.read()
|
2015-02-19 01:23:09 +00:00
|
|
|
nonce = os.urandom(SecretBox.NONCE_SIZE)
|
2015-02-11 01:04:28 +00:00
|
|
|
encrypted = box.encrypt(plaintext, nonce)
|
|
|
|
|
2015-02-19 01:23:09 +00:00
|
|
|
tdata = them_d["transit"]
|
2015-02-20 02:24:10 +00:00
|
|
|
transit_key = i.derive_key(APPID+"/transit-key")
|
|
|
|
transit_sender.set_transit_key(transit_key)
|
2015-02-19 01:23:09 +00:00
|
|
|
transit_sender.add_receiver_hints(tdata["direct_connection_hints"])
|
|
|
|
skt = transit_sender.establish_connection()
|
2015-02-20 00:30:24 +00:00
|
|
|
|
|
|
|
print("Sending %d bytes.." % filesize)
|
2015-02-20 01:04:52 +00:00
|
|
|
sent = 0
|
|
|
|
while sent < len(encrypted):
|
|
|
|
more = skt.send(encrypted[sent:])
|
|
|
|
sent += more
|
2015-02-15 17:53:59 +00:00
|
|
|
|
2015-02-20 00:30:24 +00:00
|
|
|
print("File sent.. waiting for confirmation")
|
2015-02-20 00:51:59 +00:00
|
|
|
# ack is a short newline-terminated string, followed by socket close. A long
|
|
|
|
# read is probably good enough.
|
|
|
|
ack = skt.recv(300)
|
2015-02-20 00:30:24 +00:00
|
|
|
if ack == "ok\n":
|
|
|
|
print("Confirmation received. Transfer complete.")
|
2015-02-20 00:51:59 +00:00
|
|
|
sys.exit(0)
|
2015-02-20 00:30:24 +00:00
|
|
|
else:
|
2015-02-20 00:51:59 +00:00
|
|
|
print("Transfer failed (remote says: %r)" % ack)
|
|
|
|
sys.exit(1)
|