def receive_login(connection, client_commonName): while True: if client_commonName: print(client_commonName) username_msg = m2proto.recv(connection) if not username_msg or username_msg[0] != 8: return None print(username_msg[1]) if(username_msg[1] != client_commonName): return None else: print("Client's username is verified against certificate's common name..!!") else: username_msg = m2proto.recv(connection) if not username_msg or username_msg[0] != 8: return None password_msg = m2proto.recv(connection) if not password_msg or password_msg[0] != 9: return None result = check_user_credentials_in_auth_thread(auth_queue, username_msg[1], password_msg[1]) if result == 10 or result == 12: m2proto.send(connection, result) print(username_msg[1]) return username_msg[1] else: m2proto.send(connection, 11)
def receive(): global file_to_send prefix = None file_sender = None file_to_receive = None response = m2proto.recv(client) while response is not None: # receive and print responses from the server (can be many) (msg_type, payload) = response if msg_type == 13: prefix = payload elif msg_type == 0: ui.add_output(prefix, payload) prefix = None elif msg_type == 14: file_sender = payload elif msg_type == 15: incoming_filename = payload try: file_to_receive = open(incoming_filename, "xb") except: # likely either FileExistsError or PermissionError, but we don't really care ui.add_output( None, "Unable to receive file from " + file_sender + ": " + incoming_filename) file_sender = None file_to_receive = None with client_lock: m2proto.send(client, 17) else: with client_lock: m2proto.send(client, 16) ui.add_output( None, "Receiving file from " + file_sender + ": " + incoming_filename) elif msg_type == 4: file_to_receive.write(payload) elif msg_type == 18: file_to_receive.close() ui.add_output(None, "Finished receiving file.") elif msg_type == 16: ui.add_output(None, "Sending file...") with client_lock: fd = file_to_send file_to_send = None Thread(target=send_file, daemon=True, args=(fd, )).start() elif msg_type == 17: ui.add_output(None, "Cannot send file.") with client_lock: if file_to_send is not None: file_to_send.close() file_to_send = None response = m2proto.recv(client) ui.send_exit_signals()
def login(username): while True: # username = input("Username: "******"Connection closed1.") return False password = getpass("Password: "******"Connection closed2.") return False response = m2proto.recv(client) if not response: print("Connection closed3.") return False elif response[0] == 10: print("Login successful.") return True elif response[0] == 12: print("New user registered.") return True elif response[0] == 11: print("Login failed.") else: print(f"Unexpected message type: {response[0]}") return False
def __test_recv(self, socket_data, expected_type, expected_payload): socket = FakeReadableSocket(socket_data) self.assertEqual(m2proto.recv(socket), (expected_type, expected_payload))
def test_recv_error_with_partial_payload(self): socket = FakeReadableSocket(b'\x00\x05abc', True) self.assertIsNone(m2proto.recv(socket))
def test_recv_error_after_second_byte(self): socket = FakeReadableSocket(b'\x00\x05', True) self.assertIsNone(m2proto.recv(socket))
def test_recv_error(self): socket = FakeReadableSocket(b'', True) self.assertIsNone(m2proto.recv(socket))
def test_recv_end_after_first_byte(self): socket = FakeReadableSocket(b'\x00') self.assertIsNone(m2proto.recv(socket))
def test_recv_end(self): socket = FakeReadableSocket(b'') self.assertIsNone(m2proto.recv(socket))
def client_thread(connection, address, threadNumber, client_commonName): global file_transfer_source_connection, file_transfer_target_connection try: if not client_commonName: username = receive_login(connection, '') else: print("Client's commonName : " + client_commonName) username = receive_login(connection, client_commonName) if username is not None: with clients_lock: clients[threadNumber] = (connection, username) while True: data = m2proto.recv(connection) if data is not None: (msg_type, payload) = data if msg_type == 0: print(f"From connected Client {address}): " + str(payload)) with clients_lock: # broadcast msg to all clients for target_connection, target_username in clients.values(): m2proto.send(target_connection, 13, username) m2proto.send(target_connection, 0, payload) elif msg_type == 14: with clients_lock: if file_transfer_source_connection is None: file_transfer_source_connection = connection file_transfer_target_connection = None for target_connection, target_username in clients.values(): if payload == target_username: file_transfer_target_connection = target_connection break if file_transfer_target_connection is None: file_transfer_source_connection = None elif msg_type == 15: with clients_lock: if file_transfer_source_connection != connection or file_transfer_target_connection is None: m2proto.send(connection, 17) else: m2proto.send(file_transfer_target_connection, 14, username) m2proto.send(file_transfer_target_connection, 15, payload) elif msg_type == 16: with clients_lock: if file_transfer_target_connection == connection: m2proto.send(file_transfer_source_connection, 16) elif msg_type == 17: with clients_lock: if file_transfer_target_connection == connection: m2proto.send(file_transfer_source_connection, 17) file_transfer_source_connection = None file_transfer_target_connection = None elif msg_type == 18: with clients_lock: if file_transfer_source_connection == connection: m2proto.send(file_transfer_target_connection, 18) file_transfer_source_connection = None file_transfer_target_connection = None elif msg_type == 4: with clients_lock: if file_transfer_source_connection == connection: m2proto.send(file_transfer_target_connection, 4, payload) else: break finally: with clients_lock: try: del clients[threadNumber] connection.shutdown(socket.SHUT_RDWR) connection.close() except: pass