Files
quantumtunnel/demo/client.py
T
2026-10-07 03:07:34 +00:00

51 lines
1.6 KiB
Python

"""Demo client: python demo/client.py
Connects to ws://127.0.0.1:8765, initiates the handshake, prompts for
the out-of-band digest comparison, then relays stdin lines encrypted.
Empty line quits.
"""
import asyncio
from common import key_store, save_store, setup_logging
from websockets import connect
from websockets.exceptions import ConnectionClosed
from quantumpipe import ProtocolError, SecSocket, Verification, sas
log = setup_logging("client")
async def confirm_digest(v: Verification) -> bool | None:
print(f"\n*** compare these emojis with the server:\n{sas.format(v.sas)}")
answer = await asyncio.to_thread(input, "*** match? [y]es / [n]o / [s]kip: ")
return {"y": True, "n": False}.get(answer.strip().lower()[:1] or "s")
async def main() -> None:
store = key_store("client")
async with connect("ws://127.0.0.1:8765") as ws:
sock = SecSocket(ws, store, "peer", handlers={Verification: confirm_digest})
try:
await sock.connect()
except (ProtocolError, ConnectionClosed) as e:
log.error("handshake failed: %s", e)
return
finally:
save_store("client", store) # rotation, flag, burn, delete
log.info(
"handshake done (%s, verified=%s); type lines, empty line quits",
sock.session.state,
sock.session.verified,
)
while line := await asyncio.to_thread(input, "> "):
await sock.send(line)
print("server:", await sock.receive())
if __name__ == "__main__":
try:
asyncio.run(main())
except (KeyboardInterrupt, EOFError):
pass