Commit f2f280ff authored by ibuler's avatar ibuler

Add change win size event

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