Commit b273218f authored by ibuler's avatar ibuler

[Feture] ..

parent daa71f39
...@@ -38,30 +38,30 @@ class Coco: ...@@ -38,30 +38,30 @@ class Coco:
self.config = self.config_class(BASE_DIR, defaults=self.default_config) self.config = self.config_class(BASE_DIR, defaults=self.default_config)
self.sessions = [] self.sessions = []
self.connections = [] self.connections = []
self.sshd = SSHServer(self)
self.ws = None self.ws = None
self.root_path = root_path
self.name = name
if name: if name is None:
self.name = name
else:
self.name = self.config['NAME'] self.name = self.config['NAME']
if root_path is None: if root_path is None:
self.root_path = BASE_DIR
self.make_logger() self.make_logger()
self.sshd = None
def make_logger(self): def make_logger(self):
create_logger(self) create_logger(self)
@staticmethod def prepare(self):
def bootstrap(): self.sshd = SSHServer(self)
pass pass
def heartbeat(self): def heartbeat(self):
pass pass
def run_forever(self): def run_forever(self):
self.prepare()
print(time.ctime()) print(time.ctime())
print('Coco version %s, more see https://www.jumpserver.org' % __version__) print('Coco version %s, more see https://www.jumpserver.org' % __version__)
......
...@@ -33,7 +33,7 @@ class InteractiveServer: ...@@ -33,7 +33,7 @@ class InteractiveServer:
def dispatch(self): def dispatch(self):
pass pass
def run(self): def active(self):
self.display_banner() self.display_banner()
while True: while True:
try: try:
......
...@@ -22,13 +22,6 @@ class SSHInterface(paramiko.ServerInterface): ...@@ -22,13 +22,6 @@ class SSHInterface(paramiko.ServerInterface):
self.event = threading.Event() self.event = threading.Event()
def check_auth_interactive(self, username, submethods): def check_auth_interactive(self, username, submethods):
"""
:param username: the username of the authenticating client
:param submethods: a comma-separated list of methods preferred
by the client (usually empty)
:return: AUTH_FAILED if this auth method isn’t supported;
otherwise an object containing queries for the user
"""
logger.info("Check auth interactive: %s %s" % (username, submethods)) logger.info("Check auth interactive: %s %s" % (username, submethods))
return paramiko.AUTH_FAILED return paramiko.AUTH_FAILED
...@@ -56,7 +49,7 @@ class SSHInterface(paramiko.ServerInterface): ...@@ -56,7 +49,7 @@ class SSHInterface(paramiko.ServerInterface):
def validate_auth(self, username, password="", key=""): def validate_auth(self, username, password="", key=""):
# Todo: Implement it # Todo: Implement it
self.request.user = "guang" self.request.user = "guang"
return True return paramiko.AUTH_SUCCESSFUL
def check_channel_direct_tcpip_request(self, chanid, origin, destination): def check_channel_direct_tcpip_request(self, chanid, origin, destination):
logger.debug("Check channel direct tcpip request: %d %s %s" % logger.debug("Check channel direct tcpip request: %d %s %s" %
...@@ -93,12 +86,12 @@ class SSHInterface(paramiko.ServerInterface): ...@@ -93,12 +86,12 @@ class SSHInterface(paramiko.ServerInterface):
self, channel, term, width, height, self, channel, term, width, height,
pixelwidth, pixelheight, modes): pixelwidth, pixelheight, modes):
logger.debug("Check channel pty request: %s %s %s %s %s %s" % logger.debug("Check channel pty request: %s %s %s %s %s %s" %
(channel, term, width, height, pixelwidth, pixelheight)) (channel, term, width, height, pixelwidth, pixelheight))
self.request.type = 'pty' self.request.type = 'pty'
self.request.meta = { self.request.meta = {
'channel': channel, 'term': term, 'width': width, 'channel': channel, 'term': term, 'width': width,
'height': height, 'pixelwidth': pixelwidth, 'height': height, 'pixelwidth': pixelwidth,
'pixelheight': pixelheight, 'models': modes, 'pixelheight': pixelheight,
} }
self.event.set() self.event.set()
return True return True
...@@ -109,6 +102,9 @@ class SSHInterface(paramiko.ServerInterface): ...@@ -109,6 +102,9 @@ class SSHInterface(paramiko.ServerInterface):
def check_channel_shell_request(self, channel): def check_channel_shell_request(self, channel):
logger.info("Check channel shell request: %s" % channel) logger.info("Check channel shell request: %s" % channel)
self.request.type = 'shell'
self.request.meta = {'channel': channel}
self.event.set()
return True return True
def check_channel_subsystem_request(self, channel, name): def check_channel_subsystem_request(self, channel, name):
......
...@@ -9,6 +9,7 @@ import sys ...@@ -9,6 +9,7 @@ import sys
from .utils import ssh_key_gen from .utils import ssh_key_gen
from .interface import SSHInterface from .interface import SSHInterface
from .interactive import InteractiveServer
logger = logging.getLogger(__file__) logger = logging.getLogger(__file__)
BACKLOG = 5 BACKLOG = 5
...@@ -22,7 +23,6 @@ class Request: ...@@ -22,7 +23,6 @@ class Request:
self.addr = addr self.addr = addr
self.user = None self.user = None
self.change_size_event = threading.Event() self.change_size_event = threading.Event()
self.win_size = {}
class SSHServer: class SSHServer:
...@@ -54,7 +54,7 @@ class SSHServer: ...@@ -54,7 +54,7 @@ class SSHServer:
def run(self): def run(self):
self.listen() self.listen()
max_conn_num = self.app['MAX_CONNECTIONS'] max_conn_num = self.app.config['MAX_CONNECTIONS']
while not self.stop_event.is_set(): while not self.stop_event.is_set():
try: try:
client, addr = self.sock.accept() client, addr = self.sock.accept()
...@@ -102,7 +102,7 @@ class SSHServer: ...@@ -102,7 +102,7 @@ class SSHServer:
def dispatch(self, request, channel): def dispatch(self, request, channel):
if request.type == 'pty': if request.type == 'pty':
pass InteractiveServer(self.app, request, channel).active()
elif request.type == 'exec': elif request.type == 'exec':
pass pass
elif request.type == 'subsystem': elif request.type == 'subsystem':
......
#!coding: utf-8 #!coding: utf-8
import base64
import calendar
import os import os
import re
import paramiko import paramiko
from io import StringIO from io import StringIO
import hashlib
import threading
import time
import pyte
def ssh_key_string_to_obj(text): def ssh_key_string_to_obj(text):
...@@ -61,4 +70,99 @@ def ssh_key_gen(length=2048, type='rsa', password=None, ...@@ -61,4 +70,99 @@ def ssh_key_gen(length=2048, type='rsa', password=None,
public_key = ssh_pubkey_gen(private_key_obj, username=username, hostname=hostname) public_key = ssh_pubkey_gen(private_key_obj, username=username, hostname=hostname)
return private_key, public_key return private_key, public_key
except IOError: except IOError:
raise IOError('These is error when generate ssh key.') raise IOError('These is error when generate ssh key.')
\ No newline at end of file
def content_md5(data):
"""计算data的MD5值,经过Base64编码并返回str类型。
返回值可以直接作为HTTP Content-Type头部的值
"""
if isinstance(data, str):
data = hashlib.md5(data.encode('utf-8'))
return base64.b64encode(data.digest())
_STRPTIME_LOCK = threading.Lock()
_GMT_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"
_ISO8601_FORMAT = "%Y-%m-%dT%H:%M:%S.000Z"
def to_unixtime(time_string, format_string):
with _STRPTIME_LOCK:
return int(calendar.timegm(time.strptime(str(time_string), format_string)))
def http_date(timeval=None):
"""返回符合HTTP标准的GMT时间字符串,用strftime的格式表示就是"%a, %d %b %Y %H:%M:%S GMT"。
但不能使用strftime,因为strftime的结果是和locale相关的。
"""
return formatdate(timeval, usegmt=True)
def http_to_unixtime(time_string):
"""把HTTP Date格式的字符串转换为UNIX时间(自1970年1月1日UTC零点的秒数)。
HTTP Date形如 `Sat, 05 Dec 2015 11:10:29 GMT` 。
"""
return to_unixtime(time_string, _GMT_FORMAT)
def iso8601_to_unixtime(time_string):
"""把ISO8601时间字符串(形如,2012-02-24T06:07:48.000Z)转换为UNIX时间,精确到秒。"""
return to_unixtime(time_string, _ISO8601_FORMAT)
def make_signature(access_key_secret, date=None):
if isinstance(date, bytes):
date = date.decode("utf-8")
if isinstance(date, int):
date_gmt = http_date(date)
elif date is None:
date_gmt = http_date(int(time.time()))
else:
date_gmt = date
data = str(access_key_secret) + "\n" + date_gmt
return content_md5(data)
class TtyIOParser(object):
def __init__(self, width=80, height=24):
self.screen = pyte.Screen(width, height)
self.stream = pyte.ByteStream()
self.stream.attach(self.screen)
self.ps1_pattern = re.compile(r'^\[?.*@.*\]?[\$#]\s|mysql>\s')
def clean_ps1_etc(self, command):
return self.ps1_pattern.sub('', command)
def parse_output(self, data, sep='\n'):
output = []
if not isinstance(data, bytes):
data = data.encode('utf-8', 'ignore')
self.stream.feed(data)
for line in self.screen.display:
if line.strip():
output.append(line)
self.screen.reset()
return sep.join(output[0:-1])
def parse_input(self, data):
command = []
if not isinstance(data, bytes):
data = data.encode('utf-8', 'ignore')
self.stream.feed(data)
for line in self.screen.display:
line = line.strip()
if line:
command.append(line)
if command:
command = command[-1]
else:
command = ''
self.screen.reset()
command = self.clean_ps1_etc(command)
return command
...@@ -16,6 +16,7 @@ except: ...@@ -16,6 +16,7 @@ except:
coco = Coco() coco = Coco()
coco.config.from_object(conf) coco.config.from_object(conf)
print(coco.root_path)
if __name__ == '__main__': if __name__ == '__main__':
coco.run_forever() coco.run_forever()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment