Skip to content

Commit 78a6459

Browse files
committed
update 5.1
New ServerManager for manage multiple server with multiple protocol. ProWrapper for translate protocol from many protocol to one protocol (function).
1 parent 1b15383 commit 78a6459

27 files changed

Lines changed: 1410 additions & 283 deletions

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# What is PyserSSH
22

3+
This library will be **Pyserminal** (Python Server Terminal) as it supports multiple protocols such as ssh telnet rlogin and mores...
4+
35
PyserSSH is a free and open-source Python library designed to facilitate the creation of customizable SSH terminal servers. Initially developed for research purposes to address the lack of suitable SSH server libraries in Python, PyserSSH provides a flexible and user-friendly solution for implementing SSH servers, making it easier for developers to handle user interactions and command processing.
46

57
The project was started by a solo developer to create a more accessible and flexible tool for managing SSH connections and commands. It offers a simplified API compared to other libraries, such as Paramiko, SSHim, and Twisted, which are either outdated or complex for new users.
@@ -32,15 +34,15 @@ pip install git+https://git.damp11113.xyz/DPSoftware-Foundation/PyserSSH.git
3234
# Quick Example
3335
This Server use port **2222** for default port
3436
```py
35-
from PyserSSH import Server, Send, AccountManager
37+
from PyserSSH import Server, AccountManager
3638

37-
useraccount = AccountManager(anyuser=True)
39+
useraccount = AccountManager(allow_guest=True)
3840
ssh = Server(useraccount)
3941

4042
@ssh.on_user("command")
4143
def command(client, command: str):
4244
if command == "hello":
43-
Send(client, "world!")
45+
client.send("world!")
4446

4547
ssh.run("your private key file")
4648
```

demo/demo1.py

Lines changed: 30 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
11
import os
2+
os.environ["damp11113_load_all_module"] = "NO"
3+
4+
from damp11113.utils import TextFormatter
5+
from damp11113.file import sort_files, allfiles
26
import socket
37
import time
48
import cv2
59
import traceback
610
import requests
711
from bs4 import BeautifulSoup
812
import numpy as np
13+
import logging
914

10-
#import logging
11-
#logging.basicConfig(level=logging.DEBUG)
15+
# Configure logging
16+
logging.basicConfig(format='[{asctime}] [{levelname}] {name}: {message}', datefmt='%Y-%m-%d %H:%M:%S', style='{', level=logging.DEBUG)
1217

1318
from PyserSSH import Server, AccountManager
14-
from PyserSSH.interactive import Send, wait_input, wait_inputkey, wait_choose, Clear, wait_inputmouse
15-
from PyserSSH.system.info import __version__, Flag_TH
19+
from PyserSSH.interactive import Send, wait_input, wait_inputkey, wait_choose, Clear, wait_inputmouse
20+
from PyserSSH.system.info import version, Flag_TH
1621
from PyserSSH.extensions.processbar import indeterminateStatus, LoadingProgress
1722
from PyserSSH.extensions.dialog import MenuDialog, TextDialog, TextInputDialog
1823
from PyserSSH.extensions.moredisplay import clickable_url, Send_karaoke_effect
1924
from PyserSSH.extensions.moreinteractive import ShowCursor
2025
from PyserSSH.extensions.remodesk import RemoDesk
2126
from PyserSSH.extensions.XHandler import XHandler
2227
from PyserSSH.system.clientype import Client
23-
from PyserSSH.system.remotestatus import remotestatus
28+
from PyserSSH.system.RemoteStatus import remotestatus
29+
from PyserSSH.utils.ServerManager import ServerManager
30+
31+
useraccount = AccountManager(allow_guest=True, autoload=True, autosave=True)
2432

