Skip to content

Commit

Permalink
Change of Structure: There's now a class "ReverseProxy". Behavior
Browse files Browse the repository at this point in the history
of the standalone app isn't changed. This will allow easy
integration/customisation with other projects.
  • Loading branch information
GamingCoookie committed Mar 7, 2022
1 parent 0f8df85 commit 2cb2c4b
Showing 1 changed file with 108 additions and 104 deletions.
212 changes: 108 additions & 104 deletions reverse_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import selectors
import os
import pickle
from threading import Thread


def safe_send(conn, msg):
Expand All @@ -34,118 +35,121 @@ def safe_send(conn, msg):
totalsent += sent


def send_to_server(from_client, to_server):
schedule_close = False
ip6 = re.compile(f'\\[[^]]*]:{port}')
msg = from_client.recv(2048)

if len(msg) == 0:
safe_send(to_server, msg)
from_client.close()
sel.unregister(from_client)
schedule_close = True

msg = str(msg, 'ISO-8859-1', 'ignore')

ipm = ip6.search(msg)
msg = msg.replace(msg[ipm.start():ipm.end()], f'127.0.0.1:{port}')
msg = msg.encode('ISO-8859-1')

safe_send(to_server, msg)
if schedule_close:
to_server.close()
sel.unregister(to_server)
def clear_screen():
os.system('cls')
print('Simple Reverse IPv6 to IPv4 TCP proxy\nVersion 1.0')
print('-' * 100)


def send_to_client(to_client, from_server):
eor = re.compile('\\r\\n\\r\\n\\Z')
msg = from_server.recv(2048)
class ReverseProxy(Thread):
def __init__(self, addr: str = None, port: int = None, standalone: bool = False):
self.addr = (addr, port) if addr is not None else None
self.port = port
self.standalone = standalone
self.sel = None

Thread.__init__(self, name=f'{addr=} {port=}')

def accept_connection(self, sock):
client, addr = sock.accept()
client.setblocking(False)
server = socket.create_connection(("127.0.0.1", self.port))
server.setblocking(False)
self.sel.register(client, selectors.EVENT_READ, (self.send_to_server, client, server))
self.sel.register(server, selectors.EVENT_READ, (self.send_to_client, client, server))

def run(self):
if self.standalone:
clear_screen()
try:
config_file = open('config.txt', 'rb')
self.addr = pickle.loads(config_file.read())
config_file.close()
except FileNotFoundError:
pass
except EOFError:
self.addr = None
if not self.addr:
self.port = input("Which port do you want? (Default: 7245)\nEnter: ")
if self.port:
self.port = int(self.port)
else:
self.port = 7245
addrs = socket.getaddrinfo(socket.gethostname(), self.port, family=socket.AF_INET6)
valid_addrs = []
for addr in addrs:
if not addr[4][0].startswith('fe80'):
valid_addrs.append(addr)

if len(valid_addrs) > 1:
print("Please select which address to bind to:")
for addr in valid_addrs:
print(f"[{valid_addrs.index(addr) + 1}] {addr[4][0]}")
selection = int(input("Enter: ")) - 1
self.addr = valid_addrs[selection][4][:2]
else:
self.addr = valid_addrs[0][4][:2]

if input('Do you want to safe config for next time?(Y/N)\nEnter: ') == 'Y':
config_file = open('config.txt', 'wb')
config_file.write(pickle.dumps(self.addr))
config_file.close()

clear_screen()

print(f"Reverse Proxy is up and running on [{self.addr[0]}] with port {self.addr[1]}")

self.sel = selectors.DefaultSelector()
ipv6side = socket.create_server(self.addr, family=socket.AF_INET6, backlog=20)
ipv6side.setblocking(False)
self.sel.register(ipv6side, selectors.EVENT_READ, self.accept_connection)

while True:
events = self.sel.select()
for key, mask in events:
callback = key.data
if isinstance(callback, tuple):
callback[0](callback[1], callback[2])
else:
callback(key.fileobj)

def send_to_client(self, to_client, from_server):
eor = re.compile('\\r\\n\\r\\n\\Z')
msg = from_server.recv(2048)

eorm = eor.search(str(msg, 'ISO-8859-1', 'ignore'))
if eorm or len(msg) == 0:
safe_send(to_client, msg)
to_client.close()
from_server.close()
self.sel.unregister(to_client)
self.sel.unregister(from_server)
return

eorm = eor.search(str(msg, 'ISO-8859-1', 'ignore'))
if eorm or len(msg) == 0:
safe_send(to_client, msg)
to_client.close()
from_server.close()
sel.unregister(to_client)
sel.unregister(from_server)
return

safe_send(to_client, msg)
def send_to_server(self, from_client, to_server):
ip6 = re.compile(f'\\[[^]]*]:{self.port}')
msg = from_client.recv(2048)

ipm = ip6.search(str(msg, 'ISO-8859-1', 'ignore'))
if ipm:
msg = str(msg, 'ISO-8859-1', 'ignore')
msg = msg.replace(msg[ipm.start():ipm.end()], f'127.0.0.1:{self.port}')
msg = msg.encode('ISO-8859-1')

def accept_connection(sock):
client, addr = sock.accept()
client.setblocking(False)
server = socket.create_connection(("127.0.0.1", port))
server.setblocking(False)
sel.register(client, selectors.EVENT_READ, (send_to_server, client, server))
sel.register(server, selectors.EVENT_READ, (send_to_client, client, server))
if len(msg) == 0:
safe_send(to_server, msg)
to_server.close()
from_client.close()
self.sel.unregister(from_client)
self.sel.unregister(to_server)
return


def clear_screen():
os.system('cls')
print('Simple Reverse IPv6 to IPv4 TCP proxy\nVersion 1.0')
print('-' * 100)


def main():
global sel
global port
addr = None
clear_screen()

try:
config_file = open('config.txt', 'rb')
addr = pickle.loads(config_file.read())
config_file.close()
except FileNotFoundError:
pass
except EOFError:
addr = None
if not addr:
port = input("Which port do you want? (Default: 7245)\nEnter: ")
if port:
port = int(port)
else:
port = 7245
addrs = socket.getaddrinfo(socket.gethostname(), port, family=socket.AF_INET6)
valid_addrs = []
for addr in addrs:
if not addr[4][0].startswith('fe80'):
valid_addrs.append(addr)

if len(valid_addrs) > 1:
print("Please select which address to bind to:")
for addr in valid_addrs:
print(f"[{valid_addrs.index(addr) + 1}] {addr[4][0]}")
selection = int(input("Enter: ")) - 1
addr = valid_addrs[selection][4][:2]
else:
addr = valid_addrs[0][4][:2]

if input('Do you want to safe config for next time?(Y/N)\nEnter: ') == 'Y':
config_file = open('config.txt', 'wb')
config_file.write(pickle.dumps(addr))
config_file.close()

clear_screen()

print(f"Reverse Proxy is up and running on [{addr[0]}] with port {addr[1]}")

sel = selectors.DefaultSelector()
ipv6side = socket.create_server(addr, family=socket.AF_INET6, backlog=20)
ipv6side.setblocking(False)
sel.register(ipv6side, selectors.EVENT_READ, accept_connection)

while True:
events = sel.select()
for key, mask in events:
callback = key.data
if isinstance(callback, tuple):
callback[0](callback[1], callback[2])
else:
callback(key.fileobj)
safe_send(to_server, msg)


if __name__ == '__main__':
main()
p = ReverseProxy(standalone=True)
p.start()
p.join()

0 comments on commit 2cb2c4b

Please sign in to comment.