Complete Code

# Import necessary modules
import paramiko  # For SSH and SFTP operations
from getpass import getpass  # For secure password input
import re  # For regex operations
import os  # For operating system dependent functionality

# Define the secure_download class
class secure_download():
    # Initialise the class with given parameters
    def __init__(self, ip, port, username, password):
        self.ip = ip  # IP of the SFTP server
        self.port = port  # Port of the SFTP server
        self.username = username  # Username for SFTP server
        self.password = password  # Password for SFTP server
        self.conn = None  # Placeholder for the connection object
        self.action = None  # Placeholder for the SFTP client
        self.initiate_connection()  # Start the connection

    # Function to start the connection
    def initiate_connection(self):
        try:
            # Create a new transport object with the server's IP and port
            self.conn = paramiko.Transport((self.ip, self.port))
            # Authenticate the transport object with the given username and password
            self.conn.connect(username=self.username, password=self.password)
            # Create a new SFTP client from the authenticated transport object
            self.action = paramiko.SFTPClient.from_transport(self.conn)
            print("Connected to host: " + self.ip)
            # Start the download
            self.initiate_download()
        except paramiko.AuthenticationException as err:
            # Handle authentication errors
            print("Error authenticating with host: " + str(err))
        except paramiko.SSHException as err:
            # Handle other SSH errors
            print("Error establishing SSH connection: " + str(err))
        except Exception as err:
            # Handle all other exceptions
            print("Could not connect: " + str(err))
        finally:
            pass  # Do nothing in the finally clause

    # Function to start the download
    def initiate_download(self):
        # Ask the user for the file to download
        file = input("Enter file to download: ")
        try:
            # Inform the user that the download is starting
            print("\n[*] Attempting to download: " + file + " [*]")
            # Download the file to the current working directory
            self.action.get(file, (str(os.getcwd()) + "/" + str(file.split("/")[-1])))
            # Inform the user that the download was successful
            print("[*] " + file + " downloaded successfully [*]\n")
        except Exception as err:
            # Handle all exceptions during the download
            print("Error downloading: " + str(err))
        finally:
            # Always close the connection
            print("Closing connection.")
            self.conn.close()

# Function to check if the given IP and port are valid
def check_ip_port(ip, port):
    # Define a regex pattern for an IP address
    pattern = r'^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$'
    # Check if the given IP matches the pattern and the port is in the valid range
    if re.match(pattern, ip) and 0 <= port <= 65535:
        return True
    # Return False if the IP or port is invalid
    return False

# Main function
def main():
    # Print the program's title
    print("\n[*] Secure Download [*]")

    # Loop until the user enters a valid IP and port
    while True:
        # Ask the user for the IP and port
        ip = input("\nEnter IP: ")
        port = int(input("Enter port: "))
        # If the IP and port are valid, break the loop
        if check_ip_port(ip, port):
            break
        # If the IP or port is invalid, ask the user to enter them again
        print("Please enter a correct IP/Port.")

    # Ask the user for the username and password
    username = input("Enter username: ")
    password = getpass(prompt="Enter password: ", stream=None) 
    # Create a new secure_download object with the given parameters and start the download
    secure_download(ip, port, username, password)

# If this file is being run as a script, start the main function
if __name__ == '__main__':
    main()