25-
useraccount = AccountManager(allow_guest=True)
26-
useraccount.add_account("admin", "") # create user without password
27-
useraccount.add_account("test", "test") # create user without password
28-
useraccount.add_account("demo")
29-
useraccount.add_account("remote", "12345", permissions=["remote_desktop"])
30-
useraccount.set_user_enable_inputsystem_echo("remote", False)
31-
useraccount.set_user_sftp_allow("admin", True)
33+
if not os.path.isfile("autosave_session.ses"):
34+
useraccount.add_account("admin", "", sudo=True) # create user without password
35+
useraccount.add_account("test", "test") # create user without password
36+
useraccount.add_account("demo")
37+
useraccount.add_account("remote", "12345", permissions=["remote_desktop"])
38+
useraccount.set_user_enable_inputsystem_echo("remote", False)
39+
useraccount.set_user_sftp_allow("admin", True)
3240

3341
XH = XHandler()
3442
ssh = Server(useraccount,
@@ -42,64 +50,7 @@
4250

4351
servername = "PyserSSH"
4452

45-
loading = ["PyserSSH", "Extensions"]
46-
47-
class TextFormatter:
48-
RESET = "\033[0m"
49-
TEXT_COLORS = {
50-
"black": "\033[30m",
51-
"red": "\033[31m",
52-
"green": "\033[32m",
53-
"yellow": "\033[33m",
54-
"blue": "\033[34m",
55-
"magenta": "\033[35m",
56-
"cyan": "\033[36m",
57-
"white": "\033[37m"
58-
}
59-
TEXT_COLOR_LEVELS = {
60-
"light": "\033[1;{}m", # Light color prefix
61-
"dark": "\033[2;{}m" # Dark color prefix
62-
}
63-
BACKGROUND_COLORS = {
64-
"black": "\033[40m",
65-
"red": "\033[41m",
66-
"green": "\033[42m",
67-
"yellow": "\033[43m",
68-
"blue": "\033[44m",
69-
"magenta": "\033[45m",
70-
"cyan": "\033[46m",
71-
"white": "\033[47m"
72-
}
73-
TEXT_ATTRIBUTES = {
74-
"bold": "\033[1m",
75-
"italic": "\033[3m",
76-
"underline": "\033[4m",
77-
"blink": "\033[5m",
78-
"reverse": "\033[7m",
79-
"strikethrough": "\033[9m"
80-
}
81-
82-
@staticmethod
83-
def format_text_truecolor(text, color=None, background=None, attributes=None, target_text=''):
84-
formatted_text = ""
85-
start_index = text.find(target_text)
86-
end_index = start_index + len(target_text) if start_index != -1 else len(text)
87-
88-
if color:
89-
formatted_text += f"\033[38;2;{color}m"
90-
91-
if background:
92-
formatted_text += f"\033[48;2;{background}m"
93-
94-
if attributes in TextFormatter.TEXT_ATTRIBUTES:
95-
formatted_text += TextFormatter.TEXT_ATTRIBUTES[attributes]
96-
97-
if target_text == "":
98-
formatted_text += text + TextFormatter.RESET
99-
else:
100-
formatted_text += text[:start_index] + text[start_index:end_index] + TextFormatter.RESET + text[end_index:]
101-
102-
return formatted_text
53+
loading = ["PyserSSH", "openRemoDesk", "XHandler", "RemoteStatus"]
10354

10455
@ssh.on_user("pre-shell")
10556
def guestauth(client):
@@ -185,7 +136,7 @@ def connect(client):
185136
wm = f"""{Flag_TH()}{'–'*50}
186137
Hello {client['current_user']},
187138
188-
This is testing server of PyserSSH v{__version__}.
139+
This is testing server of PyserSSH v{version}.
189140
190141
Visit: {clickable_url("https://damp11113.xyz", "DPCloudev")}
191142
{'–'*50}"""
@@ -258,9 +209,9 @@ def xh_typing(client: Client, messages, speed = 1):
258209
Send(client, "")
259210

260211
@XH.command(name="renimtest")
261-
def xh_renimtest(client: Client, path: str):
212+
def xh_renimtest(client: Client):
262213
Clear(client)
263-
image = cv2.imread(f"opensource.png", cv2.IMREAD_COLOR)
214+
image = cv2.imread("opensource.png", cv2.IMREAD_COLOR)
264215
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
265216

266217
width, height = client['windowsize']["width"] - 5, client['windowsize']["height"] - 5
@@ -458,12 +409,14 @@ def xh_status(client: Client):
458409
#@ssh.on_user("command")
459410
#def command(client: Client, command: str):
460411

461-
ssh.run(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'private_key.pem'))
412+
#ssh.run(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'private_key.pem'))
462413

