def send_message(self, to, content): """Method for forming a text message to be sent to a target user.""" req = self.form_text_message(to, content) with socket_lock: send_message(req, self._socket, CLIENT_LOG) self.process_server_answer( receive_message(self._socket, CLIENT_LOG)) CLIENT_LOG.info(f'Sent a message to the user {to}')
def connection_init(self, port, ip): """Method for starting a server connection. Opens socket, connects to the server over network, performs handshake and authorization.""" self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._socket.settimeout(5) connected = False for i in range(5): CLIENT_LOG.info(f'Connecting - try #{i + 1}') try: self._socket.connect((ip, port)) except (OSError, ConnectionRefusedError): pass else: connected = True break time.sleep(1) if not connected: CLIENT_LOG.critical( f"Couldn't connect to the server ({ip}:{port}).") raise ServerError("Couldn't connect to the server!") CLIENT_LOG.debug( f'Connection with server {ip}:{port} established, starting AUTH process.' ) passwd_bytes = self.password.encode('utf-8') salt = self.username.lower().encode('utf-8') passwd_hash = hashlib.pbkdf2_hmac('sha512', passwd_bytes, salt, 10000) passwd_hash_string = binascii.hexlify(passwd_hash) CLIENT_LOG.debug(f'Passwd hash ready: {passwd_hash_string}') self.pubkey = self.keys.publickey().export_key().decode('ascii') try: with socket_lock: send_message(self.form_presence_message(), self._socket, CLIENT_LOG) ans = receive_message(self._socket, CLIENT_LOG) if JIM.RESPONSE in ans: if ans[JIM.RESPONSE] == 400: raise ServerError(ans[JIM.ERROR]) elif ans[JIM.RESPONSE] == ResCodes.AUTH_PROCESS: ans_data = ans[JIM.DATA] hash = hmac.new(passwd_hash_string, ans_data.encode('utf-8'), 'MD5') digest = hash.digest() to_send = form_response(ResCodes.AUTH_PROCESS) to_send[JIM.DATA] = binascii.b2a_base64(digest).decode( 'ascii') send_message(to_send, self._socket, CLIENT_LOG) self.process_server_answer( receive_message(self._socket, CLIENT_LOG)) # self.process_server_answer( # receive_message(self._socket, CLIENT_LOG)) except (OSError, json.JSONDecodeError) as err: CLIENT_LOG.critical('Connection lost.', exc_info=err) raise ServerError('Server connection lost!') CLIENT_LOG.info('Server received our presence message.')
if __name__ == '__main__': address, port, username, password = arg_parser() app = QApplication(sys.argv) init_dialog = UserNameDialog() if not username or not password: app.exec_() if init_dialog.ok_pressed: username = init_dialog.client_name.text() password = init_dialog.client_passwd.text() CLIENT_LOG.debug(f'Using name = {username}, pw = {password}') else: exit(0) CLIENT_LOG.info( f'Started a client, params: {address}:{port} (@{username})') dir_path = os.path.dirname(os.path.realpath(__file__)) key_file = os.path.join(dir_path, f'{username}.key') if not os.path.exists(key_file): keys = RSA.generate(2048, os.urandom) with open(key_file, 'wb') as key_f: key_f.write(keys.export_key()) else: with open(key_file, 'rb') as key_f: keys = RSA.import_key(key_f.read()) CLIENT_LOG.debug('Keys loaded') db = ClientBase(username)