* Added full utf-8 support via base85

* removed connection established message, apps can send that themselves (yam util does)
This commit is contained in:
Kevin Froman 2020-04-30 14:44:31 -05:00
parent 0dd9c1e9ac
commit e658da13be
7 changed files with 77 additions and 20 deletions

View File

@ -2,6 +2,12 @@
This project uses Semantic Versioning
## 2.0.0
* Added full utf-8 support via base85
* removed connection established message, apps can send that themselves (yam util does)
## 1.2.0
* finished basic client tests

View File

@ -7,7 +7,7 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
packages = find_packages(exclude=['contrib', 'docs', 'tests'])
setup(name='youandme',
version='1.2.0',
version='2.0.0',
description='Simple private data sharing via bytearrays, Tor tunneling and metadata paranoia',
long_description=long_description,
long_description_content_type='text/markdown',

View File

@ -19,6 +19,7 @@ except ModuleNotFoundError:
from youandme.commands import terminator
from youandme.server import server
from youandme.client import client
from youandme.stream import encode_and_send, decoded_recv_stream
class Connection:
@ -82,7 +83,7 @@ def connector(host, send_data, recv_data,
def chat(mode, send_data, recv_data, alpha):
print("A notice will be shown when connection is established," +
print("A notice will be shown when connection is established, " +
"but messages may be typed now.")
display_buffer = []
@ -94,17 +95,32 @@ def chat(mode, send_data, recv_data, alpha):
print(_Address.address)
def display_new():
for message in get_messages
buffer = []
while True:
try:
for message in decoded_recv_stream(recv_data, 0.5):
if alpha:
for c in message:
c = c.decode('utf-8')
if c not in printable:
continue
if len(buffer) < 1000:
buffer.append(c)
print("\033[1;33m" + "".join(buffer) + "\033[0m")
else:
print("\033[1;33m" + message.decode('utf-8') + "\033[0m")
except ValueError:
pass
Thread(target=display_new, daemon=True).start()
def make_message():
while True:
new = input("\033[0m").encode('utf-8') # nosec
for b in new:
send_data.append(b)
send_data.append(ord(b"\n"))
encode_and_send(send_data, new)
Thread(target=make_message, daemon=True).start()
encode_and_send(send_data, "Connection established")
while True:
try:
if not Connection.connected:

View File

@ -4,7 +4,6 @@ from time import sleep
import socks
from .commands import garbage_character
from .commands import WELCOME_MESSAGE
def client(delay: int, hs_id: str, socks_port, send_data: bytearray, recv_data: bytearray, connection: "Connection"):
@ -16,8 +15,6 @@ def client(delay: int, hs_id: str, socks_port, send_data: bytearray, recv_data:
hs_id += '.onion'
def send_loop():
for i in WELCOME_MESSAGE:
send_data.append(ord(i))
while True:
to_send = None
if send_data:

View File

@ -7,7 +7,6 @@ if typing.TYPE_CHECKING:
from stem.control import Controller
from.commands import garbage_character
from.commands import WELCOME_MESSAGE
def server(delay: int, controller: 'Controller', socket_conn, send_data: bytearray, recv_data: bytearray, connection: "Connection"):
@ -28,7 +27,6 @@ def server(delay: int, controller: 'Controller', socket_conn, send_data: bytearr
socket_conn.sendall(chr(char).encode('utf-8'))
except OSError:
connection.connected = False
first_rec = True
with socket_conn:
Thread(target=send_loop, daemon=True).start()
while True:
@ -38,10 +36,7 @@ def server(delay: int, controller: 'Controller', socket_conn, send_data: bytearr
connection.connected = False
break
if not data: break
if first_rec:
for i in WELCOME_MESSAGE:
send_data.append(ord(i))
first_rec = False
if data != garbage_character and data:
for i in data:
recv_data.append(i)

View File

@ -1,19 +1,33 @@
from base64 import b85encode, b85decode
from time import sleep
import sys
from typing import Union
from youandme.commands import terminator
_b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
_b85alphabet = bytearray(b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")
def decoded_recv_stream(raw_stream: bytearray, delay_seconds: int, max_buffer_size=) -> bytes:
def decoded_recv_stream(raw_stream: bytearray, delay_seconds: int) -> bytes:
while True:
for byte in raw_stream:
if byte == terminator:
yield b85decode(raw_stream[:len(raw_stream) - 1])
raw_stream.pop()
yield b85decode(raw_stream)
raw_stream.clear()
continue
if byte not in _b85alphabet:
raise ValueError('Not valid base85 encoding')
sleep(delay_seconds)
def encode_and_send(send_stream: bytearray, data: Union[bytes, str]):
try:
data = data.encode('utf-8')
except AttributeError:
pass
encoded = b85encode(data)
for c in encoded:
send_stream.append(c)
send_stream.append(terminator)

View File

@ -14,6 +14,7 @@ def add_encoded_to_bytes_array_valid(message, array: bytearray):
array.append(m)
array.append(terminator)
class TestStream(unittest.TestCase):
def test_stream_get(self):
@ -27,8 +28,36 @@ class TestStream(unittest.TestCase):
c = 0
for message in stream.decoded_recv_stream(recv_data, 1):
self.assertEqual(message.decode('utf-8'), data)
self.assertNotIn(terminator, message)
break
def test_stream_send(self):
send_data = bytearray()
recv_data = bytearray()
data = "hello world"
data_bytes = data.encode('utf-8')
encoded = b85encode(data_bytes)
stream.encode_and_send(send_data, data)
for i in send_data:
if i != terminator:
self.assertIn(chr(i).encode('utf-8'), encoded)
self.assertEqual(data_bytes, b85decode(send_data[:len(send_data) - 1]))
def test_stream_send_has_terminator(self):
send_data = bytearray()
recv_data = bytearray()
data = "hello world"
data_bytes = data.encode('utf-8')
encoded = b85encode(data_bytes)
stream.encode_and_send(send_data, data)
self.assertEqual(send_data.pop(), terminator)
unittest.main()