463-
#manager = ServerManager()
414+
manager = ServerManager()
464415

465416
# Add servers to the manager
466-
#manager.add_server("server1", server1)
417+
manager.add_server("ssh", ssh, os.path.join(os.path.dirname(os.path.realpath(__file__)), 'private_key.pem'))
418+
manager.add_server("telnet", ssh, "", protocol="telnet")
467419

468420
# Start a specific server
469-
#manager.start_server("server1", private_key_path="key")
421+
manager.start_server("ssh")
422+
manager.start_server("telnet")

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name='PyserSSH',
5-
version='5.0',
5+
version='5.1',
66
license='MIT',
77
author='DPSoftware Foundation',
88
author_email='[email protected]',

src/PyserSSH/__init__.py

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/DPSoftware-Foundation/PyserSSH
3-
Copyright (C) 2023-2024 DPSoftware Foundation (MIT)
3+
Copyright (C) 2023-present DPSoftware Foundation (MIT)
44
55
Visit https://github.com/DPSoftware-Foundation/PyserSSH
66
@@ -37,15 +37,15 @@
3737
https://en.wikipedia.org/wiki/ANSI_escape_code
3838
"""
3939
import os
40-
import ctypes
4140
import logging
4241

4342
from .interactive import *
4443
from .server import Server
4544
from .account import AccountManager
46-
from .system.info import system_banner
45+
from .system.info import system_banner, version
4746

4847
if os.name == 'nt':
48+
import ctypes
4949
kernel32 = ctypes.windll.kernel32
5050
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
5151

@@ -67,45 +67,10 @@
6767
if os.environ["pyserssh_systemmessage"] == "YES":
6868
print(system_banner)
6969

70-
# Server Managers
71-
72-
class ServerManager:
73-
def __init__(self):
74-
self.servers = {}
75-
76-
def add_server(self, name, server):
77-
if name in self.servers:
78-
raise ValueError(f"Server with name '{name}' already exists.")
79-
self.servers[name] = server
80-
81-
def remove_server(self, name):
82-
if name not in self.servers:
83-
raise ValueError(f"No server found with name '{name}'.")
84-
del self.servers[name]
85-
86-
def get_server(self, name):
87-
return self.servers.get(name)
88-
89-
def start_server(self, name, protocol="ssh", *args, **kwargs):
90-
server = self.get_server(name)
91-
if not server:
92-
raise ValueError(f"No server found with name '{name}'.")
93-
print(f"Starting server '{name}'...")
94-
server.run(*args, **kwargs)
95-
96-
def stop_server(self, name):
97-
server = self.get_server(name)
98-
if not server:
99-
raise ValueError(f"No server found with name '{name}'.")
100-
print(f"Stopping server '{name}'...")
101-
server.stop_server()
102-
103-
def start_all_servers(self, *args, **kwargs):
104-
for name, server in self.servers.items():
105-
print(f"Starting server '{name}'...")
106-
server.run(*args, **kwargs)
107-
108-
def stop_all_servers(self):
109-
for name, server in self.servers.items():
110-
print(f"Stopping server '{name}'...")
111-
server.stop_server()
70+
__author__ = "damp11113"
71+
__url__ = "https://github.com/DPSoftware-Foundation/PyserSSH"
72+
__copyright__ = "2023-present"
73+
__license__ = "MIT"
74+
__version__ = version
75+
__department__ = "DPSoftware"
76+
__organization__ = "DOPFoundation"

0 commit comments

Comments
 (0)