def __init__(self, *args, **kwargs): super(AdminGuacamole, self).__init__(*args, **kwargs) self.client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) self.group_name = self.scope['url_route']['kwargs']['group_name'] self.fort_server = ServerAssets.objects.select_related('assets').get( id=self.scope['path'].split('/')[3]) self.guacamole_thread = GuacamoleThread(self)
def _do_connect(request): # Connect to guacd daemon client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) # client.handshake(protocol='rdp', # hostname=settings.SSH_HOST, # port=settings.SSH_PORT, # username=settings.SSH_USER, # password=settings.SSH_PASSWORD) # security='any',) client.handshake(protocol='ssh', hostname='192.168.0.165', port=8787, username='******', password='******') # security='any',) cache_key = str(uuid.uuid4()) with sockets_lock: logger.info('Saving socket with key %s', cache_key) sockets[cache_key] = client response = HttpResponse(content=cache_key) response['Cache-Control'] = 'no-cache' return response
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 connect(self, message, id): self.message.reply_channel.send({"accept": True}) client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) try: data = ServerInfor.objects.get(id=id) if data.credential.protocol in ['vnc', 'rdp', 'telnet']: pass else: self.message.reply_channel.send({"accept": False}) except ObjectDoesNotExist: #server info not exist self.message.reply_channel.send({"accept": False}) client.handshake(protocol=data.credential.protocol, hostname=data.ip, port=data.credential.port, username=data.credential.username, password=data.credential.password) #security='any',) cache_key = str(uuid.uuid4()) self.message.reply_channel.send( {"text": '0.,{0}.{1};'.format(len(cache_key), cache_key)}, immediately=True) #'0.,36.83940151-b2f9-4743-b5e4-b6eb85a97743;' guacamolethread = GuacamoleThread(self.message, client) guacamolethread.setDaemon = True guacamolethread.start() guacamolethreadwrite = GuacamoleThreadWrite(self.message, client) guacamolethreadwrite.setDaemon = True guacamolethreadwrite.start()
def _do_connect(request): # Connect to guacd daemon vcdUser = str(request.user) client = GuacamoleClient('guacd', 4822) #command = requests.get(backendServer) #logging.warning(str(command.content)) #if not vcdUser in command.content: # logging.warning("sleeping 2 seconds") time.sleep(2) #logging.warning("continueeeee") client.handshake(protocol='rdp', hostname='vcd-' + vcdUser, port=3389, username= vcdUser, password= vcdUser, width=request.POST.get("width"), height=request.POST.get("height")) cache_key = str(uuid.uuid4()) with sockets_lock: logger.info('Saving socket with key %s', cache_key) sockets[cache_key] = client response = HttpResponse(content=cache_key) response['Cache-Control'] = 'no-cache' return response
class AdminGuacamole(WebsocketConsumer): def __init__(self, *args, **kwargs): super(AdminGuacamole, self).__init__(*args, **kwargs) self.client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) self.group_name = self.scope['url_route']['kwargs']['group_name'] self.fort_server = ServerAssets.objects.select_related('assets').get( id=self.scope['path'].split('/')[3]) self.guacamole_thread = GuacamoleThread(self) def connect(self): self.accept('guacamole') self.client.handshake( protocol='rdp', hostname=self.fort_server.assets.asset_management_ip, port=self.fort_server.port, password=CryptPwd().decrypt_pwd(self.fort_server.password), username=self.fort_server.username) self.send('0.,{0}.{1};'.format(len(self.group_name), self.group_name)) self.guacamole_thread.setDaemon(True) self.guacamole_thread.start() def disconnect(self, event): self.guacamole_thread.stop() def receive(self, text_data=None, bytes_data=None): with self.guacamole_thread.write_lock: self.client.send(text_data)
def connect(self, message, id): self.message.reply_channel.send({"accept": True}) client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) try: data = ServerInfor.objects.get(id=id) if data.credential.protocol in ['vnc', 'rdp', 'telnet']: pass else: self.message.reply_channel.send({"accept": False}) except ObjectDoesNotExist: #server info not exist self.message.reply_channel.send({"accept": False}) cache_key = str(uuid.uuid4()) directory_date_time = now() recording_path = os.path.join( MEDIA_ROOT, '{0}-{1}-{2}'.format(directory_date_time.year, directory_date_time.month, directory_date_time.day)) client.handshake( width=data.credential.width, height=data.credential.height, protocol=data.credential.protocol, hostname=data.ip, port=data.credential.port, username=data.credential.username, password=data.credential.password, recording_path=recording_path, recording_name=cache_key, create_recording_path='true', enable_wallpaper='true', ignore_cert='true', ) #security='tls',) self.message.reply_channel.send( {"text": '0.,{0}.{1};'.format(len(cache_key), cache_key)}, immediately=True) #'0.,36.83940151-b2f9-4743-b5e4-b6eb85a97743;' audit_log = Log.objects.create( user=User.objects.get(username=self.message.user), server=data, channel=self.message.reply_channel.name, width=data.credential.width, height=data.credential.height, log=cache_key) audit_log.save() guacamolethread = GuacamoleThread(self.message, client) guacamolethread.setDaemon = True guacamolethread.start() guacamolethreadwrite = GuacamoleThreadWrite(self.message, client) guacamolethreadwrite.setDaemon = True guacamolethreadwrite.start()
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 __init__(self, *args, **kwargs): super(AdminGuacamole, self).__init__(*args, **kwargs) self.client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT, timeout=5) self.group_name = self.scope['url_route']['kwargs']['group_name'] self.server = ServerAssets.objects.select_related('assets').get(id=self.scope['path'].split('/')[3]) self.guacamole_thread = GuacamoleThread(self) self.query_list = self.scope['query_string'].decode('utf8').split(',') self.remote_ip = self.query_list[0].strip() self.width = self.query_list[1].strip() self.height = self.query_list[2].strip() self.dpi = self.query_list[3].strip() self.server_ip = self.server.assets.asset_management_ip
async def connect(self): """ Initiate the GuacamoleClient and create a connection to it. """ guacd_hostname = web_cfg.guacamole.guacd_host or "localhost" guacd_port = int(web_cfg.guacamole.guacd_port) or 4822 guacd_recording_path = web_cfg.guacamole.guacd_recording_path or "" guest_protocol = web_cfg.guacamole.guest_protocol or "vnc" guest_width = int(web_cfg.guacamole.guest_width) or 1280 guest_height = int(web_cfg.guacamole.guest_height) or 1024 guest_username = web_cfg.guacamole.username or "" guest_password = web_cfg.guacamole.password or "" params = urllib.parse.parse_qs(self.scope["query_string"].decode()) if "rdp" in guest_protocol: guest_host = params.get("guest_ip", "") guest_port = int(web_cfg.guacamole.guest_rdp_port) or 3389 else: guest_host = "localhost" ports = params.get("vncport", ["5900"]) guest_port = int(ports[0]) guacd_recording_name = params.get("recording_name", ["task-recording"])[0] self.client = GuacamoleClient(guacd_hostname, guacd_port) self.client.handshake( protocol=guest_protocol, width=guest_width, height=guest_height, hostname=guest_host, port=guest_port, username=guest_username, password=guest_password, recording_path=guacd_recording_path, recording_name=guacd_recording_name, ) if self.client.connected: # start receiving data from GuacamoleClient loop = asyncio.get_event_loop() self.task = loop.create_task(self.open()) # Accept connection await self.accept(subprotocol="guacamole") else: await self.close()
class GuacamoleConsumer(WebsocketConsumer): def __init__(self, *args, **kwargs): super(GuacamoleConsumer, self).__init__(*args, **kwargs) self.client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT, timeout=5) self.group_name = self.scope['url_route']['kwargs']['group_name'] self.fort_server = ServerAssets.objects.select_related('assets').get( id=self.scope['path'].split('/')[3]) self.fort_user = FortServerUser.objects.get( id=self.scope['path'].split('/')[4]) self.guacamole_thread = GuacamoleThread(self) self.query_list = self.scope['query_string'].decode('utf8').split(',') self.remote_ip = self.query_list[0].strip() self.width = self.query_list[1].strip() self.height = self.query_list[2].strip() self.dpi = self.query_list[3].strip() self.fort = None def connect(self): self.accept('guacamole') host_ip = self.fort_server.assets.asset_management_ip username = self.fort_user.fort_username self.fort = r'{}@{}'.format(username, host_ip) server_protocol = self.fort_user.fort_server.server_protocol if server_protocol == 'vnc': self.client.handshake(protocol=server_protocol, hostname=host_ip, port=self.fort_user.fort_vnc_port, password=self.fort_user.fort_password, width=self.width, height=self.height, dpi=self.dpi) elif server_protocol == 'rdp': self.client.handshake(protocol=server_protocol, hostname=host_ip, port=self.fort_server.port, password=self.fort_user.fort_password, username=username, width=self.width, height=self.height, dpi=self.dpi) self.send('0.,{0}.{1};'.format(len(self.group_name), self.group_name)) self.guacamole_thread.setDaemon(True) self.guacamole_thread.start() def disconnect(self, event): try: self.guacamole_thread.record() finally: self.guacamole_thread.stop() self.client.close() def receive(self, text_data=None, bytes_data=None): with self.guacamole_thread.write_lock: self.client.send(text_data)
def _do_connect(request): # Connect to guacd daemon client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) client.handshake(protocol='vnc', hostname='10.1.19.11', port=5901, password='******') cache_key = str(uuid.uuid4()) with sockets_lock: logger.info('Saving socket with key %s', cache_key) sockets[cache_key] = client response = HttpResponse(content=cache_key) response['Cache-Control'] = 'no-cache' return response
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)
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': if 'security' not in kwargs.keys(): kwargs['security'] = 'any' self.guacamoleclient.handshake( protocol=protocol, port=port, username=username, password=password, hostname=hostname, width=width, height=height, dpi=dpi, # domain='SWAD.COM', # 域验证服务器 # security='nla', # rdp,nla,nla-ext,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 __init__(self, *args, **kwargs): super(MyGuacamole, self).__init__(*args, **kwargs) self.client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT, timeout=5) self.group_name = self.scope['url_route']['kwargs']['group_name'] self.guacamole_thread = GuacamoleThread(self) self.query_list = self.scope['query_string'].decode('utf8').split(',') self.remote_ip = self.query_list[0].strip() self.width = self.query_list[1].strip() self.height = self.query_list[2].strip() self.dpi = self.query_list[3].strip() self.ip = None self.port = None self.username = None self.password = None self.record_dir = 'admin_guacamole_records' if self.scope[ 'user'].is_superuser else 'fort_guacamole_records'
def _do_connect(request): # Connect to guacd daemon client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) client.handshake(protocol='ssh', hostname=settings.SSH_HOST, port=settings.SSH_PORT, username=settings.SSH_USER, password=settings.SSH_PASSWORD) cache_key = str(uuid.uuid4()) with sockets_lock: logger.info('Saving socket with key %s', cache_key) sockets[cache_key] = client response = HttpResponse(content=cache_key) response['Cache-Control'] = 'no-cache' return response
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 connect(self, message): self.message.reply_channel.send({"accept": True}) client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) client.handshake(protocol='rdp', hostname=settings.SSH_HOST, port=settings.SSH_PORT, username=settings.SSH_USER, password=settings.SSH_PASSWORD) #security='any',) cache_key = str(uuid.uuid4()) self.message.reply_channel.send({"text":'0.,{0}.{1};'.format(len(cache_key),cache_key)},immediately=True) #'0.,36.83940151-b2f9-4743-b5e4-b6eb85a97743;' guacamolethread=GuacamoleThread(self.message,client) guacamolethread.setDaemon = True guacamolethread.start() guacamolethreadwrite=GuacamoleThreadWrite(self.message,client) guacamolethreadwrite.setDaemon = True guacamolethreadwrite.start()
async def connect(self): """ Initiate the GuacamoleClient and create a connection to it. """ guacd_hostname = os.getenv('GUACD_SERVICE_HOST', 'guacd') guacd_port = int(os.getenv('GUACD_SERVICE_PORT', '4822')) settings = get_xblock_settings() params = urllib.parse.parse_qs(self.scope['query_string'].decode()) stack_name = params.get('stack')[0] stack = await database_sync_to_async(self.get_stack)(stack_name) default_port = 3389 if stack.protocol == 'rdp' else 22 self.read_only = bool(strtobool(params.get('read_only')[0])) self.client = GuacamoleClient(guacd_hostname, guacd_port) self.client.handshake( protocol=stack.protocol, width=params.get('width', [1024])[0], height=params.get('height', [768])[0], hostname=stack.ip, port=params.get('port', [default_port])[0], username=stack.user, password=stack.password, private_key=stack.key, color_scheme=settings.get("terminal_color_scheme"), font_name=settings.get("terminal_font_name"), font_size=settings.get("terminal_font_size"), ) if self.client.connected: # start receiving data from GuacamoleClient loop = asyncio.get_event_loop() self.task = loop.create_task(self.open()) # Accept connection await self.accept(subprotocol='guacamole') else: await self.close()
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, hostname=hostname, port=port, username=username, password=password, 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: self.websocker.close(3001)
def _do_connect(task): if not task.guest: return JsonResponse( { "status": "failed", "message": "task is not assigned to a machine yet", }, status=500) machine = db.view_machine_by_label(task.guest.label) rcparams = machine.rcparams protocol = rcparams.get("protocol") host = rcparams.get("host") port = rcparams.get("port") guacd_host = config("cuckoo:remotecontrol:guacd_host") guacd_port = config("cuckoo:remotecontrol:guacd_port") try: guac = GuacamoleClient(guacd_host, guacd_port, debug=False) guac.handshake(protocol=protocol, hostname=host, port=port) except (socket.error, GuacamoleError) as e: log.error("Failed to connect to guacd on %s:%d -> %s", guacd_host, guacd_port, e) return JsonResponse( { "status": "failed", "message": "connection failed", }, status=500) cache_key = str(uuid.uuid4()) with sockets_lock: sockets[cache_key] = guac response = HttpResponse(content=cache_key) response["Cache-Control"] = "no-cache" return response
def _do_connect(task): if not task.guest: return JsonResponse({ "status": "failed", "message": "task is not assigned to a machine yet", }, status=500) machine = db.view_machine_by_label(task.guest.label) rcparams = machine.rcparams protocol = rcparams.get("protocol") host = rcparams.get("host") port = rcparams.get("port") guacd_host = config("cuckoo:remotecontrol:guacd_host") guacd_port = config("cuckoo:remotecontrol:guacd_port") try: guac = GuacamoleClient(guacd_host, guacd_port, debug=False) guac.handshake(protocol=protocol, hostname=host, port=port) except (socket.error, GuacamoleError) as e: log.error( "Failed to connect to guacd on %s:%d -> %s", guacd_host, guacd_port, e ) return JsonResponse({ "status": "failed", "message": "connection failed", }, status=500) cache_key = str(uuid.uuid4()) with sockets_lock: sockets[cache_key] = guac response = HttpResponse(content=cache_key) response["Cache-Control"] = "no-cache" return response
def websocket_receive(self, text=None, bytes=None, **kwargs): client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) client.handshake(protocol='vnc', hostname='10.1.19.11', port=5901, password='******') cache_key = str(uuid.uuid4()) self.send( json.dumps({ "type": "websocket.send", "text": '0.,{0}.{1};'.format(len(cache_key), cache_key), })) # '0.,36.83940151-b2f9-4743-b5e4-b6eb85a97743;' guacamolethread = GuacamoleThread(self, client) guacamolethread.setDaemon = True guacamolethread.start() guacamolethreadwrite = GuacamoleThreadWrite(self, client) guacamolethreadwrite.setDaemon = True guacamolethreadwrite.start() print(text) # print 'receive',text self.queue().publish(self.channel_name, text['text'])
class MyGuacamole(WebsocketConsumer): def __init__(self, *args, **kwargs): super(MyGuacamole, self).__init__(*args, **kwargs) self.client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT, timeout=5) self.group_name = self.scope['url_route']['kwargs']['group_name'] self.guacamole_thread = GuacamoleThread(self) self.query_list = self.scope['query_string'].decode('utf8').split(',') self.remote_ip = self.query_list[0].strip() self.width = self.query_list[1].strip() self.height = self.query_list[2].strip() self.dpi = self.query_list[3].strip() self.ip = None self.port = None self.username = None self.password = None self.record_dir = 'admin_guacamole_records' if self.scope[ 'user'].is_superuser else 'fort_guacamole_records' def connect(self): if self.scope["user"].is_anonymous: self.close(code=1007) else: self.accept('guacamole') self.client.handshake(protocol='rdp', hostname=self.ip, port=self.port, password=self.password, username=self.username, width=self.width, height=self.height, dpi=self.dpi) self.send('0.,{0}.{1};'.format(len(self.group_name), self.group_name)) self.guacamole_thread.setDaemon(True) self.guacamole_thread.start() def disconnect(self, event): try: self.guacamole_thread.record() finally: self.guacamole_thread.stop() self.client.close() def receive(self, text_data=None, bytes_data=None): with self.guacamole_thread.write_lock: self.client.send(text_data)
def connect(self, message, id): self.message.reply_channel.send({"accept": True}) if not self.authenticate: self.message.reply_channel.send( { "text": json.dumps({ 'status': False, 'message': 'You must login to the system!' }) }, immediately=True) self.message.reply_channel.send({"accept": False}) else: client = GuacamoleClient(settings.GUACD_HOST, settings.GUACD_PORT) log_object = Log.objects.get(id=id) cache_key = str(log_object.gucamole_client_id) data = log_object.server print 'cache_key', cache_key client.handshake( width=data.credential.width, height=data.credential.height, protocol=data.credential.protocol, hostname=data.ip, port=data.credential.port, username=data.credential.username, password=data.credential.password, read_only=True, ) client.send_instruction(Instruction('select', cache_key)) #self.message.reply_channel.send({"text":'0.,{0}.{1};'.format(len(cache_key),cache_key)},immediately=True) guacamolethread = GuacamoleThread(self.message, client) guacamolethread.setDaemon = True guacamolethread.start() guacamolethreadwrite = GuacamoleThreadWrite(self.message, client) guacamolethreadwrite.setDaemon = True guacamolethreadwrite.start()
class GuacamoleClientTest(TestCase): def setUp(self): self.client = GuacamoleClient('127.0.0.1', 4822) # patch `send` self.client.send = MagicMock() self.client.close = MagicMock() def test_handshake(self): """ Test successful handshake. """ global step step = 0 client_id = '$260d01da-779b-4ee9-afc1-c16bae885cc7' expected = ['select', 'size', 'audio', 'video', 'image', 'connect'] def mock_send_instruction_handshake(instruction): global step assert instruction.opcode == expected[step] step += 1 # mock and vaidate send_instruction in handshake self.client.send_instruction = MagicMock( side_effect=mock_send_instruction_handshake) # successful `args` response for `select` instruction self.client.receive = MagicMock( side_effect=[ '4.args,8.hostname,4.port,6.domain,8.username;', '5.ready,37.%s;' % client_id ]) self.client.handshake(protocol='rdp') self.assertTrue(self.client.connected) self.assertEqual(self.client.id, client_id) def test_handshake_invalid_protocol(self): """ Test invalid handshake. """ with self.assertRaises(GuacamoleError): self.client.handshake(protocol='invalid') def test_handshake_protocol_failure(self): """ Test invalid protocol instruction. """ # expected `args` self.client.receive = MagicMock( side_effect=['7.invalid,8.hostname,4.port,6.domain,8.username;']) with self.assertRaises(GuacamoleError): self.client.handshake(protocol='rdp') def test_handshake_invalid_instruction(self): """ Test invalid instruction. """ self.client.receive = MagicMock() self.client.receive.return_value = '' with self.assertRaises(InvalidInstruction): self.client.handshake(protocol='rdp') def test_handshake_invalid_instruction_args(self): """ Test invalid instruction. """ # invalid arg length self.client.receive = MagicMock() self.client.receive.return_value = '5.args;' with self.assertRaises(InvalidInstruction): self.client.handshake(protocol='rdp') def test_handshake_invalid_instruction_termination(self): """ Test invalid instruction. """ # invalid instruction terminator `;` self.client.receive = MagicMock( side_effect=['4.args,8.hostname,4.port,6.domain,8.username']) with self.assertRaises(InvalidInstruction): self.client.handshake(protocol='rdp')
def setUp(self): self.client = GuacamoleClient('127.0.0.1', 4822) # patch `send` self.client.send = MagicMock() self.client.close = MagicMock()
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)
def connect(self, message, id): self.message.reply_channel.send({"accept": True}) user = get_redis_instance().get(id) if not self.authenticate(id): self.message.reply_channel.send({"text": json.dumps( {'status': False, 'message': 'You must login to the system!'})}, immediately=True) self.message.reply_channel.send({"accept": False}) else: # permission auth username = get_redis_instance().get(id) try: Permission.objects.get( user__username=username, groups__servers__id=int(id[-1])) except ObjectDoesNotExist: self.message.reply_channel.send({"text": json.dumps( '\033[1;3;31mYou have not permission to connect server !\033[0m')}, immediately=True) self.message.reply_channel.send({"accept": False}) return except MultipleObjectsReturned: pass client = GuacamoleClient( settings.GUACD_HOST, settings.GUACD_PORT) try: data = ServerInfor.objects.get(id=int(id[-1])) if data.credential.protocol in ['vnc', 'rdp', 'telnet']: pass else: self.message.reply_channel.send({"accept": False}) except ObjectDoesNotExist: # server info not exist self.message.reply_channel.send({"accept": False}) cache_key = str(uuid.uuid4()) directory_date_time = now() recording_path = os.path.join(MEDIA_ROOT, '{0}-{1}-{2}'.format( directory_date_time.year, directory_date_time.month, directory_date_time.day)) if isinstance(username, bytes): username = username.decode() drive_path = os.path.join(MEDIA_ROOT, str(username), 'Download') """ Create recording media file and drive path """ mkdir_p(recording_path) mkdir_p(drive_path) try: client.handshake(width=data.credential.width, height=data.credential.height, protocol=data.credential.protocol, hostname=data.ip, port=data.credential.port, username=data.credential.username, password=data.credential.password, recording_path=recording_path, recording_name=cache_key, create_recording_path='true', enable_wallpaper='true', ignore_cert='true', enable_drive='true', drive_path=drive_path, create_drive_path='true', security=data.credential.security, # console_audio='true', # enable_audio_input='true', # disable_audio='false', # console='true', enable_full_window_drag='true', resize_method="reconnect" # display-update ) except Exception as e: print(e) print(traceback.print_exc()) self.message.reply_channel.send({"accept": False}) return self.message.reply_channel.send( {"text": '0.,{0}.{1};'.format(len(cache_key), cache_key)}, immediately=True) audit_log = Log.objects.create(user=User.objects.get(username=username), server=data, channel=self.message.reply_channel.name, width=data.credential.width, height=data.credential.height, log=cache_key, gucamole_client_id=client._id) audit_log.save() guacamolethread = GuacamoleThread(self.message, client) guacamolethread.setDaemon = True guacamolethread.start() guacamolethreadwrite = GuacamoleThreadWrite(self.message, client) guacamolethreadwrite.setDaemon = True guacamolethreadwrite.start()
def disconnect(self, message, id): # close threading print('disconnect') try: log_object = Log.objects.get(id=id) cache_key = log_object.gucamole_client_id client = GuacamoleClient( settings.GUACD_HOST, settings.GUACD_PORT) client.send_instruction(Instruction('select', cache_key)) instruction = client.read_instruction() kwargs = {'width': 1024, 'height': 768, 'read_only': 'true'} connection_args = [ kwargs.get(arg.replace('-', '_'), '') for arg in instruction.args ] client.send_instruction(Instruction('size', 1024, 768, 96)) client.send_instruction(Instruction('audio', *list())) client.send_instruction(Instruction('video', *list())) client.send_instruction(Instruction('image', *list())) client.send_instruction(Instruction('connect', *connection_args)) client.send_instruction(Instruction( 'disconnect', *connection_args)) except: pass finally: self.message.reply_channel.send({"accept": False})
def connect(self, message, id): self.message.reply_channel.send({"accept": True}) if not self.authenticate: self.message.reply_channel.send({"text": json.dumps( {'status': False, 'message': 'You must login to the system!'})}, immediately=True) self.message.reply_channel.send({"accept": False}) else: # permission auth if not self.haspermission('common.can_monitor_serverinfo'): self.message.reply_channel.send({"text": json.dumps( {'status': False, 'message': 'You have not permission to monitor user action!'})}, immediately=True) self.message.reply_channel.send({"accept": False}) client = GuacamoleClient( settings.GUACD_HOST, settings.GUACD_PORT) log_object = Log.objects.get(id=id) cache_key = str(log_object.gucamole_client_id) data = log_object.server # draft version for real time monitor client.send_instruction(Instruction('select', cache_key)) instruction = client.read_instruction() kwargs = {'width': 1024, 'height': 768, 'read_only': 'true'} connection_args = [ kwargs.get(arg.replace('-', '_'), '') for arg in instruction.args ] client.send_instruction(Instruction('size', 1024, 768, 96)) client.send_instruction(Instruction('audio', *list())) client.send_instruction(Instruction('video', *list())) client.send_instruction(Instruction('image', *list())) client.send_instruction(Instruction('connect', *connection_args)) # self.message.reply_channel.send({"text":'0.,{0}.{1};'.format(len(cache_key),cache_key)},immediately=True) guacamolethread = GuacamoleThread(self.message, client) guacamolethread.setDaemon = True guacamolethread.start() guacamolethreadwrite = GuacamoleThreadWrite(self.message, client) guacamolethreadwrite.setDaemon = True guacamolethreadwrite.start()
def disconnect(self, message, id): # close threading print('disconnect') try: audit_log = Log.objects.get( channel=self.message.reply_channel.name) audit_log.is_finished = True audit_log.end_time = now() audit_log.save() cache_key = audit_log.gucamole_client_id client = GuacamoleClient( settings.GUACD_HOST, settings.GUACD_PORT) client.send_instruction(Instruction('select', cache_key)) instruction = client.read_instruction() kwargs = {'width': 1024, 'height': 768, 'read_only': 'true'} connection_args = [ kwargs.get(arg.replace('-', '_'), '') for arg in instruction.args ] client.send_instruction(Instruction('size', 1024, 768, 96)) client.send_instruction(Instruction('audio', *list())) client.send_instruction(Instruction('video', *list())) client.send_instruction(Instruction('image', *list())) client.send_instruction(Instruction('connect', *connection_args)) client.send_instruction(Instruction( 'disconnect', *connection_args)) except: pass finally: get_redis_instance().delete(id) self.message.reply_channel.send({"accept": False})