2025-02-09 18:23:09 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
"""
|
|
|
|
Serve a ptpython console using both telnet and ssh.
|
|
|
|
|
|
|
|
Thanks to Vincent Michel for this!
|
|
|
|
https://gist.github.com/vxgmichel/7685685b3e5ead04ada4a3ba75a48eef
|
|
|
|
"""
|
|
|
|
|
|
|
|
import asyncio
|
|
|
|
import pathlib
|
|
|
|
|
|
|
|
import asyncssh
|
|
|
|
from prompt_toolkit import print_formatted_text
|
2025-02-09 18:31:25 +01:00
|
|
|
from prompt_toolkit.contrib.ssh.server import (
|
|
|
|
PromptToolkitSSHServer,
|
|
|
|
PromptToolkitSSHSession,
|
|
|
|
)
|
2025-02-09 18:23:09 +01:00
|
|
|
from prompt_toolkit.contrib.telnet.server import TelnetServer
|
|
|
|
|
|
|
|
from ptpython.repl import embed
|
|
|
|
|
|
|
|
|
2025-02-09 18:31:25 +01:00
|
|
|
def ensure_key(filename: str = "ssh_host_key") -> str:
|
2025-02-09 18:23:09 +01:00
|
|
|
path = pathlib.Path(filename)
|
|
|
|
if not path.exists():
|
|
|
|
rsa_key = asyncssh.generate_private_key("ssh-rsa")
|
|
|
|
path.write_bytes(rsa_key.export_private_key())
|
|
|
|
return str(path)
|
|
|
|
|
|
|
|
|
2025-02-09 18:31:25 +01:00
|
|
|
async def interact(connection: PromptToolkitSSHSession) -> None:
|
2025-02-09 18:23:09 +01:00
|
|
|
global_dict = {**globals(), "print": print_formatted_text}
|
|
|
|
await embed(return_asyncio_coroutine=True, globals=global_dict)
|
|
|
|
|
|
|
|
|
2025-02-09 18:31:25 +01:00
|
|
|
async def main(ssh_port: int = 8022, telnet_port: int = 8023) -> None:
|
2025-02-09 18:23:09 +01:00
|
|
|
ssh_server = PromptToolkitSSHServer(interact=interact)
|
|
|
|
await asyncssh.create_server(
|
|
|
|
lambda: ssh_server, "", ssh_port, server_host_keys=[ensure_key()]
|
|
|
|
)
|
|
|
|
print(f"Running ssh server on port {ssh_port}...")
|
|
|
|
|
|
|
|
telnet_server = TelnetServer(interact=interact, port=telnet_port)
|
|
|
|
telnet_server.start()
|
|
|
|
print(f"Running telnet server on port {telnet_port}...")
|
|
|
|
|
|
|
|
while True:
|
|
|
|
await asyncio.sleep(60)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
asyncio.run(main())
|