mirror of
https://github.com/damp11113/PyserSSH.git
synced 2025-04-27 22:48:11 +00:00
update 4.3
add account autosave fix timeout
This commit is contained in:
parent
c9ffdf5201
commit
79353cf668
@ -15,8 +15,6 @@ Install from github
|
||||
```bash
|
||||
pip install git+https://github.com/damp11113/PyserSSH.git
|
||||
```
|
||||
## Optional Packages
|
||||
- [damp11113-library](https://github.com/damp11113/damp11113-library)
|
||||
|
||||
# Quick Example
|
||||
```py
|
||||
|
9
setup.py
9
setup.py
@ -5,20 +5,17 @@ with open('README.md', 'r', encoding='utf-8') as f:
|
||||
|
||||
setup(
|
||||
name='PyserSSH',
|
||||
version='4.2.1', # update pypi (no update for 4.3)
|
||||
version='4.3',
|
||||
license='MIT',
|
||||
author='damp11113',
|
||||
author_email='damp51252@gmail.com',
|
||||
packages=find_packages('src'),
|
||||
package_dir={'': 'src'},
|
||||
url='https://github.com/damp11113/PyserSSH',
|
||||
description="A easy ssh server",
|
||||
description="python scriptable ssh server library. based on Paramiko",
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/markdown',
|
||||
install_requires=[
|
||||
"paramiko"
|
||||
],
|
||||
extras_require={
|
||||
"fullsyscom": ["damp11113"]
|
||||
}
|
||||
]
|
||||
)
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
@ -60,7 +60,7 @@ try:
|
||||
except:
|
||||
os.environ["pyserssh_log"] = "NO"
|
||||
|
||||
if os.environ["pyserssh_log"]:
|
||||
if os.environ["pyserssh_log"] == "NO":
|
||||
logger = logging.getLogger("PyserSSH")
|
||||
logger.disabled = True
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
@ -26,16 +26,45 @@ SOFTWARE.
|
||||
"""
|
||||
|
||||
import pickle
|
||||
import time
|
||||
import atexit
|
||||
import threading
|
||||
|
||||
class AccountManager:
|
||||
def __init__(self, anyuser=False, historylimit=10):
|
||||
def __init__(self, anyuser=False, historylimit=10, autosave=False, autosavedelay=60, autoload=False, autoloadfile="autosave_session.ses"):
|
||||
self.accounts = {}
|
||||
self.anyuser = anyuser
|
||||
self.historylimit = historylimit
|
||||
self.autosavedelay = autosavedelay
|
||||
|
||||
self.__autosavework = False
|
||||
self.__autosaveworknexttime = 0
|
||||
|
||||
if self.anyuser:
|
||||
print("history system can't work if 'anyuser' is enable")
|
||||
|
||||
if autoload:
|
||||
self.load(autoloadfile)
|
||||
|
||||
if autosave:
|
||||
self.__autosavethread = threading.Thread(target=self.__autosave)
|
||||
self.__autosavethread.start()
|
||||
atexit.register(self.__saveexit)
|
||||
|
||||
def __autosave(self):
|
||||
self.save("autosave_session.ses")
|
||||
self.__autosaveworknexttime = time.time() + self.autosavedelay
|
||||
self.__autosavework = True
|
||||
while self.__autosavework:
|
||||
if int(self.__autosaveworknexttime) == int(time.time()):
|
||||
self.save("autosave_session.ses")
|
||||
self.__autosaveworknexttime = time.time() + self.autosavedelay
|
||||
|
||||
def __saveexit(self):
|
||||
self.__autosavework = False
|
||||
self.save("autosave_session.ses")
|
||||
self.__autosavethread.join()
|
||||
|
||||
def validate_credentials(self, username, password):
|
||||
if username in self.accounts and self.accounts[username]["password"] == password or self.anyuser:
|
||||
return True
|
||||
@ -66,11 +95,11 @@ class AccountManager:
|
||||
if username in self.accounts:
|
||||
self.accounts[username]["permissions"] = new_permissions
|
||||
|
||||
def save_to_file(self, filename):
|
||||
def save(self, filename="session.ssh"):
|
||||
with open(filename, 'wb') as file:
|
||||
pickle.dump(self.accounts, file)
|
||||
|
||||
def load_from_file(self, filename):
|
||||
def load(self, filename):
|
||||
try:
|
||||
with open(filename, 'rb') as file:
|
||||
self.accounts = pickle.load(file)
|
||||
@ -114,12 +143,24 @@ class AccountManager:
|
||||
def get_user_timeout(self, username):
|
||||
if username in self.accounts and "timeout" in self.accounts[username]:
|
||||
return self.accounts[username]["timeout"]
|
||||
return 0
|
||||
return None
|
||||
|
||||
def set_user_timeout(self, username, timeout=0):
|
||||
def set_user_timeout(self, username, timeout=None):
|
||||
if username in self.accounts:
|
||||
self.accounts[username]["timeout"] = timeout
|
||||
|
||||
def get_user_last_login(self, username):
|
||||
if username in self.accounts and "lastlogin" in self.accounts[username]:
|
||||
return self.accounts[username]["lastlogin"]
|
||||
return None
|
||||
|
||||
def set_user_last_login(self, username, ip, timelogin=time.time()):
|
||||
if username in self.accounts:
|
||||
self.accounts[username]["lastlogin"] = {
|
||||
"ip": ip,
|
||||
"time": timelogin
|
||||
}
|
||||
|
||||
def add_history(self, username, command):
|
||||
if not self.anyuser:
|
||||
if username in self.accounts:
|
||||
@ -158,4 +199,4 @@ class AccountManager:
|
||||
if username in self.accounts and "lastcommand" in self.accounts[username]:
|
||||
command = self.accounts[username]["lastcommand"]
|
||||
return command
|
||||
return None # User or history not found
|
||||
return None # User or history not found
|
||||
|
@ -1,3 +1,30 @@
|
||||
"""
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
import inspect
|
||||
import shlex
|
||||
|
||||
|
38
src/PyserSSH/extensions/__init__.py
Normal file
38
src/PyserSSH/extensions/__init__.py
Normal file
@ -0,0 +1,38 @@
|
||||
"""
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
"""
|
||||
note
|
||||
|
||||
ansi cursor arrow
|
||||
up - \x1b[A
|
||||
down - \x1b[B
|
||||
left - \x1b[D
|
||||
right - \x1b[C
|
||||
|
||||
https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
"""
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
@ -102,17 +102,18 @@ def wait_input(client, prompt="", defaultvalue=None, cursor_scroll=False, echo=T
|
||||
channel.sendall(b'\r\n')
|
||||
|
||||
except socket.timeout:
|
||||
channel.setblocking(False)
|
||||
channel.settimeout(None)
|
||||
channel.sendall(b'\r\n')
|
||||
output = ""
|
||||
except Exception:
|
||||
channel.setblocking(False)
|
||||
channel.settimeout(None)
|
||||
channel.sendall(b'\r\n')
|
||||
raise
|
||||
else:
|
||||
output = buffer.decode('utf-8')
|
||||
|
||||
if timeout != 0:
|
||||
channel.settimeout(0)
|
||||
channel.setblocking(False)
|
||||
channel.sendall(b'\r\n')
|
||||
|
||||
# Return default value if specified and no input given
|
||||
if defaultvalue is not None and not output.strip():
|
||||
return defaultvalue
|
||||
@ -144,14 +145,14 @@ def wait_inputkey(client, prompt="", raw=False, timeout=0):
|
||||
return byte
|
||||
|
||||
except socket.timeout:
|
||||
channel.settimeout(0)
|
||||
channel.setblocking(False)
|
||||
channel.settimeout(None)
|
||||
channel.send("\r\n")
|
||||
return None
|
||||
except Exception:
|
||||
if timeout != 0:
|
||||
channel.settimeout(0)
|
||||
channel.setblocking(False)
|
||||
channel.setblocking(False)
|
||||
channel.settimeout(None)
|
||||
channel.send("\r\n")
|
||||
raise
|
||||
|
||||
def wait_choose(client, choose, prompt="", timeout=0):
|
||||
@ -193,12 +194,12 @@ def wait_choose(client, choose, prompt="", timeout=0):
|
||||
if chooseindex > chooselen:
|
||||
chooseindex = chooselen
|
||||
except socket.timeout:
|
||||
channel.settimeout(0)
|
||||
channel.setblocking(False)
|
||||
channel.settimeout(None)
|
||||
channel.send("\r\n")
|
||||
return chooseindex
|
||||
except Exception:
|
||||
if timeout != 0:
|
||||
channel.settimeout(0)
|
||||
channel.setblocking(False)
|
||||
channel.setblocking(False)
|
||||
channel.settimeout(None)
|
||||
channel.send("\r\n")
|
||||
raise
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
@ -147,6 +147,8 @@ class Server:
|
||||
client_handler["last_activity_time"] = time.time()
|
||||
client_handler["last_login_time"] = time.time()
|
||||
|
||||
self.accounts.set_user_last_login(self.client_handlers[channel.getpeername()]["current_user"], peername[0])
|
||||
|
||||
#if not any(bh_session.remote_version.split("-")[2].startswith(prefix) for prefix in sftpclient):
|
||||
if not channel.out_window_size == bh_session.default_window_size:
|
||||
while self.client_handlers[channel.getpeername()]["windowsize"] == {}:
|
||||
@ -166,7 +168,8 @@ class Server:
|
||||
client_handler["connecttype"] = "ssh"
|
||||
if self.enainputsystem:
|
||||
try:
|
||||
if self.accounts.get_user_timeout(self.client_handlers[channel.getpeername()]["current_user"]) != 0:
|
||||
if self.accounts.get_user_timeout(self.client_handlers[channel.getpeername()]["current_user"]) != None:
|
||||
channel.setblocking(False)
|
||||
channel.settimeout(self.accounts.get_user_timeout(self.client_handlers[channel.getpeername()]["current_user"]))
|
||||
|
||||
channel.send(replace_enter_with_crlf(self.accounts.get_prompt(self.client_handlers[channel.getpeername()]["current_user"]) + " ").encode('utf-8'))
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
38
src/PyserSSH/system/__init__.py
Normal file
38
src/PyserSSH/system/__init__.py
Normal file
@ -0,0 +1,38 @@
|
||||
"""
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
"""
|
||||
note
|
||||
|
||||
ansi cursor arrow
|
||||
up - \x1b[A
|
||||
down - \x1b[B
|
||||
left - \x1b[D
|
||||
right - \x1b[C
|
||||
|
||||
https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
"""
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
@ -43,7 +43,14 @@ def expect(self, chan, peername, echo=True):
|
||||
currentuser = self.client_handlers[chan.getpeername()]
|
||||
try:
|
||||
while True:
|
||||
byte = chan.recv(1)
|
||||
try:
|
||||
byte = chan.recv(1)
|
||||
except socket.timeout:
|
||||
chan.setblocking(False)
|
||||
chan.settimeout(None)
|
||||
chan.close()
|
||||
raise EOFError()
|
||||
|
||||
self._handle_event("onrawtype", self.client_handlers[chan.getpeername()], byte)
|
||||
|
||||
self.client_handlers[chan.getpeername()]["last_activity_time"] = time.time()
|
||||
@ -151,9 +158,9 @@ def expect(self, chan, peername, echo=True):
|
||||
self.accounts.add_history(currentuser["current_user"], command)
|
||||
|
||||
if command.strip() != "":
|
||||
if self.accounts.get_user_timeout(self.client_handlers[chan.getpeername()]["current_user"]) != 0:
|
||||
chan.settimeout(0)
|
||||
if self.accounts.get_user_timeout(self.client_handlers[chan.getpeername()]["current_user"]) != None:
|
||||
chan.setblocking(False)
|
||||
chan.settimeout(None)
|
||||
|
||||
try:
|
||||
if self.enasyscom:
|
||||
@ -179,13 +186,13 @@ def expect(self, chan, peername, echo=True):
|
||||
except:
|
||||
logger.error("Send error")
|
||||
|
||||
if self.accounts.get_user_timeout(self.client_handlers[chan.getpeername()]["current_user"]) != 0:
|
||||
chan.setblocking(False)
|
||||
chan.settimeout(None)
|
||||
|
||||
if self.accounts.get_user_timeout(self.client_handlers[chan.getpeername()]["current_user"]) != None:
|
||||
chan.setblocking(False)
|
||||
chan.settimeout(self.accounts.get_user_timeout(self.client_handlers[chan.getpeername()]["current_user"]))
|
||||
|
||||
except socket.timeout:
|
||||
chan.settimeout(0)
|
||||
chan.setblocking(False)
|
||||
chan.close()
|
||||
except Exception as e:
|
||||
logger.error(str(e))
|
||||
finally:
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""
|
||||
PyserSSH - A SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
PyserSSH - A Scriptable SSH server. For more info visit https://github.com/damp11113/PyserSSH
|
||||
Copyright (C) 2023-2024 damp11113 (MIT)
|
||||
|
||||
Visit https://github.com/damp11113/PyserSSH
|
||||
|
Loading…
x
Reference in New Issue
Block a user