Compare commits
16 Commits
Transphase
...
Transphase
| Author | SHA1 | Date | |
|---|---|---|---|
| f36e78daf4 | |||
| 8a1905a7b6 | |||
| 71307f3bc7 | |||
| 99e9996a55 | |||
| 634c513c8c | |||
| 575568772a | |||
| d13b59b8e0 | |||
| 9c385c8379 | |||
| ad17c935ef | |||
| 26a0840ad2 | |||
| 717abbc4b2 | |||
| e634643141 | |||
| 4e0d53994c | |||
| d987dfd091 | |||
| 962af5da89 | |||
| 518929fe2d |
21
README.md
21
README.md
@@ -1,14 +1,14 @@
|
||||
# Transphase
|
||||
This is a collection of tools to copy files or proxy connections via WebSockets protocol.
|
||||
It is done in a cryptographically safe(ish) way.
|
||||
A rendevouz/relay server is used to help with data transfer.
|
||||
This is a collection of tools to copy files or proxy connections via WebSockets protocol. \
|
||||
It is done in a cryptographically safe(ish) way. \
|
||||
A relay server is used to help with data transfer.
|
||||
|
||||
**Transphase** - the relay server \
|
||||
**Transmat** - tool to copy files/directories \
|
||||
**Transplace** - HTTP proxy/exit point
|
||||
**transphase** - the relay server \
|
||||
**transmat** - tool to copy files/directories \
|
||||
**transplace** - HTTP proxy/exit point
|
||||
|
||||
### Copy files
|
||||
Transphase server should be running and accessible by the parties.
|
||||
### How to copy files using ```transmat```
|
||||
Transphase relay server should be running and accessible by the parties.
|
||||
On the sending party:
|
||||
```
|
||||
transmat --send <FILENAME>
|
||||
@@ -18,4 +18,9 @@ This will prepare the sender and output the command to run on the receiving part
|
||||
transmat --receive --password Space-Time-Continuum
|
||||
```
|
||||
|
||||
The sending party will wait for the receiving party to connect to the relay server, and then it will start the transfer. \
|
||||
With the exception of some service messages, all the data is encrypted. \
|
||||
Encryption and decryption is done only client-side, and the relay server has no useful knowledge of the data it relays. \
|
||||
Fernet module (AES128-CBC + HMAC-SHA256) is used to encrypt and authenticate the data.
|
||||
|
||||
See also ```transmat --help```
|
||||
18
transmat/diceware.py
Normal file
18
transmat/diceware.py
Normal file
File diff suppressed because one or more lines are too long
@@ -5,5 +5,4 @@ lz4==4.3.2
|
||||
progress==1.6
|
||||
pycparser==2.21
|
||||
pyjson==1.3.0
|
||||
websockets==11.0.2
|
||||
xkcdpass==1.19.3
|
||||
websockets==11.0.2
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
import asyncio, websockets
|
||||
import sys, os, base64, argparse, json, pickle
|
||||
from xkcdpass import xkcd_password as xp
|
||||
from cryptography.fernet import Fernet
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||
from progress.bar import Bar
|
||||
import diceware
|
||||
|
||||
|
||||
VERSION_NUMBER="0.1"
|
||||
|
||||
VERSION_NUMBER="0.1.3"
|
||||
SCRIPT_BASENAME = os.path.basename(sys.argv[0])
|
||||
|
||||
async def read_chunks(filename, chunk_size = 1024):
|
||||
with open(filename, "rb") as f:
|
||||
@@ -94,7 +94,6 @@ async def send_encrypted_msg(ws, k, data):
|
||||
await send_msg(ws, json.dumps(msg))
|
||||
|
||||
|
||||
|
||||
async def main():
|
||||
WS_RELAY_SERVER = "wss://transmat.exocortex.ru"
|
||||
parser = argparse.ArgumentParser()
|
||||
@@ -102,18 +101,16 @@ async def main():
|
||||
arg_group.add_argument('--receive', '--recv', action='store_true', help='Receive a file from the remote party (mutually exclusive with --send and --relay)')
|
||||
arg_group.add_argument('--send', type=str, help='Send a file to the remote party (mutually exclusive with --receive and --relay)')
|
||||
arg_group.add_argument('--version', action='store_true', help="Show version")
|
||||
#arg_group.add_argument('--relay', action='store_true', help='Run as a Relay server (mutually exclusive with --receive and --send)')
|
||||
parser.add_argument('--server', type=str, help="Specify the Relay server URL (ignored with --relay)")
|
||||
parser.add_argument('--password', type=str, help="Specify the shared password (for --receive)")
|
||||
args = parser.parse_args()
|
||||
passwd_part = server_part = ""
|
||||
send_part = f'{sys.argv[0]} --receive '
|
||||
send_part = f'{SCRIPT_BASENAME} --receive'
|
||||
if args.receive:
|
||||
role = 'receive'
|
||||
password = args.password
|
||||
if args.send and args.password is None:
|
||||
wordlist = xp.generate_wordlist(wordfile = xp.locate_wordfile(), min_length = 5, max_length = 9)
|
||||
password = xp.generate_xkcdpassword(wordlist, numwords=4, delimiter = "-", case='capitalize')
|
||||
password = diceware.generate_passphrase(4)
|
||||
passwd_part = f"--password {password}"
|
||||
if args.receive and args.password is None:
|
||||
print("Error: --password required when receiving files.")
|
||||
@@ -128,14 +125,14 @@ async def main():
|
||||
WS_RELAY_SERVER = args.server
|
||||
server_part = f'--server {WS_RELAY_SERVER}'
|
||||
if args.version:
|
||||
print(f"{sys.argv[0]} ver {VERSION_NUMBER}")
|
||||
print(f"{SCRIPT_BASENAME} ver {VERSION_NUMBER}")
|
||||
sys.exit(0)
|
||||
|
||||
k = derive_key_from_password(password)
|
||||
peer_group_id = get_peer_group_id(password)
|
||||
|
||||
if role == 'send':
|
||||
print('Run the following command on the remote party:\n\n', send_part, server_part, passwd_part, "\n")
|
||||
print('Run the following command on the remote party:\n\n', send_part, passwd_part, server_part, "\n")
|
||||
filename = os.path.basename(file_path)
|
||||
file_size = os.path.getsize(file_path)
|
||||
chunk_id = 0
|
||||
@@ -156,11 +153,14 @@ async def main():
|
||||
msg = (msgtype, peer_group_id, role, filename, chunk_size, chunk_id, number_of_chunks, chunk)
|
||||
await send_encrypted_msg(ws, k, msg)
|
||||
await asyncio.sleep(0.05)
|
||||
chunk_id += 1
|
||||
if chunk_id > number_of_chunks:
|
||||
break
|
||||
proceed = await ws.recv()
|
||||
bar.next()
|
||||
chunk_id += 1
|
||||
bar.suffix = '%(percent).1f%% done'
|
||||
print("\n")
|
||||
bar.suffix = '%(percent).1f%% complete'
|
||||
bar.update()
|
||||
print("")
|
||||
|
||||
if role =='receive':
|
||||
async with websockets.connect(WS_RELAY_SERVER) as ws:
|
||||
@@ -187,11 +187,12 @@ async def main():
|
||||
await send_encrypted_msg(ws, k, (msgtype, peer_group_id, role, "", "", "", "", "")) # request the next chunk from sender
|
||||
i += 1
|
||||
bar.next()
|
||||
if i > msg["number_of_chunks"]:
|
||||
if i > msg["number_of_chunks"] + 1:
|
||||
bar.index = 100
|
||||
bar.suffix = '%(percent).1f%% complete'
|
||||
bar.update()
|
||||
f.close()
|
||||
print("\n")
|
||||
print("")
|
||||
break
|
||||
|
||||
|
||||
6
transphase/requirements.txt
Normal file
6
transphase/requirements.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
asyncio==3.4.3
|
||||
cffi==1.15.1
|
||||
cryptography==40.0.2
|
||||
pycparser==2.21
|
||||
pyjson==1.3.0
|
||||
websockets==11.0.2
|
||||
Reference in New Issue
Block a user