Files
winget.pro/sslproxy/sslproxy.py
T
2023-11-14 09:35:23 +08:00

88 lines
2.5 KiB
Python

"""
Usage:
python sslproxy [local_port] [dest_host] [dest_port]
The defaults are local_port=8443, dest_host=localhost, dest_port=8000.
"""
import socket, ssl, sys
from functools import partial
from threading import Thread
if len(sys.argv) > 1:
local_port = int(sys.argv[1])
else:
local_port = 8443
if len(sys.argv) > 2:
dest_host = sys.argv[2]
else:
dest_host = 'localhost'
if len(sys.argv) > 3:
dest_port = int(sys.argv[3])
else:
dest_port = 8000
def forward(source, destination, prefix=''):
data = b' '
while data:
try:
data = source.recv(1024)
if data:
try:
decoded = data.decode('utf-8')
except UnicodeDecodeError:
destination.sendall(data)
else:
for line in decoded.split('\n'):
print(prefix + line)
decoded = decoded.replace(
f'\nHost: localhost:{local_port}',
f'\nHost: {dest_host}:{dest_port}'
)
destination.sendall(decoded.encode('utf-8'))
else:
source.shutdown(socket.SHUT_RD)
destination.shutdown(socket.SHUT_WR)
except ConnectionResetError:
break
local_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
local_context.load_cert_chain(
certfile="conf/localhost.cert", keyfile="conf/localhost.key"
)
if dest_port == 443:
dest_context = ssl.create_default_context()
else:
dest_context = None
bindsocket = socket.socket()
bindsocket.bind(('', local_port))
bindsocket.listen(5)
bindsocket.settimeout(.5)
print(f'Forwarding localhost:{local_port} -> {dest_host}:{dest_port}')
while True:
try:
try:
newsocket, fromaddr = bindsocket.accept()
client = local_context.wrap_socket(newsocket, server_side=True)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect((dest_host, dest_port))
if dest_context:
server = dest_context.wrap_socket(server, server_hostname=dest_host)
Thread(
target=partial(forward, prefix='-> '), args=(client, server)
).start()
Thread(
target=partial(forward, prefix='<- '), args=(server, client)
).start()
except socket.timeout:
pass
except KeyboardInterrupt:
break