示例#1
0
def encryption_setup(client, secrets=None):
    """
    Set up encryption keys between server and client

    Args:
        client <socket object> - client socket

    Kwargs:
        secrets <Secrets object> - secret keys to be exchanged with client

    Return:
        client_secrets <Secrets object> - necessary keys received from client
        client_status <bytes> - status report from client after encryption setup
        is_encrypted <bool> - client's encryption status
    """
    try:
        client.send(query_msg('Q:PUBKEY'))
        client_pubkey = client.recv(fc.BLOCK_SIZE // 2)
        client_secrets = Secrets.from_pubkey(client_pubkey)
        if client_secrets is None or not client_secrets.check_hash():
            pass  # TODO: close client connection
        client_secrets.sesskey = secrets.sesskey
        client.send(
            query_msg('Q:SESSION_KEY'))  # signal for encrypted server keys
        server_keys = client_secrets.hybrid_encrypt(secrets.keys)
        client_status = client.recv(1024)
        client.send(server_keys)
        encryption_status = client.recv(
            8)  # get confirmation of encryption setup
        is_encrypted = bool(int(encryption_status))
        return client_secrets, client_status, is_encrypted
    except Exception as ex:
        return None, None, False
示例#2
0
def ask_for_username(client, encoding=fc.DEFAULT_ENC):
    """
    Ask client for a valid username

    Args:
        client <socket object> - client socket

    Kwargs:
        encoding <str> - string coding

    Return:
        username <str> - received username
    """
    client.send(query_msg('Q:USERNAME'))
    while True:
        username = client.recv(1024).decode(encoding)
        knowns = known_users()
        if not fc.ALLOW_UNKNOWN and username in knowns:
            break
        elif fc.ALLOW_UNKNOWN and username not in clients:
            break
        else:
            try:
                client.send(query_msg('Q:CHUSERNAME'))
            except BrokenPipeError:
                fab_log('EXIT', username)
                return None
    return username
示例#3
0
 def test_query_msg(self):
     """ # fabular.comm.query_msg """
     for query in ['Q:USERNAME', 'Q:CHUSERNAME', 'Q:PUBKEY', 'Q:SESSION_KEY',
                   'Q:ACCEPT', 'Q:KILL']:
         self.printf(query)
         q = fcomm.query_msg(query)
         self.assertTrue(q)
         self.assertIsInstance(q, bytes)
         self.printout(q)
     msg = 'not a query'
     self.printf(msg)
     q = fcomm.query_msg(msg)
     self.assertFalse(q)
     self.assertIsInstance(q, bytes)
     self.printout(q)
示例#4
0
 def test_is_query(self):
     """ # fabular.comm.is_query """
     for query in ['Q:USERNAME', 'Q:CHUSERNAME', 'Q:PUBKEY',
                   'Q:SESSION_KEY', 'Q:ACCEPT', 'Q:KILL']:
         msg = fcomm.query_msg(query)
         self.printf((msg, query))
         is_q = fcomm.is_query(msg, query)
         self.assertIsInstance(is_q, bool)
         self.assertTrue(is_q)
         self.printout(is_q)
     query = 'not a query'
     msg = fcomm.query_msg(query)
     self.printf((msg, query))
     is_q = fcomm.is_query(msg, query)
     self.assertFalse(is_q)
     self.assertIsInstance(is_q, bool)
     self.printout(is_q)
示例#5
0
def handshake(server, secrets=None):
    """
    Server main loop: Accept and set up new incoming connections

    Args:
        server <socket object> - server socket

    Kwargs:
        secrets <Secrets object> - secret keys to be exchanged with client

    Return:
        None
    """
    global clients
    v = dict(verbose_mode=fc.VERBOSE)
    while True:
        try:
            client, address = server.accept()
            fab_log('CONN', address, **v)

            # set up username
            username = ask_for_username(client)
            if username:
                fab_log('USRN', username, **v)

            # encryption handshake
            client_secrets, status, is_encrypted = \
                encryption_setup(client, secrets=secrets)
            if status:
                fab_log(status, verbose_mode=3)

            # add username to user table and current clients
            status = register_user(username, client, address, is_encrypted,
                                   client_secrets)
            if status == 0:
                fab_log('LERR', username)
                known = known_users()
                try:
                    client.send(query_msg('Q:KILL'))
                    client.close()
                except BrokenPipeError:
                    pass
                continue

            # announce entry of user
            client.send(query_msg('Q:ACCEPT'))
            try:
                fab_log(client.recv(256), verbose_mode=3)
                broadcast(fab_msg('ENTR', username))
            except UnicodeDecodeError:
                pass

            handle_thread = threading.Thread(target=handle,
                                             args=(
                                                 server,
                                                 username,
                                             ))
            handle_thread.daemon = True
            handle_thread.start()

        except KeyboardInterrupt:
            fab_log('ENDS', verbose_mode=3)
            return