### Install and Install Git Hooks Source: https://github.com/jquast/telnetlib3/blob/master/CONTRIBUTING.rst Install the pre-commit tool and its hooks to automatically format code before each commit. ```bash pip install pre-commit pre-commit install --install-hooks ``` -------------------------------- ### Install and Run Tox Source: https://github.com/jquast/telnetlib3/blob/master/CONTRIBUTING.rst Install the tox testing tool and run all defined test environments. ```bash pip install --upgrade tox tox ``` -------------------------------- ### Install telnetlib3 with Extras Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Install telnetlib3 with optional dependencies for full fingerprinting support. ```shell pip install telnetlib3[extras] ``` -------------------------------- ### Simple Telnet Server Example Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst A basic asyncio-based telnet server that prompts the user and responds. It uses the `telnetlib3.create_server` function. ```python import asyncio import telnetlib3 async def shell(reader, writer): writer.write('\r\nWould you like to play a game? ') inp = await reader.readline() if inp: writer.echo(inp) writer.write('\r\nThey say the only way to win ' 'is to not play at all.\r\n') await writer.drain() writer.close() async def main(): server = await telnetlib3.create_server(port=6023, shell=shell) await server.wait_closed() asyncio.run(main()) ``` -------------------------------- ### Run Telnet Fingerprint Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Start a telnetlib3-fingerprint-server to listen for clients and fingerprint them. ```bash telnetlib3-fingerprint-server ``` -------------------------------- ### Run a Default Telnet Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Start a default telnetlib3 server bound to localhost and port 6023. ```bash telnetlib3-server ``` -------------------------------- ### MUD Server Connection Example Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Connects to the public telnetlib3 demonstration MUD server. This is useful for testing MUD client compatibility. ```bash telnet 1984.ws 6063 ``` -------------------------------- ### Install Editable Package Source: https://github.com/jquast/telnetlib3/blob/master/CONTRIBUTING.rst Install the project in editable mode to make local changes available to the Python interpreter. ```bash pip install --editable . ``` -------------------------------- ### Run TLS Server from CLI Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Starts a Telnetlib3 server that accepts TLS connections on a specified port. Requires certificate and key files. ```default telnetlib3-server --ssl-certfile cert.pem --ssl-keyfile key.pem 0.0.0.0 6023 ``` -------------------------------- ### Running a Shell Callback Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Example of how to run a shell callback using the telnetlib3-server command. Ensure the callback is accessible via the specified path. ```shell telnetlib3-server --shell=bin.server_wargame.shell ``` -------------------------------- ### Command-line Client with Retro Encodings Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Examples of using the telnetlib3-client command-line tool with ATASCII and PETSCII encodings to connect to specific BBS servers. ```bash telnetlib3-client --encoding=atascii area52.tk 5200 ``` ```bash telnetlib3-client --encoding=petscii bbs.example.com 6400 ``` -------------------------------- ### Run TLS Server with Custom Shell Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Starts a Telnetlib3 TLS server using a custom shell callback defined in a separate module. Requires certificate and key files. ```default telnetlib3-server --ssl-certfile cert.pem --ssl-keyfile key.pem \ --shell=bin.server_tls.shell ``` -------------------------------- ### Connect to Nethack Server Source: https://github.com/jquast/telnetlib3/blob/master/README.rst Connect to a specified Telnet server using the telnetlib3-client utility. This example shows connecting to a roguelike server. ```bash telnetlib3-client nethack.alt.org ``` -------------------------------- ### Run Mixed TLS/Plain Telnet Server (Auto-Detect) Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Starts a Telnetlib3 server that automatically detects and handles both TLS and plain telnet clients on the same port. A custom timeout can be specified. ```default telnetlib3-server --ssl-certfile cert.pem --ssl-keyfile key.pem \ --tls-auto --line-mode --shell bin.server_mud.shell 0.0.0.0 6023 ``` ```default telnetlib3-server --ssl-certfile cert.pem --ssl-keyfile key.pem \ --tls-auto=2.0 0.0.0.0 6023 ``` -------------------------------- ### Blocking Client Example Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md A traditional blocking telnet client implementation using TelnetConnection for interactive server communication. ```python # std imports import sys # local from telnetlib3.sync import TelnetConnection def main(): """Connect to a telnet server and interact.""" host = sys.argv[1] if len(sys.argv) > 1 else "localhost" port = int(sys.argv[2]) if len(sys.argv) > 2 else 6023 print(f"Connecting to {host}:{port}...") with TelnetConnection(host, port, timeout=10) as conn: print(f"Connected to {host}:{port}") # Read initial server greeting try: greeting = conn.read(timeout=2) if greeting: print(greeting, end="") except TimeoutError: pass # Interactive loop while True: try: user_input = input(">>> ") conn.write(user_input + "\r\n") conn.flush() # Read response response = conn.read(timeout=5) if response: print(response, end="") ``` -------------------------------- ### Miniboa-Compatible Server Handler Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Example of a server handler demonstrating Miniboa-compatible properties and methods for connection details and message handling. It uses BlockingTelnetServer for synchronous operation. ```python from telnetlib3.sync import BlockingTelnetServer def handler(client): # Miniboa-compatible properties print(f"Connected: {client.addrport()}") print(f"Terminal: {client.terminal_type}") print(f"Size: {client.columns}x{client.rows}") # Miniboa-compatible send (converts \n to \r\n) client.send("Welcome!\n") while client.active: if client.idle() > 300: client.send("Timeout.\n") client.deactivate() break try: line = client.readline(timeout=1) except TimeoutError: continue if line: client.send(f"Echo: {line}") server = BlockingTelnetServer('0.0.0.0', 6023, handler=handler) server.serve_forever() ``` -------------------------------- ### Run MUD Server with Line Mode Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Starts a MUD server using telnetlib3 with line mode enabled, suitable for MUD clients. It specifies the shell script to run. ```bash telnetlib3-server --line-mode --shell bin.server_mud.shell ``` -------------------------------- ### Blocking Echo Server Implementation Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md A complete blocking echo server example using BlockingTelnetServer, where each client connection is handled in its own thread. ```python # local from telnetlib3.sync import BlockingTelnetServer def handle_client(conn): """Handle a single client connection (runs in its own thread).""" conn.write("Welcome! Type messages and I'll echo them back.\r\n") conn.write("Type 'quit' to disconnect.\r\n\r\n") conn.flush() while True: try: line = conn.readline(timeout=300) # 5 minute timeout if not line: break line = line.strip() if line.lower() == "quit": conn.write("Goodbye!\r\n") conn.flush() break conn.write(f"Echo: {line}\r\n") conn.flush() except TimeoutError: conn.write("\r\nTimeout - disconnecting.\r\n") conn.flush() break conn.close() ``` -------------------------------- ### Connect with Specific Encoding (big5bbs) Source: https://github.com/jquast/telnetlib3/blob/master/README.rst Connect to a Telnet server using the 'big5bbs' character encoding. This is an example of manually setting a non-standard encoding for specific BBS systems. ```bash telnetlib3-client --encoding=big5bbs bbs.ccns.ncku.edu.tw 3456 ``` -------------------------------- ### Create Server and Wait for Clients Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Demonstrates direct use of `create_server()` and `wait_for_client()` for accessing client protocols without a shell callback. This script requires server-level control. ```python # local import telnetlib3 async def main(): """Start server and wait for clients.""" server = await telnetlib3.create_server(host="127.0.0.1", port=6023) print("Server running on localhost:6023") print("Connect with: telnet localhost 6023") while True: print("Waiting for client...") client = await server.wait_for_client() print("Client connected!") # Access negotiated terminal information term = client.get_extra_info("TERM") or "unknown" cols = client.get_extra_info("cols") or 80 rows = client.get_extra_info("rows") or 24 print(f"Terminal: {term}") print(f"Window size: {cols}x{rows}") # Send welcome message client.writer.write(f"\r\nWelcome! Your terminal is {term} ({cols}x{rows})\r\n") ``` -------------------------------- ### Report Telnet Server Fingerprint Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Use telnetlib3-fingerprint to get the fingerprint of a remote Telnet server. ```bash telnetlib3-fingerprint 1984.ws ``` -------------------------------- ### Create server and wait for client Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Creates a telnetlib3 server and waits for a client to connect and complete initial negotiation. ```python server = await telnetlib3.create_server(port=6023) client = await server.wait_for_client() client.writer.write("Welcome!\r\n") ``` -------------------------------- ### Run a Custom Telnet Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Configure a telnetlib3 server with a custom IP address, port, and a specific shell. ```bash telnetlib3-server 0.0.0.0 1984 --shell=bin.server_wargame.shell ``` -------------------------------- ### Host MUD Server with MCCP Compression Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Configure and host a MUD server that advertises MCCP2/MCCP3 compression. This enables compression for clients. ```bash # host a MUD server that advertises MCCP2/MCCP3 telnetlib3-server --compression --shell=my_mud.shell ``` -------------------------------- ### Run server_wait_for_negotiation.py Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Command to run the server with the specified shell callback. ```bash telnetlib3-server --shell=bin.server_wait_for_negotiation.shell ``` -------------------------------- ### Connect to MUD with MCCP Compression Source: https://github.com/jquast/telnetlib3/blob/master/README.rst Connect to a MUD server that offers MCCP compression. The client will passively accept compression if offered. ```bash telnetlib3-client dunemud.net 6789 ``` -------------------------------- ### Binary Mode Shell Callback and Server Creation Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Demonstrates how to configure telnetlib3 for binary mode using encoding=False, enabling the shell callback to work with raw bytes. ```python async def binary_shell(reader, writer): writer.write(b"Hello, world!\r\n") # bytes data = await reader.read(1) # returns bytes await telnetlib3.create_server( host="127.0.0.1", port=6023, shell=binary_shell, encoding=False ) ``` -------------------------------- ### Run Fingerprinting Server CLI Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Run the dedicated CLI entry point for the telnetlib3 Fingerprinting Server. Accepts standard telnetlib3-server options. ```shell telnetlib3-fingerprint-server --data-dir data ``` -------------------------------- ### Connect to Fingerprinting Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Connect to the public telnetlib3 demonstration Fingerprinting Server. ```shell telnet 1984.ws 555 ``` -------------------------------- ### Run Minimal Shell Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Command to run the telnetlib3 server with a specified shell callback. Connect using the telnet client. ```default telnetlib3-server --shell=bin.server_wargame.shell ``` ```default telnet localhost 6023 ``` -------------------------------- ### Run client_wargame.py Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Command to run the client with the specified shell callback. ```bash telnetlib3-client --shell=bin.client_wargame.shell localhost 6023 ``` -------------------------------- ### Telnetlib3 Server Modes Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Demonstrates how to run the telnetlib3 server in raw PTY mode for programs handling their own I/O, or in line mode for simpler programs. ```bash # Default: raw PTY (correct for curses programs) telnet3-server --pty-exec /bin/bash -- --login ``` ```bash # Line mode: cooked PTY with echo (for simple programs like bc) telnet3-server --pty-exec /bin/bc --line-mode ``` -------------------------------- ### create_server() and wait_for_client() Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Creates a telnet server and waits for a client to connect. Once connected, it returns a client protocol object that can be used to interact with the client. ```APIDOC ## create_server() and wait_for_client() ### Description Creates a telnet server and waits for a client to connect. Once connected, it returns a client protocol object that can be used to interact with the client. ### Method Asynchronous function call ### Parameters None explicitly documented for `create_server` in this context, `wait_for_client` takes no parameters. ### Request Example ```python server = await telnetlib3.create_server(port=6023) client = await server.wait_for_client() client.writer.write("Welcome!\r\n") ``` ### Response #### Success Response - `server`: An instance of the `Server` class. - `client`: A client protocol object representing the connected client. ``` -------------------------------- ### Create TLS Server Programmatically Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Programmatically creates a Telnetlib3 server with TLS enabled. An SSLContext must be loaded with certificate and key files. ```python import ssl import telnetlib3 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ctx.load_cert_chain("cert.pem", keyfile="key.pem") server = await telnetlib3.create_server(host="0.0.0.0", port=6023, shell=shell, ssl=ctx) ``` -------------------------------- ### Connect to MUD with MCCP Compression Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Connect to a MUD server that offers MCCP compression. This snippet shows how to connect to a specific MUD. ```bash # connect to a MUD that offers MCCP compression telnetlib3-client dunemud.net 6789 ``` -------------------------------- ### Connect in Raw Mode Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst For retro BBS systems or serial-like transmissions, use the --raw-mode argument to connect without Telnet negotiation. ```bash telnetlib3-client --raw-mode area52.tk 5200 --encoding=atascii ``` -------------------------------- ### Connect to Local MUD Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Connects to a locally running MUD server on the default port. Use this to test your MUD client against a local instance. ```bash telnetlib3-client localhost 6023 ``` -------------------------------- ### Host External Program with Pseudo-Terminal Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Use telnetlib3-server to host an external program like bash, enabling pseudo-terminal support. ```bash telnetlib3-server --pty-exec /bin/bash -- --login ``` -------------------------------- ### Host External Program in Linemode Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Host an external program using telnetlib3-server with the --pty-exec argument and specify --line-mode for line-based input. ```bash telnetlib3-server --pty-exec /bin/bc --line-mode ``` -------------------------------- ### Perform Static Analysis with Tox Source: https://github.com/jquast/telnetlib3/blob/master/CONTRIBUTING.rst Run static analysis checks using the 'sa' target in tox. ```bash tox -esa ``` -------------------------------- ### Connect to a Telnet Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Use the telnetlib3-client utility to connect to a Telnet server. You can specify the server address and port. ```bash telnetlib3-client nethack.alt.org ``` ```bash telnetlib3-client xibalba.l33t.codes 44510 ``` -------------------------------- ### Client auto-answers questions Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md This client shell callback connects to a server and automatically answers questions. It demonstrates the client shell callback pattern. ```python async def shell(reader, writer): """Handle client session, auto-answering questions.""" while True: outp = await reader.read(1024) if not outp: break if "?" in outp: writer.write("y\r\n") print(outp, flush=True, end="") print() ``` -------------------------------- ### Connect to TLS Server (Self-Signed) Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Connects to a Telnetlib3 server using TLS with a self-signed certificate. The certificate file must be explicitly provided. ```default telnetlib3-client --ssl --ssl-cafile cert.pem localhost 6023 ``` -------------------------------- ### Simple Asyncio Telnet Server Source: https://github.com/jquast/telnetlib3/blob/master/README.rst A basic telnet server implementation using asyncio. It prompts the user, reads input, and closes the connection. ```python import asyncio import telnetlib3 async def shell(reader, writer): writer.write('\r\nWould you like to play a game? ') inp = await reader.readline() if inp: writer.echo(inp) writer.write('\r\nThey say the only way to win ' \ 'is to not play at all.\r\n') await writer.drain() writer.close() async def main(): server = await telnetlib3.create_server(port=6023, shell=shell) await server.wait_closed() asyncio.run(main()) ``` -------------------------------- ### Connect to TLS Server (CA-Signed) Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Connects to a Telnetlib3 server using TLS with a CA-signed certificate. The system's CA store is used automatically. ```default telnetlib3-client --ssl dunemud.net 6788 ``` -------------------------------- ### Moderate Fingerprints Script Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Set the data directory and run the interactive CLI script for reviewing and assigning names to client fingerprints. ```shell export TELNETLIB3_DATA_DIR=./data python bin/moderate_fingerprints.py ``` -------------------------------- ### Running the Binary Echo Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Command to run the telnetlib3 server with the binary echo shell callback, disabling encoding for raw byte I/O. ```bash telnet3-server --encoding=false --shell=bin.server_binary.shell ``` -------------------------------- ### Broadcast Server with Client Handling Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md A chat-style server that broadcasts messages from one client to all others. It demonstrates using `clients` for shared state, handling multiple clients with asyncio tasks, and using `wait_for()` for negotiation states. ```python async def handle_client(server, client, client_id): """Handle a single client, broadcasting their input to all others.""" client.writer.write(f"\r\nYou are client #{client_id}\r\n") client.writer.write("Type messages to broadcast (Ctrl+] to disconnect)\r\n\r\n") # Wait for BINARY mode if available try: await asyncio.wait_for(client.writer.wait_for(remote={"BINARY": True}), timeout=2.0) except asyncio.TimeoutError: pass # Continue without BINARY mode while True: data = await client.reader.read(1024) if not data: break # Broadcast to all other clients message = f"[Client #{client_id}]: {data}" for other in server.clients: if other is not client: other.writer.write(message) # Notify others of disconnect for other in server.clients: ``` -------------------------------- ### BlockingTelnetServer with Manual Accept Loop Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Set up a blocking telnet server with a manual accept loop, allowing custom threading strategies for handling client connections. ```python import threading server = BlockingTelnetServer('localhost', 6023) server.start() while True: conn = server.accept() threading.Thread(target=handle_client, args=(conn,)).start() ``` -------------------------------- ### Miniboa Send Compatibility Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Demonstrates how the send() method normalizes newlines to \r\n for Miniboa compatibility, while write() sends data as-is. ```python conn.send("Hello!\n") # OK -- sends \r\n on the wire conn.send("Hello!\r\n") # OK -- also sends \r\n on the wire conn.write("Hello!\r\n") # OK -- write() sends as-is ``` -------------------------------- ### Server.clients Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Provides access to a collection of all currently connected client protocols. ```APIDOC ## Server.clients ### Description Provides access to a collection of all currently connected client protocols. This can be used to iterate over connected clients for broadcasting messages or other group operations. ### Method Property access ### Parameters None ### Request Example ```python # Broadcast to all clients for client in server.clients: client.writer.write("Server announcement\r\n") ``` ### Response - `server.clients`: An iterable collection of connected client protocol objects. ``` -------------------------------- ### Automated Client Script Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Connect to a Telnet server using an automated script by specifying the shell module path. ```bash telnetlib3-client --shell bin.client_wargame.shell 1984.ws 666 ``` -------------------------------- ### Wait for BINARY mode negotiation Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Waits for the client to enable BINARY mode using `wait_for()` with a timeout. ```python await asyncio.wait_for( client.writer.wait_for(remote={"BINARY": True}), timeout=5.0 ) ``` -------------------------------- ### TelnetConnection Client Usage (Context Manager) Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Use TelnetConnection as a context manager for recommended client usage. Ensures proper connection lifecycle management. ```python from telnetlib3.sync import TelnetConnection # Using context manager (recommended) with TelnetConnection('localhost', 6023) as conn: conn.write('hello\r\n') response = conn.readline() print(response) ``` -------------------------------- ### Run Development Tests with Tox Source: https://github.com/jquast/telnetlib3/blob/master/CONTRIBUTING.rst Use the 'develop' tox target for enhanced development testing, which includes verbose output and automatic re-triggering on file changes. ```bash tox -e develop ``` -------------------------------- ### client.writer.wait_for() Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Waits for specific telnet option negotiation states to be met. ```APIDOC ## client.writer.wait_for() ### Description Waits for specific telnet option negotiation states. This method is useful for ensuring that certain terminal capabilities or modes are established before proceeding with application logic. ### Method Asynchronous function call ### Parameters - `remote` (dict) - Optional - Dictionary of options to wait for in `remote_option` (client WILL). - `local` (dict) - Optional - Dictionary of options to wait for in `local_option` (client DO). - `pending` (dict) - Optional - Dictionary of options to wait for in `pending_option`. Option names are strings, e.g., "BINARY", "ECHO", "NAWS", "TTYPE". ### Request Example ```python # Wait for BINARY mode await asyncio.wait_for( client.writer.wait_for(remote={"BINARY": True}), timeout=5.0 ) # Wait for terminal type negotiation to complete await asyncio.wait_for( client.writer.wait_for(pending={"TTYPE": False}), timeout=5.0 ) ``` ### Response This method does not return a value upon successful completion but raises `asyncio.TimeoutError` if the negotiation does not complete within the specified timeout. ``` -------------------------------- ### Connect to BBS Server with Port Source: https://github.com/jquast/telnetlib3/blob/master/README.rst Connect to a Telnet BBS server, specifying both the hostname and port. This is useful for servers not running on the default Telnet port. ```bash telnetlib3-client xibalba.l33t.codes 44510 ``` -------------------------------- ### Server waits for negotiation Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md This server callback demonstrates using `wait_for()` to await specific telnet option negotiation states before proceeding. It waits for NAWS, TTYPE, and BINARY negotiation. ```python async def shell(_reader, writer): """Handle client with explicit negotiation waits.""" writer.write("\r\nWaiting for terminal negotiation...\r\n") # Wait for NAWS, TTYPE, and BINARY negotiation to complete try: await asyncio.wait_for( writer.wait_for( local={"NAWS": True, "BINARY": True}, remote={"BINARY": True}, pending={"TTYPE": False}, ), timeout=1.5, ) cols = writer.get_extra_info("cols") rows = writer.get_extra_info("rows") term = writer.get_extra_info("TERM") writer.write(f"Window size: {cols}x{rows}\r\n") writer.write(f"Terminal type: {term}\r\n") writer.write("Binary mode enabled (bidirectional)\r\n") except asyncio.TimeoutError: writer.write("Negotiation timed out\r\n") writer.write("\r\nNegotiation complete. Goodbye!\r\n") await writer.drain() writer.close() ``` -------------------------------- ### Storage Path for Fingerprint Results Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Illustrates the directory structure for storing fingerprint results as JSON files, organized by telnet and terminal hash. ```shell /client/// ``` -------------------------------- ### Run Telnet Server Fingerprinter Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Connects to a remote telnet server to probe options, capture the login banner, and save a structured JSON fingerprint. Use this to analyze server capabilities. ```bash telnetlib3-fingerprint example.com 23 ``` -------------------------------- ### Request MCCP Compression from Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Actively request MCCP compression from a server when connecting. This ensures compression is used if supported. ```bash # actively request compression from a server telnetlib3-client --compression dunemud.net 6789 ``` -------------------------------- ### Telnet Client Connecting to Local Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst An asyncio client that connects to a local telnet server, reads output, and sends a response. It uses `telnetlib3.open_connection`. ```python import asyncio import telnetlib3 async def shell(reader, writer): while True: output = await reader.read(1024) if not output: break if '?' in output: writer.write('y\r\n') print(output, end='', flush=True) print() async def main(): reader, writer = await telnetlib3.open_connection('localhost', 6023) await shell(reader, writer) asyncio.run(main()) ``` -------------------------------- ### TelnetConnection Client Usage (Manual Lifecycle) Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Manually manage the lifecycle of a TelnetConnection client. Useful for more control over connect, read, and close operations. ```python from telnetlib3.sync import TelnetConnection # Manual lifecycle conn = TelnetConnection('localhost', 6023, encoding='utf8') conn.connect() try: conn.write('command\r\n') data = conn.read_until(b'>>> ') print(data) finally: conn.close() ``` -------------------------------- ### TLS Echo Shell Callback Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md A simple echo shell callback for a TLS-encrypted server. It demonstrates the `ssl=` parameter on `create_server()` and displays the TLS version. ```python async def shell(reader, writer): """Simple echo shell over TLS.""" ssl_obj = writer.get_extra_info("ssl_object") if ssl_obj is not None: version = ssl_obj.version() or "TLS" writer.write(f"Welcome to the TLS echo server! ({version} Secured)\r\n") else: writer.write("Welcome to the echo server!\r\n") await writer.drain() while True: data = await reader.read(256) if not data: ``` -------------------------------- ### Advanced Negotiation with wait_for Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Blocks until telnet options are negotiated, retrieving terminal type, columns, and rows. Supports remote, local, and pending option negotiation. ```python conn.wait_for(remote={'NAWS': True, 'TTYPE': True}, timeout=5.0) term = conn.get_extra_info('TERM') cols = conn.get_extra_info('cols') rows = conn.get_extra_info('rows') ``` -------------------------------- ### Connect with Specific Encoding (cp437) Source: https://github.com/jquast/telnetlib3/blob/master/README.rst Connect to a Telnet server and manually specify the character encoding to be used for communication. This is crucial for servers that do not negotiate encoding properly. ```bash telnetlib3-client --encoding=cp437 20forbeers.com 1337 ``` -------------------------------- ### Binary Echo Server Callback Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md A Python callback function for the telnetlib3 server that echoes client input back as hex bytes. It demonstrates using encoding=False for raw byte I/O. ```python async def shell(reader, writer): """Echo client input back as hex bytes.""" writer.write(b"[binary echo server] type something:\r\n") await writer.drain() data = await reader.read(128) if data: hex_str = " ".join(f"{b:02x}" for b in data) writer.write(f"hex: {hex_str}\r\n".encode("ascii")) await writer.drain() writer.close() ``` -------------------------------- ### Reject MCCP Compression from Server Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst Explicitly reject MCCP compression even if the server offers it. Use this if compression causes issues or is not desired. ```bash # reject compression even if the server offers it telnetlib3-client --no-compression dunemud.net 6789 ``` -------------------------------- ### Importing Telnet for Legacy Compatibility Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Use these import statements to maintain compatibility with the legacy `telnetlib` module. The `telnetlib3` shim ensures that `import telnetlib` continues to work. ```python from telnetlib import Telnet from telnetlib3.telnetlib import Telnet ``` -------------------------------- ### Open TLS Connection Programmatically (CA-Signed) Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Programmatically opens a Telnetlib3 connection to a TLS server with a CA-signed certificate. `ssl=True` is sufficient. ```python import ssl import telnetlib3 # CA-signed server, just pass ssl=True reader, writer = await telnetlib3.open_connection("dunemud.net", 6788, ssl=True) ``` -------------------------------- ### BSD Telnet Client Send Synch Command Source: https://github.com/jquast/telnetlib3/blob/master/DESIGN.rst Instructs the BSD Telnet client to send the legacy 'Synch' mechanism. This involves sending IAC marked as MSG_OOB, followed by DM. ```text telnet> send synch ``` -------------------------------- ### Minimal Shell Callback Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md A basic shell callback that handles a single client connection by asking a question and responding to user input. It closes the connection after the interaction. ```python async def shell(reader, writer): """Handle a single client connection.""" writer.write("\r\nWould you like to play a game? ") inp = await reader.read(1) if inp: writer.echo(inp) writer.write("\r\nThey say the only way to win is to not play at all.\r\n") await writer.drain() writer.close() ``` -------------------------------- ### Actively Request MCCP Compression Source: https://github.com/jquast/telnetlib3/blob/master/README.rst Use this option to actively request MCCP compression from a MUD server, even if it doesn't explicitly offer it first. ```bash telnetlib3-client --compression dunemud.net 6789 ``` -------------------------------- ### Connect/Fingerprint without Verification Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Connects to or fingerprints a TLS server while skipping certificate verification. This is insecure and should only be used for testing or trusted networks. ```default telnetlib3-client --ssl-no-verify example.com 6023 ``` ```default telnetlib3-fingerprint --ssl-no-verify example.com 6023 ``` -------------------------------- ### Protocol State Inspection with writer Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Accesses the writer property to inspect the protocol state, including the mode and the enabled status of remote options like ECHO. ```python writer = conn.writer print(f"Mode: {writer.mode}") # 'local', 'remote', or 'kludge' print(f"ECHO enabled: {writer.remote_option.enabled(ECHO)}") ``` -------------------------------- ### Broadcast to all clients Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Iterates through the `clients` property of the server to send a message to all currently connected client protocols. ```python # Broadcast to all clients for client in server.clients: client.writer.write("Server announcement\r\n") ``` -------------------------------- ### Open TLS Connection Programmatically (Self-Signed) Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Programmatically opens a Telnetlib3 connection to a TLS server with a self-signed certificate. An SSLContext must be created and configured with the CA file. ```python import ssl import telnetlib3 # Self-signed, load the server's cert explicitly ctx = ssl.create_default_context(cafile="cert.pem") reader, writer = await telnetlib3.open_connection("localhost", 6023, ssl=ctx) ``` -------------------------------- ### BlockingTelnetServer with Handler Function Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Implement a blocking telnet server that spawns a new thread for each client connection using a provided handler function. ```python from telnetlib3.sync import BlockingTelnetServer def handle_client(conn): """Called in a new thread for each client.""" conn.write('Welcome!\r\n') while True: line = conn.readline(timeout=60) if not line or line.strip() in ('quit', b'quit'): break conn.write(f'Echo: {line}') conn.close() # Simple: auto-spawns thread per client server = BlockingTelnetServer('localhost', 6023, handler=handle_client) server.serve_forever() ``` -------------------------------- ### Connect with Specific Encoding Source: https://github.com/jquast/telnetlib3/blob/master/docs/intro.rst When connecting to servers that transmit non-ASCII characters, manually specify the encoding using the --encoding argument. ```bash telnetlib3-client --encoding=cp437 20forbeers.com 1337 ``` ```bash telnetlib3-client --encoding=big5bbs bbs.ccns.ncku.edu.tw 3456 ``` -------------------------------- ### Generate Self-Signed Certificate Source: https://github.com/jquast/telnetlib3/blob/master/docs/guidebook.md Generates a self-signed RSA certificate for testing TLS connections. The certificate is valid for 365 days and uses 'localhost' as the common name. ```default openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \ -days 365 -nodes -subj '/CN=localhost' ```