Skip to content

Latest commit

 

History

History
131 lines (95 loc) · 9.03 KB

README.md

File metadata and controls

131 lines (95 loc) · 9.03 KB

Reactive File Transfer (RFT)

alt text alt text ☑️ Bandit verified  |  ☑️ Synk verified  |  ☑️ Pylint verified 9.89/10

Prereqs

This program runs on Windows and Linux, written in Python version 3.10.6

Purpose

Reactive file transfer establishes an automated multi-directional encrypted file transfer service with password protection. By utilizing active file system monitoring, the program features designated directories that are synced across remote systems. When a file system modification is activated due to moving data in the designated Outgoing directory, it automatically transfers to the remote systems Incoming directory. RFT features a combination of AESGCM symmetrical encryption with HMAC integrity check that is protected with AESGCM authenticated encryption when exchanged. The AESGCM algorithm utilized features 256 bit and 96 bit nonce as recommended by NIST standards.

Installation

  • Run the setup.py script to build a virtual environment and install all external packages in the created venv.

Examples:
  - Windows: python setup.py venv
  - Linux: python3 setup.py venv

  • Once virtual env is built traverse to the (Scripts-Windows or bin-Linux) directory in the environment folder just created.
  • For Windows, in the venv\Scripts directory, execute activate or activate.bat script to activate the virtual environment.
  • For Linux, in the venv/bin directory, execute source activate to activate the virtual environment.
  • If for some reason issues are experienced with the setup script, the alternative is to manually create an environment, activate it, then run pip install -r packages.txt in project root.

How To Use

  • Ensure the prereqs are met (most later versions of 3 should work) and the installation steps have been followed
  • Run the program as instructed below and enter session password when prompted

Examples:
  - Windows: python reactive_file_transfer.py <remote_ip> <remote_port>
  - Linux: python3 reactive_file_transfer.py <remote_ip> <remote_port>

  • Once the network connection is established and authenticated, the program should be ready to transfer files
  • Simply drag or move data into the Outgoing folder for the remote host to receive it in their Incoming folder and vice versa

Function Layout

-- reactive_file_transfer.py --

auto_file_incoming  -  Polls the read queue for incoming chunks of data and writes data to file name until delimiter is detected.

OutgoingFileDetector  -  Watchdog event is triggered per file system modification is designated outgoing folder. Data is read from the event file and feed into the send queue to be transferred through the network socket in chunks of data set by BUFFER_SIZE pseudo-constant.

on_modified  -  Watchdog event is triggered per file system modification is designated outgoing folder. Data is read from the event file and feed into the send queue to be transferred through the network socket in chunks of data set by BUFFER_SIZE pseudo-constant.

auto_file_outgoing  -  Registers watchdog file system monitoring directory and continually monitors file system to trigger OutgoingFileDetector() watchdog event.

main  -  Runs test network check to see if remote system is already established as a server. Depending on the result, the system is established as client or server to avoid centralized server. After the network socket is established, background daemon threads are spawned to display program output, handle monitoring outing data directory, and handle writing incoming data. Finally, the main thread polls the network socket in a non-blocking manner; getting data from the send queue and sending it, and reading data from the socket and putting it in the read queue.

-- crypto_handlers.py --

authenticated_decrypt  -  Decrypts the symmetrical AESGCM key used for encrypting and decrypting transfer data.

authenticated_encrypt  -  Encrypts the symmetrical AESGCM used for encrypting and decrypting transfer data.

symm_decrypt  -  Verifies the HMAC signature with associated data and decrypts encrypted data to plain text.

symm_encrypt  -  Encrypts the plain text data to be sent with AESGCM and creates HMAC verification signature.

-- network_handlers.py --

client_init  -  Function is called after test socket connection attempt is successful indicating a server is already established on the other end. After gathering session password from user, the final socket connection is re-setup and continually attempted on five second intervals until successful. Once connected, the input password is hashed and send to the remote system for authentication. If successfully authenticated, an encrypted symmetrical key is sent back and decrypted using the authenticated password to be returned to main.

linux_ip_query  -  Runs ifconfig, gathers results, and displays IPs matched through regex.

port_check  -  Creates TCP socket and checks to see if remote port on specified IP address is active.

server_init  -  Function is called after test socket connection attempt is not successful indicating a server is current not present on the other end. After gathering the session password, the hostname is queried and used to get the IP address used to bind to the port. The server then waits for the incoming test connection, which when connected, null bytes are continually sent until an error is raised to the client side timing out. The raised error is ignored and execution is passed to wait for the final incoming connection. Once established, the server end waits for the clients hashed password to arrive and verifies it through hashing algorithm. If successful, a key set is generated and encrypted with the session password and sent back to the client. Finally, the server waits to receive a confirmation status message to ensure the key was received and decrypted.

-- utils.py --

banner_display  -  Renders and displays the programs pyfiglet banner.

base64_parse  -  Ensure the received chunk of data has base64 "=" padding removed, to be recalculated to prevent decoding errors.

error_query  -  Looks up the errno message to get description.

int_convert  -  Convert the passed in size as string to int, handles errors accordingly.

parse_start_bytes  -  Takes the input data chunk containing file name and size to be transferred with divider in the middle.

pass_input  -  Gathers user input for session password and second password input for verification.

print_err  -  Displays error via stderr.

split_handler  -  Takes the passed in data and splits it based on specified divisor in error handled procedure.

validate_ip  -  Checks the input target IP arg against regex validation.

validate_port  -  Checks the input port arg against regex validation and max value.

Exit Codes

-- reactive_file_transfer.py --

0 - Successful operation (main)
1 - Unknown exception occurred (main)
2 - Improper number of args were passed in on execution (main)

-- crypto_handlers.py --

8 - Error occurred during AESCCM algorithm initialization or session key decryption (aesccm_decrypt)
10 - Error occurred encrypting sessions symmetrical cryptographic key (aesccm_encrypt)
12 - Error occurred encrypting data chunk to be sent to remote host (fernet_encrypt)
13 - Error occurred decrypting data chunk received by remote host (fernet_decrypt)

-- network_handlers.py --

6 - Password local hashing or remote authentication failed on remote server host (client_init)
9 - Received client hash does not match established session password (server_init)
11 - If error occurred on the client side parsing and decrypting session symmetrical key (server_init)

-- utils.py --

3 - Error occurred validating input IP address arg (validate_ip)
4 - Error occurred validating input port numer arg (validate_port)
5 - Error occurred rendering pyfiglet program banner (banner_display)
7 - The retrieved key data lacks multiple values to split (split_handler)
14 - Error occurred converting string number to integer (int_convert)
15 - If three consecutive errors occur overwriting and deleting file data (secure_delete)