Exemple #1
0
    def send_client(self, flag):
        """
        Handles the sending feature to the respective clients that are connected to the Broker        
        @param flag: <str> Requested flag to be performed
        @return: No return
        """
        # Load the RSA Cipher
        self.rsa_cipher = RSACipher()

        # Encryption list for temporary storage
        enc = []

        recipient_df = CLIENT_DF.loc[CLIENT_DF['id'] == self.request]
        client_sess, client_name, pubkey = recipient_df.values[0]
        client_pubkey = self.rsa_cipher.importRSAKey(pubkey)

        if flag == ZONE_FILE:
            logging.info(f"Sending Zone file to {client_name}")
            # Open and read the zone file bye by byte
            with open(ZONE_DB_DIR, "rb") as in_file:
                while (byte := in_file.read(1)):
                    # Encrypt the Zone file with RSA Cipher
                    ciphertext = self.rsa_cipher.encrypt_with_RSA(
                        pub_key=client_pubkey, data=byte)
                    enc.append(ciphertext)

            # Serialize the encrypted data and send to the client
            msg = (enc, blockchain.chain)
            client_sess.sendall(pickle.dumps(msg))

            # Send Zone File flag to indicate EOL
            client_sess.sendall(ZONE_FILE)

            # Reset the encryption list
            enc = []
Exemple #2
0
 def get_pubkey(pubkey_dir):
     """
     Function to get Public Key of Alice
     @param pubkey_dir: <str> Directory of the client's Public Key
     @return:
     """
     rsa_cipher = RSACipher()
     return rsa_cipher.load_pubkey(pubkey_dir).publickey().exportKey(
         format='PEM', passphrase=None, pkcs=1)
Exemple #3
0
    def message_handle(self):
        """ Handles the message between server and client """

        # Load the RSACipher for encryption/decryption
        self.rsa_cipher = RSACipher()
        privkey = self.rsa_cipher.load_privkey(SECRET_KEY)

        try:
            # Prepare for incoming data
            data = b""
            while True:
                packet = self.client_sock.recv(BUFSIZE)

                # Break out of the loop the connection is lost to the server
                if not packet:
                    break

                elif CONSENSUS in packet:
                    # Strip the flag
                    data += packet.rstrip(CONSENSUS)

                    # Load the encrypted data list
                    chain = pickle.loads(data)

                    # Reset the data buffer
                    data, packet = b"", b""

                    # Verify the given blockchain
                    if self.blockchain.verify_blockchain(chain):
                        # Update the client Blockchain
                        self.blockchain.chain = chain

                # ZONE FILE HANDLER
                elif ZONE_FILE in packet:
                    # Strip the flag
                    data += packet.rstrip(ZONE_FILE)

                    # Load the encrypted data list
                    enc, chain = pickle.loads(data)

                    # Reset the data buffer
                    data, packet = b"", b""

                    # Prepare to write zone file contents locally and stored in client/ folder
                    print(
                        f"[+] Zone file received from Broker, saving under: {DEFAULT_ZONE_FILE}"
                    )
                    with open(DEFAULT_ZONE_FILE, "wb") as out_file:
                        for ciphertext in enc:
                            plaintext = self.rsa_cipher.decrypt_with_RSA(
                                privkey, ciphertext)
                            out_file.write(plaintext)

                    # Verify the given blockchain
                    if self.blockchain.verify_blockchain(chain):
                        # Update the client Blockchain
                        self.blockchain.chain = chain

                        # Run the user_menu
                        threading.Thread(target=self.user_menu).start()

                # NEW DOMAIN File Handler
                elif NEW_DOMAIN in packet:
                    print("[+] Receiving a new domain zone file")
                    # Strip the flag
                    data += packet.rstrip(NEW_DOMAIN)
                    # Load the encrypted data into a dictionary
                    new_domain = json.loads(
                        self.rsa_cipher.decrypt_with_RSA(priv_key=privkey,
                                                         data=data))

                    # Reset the data buffer
                    data, packet = b"", b""

                    # Extract the domain_name
                    domain_name = list(new_domain.keys())[0]
                    new_domain_zone_fpath = f"client/{UUID}/{domain_name}.json"

                    print(
                        f"[+] Writing new zone file: {domain_name} to {new_domain_zone_fpath}"
                    )
                    # Save the new domain zone file locally
                    with open(new_domain_zone_fpath, "w") as out_file:
                        out_file.write(json.dumps(new_domain))

                # Concatenate the data
                data += packet

        except KeyboardInterrupt:
            self.client_sock.close()

        except socket.error:
            self.client_sock.close()
