Sunday, May 25, 2025

Python-Based Local Network Folder Sharing with Authentication

 


Overview

This improved solution allows you to securely share folders on your local network with a simple one-click operation, featuring:

  • Basic HTTP authentication

  • Customizable credentials

  • Optional SSL/TLS encryption

  • Directory listing control

  • Cross-platform compatibility


Code Implementation


python
import os
import sys
import getpass
from http.server import HTTPServer, SimpleHTTPRequestHandler
from functools import partial
import socket
import ssl
import argparse
import base64

class AuthHTTPRequestHandler(SimpleHTTPRequestHandler):
    """HTTP request handler with basic authentication"""
    
    def __init__(self, *args, username=None, password=None, **kwargs):
        self.username = username
        self.password = password
        super().__init__(*args, **kwargs)
    
    def do_GET(self):
        """Handle GET requests with authentication"""
        auth_header = self.headers.get('Authorization', '')
        
        if not (self.username and self.password):
            # No authentication required
            return super().do_GET()
            
        if auth_header.startswith('Basic '):
            auth_decoded = base64.b64decode(auth_header[6:]).decode('utf-8')
            if auth_decoded == f"{self.username}:{self.password}":
                return super().do_GET()
        
        # Authentication failed
        self.send_response(401)
        self.send_header('WWW-Authenticate', 'Basic realm="Folder Sharing"')
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'Authentication required')

def get_local_ip():
    """Get the local IP address of the machine"""
    try:
        # Create a dummy socket to get the local IP
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception:
        return "127.0.0.1"

def share_folder(folder_path, port=8000, username=None, password=None, use_ssl=False):
    """Share a folder over the local network with optional authentication"""
    if not os.path.isdir(folder_path):
        print(f"Error: {folder_path} is not a valid directory")
        return
    
    os.chdir(folder_path)
    handler = partial(AuthHTTPRequestHandler, username=username, password=password)
    
    try:
        server = HTTPServer(('0.0.0.0', port), handler)
        
        if use_ssl:
            # Generate self-signed certificate (you should replace this with a proper certificate)
            cert_path = "selfsigned.pem"
            if not os.path.exists(cert_path):
                print("Generating temporary self-signed certificate...")
                import subprocess
                subprocess.run(f"openssl req -new -x509 -keyout {cert_path} -out {cert_path} -days 365 -nodes -subj '/CN=localhost'", shell=True)
            
            server.socket = ssl.wrap_socket(
                server.socket,
                server_side=True,
                certfile=cert_path,
                ssl_version=ssl.PROTOCOL_TLS
            )
        
        local_ip = get_local_ip()
        protocol = "https" if use_ssl else "http"
        
        print(f"\nSharing folder: {folder_path}")
        print(f"Access on your local network at: {protocol}://{local_ip}:{port}")
        if username and password:
            print(f"Username: {username}\nPassword: {password}")
        print("\nPress Ctrl+C to stop sharing...")
        
        server.serve_forever()
    except KeyboardInterrupt:
        print("\nSharing stopped")
    except Exception as e:
        print(f"Error: {str(e)}")

def main():
    parser = argparse.ArgumentParser(description='Share a folder on your local network with authentication')
    parser.add_argument('folder', nargs='?', default=os.getcwd(), help='Folder to share (default: current directory)')
    parser.add_argument('-p', '--port', type=int, default=8000, help='Port to use (default: 8000)')
    parser.add_argument('-u', '--username', help='Username for authentication (optional)')
    parser.add_argument('-s', '--ssl', action='store_true', help='Enable SSL/TLS encryption')
    
    args = parser.parse_args()
    
    password = None
    if args.username:
        password = getpass.getpass("Enter password for authentication: ")
    
    share_folder(
        folder_path=args.folder,
        port=args.port,
        username=args.username,
        password=password,
        use_ssl=args.ssl
    )

if __name__ == '__main__':
    main()

Features

  1. Authentication:

    • Basic HTTP authentication to restrict access

    • Customizable username and password

    • Optional authentication (can be disabled)

  2. Security:

    • Optional SSL/TLS encryption

    • Self-signed certificate generation (for testing)

    • Recommended to use proper certificates for production

  3. Usability:

    • Simple command-line interface

    • Automatic detection of local IP address

    • Clear instructions for accessing the shared folder

  4. Flexibility:

    • Customizable port number

    • Works with any folder (defaults to current directory)

    • Cross-platform (Windows, macOS, Linux)


Usage Instructions

  1. Basic sharing (no authentication):

    python share_folder.py /path/to/folder
  2. With authentication:

    python share_folder.py /path/to/folder -u username

    (You'll be prompted for a password)

  3. With SSL encryption:

    python share_folder.py /path/to/folder -s
  4. Custom port:

    python share_folder.py /path/to/folder -p 8080


Security Notes

  1. For production use, replace the self-signed certificate with a properly signed one

  2. Basic authentication transmits credentials in base64 (not encrypted) - always use with SSL

  3. The script binds to all network interfaces (0.0.0.0) - ensure your firewall is properly configured

  4. For sensitive data, consider additional security measures beyond this script

This enhanced version provides a more robust and secure solution for local network file sharing while maintaining ease of use.

Resources: https://bit.ly/43u7Bwp

To install Python on Windows, download it here: https://www.python.org/downloads/windows/

No comments:

Post a Comment