Skip to content

Commit

Permalink
Merge branch 'file_transfer'
Browse files Browse the repository at this point in the history
  • Loading branch information
ESoro25 committed Dec 13, 2021
2 parents 4fd093d + c391267 commit 3eb6cf6
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 146 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.json
__pychache__
150 changes: 150 additions & 0 deletions broadcast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import socket
import time
import threading
import json
from functools import lru_cache
from base64 import b64encode, b64decode
from Crypto.Hash import SHA256
from contacts import decrypt_contacts
from send_file import init_file_tcp_server

def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip

def init_broadcast_socket():
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
server.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
return server

def init_client_socket():
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
return client

def init_tcp_server_socket():
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcp_server.bind((get_ip(),5000)) #Bind to localhost for testing, replace with get_ip() in production
tcp_server.listen(5)
return tcp_server

def init_tcp_client_socket(IP):
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcp_client.connect((IP, 5000))
return tcp_client


#############
# UDP broadcast
#############

def broadcaster(socket):
try:
while True:
socket.sendto(get_own_hash().encode(), ("255.255.255.255", 5005))
time.sleep(3)
except KeyboardInterrupt:
pass

def receiver(socket):
socket.bind(("255.255.255.255", 5005))
while True:
data, addr = socket.recvfrom(1024)
if addr[0] != get_ip():
if check_incoming_hash(data.decode()):
online_contacts[get_email_from_hash(data.decode())] = addr[0]
# Open TCP Connection to user if they are in our contacts
threading.Thread(target=send_tcp, args=(init_tcp_client_socket(addr[0]),),daemon=True).start()

def validate_payload(client, addr):
payload = client.recv(1024)
if b'securedrop' in b64decode(payload):
decoded_hash = b64decode(payload).decode().replace('securedrop','')
client.send(b'1') if check_incoming_hash(decoded_hash) else client.send(b'0')

##############
# TCP
##############


def serve_tcp(socket):
try:
while True:
client, addr = socket.accept()
threading.Thread(target=validate_payload, args=(client,addr),daemon=True).start()
finally:
socket.close()

def send_tcp(socket):
payload = b64encode(b'securedrop'+get_own_hash().encode())
try:
socket.sendall(payload)
data = socket.recv(1024)
except KeyboardInterrupt:
print('tcp socket error')
socket.close()

if data.decode() == '0':
update_online_contacts(socket.getpeername()[0])

time.sleep(1)

@lru_cache
def get_own_hash():
with open('user_info.json', 'r') as f:
user_info = json.load(f)
return SHA256.new(user_info['email_address'].encode()).hexdigest()

@lru_cache
def check_incoming_hash(data):
contacts = decrypt_contacts()

for contact in contacts:
#print(contact['email_hash'])
if contact['email_hash'] == data:
return True
return False

@lru_cache
def update_online_contacts(ip):
tmp = []
for k,v in contacts.items():
if v == ip: tmp.append(k)
for key in tmp:
online_contacts.pop(key)

@lru_cache
def get_email_from_hash(data):
contacts = decrypt_contacts()

for contact in contacts:
if contact['email_hash'] == data:
return contact['email_address']

def print_online_contacts():
for key in online_contacts:
print('\t - ', key)

def return_contacts_dict():
return online_contacts

def start_networking():
global online_contacts
online_contacts = {}

threading.Thread(target=broadcaster,args=(init_broadcast_socket(),),daemon=True).start() #UDP Broadcaster
threading.Thread(target=receiver,args=(init_client_socket(),),daemon=True).start() #UDP Listener

threading.Thread(target=serve_tcp, args=(init_tcp_server_socket(),),daemon=True).start() #TCP Server

init_file_tcp_server()

if __name__ == '__main__':
start_networking()
87 changes: 44 additions & 43 deletions contacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,76 @@
import sys
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Hash import SHA256
from blake3 import blake3
import os.path

def decrypt_contacts():
try:
with open("user_contacts.json", "rb") as f:
nonce, tag, ciphertext = [ f.read(x) for x in (16, 16, -1) ]

cipher = AES.new(get_derived_key(), AES.MODE_EAX, nonce)
data = cipher.decrypt_and_verify(ciphertext, tag)

return json.loads(data.decode())

from input import main
except FileNotFoundError:
with open('user_contacts.json', 'w') as f:
contacts_list.append(new_contact)
json.dump(contacts_list, f, indent=4)

def list():
try:
with open("user_contacts_enc.json", "rb") as f:
nonce, tag, ciphertext = [ f.read(x) for x in (16, 16, -1) ]
with open("user_contacts.json", "rb") as f:
plaintext = f.read()

cipher = AES.new(get_derived_key(), AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)

cipher = AES.new(get_derived_key(), AES.MODE_EAX, nonce)
data = cipher.decrypt_and_verify(ciphertext, tag)

data_object = json.loads(data.decode())
print(json.dumps(data_object,indent=4))
except FileNotFoundError:
sys.exit("No contacts found!")
with open("user_contacts.json", "wb") as f:
[ f.write(x) for x in (cipher.nonce, tag, ciphertext) ]

print('Contact Added.')

def list():
print(json.dumps(decrypt_contacts(),indent=4))

def main():
global new_contact
global contacts_list

new_contact = {}
contacts_list = []

try:
new_contact['full_name'] = input("Enter Full Name of contact: ").strip().title()
new_contact['email_address'] = input("Enter Email Address of contact: ")
new_contact['email_hash'] = SHA256.new(new_contact['email_address'].encode()).hexdigest()

try:
with open('user_contacts.json', 'r+') as f:
contacts = json.load(f)

for contact in contacts:
if contact['email_address'] == new_contact['email_address']:
contact.update(new_contact)
f.seek(0)
json.dump(contacts, f, indent=4)
break

else:
contacts.append(new_contact)
f.seek(0)
json.dump(contacts, f, indent=4)

except FileNotFoundError:
with open('user_contacts.json', 'w') as f:
contacts_list.append(new_contact)
json.dump(contacts_list, f, indent=4)
contacts = decrypt_contacts()

for contact in contacts:
if contact['email_address'] == new_contact['email_address']:
contact.update(new_contact)
f.seek(0)
json.dump(contacts, f, indent=4)
break

else:
contacts.append(new_contact)
f.seek(0)
json.dump(contacts, f, indent=4)

print("Contact Added.")

except KeyboardInterrupt:
sys.exit()

with open("user_contacts.json", "rb") as f:
plaintext = f.read()

cipher = AES.new(get_derived_key(), AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)

with open("user_contacts_enc.json", "wb") as f:
[ f.write(x) for x in (cipher.nonce, tag, ciphertext) ]

def get_derived_key():
try:
with open('user_info.json', 'r') as f:
user_info = json.load(f)

key_material = user_info['email_address']
key_material = user_info['password']

with open('/etc/machine-id','r') as f:
context = f.read()
Expand All @@ -78,7 +80,6 @@ def get_derived_key():

except FileNotFoundError as missing_file:
sys.exit("Could not open file " + missing_file.filename)


if __name__ == "__main__":
main()
Expand Down
71 changes: 0 additions & 71 deletions input.py

This file was deleted.

2 changes: 0 additions & 2 deletions login.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from Crypto.Hash import SHA256
from Crypto.Protocol.KDF import bcrypt_check


def main():

with open('user_info.json', 'r') as f:
Expand Down Expand Up @@ -33,6 +32,5 @@ def main():
except KeyboardInterrupt:
sys.exit()


if __name__ == '__main__':
main()
Loading

0 comments on commit 3eb6cf6

Please sign in to comment.