Feature/py iot (#4)
* Changing files but having issues with space tabs. * Removed config. Fixed indents. * Removed config. * Fixed test config. Fixed syntax in cli. * Editing cli and hub to finally commit transactions. * Added better logging logic. Will clean up in the morning. * Hub is more functional. * Edited IoT to gen keys. * Public keys are now generated, sent, and stored. However, they are not transmitted when a new client joins. * Added crypto testing * Communication is now functional.
This commit is contained in:
parent
5d0a26ca7e
commit
a85b08f050
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@ __pycache__/
|
|||
*.py[cod]
|
||||
*$py.class
|
||||
config.yaml
|
||||
config.yml
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
|
55
src/cipher.py
Normal file
55
src/cipher.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
import time
|
||||
import json
|
||||
from random import random
|
||||
|
||||
class Client:
|
||||
def __init__(self, ws):
|
||||
self.new = True
|
||||
self.ws = ws
|
||||
self.n = None
|
||||
self.e = None
|
||||
|
||||
|
||||
def log_prefix(t, client=None):
|
||||
if client is None:
|
||||
return str(time.time()) + ' [' + t + ':srv] '
|
||||
return str(time.time()) + ' [' + t + ':' + str(client['id']) + '] '
|
||||
|
||||
|
||||
def load_msg(message):
|
||||
try:
|
||||
msg = json.loads(message)
|
||||
except:
|
||||
msg = message
|
||||
return msg
|
||||
|
||||
|
||||
def load_pub_key(cli, msg):
|
||||
try:
|
||||
cli.n = msg['pub_key']['n']
|
||||
cli.e = msg['pub_key']['e']
|
||||
return True
|
||||
except:
|
||||
print('\tMessage had no attribute pub_key. Failed.')
|
||||
return False
|
||||
|
||||
|
||||
def gen_comm_msg(to, ident, msg):
|
||||
message = {
|
||||
'type':'message',
|
||||
'to': to,
|
||||
'id': ident,
|
||||
'contents': msg
|
||||
}
|
||||
return json.dumps(message)
|
||||
|
||||
|
||||
def gen_pub_key_msg(n, e):
|
||||
message = {
|
||||
'type': 'pub_key',
|
||||
'pub_key':{
|
||||
'n':n,
|
||||
'e':e
|
||||
}
|
||||
}
|
||||
return json.dumps(message)
|
162
src/cli.py
Normal file
162
src/cli.py
Normal file
|
@ -0,0 +1,162 @@
|
|||
"""
|
||||
Python client based on https://pypi.org/project/websocket-client/
|
||||
|
||||
@author hornetfighter515
|
||||
@author Todorov-Lachezar
|
||||
"""
|
||||
|
||||
import websocket
|
||||
import _thread
|
||||
import time
|
||||
import ssl
|
||||
import yaml
|
||||
import json
|
||||
import rsa
|
||||
import random # for message id generation
|
||||
import cipher
|
||||
|
||||
ext = False
|
||||
authed = False
|
||||
clis = []
|
||||
messages = {}
|
||||
|
||||
def authed_ext_send(ws, msg):
|
||||
msg = rsa.encrypt(msg.encode(), clis[0]).decode('latin')
|
||||
message_id = random.random()
|
||||
if len(clis) <= 1: # if there are no IoTs
|
||||
# send the message once-encrypted
|
||||
message = cipher.gen_comm_msg(0, message_id, msg)
|
||||
ws.send(message)
|
||||
return
|
||||
# otherwise, slice and twice encrypt it
|
||||
twice_es = []
|
||||
modifier = len(msg)/(len(clis)-1)
|
||||
for i in range(1,len(clis)):
|
||||
start = int( (i-1) * modifier)
|
||||
end = int(i*modifier)
|
||||
# makes a slice of the encrypted message, and indicates the intended
|
||||
# recipient
|
||||
contents = rsa.encrypt(msg[start:end].encode('latin'),
|
||||
clis[i]).decode('latin')
|
||||
message = cipher.gen_comm_msg(i, message_id, contents)
|
||||
twice_es.append(message)
|
||||
for m in twice_es:
|
||||
ws.send(m)
|
||||
|
||||
|
||||
def authed_int_send(ws, msg):
|
||||
to = int(input(f"Who's it to? 0-{len(clis)}>"))
|
||||
e_msg = rsa.encrypt(msg.encode(), clis[int(to)]).decode('latin')
|
||||
message_id = random.random()
|
||||
msg = cipher.gen_comm_msg(to, message_id, e_msg)
|
||||
ws.send(msg)
|
||||
|
||||
|
||||
def init_send(ws):
|
||||
message = cipher.gen_pub_key_msg(pub['n'], pub['e'])
|
||||
ws.send(message)
|
||||
|
||||
|
||||
def send(ws, msg):
|
||||
try:
|
||||
if ext:
|
||||
authed_ext_send(ws, msg)
|
||||
else:
|
||||
authed_int_send(ws, msg)
|
||||
except Exception as e:
|
||||
print(f'Sending message {msg} failed: {e}')
|
||||
|
||||
|
||||
def on_message(ws, message):
|
||||
msg = json.loads(message)
|
||||
global authed
|
||||
if msg['type'] == 'pub_key':
|
||||
authed = True
|
||||
if ext:
|
||||
k = rsa.PublicKey(msg['available_cli']['n'],
|
||||
msg['available_cli']['e'])
|
||||
if len(clis) == 0:
|
||||
clis.append(k)
|
||||
else:
|
||||
clis[0] = k
|
||||
for i,p in msg['available_iots'].items():
|
||||
k = rsa.PublicKey(p['n'], p['e'])
|
||||
clis.append(k)
|
||||
else:
|
||||
k = rsa.PublicKey(msg['available_cli']['n'],
|
||||
msg['available_cli']['e'])
|
||||
clis.append(k)
|
||||
|
||||
elif msg['type'] == 'message':
|
||||
# check if it's only a partial message
|
||||
try:
|
||||
if 'from' in msg:
|
||||
if msg['id'] not in messages:
|
||||
messages[msg['id']] = {}
|
||||
messages[msg['id']][msg['from']] = msg['contents']
|
||||
contents = None
|
||||
for i in range(0, 3):
|
||||
if i in messages[msg['id']]:
|
||||
if contents is None:
|
||||
contents = messages[msg['id']][i].encode('latin')
|
||||
else:
|
||||
contents += messages[msg['id']][i].encode('latin')
|
||||
if len(contents) == 256:
|
||||
m = rsa.decrypt(contents, priv).decode()
|
||||
else:
|
||||
m = ' '
|
||||
else:
|
||||
contents = msg['contents'].encode('latin')
|
||||
m = rsa.decrypt(contents, priv).decode()
|
||||
if m is not None:
|
||||
print(f"\033[F\033[1G<< {m}\n> ")
|
||||
except Exception as e:
|
||||
print(f'Failed to receive message due to {e}')
|
||||
|
||||
|
||||
def on_error(ws, error):
|
||||
print(error)
|
||||
|
||||
|
||||
def on_close(ws, close_status_code, close_msg):
|
||||
print(f"### closed. reason: {close_msg} ###")
|
||||
|
||||
|
||||
def on_open(ws):
|
||||
def run(*args):
|
||||
init_send(ws)
|
||||
running = True
|
||||
while running:
|
||||
outbound = input(">")
|
||||
if outbound == 'q':
|
||||
running = False
|
||||
else:
|
||||
send(ws, outbound)
|
||||
ws.close()
|
||||
_thread.start_new_thread(run, ())
|
||||
|
||||
|
||||
def open_socket(url, port):
|
||||
ws = websocket.WebSocketApp(f"ws://{url}:{port}",
|
||||
on_open=on_open,
|
||||
on_message=on_message,
|
||||
on_error=on_error,
|
||||
on_close=on_close)
|
||||
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open('src/config.yml', 'r') as f:
|
||||
conf = yaml.safe_load(f)
|
||||
|
||||
e = input("Are you outside of the network? (Y/n)")
|
||||
if e == 'y' or e == 'Y' or e == 'yes' or e == 'Yes':
|
||||
ext = True
|
||||
ws_conf = conf['ws']['ext']
|
||||
else:
|
||||
ws_conf = conf['ws']['int']
|
||||
print('Generating keys...')
|
||||
pub, priv = rsa.newkeys(2048)
|
||||
print('Keys generated')
|
||||
open_socket(ws_conf['url'], ws_conf['port'])
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import websocket
|
||||
import _thread
|
||||
import time
|
||||
import ssl
|
||||
import yaml
|
||||
|
||||
def on_message(ws, message):
|
||||
print(f"<< {message}")
|
||||
|
||||
def on_error(ws, error):
|
||||
print(error)
|
||||
|
||||
def on_close(ws, close_status_code, close_msg):
|
||||
print(f"### closed. reason: {close_msg} ###")
|
||||
|
||||
def on_open(ws):
|
||||
def run(*args):
|
||||
running = True
|
||||
while running:
|
||||
outbound = input(">")
|
||||
if outbound == 'q':
|
||||
running = False
|
||||
else:
|
||||
ws.send(outbound)
|
||||
ws.close()
|
||||
_thread.start_new_thread(run, ())
|
||||
|
||||
def open_socket(url, port):
|
||||
ws = websocket.WebSocketApp(f"ws://{url}:{port}",
|
||||
on_open=on_open,
|
||||
on_message=on_message,
|
||||
on_error=on_error,
|
||||
on_close=on_close)
|
||||
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open('config.yaml', 'r') as f:
|
||||
conf = yaml.safe_load(f)
|
||||
open_socket(conf['ws']['url'], conf['ws']['port'])
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
ws:
|
||||
url: localhost
|
||||
port: 6873
|
|
@ -1,35 +0,0 @@
|
|||
"""
|
||||
Encrypting and decrypting a message
|
||||
|
||||
https://www.geeksforgeeks.org/how-to-encrypt-and-decrypt-strings-in-python/
|
||||
|
||||
@author Todorov-Lachezar
|
||||
"""
|
||||
|
||||
import rsa
|
||||
|
||||
class EncryptDecrypt():
|
||||
|
||||
def make_keys(key_length):
|
||||
publicKey, privateKey = ""
|
||||
# Generates public and private keys
|
||||
# Method takes in key length as a parameter
|
||||
# Note: the key length should be >16
|
||||
if(key_length < 16):
|
||||
publicKey, privateKey = rsa.newkeys(key_length)
|
||||
return publicKey, privateKey
|
||||
else:
|
||||
return "Enter a key_length of >16"
|
||||
|
||||
|
||||
def encryption(plaintext, publicKey):
|
||||
# Encrypts the message with the public key
|
||||
# Note: make sure to encode the message before encrypting
|
||||
encMessage = rsa.encrypt(plaintext.encode(), publicKey)
|
||||
return encMessage
|
||||
|
||||
def decryption(ciphertext, privateKey):
|
||||
# Decrypts the encrypted message with the private key
|
||||
# Note: make sure to decode the message after decryption
|
||||
decMessage = rsa.decrypt(ciphertext, privateKey).decode()
|
||||
return decMessage
|
|
@ -1,3 +0,0 @@
|
|||
ws:
|
||||
url: localhost
|
||||
port: 6873
|
33
src/e_d_test.py
Normal file
33
src/e_d_test.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
"""
|
||||
oh no
|
||||
|
||||
@author hornetfighter515
|
||||
"""
|
||||
import rsa
|
||||
|
||||
print('Generating keys...')
|
||||
|
||||
(pub_one, priv_one) = rsa.newkeys(2048)
|
||||
(pub_two, priv_two) = rsa.newkeys(2048)
|
||||
(pub_three, priv_three) = rsa.newkeys(2048)
|
||||
|
||||
print('Keys generated!')
|
||||
|
||||
message = 'hello world'
|
||||
|
||||
e_one = rsa.encrypt(message.encode(), pub_one)
|
||||
e_two = rsa.encrypt(e_one[:128], pub_two)
|
||||
e_three = rsa.encrypt(e_one[128:], pub_three)
|
||||
|
||||
print('Successfully encrypted!')
|
||||
|
||||
d_three = rsa.decrypt(e_three, priv_three)
|
||||
d_two = rsa.decrypt(e_two, priv_two)
|
||||
print(str(e_one))
|
||||
print('-----------------------------')
|
||||
print(str(d_two + d_three))
|
||||
print(str(e_one) == str(d_two + d_three))
|
||||
|
||||
d_one = rsa.decrypt(d_two + d_three, priv_one)
|
||||
|
||||
print('Successfully decrypted ' + d_one.decode())
|
34
src/encrypt_decrypt.py
Executable file
34
src/encrypt_decrypt.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
"""
|
||||
Encrypting and decrypting a message
|
||||
|
||||
https://www.geeksforgeeks.org/how-to-encrypt-and-decrypt-strings-in-python/
|
||||
|
||||
@author hornetfighter515
|
||||
@author Todorov-Lachezar
|
||||
"""
|
||||
|
||||
import rsa
|
||||
|
||||
def make_keys(key_length):
|
||||
publicKey, privateKey = None,None
|
||||
# Generates public and private keys
|
||||
# Method takes in key length as a parameter
|
||||
# Note: the key length should be >16
|
||||
if(key_length > 16):
|
||||
(publicKey, privateKey) = rsa.newkeys(key_length)
|
||||
return publicKey, privateKey
|
||||
else:
|
||||
return "Enter a key_length of >16"
|
||||
|
||||
|
||||
def encryption(plaintext, publicKey):
|
||||
# Encrypts the message with the public key
|
||||
# Note: make sure to encode the message before encrypting
|
||||
encMessage = rsa.encrypt(plaintext.encode(), publicKey)
|
||||
return encMessage
|
||||
|
||||
def decryption(ciphertext, privateKey):
|
||||
# Decrypts the encrypted message with the private key
|
||||
# Note: make sure to decode the message after decryption
|
||||
decMessage = rsa.decrypt(ciphertext, privateKey).decode()
|
||||
return decMessage
|
215
src/hub.py
Normal file
215
src/hub.py
Normal file
|
@ -0,0 +1,215 @@
|
|||
"""
|
||||
Creates hub for distributed IoT
|
||||
|
||||
Websocket Server docs: https://github.com/Pithikos/python-websocket-server
|
||||
|
||||
@author hornetfighter515
|
||||
@author Lachezar Todorov
|
||||
"""
|
||||
|
||||
import threading
|
||||
from websocket_server import WebsocketServer
|
||||
import time
|
||||
import json
|
||||
from random import random
|
||||
|
||||
iot_devs = {}
|
||||
e_clients = {}
|
||||
i_client = None
|
||||
name=''
|
||||
|
||||
ext_srv = None
|
||||
int_srv = None
|
||||
iot_srv = None
|
||||
|
||||
class Client:
|
||||
def __init__(self, ws):
|
||||
self.new = True
|
||||
self.ws = ws
|
||||
self.n = None
|
||||
self.e = None
|
||||
|
||||
|
||||
def _log_prefix(t, client=None):
|
||||
if client is None:
|
||||
return str(time.time()) + ' [' + t + ':srv] '
|
||||
return str(time.time()) + ' [' + t + ':' + str(client['id']) + '] '
|
||||
|
||||
# #
|
||||
#################### INCOMING MESSAGES ########################################
|
||||
# #
|
||||
|
||||
def _load_msg(message):
|
||||
try:
|
||||
msg = json.loads(message)
|
||||
except:
|
||||
msg = message
|
||||
return msg
|
||||
|
||||
|
||||
def _pub_key(cli, msg):
|
||||
try:
|
||||
cli.n = msg['pub_key']['n']
|
||||
cli.e = msg['pub_key']['e']
|
||||
return True
|
||||
except:
|
||||
print('\tMessage had no attribute pub_key. Failed.')
|
||||
return False
|
||||
|
||||
|
||||
def _cli_pubs(coll):
|
||||
res = {}
|
||||
if len(coll) == 0:
|
||||
return res
|
||||
for c, cli in coll.items():
|
||||
res[c] = {
|
||||
"n":cli.n,
|
||||
"e":cli.e
|
||||
}
|
||||
return res
|
||||
|
||||
|
||||
def ext_msg(client, server, message):
|
||||
# external coming in to network
|
||||
print(_log_prefix('ext', client), 'sent message.')
|
||||
cli = e_clients[client['id']]
|
||||
msg = _load_msg(message)
|
||||
if cli.new:
|
||||
if _pub_key(cli, msg):
|
||||
# give IoTs or cli
|
||||
if len(iot_devs) > 0:
|
||||
print('\tThere are IoTs to send to.')
|
||||
else:
|
||||
print('\tCommunicate directly with client.')
|
||||
cli.new = False
|
||||
int_srv.send_message(i_client.ws, json.dumps({
|
||||
"type":"pub_key",
|
||||
"available_cli":{
|
||||
"n":cli.n,
|
||||
"e":cli.e
|
||||
}
|
||||
}))
|
||||
ext_srv.send_message(client, json.dumps({
|
||||
"type":"pub_key",
|
||||
"name":name,
|
||||
"available_cli":{
|
||||
"n":i_client.n,
|
||||
"e":i_client.e
|
||||
},
|
||||
"available_iots": _cli_pubs(iot_devs)
|
||||
}))
|
||||
else:
|
||||
print(f'\tMessage {msg["id"]} goes to {msg["to"]}')
|
||||
if msg['to'] == 0:
|
||||
print('\tTo internal client')
|
||||
int_srv.send_message(i_client.ws, message)
|
||||
else:
|
||||
iot_srv.send_message(iot_devs[msg['to']].ws, message)
|
||||
print('\tTo IoT device')
|
||||
|
||||
|
||||
def int_msg(client, server, message):
|
||||
# internal leaving network
|
||||
print(_log_prefix('int', client), 'Sent message.' )
|
||||
msg = _load_msg(message)
|
||||
if msg['type'] == 'pub_key':
|
||||
if i_client.new:
|
||||
if _pub_key(i_client, msg):
|
||||
print(f'\tinternal client successfully authed.')
|
||||
i_client.new = False
|
||||
return
|
||||
elif msg['type'] == 'message':
|
||||
global e_clients
|
||||
to = msg['to'] + 1
|
||||
ext_srv.send_message(e_clients[to].ws, message)
|
||||
print('\tMessage sent to external client')
|
||||
|
||||
|
||||
def iot_msg(client, server, message):
|
||||
# Partially decrypted message coming back from IoT devices
|
||||
print(_log_prefix('iot', client), 'sent message.')
|
||||
iot = iot_devs[client['id']]
|
||||
msg = _load_msg(message)
|
||||
if iot.new:
|
||||
if _pub_key(iot, msg):
|
||||
print(f'\tIoT {client["id"]} successfully authed.')
|
||||
iot.new = False
|
||||
else:
|
||||
if i_client is not None:
|
||||
int_srv.send_message(i_client.ws, message)
|
||||
print('\tInternal client safe to send to.')
|
||||
else:
|
||||
print('\tInternal client disconnected.')
|
||||
|
||||
# #
|
||||
######################### NEW CONNECTIONS #####################################
|
||||
# #
|
||||
|
||||
def ext_new(client, server):
|
||||
global e_clients
|
||||
if client['id'] not in e_clients:
|
||||
e_clients[client['id']] = Client(client)
|
||||
print(_log_prefix('ext', client) + 'Client joined.')
|
||||
# give list of iots and their pubkeys
|
||||
|
||||
def int_new(client, server):
|
||||
print(_log_prefix('int', client) + 'Client joined.')
|
||||
global i_client
|
||||
if i_client is None:
|
||||
i_client = Client(client)
|
||||
print('\tInternal client set.')
|
||||
|
||||
def iot_new(client, server):
|
||||
global iot_devs
|
||||
if client['id'] not in iot_devs:
|
||||
iot_devs[client['id']] = Client(client)
|
||||
print(_log_prefix('iot', client) + 'Device joined.')
|
||||
|
||||
|
||||
def start_server(conf, new, msg, prefix):
|
||||
ws = WebsocketServer(host=conf['url'], port=conf['port'])
|
||||
ws.set_fn_new_client(new)
|
||||
ws.set_fn_message_received(msg)
|
||||
wst = threading.Thread(target=ws.run_forever)
|
||||
wst.daemon = True
|
||||
wst.start()
|
||||
print(_log_prefix(prefix), 'Running...')
|
||||
return ws
|
||||
|
||||
def start_servers(ext_conf, int_conf, iot_conf):
|
||||
"""
|
||||
Starts a server for each type of device.
|
||||
Why create a different server for each client type? Separation of concerns
|
||||
is easier this way. Messages don't need to be sorted as heavily by which
|
||||
client they came from. Internal ports can more easily be firewalled, or not
|
||||
exposed to the outside internet at all.
|
||||
@param host: the host it is being run on
|
||||
@param port_e: the externally exposed port for clients outside the network
|
||||
@param port_i: the internal port for clients to connect to
|
||||
@param port_iot: the port for IoT devices to connect to
|
||||
"""
|
||||
# websocket server exposed, or external, for external clients
|
||||
global ext_srv
|
||||
ext_srv = start_server(ext_conf, ext_new, ext_msg, 'ext')
|
||||
|
||||
# websocket server internal
|
||||
global int_srv
|
||||
int_srv = start_server(int_conf, int_new, int_msg, 'int')
|
||||
|
||||
# websocket server for IoT devices
|
||||
global iot_srv
|
||||
iot_srv = start_server(iot_conf, iot_new, iot_msg, 'iot')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import yaml
|
||||
with open('src/config.yml', 'r') as f:
|
||||
conf = yaml.safe_load(f)
|
||||
ext_conf = conf['ws']['ext']
|
||||
int_conf = conf['ws']['int']
|
||||
iot_conf = conf['ws']['iot']
|
||||
start_servers(ext_conf, int_conf, iot_conf)
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
"""
|
||||
Creates hub for distributed IoT
|
||||
|
||||
@author hornetfighter515
|
||||
@author Lachezar Todorov
|
||||
"""
|
||||
|
||||
from websocket_server import WebsocketServer
|
||||
import time
|
||||
|
||||
class Serv():
|
||||
def __init__(self, host, port):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ws_s = WebsocketServer(host=host, port=port)
|
||||
self.ws_s.set_fn_message_received(self.message_received)
|
||||
self.ws_s.set_fn_new_client(self.new_client)
|
||||
self.ws_s.run_forever()
|
||||
|
||||
def _log_prefix(self):
|
||||
return str(time.time()) + ' [' + self.host + ':' + str(self.port) + '] '
|
||||
|
||||
def new_client(self, client, server):
|
||||
print(self._log_prefix() + 'Client joined.')
|
||||
|
||||
def message_received(self, client, server, message):
|
||||
# figure out how to identify clients...
|
||||
print(self._log_prefix() + message )
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import yaml
|
||||
with open('config.yml', 'r') as f:
|
||||
conf = yaml.safe_load(f)
|
||||
ws_conf = conf['ws']
|
||||
ext_server = Serv(ws_conf['ext']['url'], ws_conf['ext']['port'])
|
|
@ -1,7 +0,0 @@
|
|||
ws:
|
||||
ext:
|
||||
url: localhost
|
||||
port: 6873
|
||||
int:
|
||||
url: localhost
|
||||
port: 6872
|
79
src/iot.py
Normal file
79
src/iot.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
"""
|
||||
A middleman IoT websocket device which decrypts and re-encrypts a message
|
||||
|
||||
@author hornetfighter515
|
||||
@author Lachezar Todorov
|
||||
"""
|
||||
import websocket
|
||||
import _thread
|
||||
import time
|
||||
import yaml
|
||||
import json
|
||||
import rsa
|
||||
|
||||
|
||||
def send(ws, message):
|
||||
try:
|
||||
ws.send(json.dumps(message))
|
||||
except:
|
||||
print(f'Sending of message {message} failed.')
|
||||
|
||||
|
||||
def on_message(ws, message):
|
||||
# decrypt the message
|
||||
#try:
|
||||
if True:
|
||||
msg = json.loads(message)
|
||||
contents = msg['contents'].encode('latin')
|
||||
res = {
|
||||
"from":msg['to'],
|
||||
"to":0,
|
||||
"type":'message',
|
||||
"id":msg['id'],
|
||||
"contents": rsa.decrypt(contents, priv).decode('latin')
|
||||
}
|
||||
print('Forwarding message...')
|
||||
send(ws, res)
|
||||
#except:
|
||||
# print('Sending failed.')
|
||||
# send(ws, message)
|
||||
|
||||
|
||||
def on_error(ws, error):
|
||||
print(error)
|
||||
|
||||
def on_close(ws, close_status_code, close_msg):
|
||||
print(f"### closed. reason: {close_msg} ###")
|
||||
|
||||
def on_open(ws):
|
||||
def run(*args):
|
||||
send(ws, {
|
||||
"pub_key":{
|
||||
"n":pub.n,
|
||||
"e":pub.e
|
||||
}
|
||||
})
|
||||
running = True
|
||||
while running:
|
||||
time.sleep(1)
|
||||
_thread.start_new_thread(run, ())
|
||||
|
||||
def open_socket(url, port):
|
||||
ws = websocket.WebSocketApp(f"ws://{url}:{port}",
|
||||
on_open=on_open,
|
||||
on_message=on_message,
|
||||
on_error=on_error,
|
||||
on_close=on_close)
|
||||
ws.run_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open('src/config.yml', 'r') as f:
|
||||
conf = yaml.safe_load(f)
|
||||
global pub, priv
|
||||
# eventually put this in config
|
||||
print('Generating keys...')
|
||||
pub, priv = rsa.newkeys(2048)
|
||||
print('Keys generated!')
|
||||
open_socket(conf['ws']['iot']['url'], conf['ws']['iot']['port'])
|
||||
|
70
src/protocol.json
Normal file
70
src/protocol.json
Normal file
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"ext-srv":{
|
||||
"init":{
|
||||
"name":"name",
|
||||
"pub_key":"pub_key"
|
||||
},
|
||||
"msg":{
|
||||
"id":0,
|
||||
"to":0,
|
||||
"contents":"contents"
|
||||
}
|
||||
},
|
||||
"srv-ext":{
|
||||
"init":{
|
||||
"name":"name",
|
||||
"available_cli": "public_key_zero",
|
||||
"available_iots":[
|
||||
"public_key_one",
|
||||
"public_key_two"
|
||||
]
|
||||
},
|
||||
"msg":{
|
||||
"contents":"contents"
|
||||
}
|
||||
},
|
||||
"int-srv":{
|
||||
"init":{
|
||||
"name":"name",
|
||||
"pub_key":"public_key_zero"
|
||||
},
|
||||
"msg":{
|
||||
"to":0,
|
||||
"contents":"contents"
|
||||
}
|
||||
},
|
||||
"srv-int":{
|
||||
"init":{
|
||||
"available_clients":[
|
||||
"clients"
|
||||
]
|
||||
},
|
||||
"msg":{
|
||||
"id":0,
|
||||
"position":0,
|
||||
"contents":"contents"
|
||||
},
|
||||
"sys":{
|
||||
"msg"
|
||||
}
|
||||
},
|
||||
"iot-srv":{
|
||||
"init":{
|
||||
"id":0,
|
||||
"pub_key":"public_key_one"
|
||||
},
|
||||
"msg":{
|
||||
"id":0,
|
||||
"contents":"contents"
|
||||
}
|
||||
},
|
||||
"srv-iot":{
|
||||
"init":{
|
||||
"client_available":false
|
||||
},
|
||||
"msg":{
|
||||
"id":0,
|
||||
"contents":"contents"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,3 +5,6 @@ ws:
|
|||
int:
|
||||
url: localhost
|
||||
port: 6872
|
||||
iot:
|
||||
url: localhost
|
||||
port: 6871
|
Loading…
Reference in New Issue
Block a user