Exemple #4
0
class Client(object):
    def __init__(self, host, port):
        """
        Initial Connection to the Broker Address
        @param host: <str> IP Addr of the Broker
        @param port: <int> Port number of the Broker
        @return: <sock> Client socket connection to the Broker
        """
        print(f"[*] Connecting to Broker @ ({host},{port})")

        # Start the blockchain
        self.blockchain = Blockchain()

        # Initialise socket
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
            self.client_sock = sock

            # Connects to broker
            try:
                self.client_sock.connect((host, port))

            except socket.error:
                print(
                    "[!] Connection failed! Please check your network connectivity and try again."
                )
                self.client_sock.close()

            # Send client pubkey over to server on initial connection
            server_hello_msg = (UUID, self.get_pubkey(CLIENT_PUBKEY_DIR))
            self.client_sock.sendall(pickle.dumps(server_hello_msg))

            # Run the message_handle
            self.message_handle()

    def message_handle(self):
        """ Handles the message between server and client """

        # Load the RSACipher for encryption/decryption
        self.rsa_cipher = RSACipher()
        privkey = self.rsa_cipher.load_privkey(SECRET_KEY)

        try:
            # Prepare for incoming data
            data = b""
            while True:
                packet = self.client_sock.recv(BUFSIZE)

                # Break out of the loop the connection is lost to the server
                if not packet:
                    break

                elif CONSENSUS in packet:
                    # Strip the flag
                    data += packet.rstrip(CONSENSUS)

                    # Load the encrypted data list
                    chain = pickle.loads(data)

                    # Reset the data buffer
                    data, packet = b"", b""

                    # Verify the given blockchain
                    if self.blockchain.verify_blockchain(chain):
                        # Update the client Blockchain
                        self.blockchain.chain = chain

                # ZONE FILE HANDLER
                elif ZONE_FILE in packet:
                    # Strip the flag
                    data += packet.rstrip(ZONE_FILE)

                    # Load the encrypted data list
                    enc, chain = pickle.loads(data)

                    # Reset the data buffer
                    data, packet = b"", b""

                    # Prepare to write zone file contents locally and stored in client/ folder
                    print(
                        f"[+] Zone file received from Broker, saving under: {DEFAULT_ZONE_FILE}"
                    )
                    with open(DEFAULT_ZONE_FILE, "wb") as out_file:
                        for ciphertext in enc:
                            plaintext = self.rsa_cipher.decrypt_with_RSA(
                                privkey, ciphertext)
                            out_file.write(plaintext)

                    # Verify the given blockchain
                    if self.blockchain.verify_blockchain(chain):
                        # Update the client Blockchain
                        self.blockchain.chain = chain

                        # Run the user_menu
                        threading.Thread(target=self.user_menu).start()

                # NEW DOMAIN File Handler
                elif NEW_DOMAIN in packet:
                    print("[+] Receiving a new domain zone file")
                    # Strip the flag
                    data += packet.rstrip(NEW_DOMAIN)
                    # Load the encrypted data into a dictionary
                    new_domain = json.loads(
                        self.rsa_cipher.decrypt_with_RSA(priv_key=privkey,
                                                         data=data))

                    # Reset the data buffer
                    data, packet = b"", b""

                    # Extract the domain_name
                    domain_name = list(new_domain.keys())[0]
                    new_domain_zone_fpath = f"client/{UUID}/{domain_name}.json"

                    print(
                        f"[+] Writing new zone file: {domain_name} to {new_domain_zone_fpath}"
                    )
                    # Save the new domain zone file locally
                    with open(new_domain_zone_fpath, "w") as out_file:
                        out_file.write(json.dumps(new_domain))

                # Concatenate the data
                data += packet

        except KeyboardInterrupt:
            self.client_sock.close()

        except socket.error:
            self.client_sock.close()

    def send_server(self, flag):
        """ Constructs and forward data over to the broker """
        pubkey = self.rsa_cipher.load_pubkey(BROKER_PUBKEY_DIR)
        enc = []

        if flag == REGIS_DOMAIN:
            with open(self.new_zone_fpath, "rb") as in_file:
                while (byte := in_file.read(1)):
                    ciphertext = self.rsa_cipher.encrypt_with_RSA(
                        pub_key=pubkey, data=byte)
                    enc.append(ciphertext)

            print(
                "[+] Forwarding new zone file and transaction block to Broker ..."
            )
            # Serialize the encrypted data and send to the client
            msg = (enc, self.blockchain.current_transactions)
            self.client_sock.sendall(pickle.dumps(msg))

            # Send REGIS_DOMAIN flag to indicate EOL
            self.client_sock.sendall(REGIS_DOMAIN)

            enc, self.blockchain.current_transactions = [], []

        elif flag == CONSENSUS:
            print("[+] Sending request for update to Broker ...")

            # Send CONSENSUS flag to indicate update request
            self.client_sock.sendall(CONSENSUS)
