we now have two way communication
This commit is contained in:
parent
0a0de1c7b0
commit
837caa17e0
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
venv/*
|
||||||
|
testdata/*
|
||||||
|
.vscode/*
|
||||||
|
.mypy_cache/*
|
||||||
|
youandme.egg-info/*
|
||||||
|
__pycache__/*
|
||||||
|
src/__pycache__/*
|
||||||
|
src/youandme.egg-info/*
|
||||||
|
src/youandme/__pycache__/*
|
83
src/yam.py
83
src/yam.py
@ -1,4 +1,10 @@
|
|||||||
import sys
|
import sys
|
||||||
|
import socket
|
||||||
|
from time import time, sleep
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
from getch import getch
|
||||||
|
from stem.control import Controller
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from youandme.tor import launch_tor
|
from youandme.tor import launch_tor
|
||||||
@ -6,16 +12,77 @@ except ModuleNotFoundError:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
from youandme.server import server
|
from youandme.server import server
|
||||||
|
from youandme.client import client
|
||||||
|
|
||||||
def interactive_connector():
|
class _Address:
|
||||||
|
address = ""
|
||||||
|
|
||||||
|
|
||||||
|
def connector(host, send_data, recv_data, address="", control_port=1337, socks_port=1338):
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
result = sock.connect_ex(('127.0.0.1', socks_port))
|
||||||
|
if result != 0:
|
||||||
|
launch_tor(control_port=control_port, socks_port=socks_port)
|
||||||
|
print(host)
|
||||||
|
if host:
|
||||||
|
with Controller.from_port(port=control_port) as controller:
|
||||||
|
controller.authenticate()
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
ip = '127.0.0.1'
|
||||||
|
s.bind((ip, 0))
|
||||||
|
s.listen(1)
|
||||||
|
port = s.getsockname()[1]
|
||||||
|
serv = controller.create_ephemeral_hidden_service(
|
||||||
|
{1337: '127.0.0.1:' + str(port)},
|
||||||
|
key_content='ED25519-V3',
|
||||||
|
await_publication=True,
|
||||||
|
)
|
||||||
|
_Address.address = serv.service_id
|
||||||
|
conn, addr = s.accept()
|
||||||
|
server(1, controller, conn, send_data, recv_data)
|
||||||
|
else:
|
||||||
|
print('adderr', address)
|
||||||
|
if not address.endswith('.onion'):
|
||||||
|
address += '.onion'
|
||||||
|
client(1, address, socks_port, send_data, recv_data)
|
||||||
|
|
||||||
|
|
||||||
|
def chat(mode, send_data, recv_data):
|
||||||
|
if mode == 'host':
|
||||||
|
while _Address.address == "":
|
||||||
|
sleep(0.01)
|
||||||
|
print(_Address.address)
|
||||||
|
def display_new():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
char = chr(recv_data.pop(0))
|
||||||
|
print('')
|
||||||
|
print(char, end='')
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
sleep(0.1)
|
||||||
|
Thread(target=display_new, daemon=True).start()
|
||||||
|
def make_message():
|
||||||
|
while True:
|
||||||
|
new = input().encode('utf-8')
|
||||||
|
for b in new:
|
||||||
|
send_data.append(b)
|
||||||
|
Thread(target=make_message, daemon=True).start()
|
||||||
|
while True:
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
print("Starting Tor...")
|
|
||||||
launch_tor()
|
|
||||||
print("Tor started.")
|
|
||||||
server()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) >= 2:
|
||||||
if sys.argv[1] == 'interactive':
|
if sys.argv[1] == 'chat':
|
||||||
interactive_connector()
|
send_data = bytearray()
|
||||||
|
recv_data = bytearray()
|
||||||
|
if sys.argv[2] == 'host':
|
||||||
|
Thread(target=connector, args=[True, send_data, recv_data], kwargs={'socks_port': int(input("socks")), 'control_port': int(input('control port'))}, daemon=True).start()
|
||||||
|
elif sys.argv[2].startswith('conn'):
|
||||||
|
Thread(target=connector, args=[False, send_data, recv_data], kwargs={'address': sys.argv[3], 'socks_port': int(input("socks")), 'control_port': int(input('control port'))}, daemon=True).start()
|
||||||
|
else:
|
||||||
|
print('Must specify host or conn')
|
||||||
|
sys.exit(1)
|
||||||
|
chat(sys.argv[2], send_data, recv_data)
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import stem
|
||||||
|
|
||||||
|
OWN_TOR = False
|
||||||
try:
|
try:
|
||||||
from .starttor import launch_tor
|
from .starttor import launch_tor
|
||||||
|
OWN_TOR = True
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from .server import server
|
|
||||||
|
|
||||||
def interactive_connector():
|
|
||||||
server()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
if sys.argv[1] == 'interactive':
|
|
||||||
interactive_connector()
|
|
||||||
|
40
src/youandme/client.py
Normal file
40
src/youandme/client.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from threading import Thread
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
import socks
|
||||||
|
|
||||||
|
from .commands import garbage_character
|
||||||
|
|
||||||
|
|
||||||
|
def client(delay: int, hs_id, socks_port, send_data: bytearray, recv_data: bytearray):
|
||||||
|
s = socks.socksocket() # Same API as socket.socket in the standard lib
|
||||||
|
|
||||||
|
s.set_proxy(socks.SOCKS5, "127.0.0.1", socks_port, rdns=True)
|
||||||
|
|
||||||
|
def send_loop():
|
||||||
|
while True:
|
||||||
|
to_send = None
|
||||||
|
if send_data:
|
||||||
|
char = send_data.pop(0)
|
||||||
|
to_send = char
|
||||||
|
else:
|
||||||
|
to_send = garbage_character
|
||||||
|
try:
|
||||||
|
s.send(chr(to_send).encode('utf-8'))
|
||||||
|
except TypeError:
|
||||||
|
s.send(to_send)
|
||||||
|
except BrokenPipeError:
|
||||||
|
pass
|
||||||
|
sleep(delay)
|
||||||
|
|
||||||
|
# Can be treated identical to a regular socket object
|
||||||
|
s.connect((hs_id, 1337))
|
||||||
|
Thread(target=send_loop, daemon=True).start()
|
||||||
|
while True:
|
||||||
|
data = s.recv(1)
|
||||||
|
if data != garbage_character:
|
||||||
|
try:
|
||||||
|
recv_data.append(data)
|
||||||
|
except TypeError:
|
||||||
|
if data:
|
||||||
|
recv_data.append(ord(data))
|
1
src/youandme/commands.py
Normal file
1
src/youandme/commands.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
garbage_character = b'\x00'
|
@ -1,41 +1,34 @@
|
|||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
from.commands import garbage_character
|
||||||
|
|
||||||
from stem.control import Controller
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
|
|
||||||
def server():
|
def server(delay: int, controller, conn, send_data: bytearray, recv_data: bytearray):
|
||||||
send_data = bytearray()
|
def send_loop():
|
||||||
def send_loop(conn):
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.1)
|
time.sleep(delay)
|
||||||
|
try:
|
||||||
if not send_data:
|
if not send_data:
|
||||||
conn.sendall(bytes([55]))
|
conn.sendall(garbage_character)
|
||||||
else:
|
else:
|
||||||
conn.sendall(send_data.pop(0))
|
char = send_data.pop(0)
|
||||||
with Controller.from_port(port=1338) as controller:
|
try:
|
||||||
controller.authenticate()
|
conn.sendall(ord(char))
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
except TypeError:
|
||||||
ip = '127.0.0.1'
|
try:
|
||||||
s.bind((ip, 0))
|
conn.sendall(char)
|
||||||
s.listen(1)
|
except TypeError:
|
||||||
port = s.getsockname()[1]
|
conn.sendall(chr(char).encode('utf-8'))
|
||||||
serv = controller.create_ephemeral_hidden_service({
|
except OSError:
|
||||||
1337: f'{ip}:{port}'},
|
pass
|
||||||
key_content = 'ED25519-V3',
|
|
||||||
await_publication = True,
|
|
||||||
)
|
|
||||||
print('on', serv.service_id, 'to', ip, port)
|
|
||||||
conn, addr = s.accept()
|
|
||||||
with conn:
|
with conn:
|
||||||
Thread(target=send_loop, args=[conn], daemon=True).start()
|
Thread(target=send_loop, daemon=True).start()
|
||||||
print('Connected by', addr)
|
|
||||||
while True:
|
while True:
|
||||||
data = conn.recv(1)
|
data = conn.recv(1)
|
||||||
if not data: break
|
if not data: break
|
||||||
data = data.strip()
|
if data != garbage_character and data:
|
||||||
if data != bytes([55]):
|
for i in data:
|
||||||
print(data)
|
recv_data.append(i)
|
||||||
#conn.sendall(data)
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import stem.process
|
import stem.process
|
||||||
|
|
||||||
|
|
||||||
def launch_tor(control_port="1338", socks_port="1339"):
|
def launch_tor(control_port="1336", socks_port="1337"):
|
||||||
control_port = str(control_port)
|
control_port = str(control_port)
|
||||||
socks_port = str(socks_port)
|
socks_port = str(socks_port)
|
||||||
stem.process.launch_tor_with_config(
|
stem.process.launch_tor_with_config(
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
import unittest
|
|
||||||
class TestBasic(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_basic(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
unittest.main()
|
|
42
tests/test_client.py
Normal file
42
tests/test_client.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import unittest
|
||||||
|
import socket
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
import stem
|
||||||
|
import stem.process
|
||||||
|
from stem.control import Controller
|
||||||
|
from youandme import client
|
||||||
|
|
||||||
|
control_port = str(1353)
|
||||||
|
socks_port = str(1354)
|
||||||
|
|
||||||
|
stem.process.launch_tor_with_config(
|
||||||
|
config = {
|
||||||
|
'ControlPort': control_port,
|
||||||
|
'SocksPort': socks_port,
|
||||||
|
'Log': [
|
||||||
|
'NOTICE stdout'
|
||||||
|
],
|
||||||
|
}, take_ownership=True)
|
||||||
|
|
||||||
|
def send_test_data(ip, port):
|
||||||
|
time.sleep(2)
|
||||||
|
s = socket.socket()
|
||||||
|
s.connect(('127.0.0.1', port))
|
||||||
|
while True:
|
||||||
|
s.send(b"test")
|
||||||
|
for c in b"test2":
|
||||||
|
try:
|
||||||
|
s.send(chr(c).encode('utf8'))
|
||||||
|
except TypeError:
|
||||||
|
print(c)
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
class TestClient(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_client(self):
|
||||||
|
send_data = bytearray()
|
||||||
|
recv_data = bytearray()
|
||||||
|
#client(1, )
|
||||||
|
|
||||||
|
unittest.main()
|
79
tests/test_server.py
Normal file
79
tests/test_server.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import unittest
|
||||||
|
import socket
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
import stem
|
||||||
|
import stem.process
|
||||||
|
from stem.control import Controller
|
||||||
|
from youandme import server
|
||||||
|
|
||||||
|
control_port = str(1353)
|
||||||
|
socks_port = str(1354)
|
||||||
|
|
||||||
|
stem.process.launch_tor_with_config(
|
||||||
|
config = {
|
||||||
|
'ControlPort': control_port,
|
||||||
|
'SocksPort': socks_port,
|
||||||
|
'Log': [
|
||||||
|
'NOTICE stdout'
|
||||||
|
],
|
||||||
|
}, take_ownership=True)
|
||||||
|
|
||||||
|
def send_test_data(ip, port):
|
||||||
|
time.sleep(2)
|
||||||
|
s = socket.socket()
|
||||||
|
s.connect(('127.0.0.1', port))
|
||||||
|
while True:
|
||||||
|
s.send(b"test")
|
||||||
|
for c in b"test2":
|
||||||
|
try:
|
||||||
|
s.send(chr(c).encode('utf8'))
|
||||||
|
except TypeError:
|
||||||
|
print(c)
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
class TestServer(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_server(self):
|
||||||
|
send_data = bytearray()
|
||||||
|
recv_data = bytearray()
|
||||||
|
with Controller.from_port(port=int(control_port)) as controller:
|
||||||
|
controller.authenticate()
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
ip = '127.0.0.1'
|
||||||
|
s.bind((ip, 0))
|
||||||
|
s.listen(1)
|
||||||
|
port = s.getsockname()[1]
|
||||||
|
print(port)
|
||||||
|
serv = controller.create_ephemeral_hidden_service(
|
||||||
|
{1337: f'{ip}:{port}'},
|
||||||
|
key_content='ED25519-V3',
|
||||||
|
await_publication=True,
|
||||||
|
)
|
||||||
|
Thread(target=send_test_data, args=[ip, port], daemon=True).start()
|
||||||
|
conn, addr = s.accept()
|
||||||
|
Thread(target=server, args=[0.1, controller, conn, send_data, recv_data], daemon=True).start()
|
||||||
|
time.sleep(1)
|
||||||
|
max_iters = 10000000
|
||||||
|
c = 0
|
||||||
|
tested = False
|
||||||
|
filler_rec = False
|
||||||
|
while True:
|
||||||
|
c += 1
|
||||||
|
if c >= max_iters:
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
char = chr(recv_data.pop(0)).encode('utf8')
|
||||||
|
if char != b'\n':
|
||||||
|
tested = True
|
||||||
|
self.assertIn(char, b"testtest2")
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
if send_data:
|
||||||
|
print(send_data)
|
||||||
|
if not tested:
|
||||||
|
raise ValueError('not tested')
|
||||||
|
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user