Commit f2f280ff authored by ibuler's avatar ibuler

Add change win size event

parent 22ce0495
import os import os
import time import time
import threading import threading
from queue import Queue
import logging import logging
from .config import Config from .config import Config
...@@ -45,6 +44,7 @@ class Coco: ...@@ -45,6 +44,7 @@ class Coco:
self.root_path = root_path self.root_path = root_path
self.name = name self.name = name
self.lock = threading.Lock() self.lock = threading.Lock()
self.stop_evt = threading.Event()
if name is None: if name is None:
self.name = self.config['NAME'] self.name = self.config['NAME']
...@@ -71,7 +71,6 @@ class Coco: ...@@ -71,7 +71,6 @@ class Coco:
print('Coco version %s, more see https://www.jumpserver.org' % __version__) print('Coco version %s, more see https://www.jumpserver.org' % __version__)
print('Quit the server with CONTROL-C.') print('Quit the server with CONTROL-C.')
exit_queue = Queue()
try: try:
if self.config["SSHD_PORT"] != 0: if self.config["SSHD_PORT"] != 0:
self.run_sshd() self.run_sshd()
...@@ -79,10 +78,9 @@ class Coco: ...@@ -79,10 +78,9 @@ class Coco:
if self.config['WS_PORT'] != 0: if self.config['WS_PORT'] != 0:
self.run_ws() self.run_ws()
if exit_queue.get(): self.stop_evt.wait()
self.shutdown()
except KeyboardInterrupt: except KeyboardInterrupt:
self.stop_evt.set()
self.shutdown() self.shutdown()
def run_sshd(self): def run_sshd(self):
......
# coding: utf-8 # coding: utf-8
import socket import socket
import threading
import paramiko import paramiko
import time
from .session import Session from .session import Session
from .models import Server from .models import Server
...@@ -26,6 +26,7 @@ class ProxyServer: ...@@ -26,6 +26,7 @@ class ProxyServer:
session = Session(self.client, self.server) session = Session(self.client, self.server)
self.app.sessions.append(session) self.app.sessions.append(session)
self.watch_win_size_change_async()
session.bridge() session.bridge()
self.app.sessions.remove(session) self.app.sessions.remove(session)
...@@ -69,3 +70,17 @@ class ProxyServer: ...@@ -69,3 +70,17 @@ class ProxyServer:
chan = ssh.invoke_shell(term, width=width, height=height) chan = ssh.invoke_shell(term, width=width, height=height)
return Server(chan, asset, system_user) return Server(chan, asset, system_user)
def watch_win_size_change(self):
while self.request.change_size_event.wait():
self.request.change_size_event.clear()
width = self.request.meta.get('width', 80)
height = self.request.meta.get('height', 24)
print("Change win size: %s - %s" % (width, height))
self.server.chan.resize_pty(width=width, height=height)
def watch_win_size_change_async(self):
thread = threading.Thread(target=self.watch_win_size_change)
thread.daemon = True
thread.start()
...@@ -68,8 +68,7 @@ class SSHInterface(paramiko.ServerInterface): ...@@ -68,8 +68,7 @@ class SSHInterface(paramiko.ServerInterface):
return False return False
def check_channel_exec_request(self, channel, command): def check_channel_exec_request(self, channel, command):
logger.debug("Check channel exec request: %s `%s`" % logger.debug("Check channel exec request: `%s`" % command)
(channel, command))
self.request.type = 'exec' self.request.type = 'exec'
self.request.meta = {'channel': channel, 'command': command} self.request.meta = {'channel': channel, 'command': command}
self.event.set() self.event.set()
...@@ -85,8 +84,8 @@ class SSHInterface(paramiko.ServerInterface): ...@@ -85,8 +84,8 @@ class SSHInterface(paramiko.ServerInterface):
def check_channel_pty_request( def check_channel_pty_request(
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" %
(channel, term, width, height, pixelwidth, pixelheight)) (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,
......
...@@ -159,28 +159,27 @@ class WSProxy: ...@@ -159,28 +159,27 @@ class WSProxy:
self.child = child self.child = child
self.stop_event = threading.Event() self.stop_event = threading.Event()
print(self.child)
print(self.child.fileno())
self.auto_forward() self.auto_forward()
def send(self, b): def send(self, msg):
""" """
If ws use proxy send data, then send the data to child sock, then If ws use proxy send data, then send the data to child sock, then
the parent sock recv the parent sock recv
:param b: data :param msg: terminal write message {"data": "message"}
:return: :return:
""" """
if isinstance(b, str): data = msg["data"]
b = b.encode('utf-8') if isinstance(data, str):
data = data.encode('utf-8')
self.child.send(data)
def forward(self): def forward(self):
while not self.stop_event.is_set(): while not self.stop_event.is_set():
data = self.child.recv(BUF_SIZE) data = self.child.recv(BUF_SIZE)
if len(data) == 0: if len(data) == 0:
self.close() self.close()
self.ws.write_message(data) self.ws.write_message(json.dumps({"data": data.decode("utf-8")}))
def auto_forward(self): def auto_forward(self):
thread = threading.Thread(target=self.forward, args=()) thread = threading.Thread(target=self.forward, args=())
......
...@@ -65,7 +65,6 @@ class Session: ...@@ -65,7 +65,6 @@ class Session:
self.watchers + self.sharers, [], []) self.watchers + self.sharers, [], [])
for sock in r: for sock in r:
data = sock.recv(BUF_SIZE) data = sock.recv(BUF_SIZE)
print(data.decode('utf-8'))
if sock == self.server: if sock == self.server:
if len(data) == 0: if len(data) == 0:
self.close() self.close()
......
...@@ -45,16 +45,10 @@ class SSHServer: ...@@ -45,16 +45,10 @@ class SSHServer:
def run(self): def run(self):
self.listen() self.listen()
max_conn_num = self.app.config['MAX_CONNECTIONS']
while not self.stop_event.is_set(): while not self.stop_event.is_set():
try: try:
sock, addr = self.sock.accept() sock, addr = self.sock.accept()
logger.info("Get ssh request from %s: %s" % (addr[0], addr[1])) logger.info("Get ssh request from %s: %s" % (addr[0], addr[1]))
if len(self.app.clients) >= max_conn_num:
sock.close()
logger.warning("Arrive max connection number %s, "
"reject new request %s:%s" %
(max_conn_num, addr[0], addr[1]))
thread = threading.Thread(target=self.handle, args=(sock, addr)) thread = threading.Thread(target=self.handle, args=(sock, addr))
thread.daemon = True thread.daemon = True
thread.start() thread.start()
......
# coding: utf-8 # coding: utf-8
import socket import socket
import threading import json
import logging
import time
import tornado.web import tornado.web
import tornado.websocket import tornado.websocket
import tornado.httpclient import tornado.httpclient
...@@ -13,6 +13,9 @@ from .models import User, Request, Client, WSProxy ...@@ -13,6 +13,9 @@ from .models import User, Request, Client, WSProxy
from .interactive import InteractiveServer from .interactive import InteractiveServer
logger = logging.getLogger(__file__)
class BaseWehSocketHandler: class BaseWehSocketHandler:
def prepare(self): def prepare(self):
self.app = self.settings["app"] self.app = self.settings["app"]
...@@ -34,15 +37,32 @@ class InteractiveWehSocketHandler(BaseWehSocketHandler, tornado.websocket.WebSoc ...@@ -34,15 +37,32 @@ class InteractiveWehSocketHandler(BaseWehSocketHandler, tornado.websocket.WebSoc
def open(self): def open(self):
request = Request(self.request.remote_ip) request = Request(self.request.remote_ip)
self.request.__dict__.update(request.__dict__) self.request.__dict__.update(request.__dict__)
InteractiveServer(self.app, self.request,self.client).activate_async() InteractiveServer(self.app, self.request, self.client).activate_async()
def on_message(self, message): def on_message(self, message):
print(message) try:
self.proxy.send(message) message = json.loads(message)
except json.JSONDecodeError:
logger.info("Loads websocket json message failed")
return
if message.get('event'):
self.evt_handle(message)
elif message.get('data'):
self.proxy.send(message)
def on_close(self): def on_close(self):
self.proxy.close() self.proxy.close()
def evt_handle(self, data):
if data['event'] == 'change_size':
try:
self.request.meta['width'] = data['meta']['width']
self.request.meta['height'] = data['meta']['height']
self.request.change_size_event.set()
except KeyError:
pass
class ProxyWehSocketHandler(BaseWehSocketHandler): class ProxyWehSocketHandler(BaseWehSocketHandler):
pass pass
......
...@@ -17,9 +17,6 @@ APP_NAME = "coco" ...@@ -17,9 +17,6 @@ APP_NAME = "coco"
# 监听的WS端口号,默认5000 # 监听的WS端口号,默认5000
# WS_PORT = 5000 # WS_PORT = 5000
# 最大连接线程数
# MAX_CONNECTIONS = 500
# 是否开启DEBUG # 是否开启DEBUG
# DEBUG = True # DEBUG = True
......
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