class MainNamespace(Namespace): def __init__(self, namespace): super(MainNamespace, self).__init__(namespace) self.remote_ip = None self.remote_protocol = None self.remote_port = None self.username = None self.width = None self.height = None self.password = None self.client = None self.connect_status = False def on_connect(self): current_app.logger.debug('Socket connected.') self.client = GuacamoleClient(GUACD_PATH, GUACD_PORT) def on_disconnect(self): self.client.close() def on_remote(self, data): self.remote_ip = data.get('ip') self.remote_protocol = data.get('protocol') self.remote_port = data.get('port') self.width = data.get('width') self.height = data.get('height') self.username = data.get('username') self.password = data.get('password') if self.username and self.password: self.client.handshake(protocol=self.remote_protocol, hostname=self.remote_ip, port=self.remote_port, width=self.width, height=self.height, username=self.username, password=self.password) else: self.client.handshake(protocol=self.remote_protocol, hostname=self.remote_ip, port=self.remote_port, width=self.width, height=self.height) self.connect_status = True # emit('connect_status', {'status': self.connect_status}, Namespace='/data') while True: instruction = self.client.receive() if instruction: if 'disconnect' in instruction: emit('message', instruction, namespace='/data') self.client.close() # emit('connect_status', {'status': False}, Namespace='/data') break emit('message', instruction, namespace='/data') def on_message(self, message): if self.connect_status: self.client.send(message)
class GuacamoleApplication(WebSocketApplication): def __init__(self, ws): self.client = None super(GuacamoleApplication, self).__init__(ws) self.config = configparser.ConfigParser() self.config.read('config.ini') # self.fernet = Fernet(bytes(self.config['DEFAULT']['FERNET_KEY'])) logging.basicConfig(filename='crowbar-guacamole.log', level=logging.DEBUG) @classmethod def protocol_name(cls): return "guacamole" def on_message(self, message, **kwargs): self.client.send(message) def on_open(self): # TODO implement check for token parameters = parse_qs(self.ws.environ['QUERY_STRING']) self.client = GuacamoleClient( str(self.config['DEFAULT']['GUACD_HOST']), 4822) self.client.handshake(protocol='rdp', hostname=parameters['hostname'][0], port=3389, width=parameters['width'][0], height=parameters['height'][0]) self.start_read_listener() def on_close(self, reason): self.client.close() self.client = None def start_read_listener(self): listener = Thread(target=self.read_listener) listener.start() def read_listener(self): """ A listener that would handle any messages sent from Guacamole server and push directly to browser client (over websocket). """ while True: instruction = self.client.receive() self.ws.send(instruction)
class GuacamoleApp(WebSocketApplication): def __init__(self, ws): self.client = None self._listener = None super(GuacamoleApp, self).__init__(ws) @classmethod def protocol_name(cls): """ Return our protocol. """ return PROTOCOL_NAME def on_open(self, *args, **kwargs): """ New Web socket connection opened. """ if self.client: # we have a running client?! self.client.close() # @TODO: get guacd host and port! self.client = GuacamoleClient('localhost', 4822) # @TODO: get Remote server connection properties self.client.handshake(protocol=PROTOCOL, hostname=HOST, port=PORT, username=USERNAME, password=PASSWORD, domain=DOMAIN, security=SEC, remote_app=APP) self._start_listener() def on_message(self, message): """ New message received on the websocket. """ # send message to guacd server self.client.send(message) def on_close(self, reason): """ Websocket closed. """ # @todo: consider reconnect from client. (network glitch?!) self._stop_listener() self.client.close() self.client = None def _start_listener(self): if self._listener: self._stop_listener() self._listener = gevent.spawn(self.guacd_listener) self._listener.start() def _stop_listener(self): if self._listener: self._listener.kill() self._listener = None def guacd_listener(self): """ A listener that would handle any messages sent from Guacamole server and push directly to browser client (over websocket). """ while True: instruction = self.client.receive() self.ws.send(instruction)
class Client: def __init__(self, websocker): self.websocker = websocker self.start_time = time.time() self.last_save_time = self.start_time tmp_date1 = time.strftime("%Y-%m-%d", time.localtime(int(self.start_time))) tmp_date2 = time.strftime("%Y%m%d%H%M%S", time.localtime(int(self.start_time))) if not os.path.isdir(os.path.join(settings.RECORD_ROOT, tmp_date1)): os.makedirs(os.path.join(settings.RECORD_ROOT, tmp_date1)) self.res_file = settings.RECORD_DIR + '/' + tmp_date1 + '/' + 'webguacamole_' + \ tmp_date2 + '_' + gen_rand_char(16) + '.txt' self.res = [] self.guacamoleclient = None def connect(self, protocol, hostname, port, username, password, width, height, dpi): try: self.guacamoleclient = GuacamoleClient( settings.GUACD.get('host'), settings.GUACD.get('port'), settings.GUACD.get('timeout'), ) if protocol == 'vnc': # vnc 登陆不需要账号 self.guacamoleclient.handshake( protocol=protocol, hostname=hostname, port=port, password=password, width=width, height=height, dpi=dpi, ) elif protocol == 'rdp': self.guacamoleclient.handshake( protocol=protocol, hostname=hostname, port=port, username=username, password=password, width=width, height=height, dpi=dpi, ) Thread(target=self.websocket_to_django).start() except Exception: self.websocker.close(3001) def django_to_guacd(self, data): try: self.guacamoleclient.send(data) except Exception: self.close() def websocket_to_django(self): try: while True: time.sleep(0.0001) data = self.guacamoleclient.receive() if not data: return if self.websocker.send_flag == 0: self.websocker.send(data) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "group.message", "text": data, }) self.res.append(data) # 指定条结果或者指定秒数就保存一次 if len(self.res) > 2000 or int(time.time() - self.last_save_time) > 60 or \ sys.getsizeof(self.res) > 2097152: tmp = list(self.res) self.res = [] self.last_save_time = time.time() res(self.res_file, tmp, False) except Exception: print(traceback.format_exc()) if self.websocker.send_flag == 0: self.websocker.send('0.;') elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "group.message", "text": '0.;', }) finally: self.close() def close(self): self.websocker.close() self.guacamoleclient.close() def shell(self, data): self.django_to_guacd(data)
class Client: def __init__(self, websocker): self.websocker = websocker self.start_time = time.time() self.last_save_time = self.start_time tmp_date1 = time.strftime("%Y-%m-%d", time.localtime(int(self.start_time))) tmp_date2 = time.strftime("%Y%m%d%H%M%S", time.localtime(int(self.start_time))) if not os.path.isdir(os.path.join(settings.RECORD_ROOT, tmp_date1)): os.makedirs(os.path.join(settings.RECORD_ROOT, tmp_date1)) self.res_file = settings.RECORD_DIR + '/' + tmp_date1 + '/' + 'webguacamole_' + \ tmp_date2 + '_' + gen_rand_char(16) + '.txt' self.res = [] self.guacamoleclient = None self.file_index = {} self.file_cmd = '' def connect(self, protocol, hostname, port, username, password, width, height, dpi, **kwargs): try: self.guacamoleclient = GuacamoleClient( settings.GUACD.get('host'), settings.GUACD.get('port'), settings.GUACD.get('timeout'), ) if protocol == 'vnc': # vnc 登陆不需要账号 self.guacamoleclient.handshake( protocol=protocol, hostname=hostname, port=port, password=password, width=width, height=height, dpi=dpi, ignore_cert="true", disable_audio="true", client_name="devops", **kwargs, ) elif protocol == 'rdp': self.guacamoleclient.handshake( protocol=protocol, port=port, username=username, password=password, hostname=hostname, width=width, height=height, dpi=dpi, security='tls', # rdp,nla,tls,any ignore_cert="true", disable_audio="true", client_name="devops", **kwargs, ) Thread(target=self.websocket_to_django).start() except Exception: logger.error(traceback.format_exc()) self.websocker.close(3001) def django_to_guacd(self, data): try: self.guacamoleclient.send(data) except Exception: self.close() def websocket_to_django(self): try: while 1: # time.sleep(0.00001) data = self.guacamoleclient.receive() if not data: message = str( base64.b64encode('连接被断开或者协议不支持'.encode('utf-8')), 'utf-8') self.websocker.send('6.toastr,1.2,{0}.{1};'.format( len(message), message)) break save_res = True if data.startswith("4.file,"): tmp = data.split(",") file_index = tmp[1].split(".")[1] file_type = tmp[2].split(".")[1] file_name_tmp = tmp[3].rstrip(";").split(".") del file_name_tmp[0] file_name = '.'.join(file_name_tmp) self.file_index[file_index] = [file_name, file_type] message = str( base64.b64encode( '开始下载文件 - {}'.format(file_name).encode('utf-8')), 'utf-8') self.websocker.send('6.toastr,1.3,{0}.{1};'.format( len(message), message)) save_res = False if self.file_index: if data.startswith("4.blob,"): tmp = data.split(",") index = tmp[1].split(".")[1] if index in self.file_index: # lenx = tmp[2].split(".")[0] # logger.info("file: {} len: {}".format(self.file_index[index][0], lenx)) save_res = False if data.startswith("3.end,"): tmp = data.split(",") index = tmp[1].rstrip(";").split(".")[1] if index in self.file_index: cmd_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.localtime(int(time.time()))) self.file_cmd += cmd_time + "\t" + '下载文件 - {}'.format( self.file_index[index][0]) + '\n' message = str( base64.b64encode('文件下载完成 - {}'.format( self.file_index[index][0]).encode( 'utf-8')), 'utf-8') self.websocker.send('6.toastr,1.3,{0}.{1};'.format( len(message), message)) save_res = False del self.file_index[index] if self.websocker.send_flag == 0: self.websocker.send(data) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "group.message", "text": data, }) if save_res: # 不保存下载文件时的数据到录像 self.res.append(data) # 指定条结果或者指定秒数就保存一次 if len(self.res) > 2000 or int(time.time() - self.last_save_time) > 60 or \ sys.getsizeof(self.res) > 2097152: tmp = list(self.res) self.res = [] self.last_save_time = time.time() res(self.res_file, tmp, False) except Exception: if self.websocker.send_flag == 0: self.websocker.send('0.;') elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "group.message", "text": '0.;', }) finally: self.close() def close(self): try: self.websocker.close() self.guacamoleclient.close() except Exception: logger.error(traceback.format_exc()) def shell(self, data): self.django_to_guacd(data)
class Client: def __init__(self, websocker): self.websocker = websocker self.start_time = time.time() self.last_save_time = self.start_time self.res_file = 'webguacamole_' + str(int( self.start_time)) + '_' + gen_rand_char(16) + '.txt' self.res = [] self.guacamoleclient = None def connect(self, protocol, hostname, port, username, password, width, height, dpi): try: self.guacamoleclient = GuacamoleClient( settings.GUACD.get('host'), settings.GUACD.get('port'), settings.GUACD.get('timeout'), ) if protocol == 'vnc': # vnc 登陆不需要账号 self.guacamoleclient.handshake( protocol=protocol, hostname=hostname, port=port, password=password, width=width, height=height, dpi=dpi, ) elif protocol == 'rdp': self.guacamoleclient.handshake( protocol=protocol, hostname=hostname, port=port, username=username, password=password, width=width, height=height, dpi=dpi, ) Thread(target=self.websocket_to_django).start() except Exception: self.websocker.close(3001) def django_to_guacd(self, data): try: self.guacamoleclient.send(data) except Exception: self.close() def websocket_to_django(self): try: while True: time.sleep(0.001) data = self.guacamoleclient.receive() if not data: return if self.websocker.send_flag == 0: self.websocker.send(data) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "group.message", "text": data, }) self.res.append(data) # 指定条结果或者指定秒数就保存一次 if len(self.res) > 1000 or int(time.time() - self.last_save_time) > 50: tmp = list(self.res) self.res = [] self.last_save_time = time.time() # windows无法正常支持celery任务 if platform.system().lower() == 'linux': celery_save_res_asciinema.delay( settings.MEDIA_ROOT + '/' + self.res_file, tmp, False) else: with open(settings.MEDIA_ROOT + '/' + self.res_file, 'a+') as f: for line in tmp: f.write('{}'.format(line)) except Exception: if self.websocker.send_flag == 0: self.websocker.send('0.;') elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "group.message", "text": '0.;', }) finally: self.close() def close(self): self.websocker.close() self.guacamoleclient.close() def shell(self, data): self.django_to_guacd(data)