Skip to content

Instantly share code, notes, and snippets.

@subzer0iq
Forked from zapstar/client.py
Created January 24, 2025 20:52
Show Gist options
  • Save subzer0iq/ab27c3e91a254790ded74faf7e085bf5 to your computer and use it in GitHub Desktop.
Save subzer0iq/ab27c3e91a254790ded74faf7e085bf5 to your computer and use it in GitHub Desktop.

Revisions

  1. @zapstar zapstar created this gist Jun 8, 2018.
    32 changes: 32 additions & 0 deletions client.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    #!/usr/bin/env python3

    import asyncio
    import ssl


    @asyncio.coroutine
    async def echo_client(data, loop):
    ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    ssl_ctx.options |= ssl.OP_NO_TLSv1
    ssl_ctx.options |= ssl.OP_NO_TLSv1_1
    ssl_ctx.load_cert_chain('client_cert.pem', keyfile='client_key.pem')
    ssl_ctx.load_verify_locations(cafile='client_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')
    reader, writer = await asyncio.open_connection('127.0.0.1', 8080, ssl=ssl_ctx, loop=loop)
    print('Sending: {}'.format(data))
    writer.write(len(data).to_bytes(4, byteorder='big'))
    writer.write(data.encode())
    await writer.drain()
    size_bytes = await reader.readexactly(4)
    size = int.from_bytes(size_bytes, byteorder='big')
    echo_data = await reader.readexactly(size)
    print('Received: {}'.format(echo_data))
    writer.close()

    if __name__ == '__main__':
    async_loop = asyncio.get_event_loop()
    send_data = "Ping!!!"
    async_loop.run_until_complete(echo_client(send_data, async_loop))
    async_loop.close()
    66 changes: 66 additions & 0 deletions server.py
    Original file line number Diff line number Diff line change
    @@ -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()