|
|
@@ -0,0 +1,66 @@ |
|
|
#!/usr/bin/env python3 |
|
|
|
|
|
import asyncio |
|
|
import ssl |
|
|
|
|
|
|
|
|
@asyncio.coroutine |
|
|
async def handle_connection(reader, writer): |
|
|
addr = writer.get_extra_info('peername') |
|
|
print('Connection established with {}'.format(addr)) |
|
|
while True: |
|
|
# Read the marker |
|
|
try: |
|
|
size_bytes = await reader.readexactly(4) |
|
|
if not size_bytes: |
|
|
print('Connection terminated with {}'.format(addr)) |
|
|
break |
|
|
except asyncio.IncompleteReadError: |
|
|
print('Connection terminated with {}'.format(addr)) |
|
|
break |
|
|
size = int.from_bytes(size_bytes, byteorder='big') |
|
|
# Read the data |
|
|
try: |
|
|
data = await reader.readexactly(size) |
|
|
if not size_bytes: |
|
|
print('Connection terminated with {}'.format(addr)) |
|
|
break |
|
|
except asyncio.IncompleteReadError: |
|
|
print('Connection terminated with {}'.format(addr)) |
|
|
break |
|
|
print('Read {} bytes from the client: {}'.format(size, addr)) |
|
|
# Reverse the string |
|
|
echo_data = ''.join(reversed(data.decode())) |
|
|
# Send the marker |
|
|
writer.write(len(echo_data).to_bytes(4, byteorder='big')) |
|
|
# Send the data itself |
|
|
writer.write(echo_data.encode()) |
|
|
# Wait for the data to be written back |
|
|
await writer.drain() |
|
|
print('Finished sending {} bytes to the client: {}'.format(size, addr)) |
|
|
|
|
|
|
|
|
def setup_server(): |
|
|
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) |
|
|
ssl_ctx.options |= ssl.OP_NO_TLSv1 |
|
|
ssl_ctx.options |= ssl.OP_NO_TLSv1_1 |
|
|
ssl_ctx.options |= ssl.OP_SINGLE_DH_USE |
|
|
ssl_ctx.options |= ssl.OP_SINGLE_ECDH_USE |
|
|
ssl_ctx.load_cert_chain('server_cert.pem', keyfile='server_key.pem') |
|
|
ssl_ctx.load_verify_locations(cafile='server_ca.pem') |
|
|
ssl_ctx.check_hostname = False |
|
|
ssl_ctx.verify_mode = ssl.VerifyMode.CERT_REQUIRED |
|
|
ssl_ctx.set_ciphers('ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384') |
|
|
loop = asyncio.get_event_loop() |
|
|
coroutine = asyncio.start_server(handle_connection, |
|
|
'127.0.0.1', |
|
|
8080, |
|
|
ssl=ssl_ctx, |
|
|
loop=loop) |
|
|
server = loop.run_until_complete(coroutine) |
|
|
print('Serving on {}'.format(server.sockets[0].getsockname())) |
|
|
loop.run_forever() |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
setup_server() |