Exemple #5
0
class ThreadedServerHandle(socketserver.BaseRequestHandler):
    def handle(self):
        global CLIENT_DF

        # Try catch the error
        try:
            # Get the user_id and public key
            user_id, user_pubkey = pickle.loads(self.request.recv(BUFSIZE))
            self.username = self.get_username(USER_DB_DIR, user_id)

            # Info message
            logging.info(f"{self.username} has started the connection.")

            # Add the new Client to the session DB
            CLIENT_DF = CLIENT_DF.append(
                {
                    "id": self.request,
                    "client_name": self.username,
                    "pubkey": user_pubkey
                },
                ignore_index=True)

            # Write Active Clients to Log File
            with open(CLIENT_SESS_LOG, "w+") as out_file:
                out_file.write(CLIENT_DF['client_name'].str.cat(sep=','))

            # Check for the logon username
            if self.username == "miner":
                # Send previous hash to miner
                self.send_miner()
            else:
                # Send Zone File to the client
                self.send_client(ZONE_FILE)

            # Run the message handler to receive client data
            self.message_handle()

        # Close the socket if client forcefully close the connection
        except socket.error:
            self.request.close()

    def send_client(self, flag):
        """
        Handles the sending feature to the respective clients that are connected to the Broker        
        @param flag: <str> Requested flag to be performed
        @return: No return
        """
        # Load the RSA Cipher
        self.rsa_cipher = RSACipher()

        # Encryption list for temporary storage
        enc = []

        recipient_df = CLIENT_DF.loc[CLIENT_DF['id'] == self.request]
        client_sess, client_name, pubkey = recipient_df.values[0]
        client_pubkey = self.rsa_cipher.importRSAKey(pubkey)

        if flag == ZONE_FILE:
            logging.info(f"Sending Zone file to {client_name}")
            # Open and read the zone file bye by byte
            with open(ZONE_DB_DIR, "rb") as in_file:
                while (byte := in_file.read(1)):
                    # Encrypt the Zone file with RSA Cipher
                    ciphertext = self.rsa_cipher.encrypt_with_RSA(
                        pub_key=client_pubkey, data=byte)
                    enc.append(ciphertext)

            # Serialize the encrypted data and send to the client
            msg = (enc, blockchain.chain)
            client_sess.sendall(pickle.dumps(msg))

            # Send Zone File flag to indicate EOL
            client_sess.sendall(ZONE_FILE)

            # Reset the encryption list
            enc = []

        elif flag == CONSENSUS:
            logging.info(f"Client {client_name} request for Consensus")

            # Send the Block Chain to Client
            client_sess.sendall(pickle.dumps(blockchain.chain))
            # Send CONSENSUS flag to indicate EOL
            client_sess.sendall(CONSENSUS)