Skip to content
Snippets Groups Projects
Commit 47156fd0 authored by Tumbul, Erwin's avatar Tumbul, Erwin
Browse files

Merge remote-tracking branch 'origin/main' into feature/android_client

# Conflicts:
#	server/server.py
parents 3319ad67 eec55416
Branches
No related tags found
No related merge requests found
...@@ -17,8 +17,8 @@ A and B in distinct networks. ...@@ -17,8 +17,8 @@ A and B in distinct networks.
- [x] Exchange messages server<->client using protobuf - [x] Exchange messages server<->client using protobuf
- [x] Android-Client - [x] Android-Client
- [x] Grab notifications - [x] Grab notifications
- [ ] Communicate with grpc service - [x] Communicate with grpc service
- [ ] Create protocol - [x] Create protocol
# Prototype 2: # Prototype 2:
......
...@@ -2,7 +2,6 @@ import sys ...@@ -2,7 +2,6 @@ import sys
sys.path.insert(0, '../..') sys.path.insert(0, '../..')
sys.path.insert(0, '../../shared/netcode') sys.path.insert(0, '../../shared/netcode')
import queue
import grpc import grpc
from shared.netcode.netcode_pb2 import * from shared.netcode.netcode_pb2 import *
from shared.netcode.netcode_pb2_grpc import NotifierCommunicationStub from shared.netcode.netcode_pb2_grpc import NotifierCommunicationStub
...@@ -10,9 +9,30 @@ from shared.netcode.netcode_pb2_grpc import NotifierCommunicationStub ...@@ -10,9 +9,30 @@ from shared.netcode.netcode_pb2_grpc import NotifierCommunicationStub
usage = "Usage:\n- Sender:\n ./client.py 1\n- Receiver:\n ./client.py 0" usage = "Usage:\n- Sender:\n ./client.py 1\n- Receiver:\n ./client.py 0"
def sendMessage(stub, msg): def sender_code(id_code):
request = Message(content=msg) comm_response = stub.Open(OpenRequest(id_code=id_code))
response = stub.SendMessage(request) comm_id = comm_response.comm_id
print("CommID:", comm_id)
stub.SendMessage(Message(comm_id=comm_id, content="init test"))
print("Starting Prompt:")
while True:
text = input()
if text == "":
print("Stopping...")
break
print("Sending:", text)
stub.SendMessage(Message(comm_id=comm_id, content=text))
def receiver_code(id_code):
comm_response = stub.Answer(AnswerRequest(id_code=id_code))
comm_id = comm_response.comm_id
print("CommID:", comm_id)
for message in stub.ReceiveMessage(ReceiveRequest(comm_id=comm_id)):
print("Received:", message.content)
if __name__ == "__main__": if __name__ == "__main__":
...@@ -25,7 +45,7 @@ if __name__ == "__main__": ...@@ -25,7 +45,7 @@ if __name__ == "__main__":
######################################################################## ########################################################################
# SETTINGS # SETTINGS
######################################################################## ########################################################################
is_sender = sys.argv[1] is_sender = sys.argv[1] == "1"
######################################################################## ########################################################################
# print info # print info
...@@ -40,26 +60,11 @@ if __name__ == "__main__": ...@@ -40,26 +60,11 @@ if __name__ == "__main__":
stub = NotifierCommunicationStub(channel) stub = NotifierCommunicationStub(channel)
if is_sender: try:
response = stub.Open(OpenRequest(id_code=1)) common_id = 1
print(response) sender_code(common_id) if is_sender else receiver_code(common_id)
except grpc.RpcError as e:
sendQueue = queue.SimpleQueue() print("Error: A grpc error occurred as", "SENDER" if is_sender else "RECEIVER")
response_future = stub.SendMessage.future(iter(sendQueue.get, None)) print("ErrorCode:", e.code().name)
sendQueue.put_nowait(Message(content="init test")) print("ErrorMessage:", e.details())
exit(1)
print("Starting Prompt:")
while True:
text = input()
if text == "":
print("Stopping...")
break
print("Sending:", text)
sendQueue.put_nowait(Message(content=text))
else:
response = stub.Answer(AnswerRequest(challenge=1))
print(response)
for message in stub.ReceiveMessage(Nothing()):
print(message.content)
...@@ -12,7 +12,12 @@ ...@@ -12,7 +12,12 @@
2. B sends A's id_code to the server. 2. B sends A's id_code to the server.
3. The server checks if it matches and returns a comm_id to B. 3. The server checks if it matches and returns a comm_id to B.
2. Generate and exchange an ephemeral key. 2. Generate and exchange an ephemeral key.
1. A and B generate a RSA key-pair. 1. A and B generate RSA public-private key pairs.
2. A and B exchange public keys.
3. A and B encrypt their chosen secret value and send them to each other.
4. A and B decrypt the received secret values and add them to their secret value.
5. The result is the ephemeral key.
3. Instantiate symmetric encryption using the ephemeral key. 3. Instantiate symmetric encryption using the ephemeral key.
1. AES, CTR-mode
4. Authenticate each other directly. 4. Authenticate each other directly.
5. (?) Check communication transcript (avoid malicious server). 5. (?) Check communication transcript (avoid malicious server).
import sys import sys
import grpc
sys.path.insert(0, '..') sys.path.insert(0, '..')
sys.path.insert(0, '../shared/netcode') sys.path.insert(0, '../shared/netcode')
from queue import SimpleQueue
from threading import Condition, Lock
from concurrent import futures from concurrent import futures
from shared.netcode.netcode_pb2 import * from shared.netcode.netcode_pb2 import *
from shared.netcode.netcode_pb2_grpc import * from shared.netcode.netcode_pb2_grpc import *
PREFIX = "Server>"
start = 0
def generate_unique_comm_id():
global start
start = start + 1
return start
class NotifierService(NotifierCommunicationServicer): class NotifierService(NotifierCommunicationServicer):
class InternalOpenRequest:
def __init__(self, id_code) -> None:
self.id_code = id_code
self.cv = Condition()
self.comm_id = None
def fulfill(self):
self.cv.acquire()
self.comm_id = generate_unique_comm_id()
self.cv.notify_all()
self.cv.release()
class CommPipe:
def __init__(self) -> None:
self.cv = Condition()
self.queue = SimpleQueue()
def relay(self, message):
self.cv.acquire()
self.queue.put(message)
self.cv.notify_all()
self.cv.release()
pass
def wait_for_message(self):
self.cv.acquire()
self.cv.wait()
message = self.queue.get()
self.cv.release()
return message
def __init__(self) -> None:
super().__init__()
self.open_ids = []
self.open_ids_lock = Lock()
self.comm_pipes = {}
self.comm_pipes_lock = Lock()
def create_pipe(self, comm_id):
pipe = self.CommPipe()
self.comm_pipes_lock.acquire()
self.comm_pipes[comm_id] = pipe
self.comm_pipes_lock.release()
return pipe
def get_pipe(self, comm_id):
self.comm_pipes_lock.acquire()
if comm_id in self.comm_pipes:
pipe = self.comm_pipes[comm_id]
self.comm_pipes_lock.release()
return pipe
else:
self.comm_pipes_lock.release()
return None
###########################################################################
# RPCs
###########################################################################
def Open(self, request, context): def Open(self, request, context):
# TODO: append id_code to list # append id_code to list
# TODO: wait for id_code answered comm_request = self.InternalOpenRequest(request.id_code)
# TODO: return comm_id comm_request.cv.acquire()
return CommResponse() self.open_ids_lock.acquire()
self.open_ids.append(comm_request)
print(PREFIX, "OpenRequest created.")
self.open_ids_lock.release()
# wait for id_code answered
comm_request.cv.wait()
# remove request
self.open_ids_lock.acquire()
self.open_ids.remove(comm_request)
self.open_ids_lock.release()
comm_request.cv.release()
# return comm_id
print(PREFIX, "OpenResponse sent.")
return CommResponse(comm_id=comm_request.comm_id)
def Answer(self, request, context): def Answer(self, request, context):
# TODO: check if if_code can be answered print(PREFIX, "AnswerRequest received.")
# TODO: return comm_id code = request.id_code
comm_id = None
# check if if_code can be answered
self.open_ids_lock.acquire()
for open_req in self.open_ids:
if code == open_req.id_code:
# found
open_req.fulfill()
comm_id = open_req.comm_id
print(PREFIX, "OpenRequest answered.")
break
self.open_ids_lock.release()
# return comm_id
if comm_id is None:
# error
context.set_code(grpc.StatusCode.NOT_FOUND)
context.set_details("Error: Open request not found.")
return CommResponse() return CommResponse()
else:
print(PREFIX, "AnswerResponse sent.")
return CommResponse(comm_id=comm_id)
def ReceiveMessage(self, request, context): def ReceiveMessage(self, request, context):
# TODO: read comm_id and wait for messages comm_id = request.comm_id
yield Message(comm_id=-1, content="test") # create pipe
comm_pipe = self.create_pipe(comm_id)
while True:
# TODO: add stop condition
# wait for message
message = comm_pipe.wait_for_message()
# echo message
yield Message(comm_id=comm_id, content=message)
def SendMessage(self, request, context): def SendMessage(self, request, context):
# TODO: read comm_id and route message comm_id = request.comm_id
print(request.comm_id) print("CommID:", request.comm_id, "| Content:", request.content)
print(request.content)
# get pipe
comm_pipe = self.get_pipe(comm_id)
if comm_pipe is None:
# error
context.set_code(grpc.StatusCode.INTERNAL)
context.set_details("Error: comm_id does not exist.")
return Nothing()
# relay message
comm_pipe.relay(request.content)
return Nothing() return Nothing()
...@@ -36,4 +158,5 @@ if __name__ == "__main__": ...@@ -36,4 +158,5 @@ if __name__ == "__main__":
NotifierService(), server) NotifierService(), server)
server.add_insecure_port('[::]:8080') server.add_insecure_port('[::]:8080')
server.start() server.start()
print("Server started...")
server.wait_for_termination() server.wait_for_termination()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment