🔨 记录 RDP 传输日志.
This commit is contained in:
@@ -43,7 +43,7 @@ import javax.annotation.PostConstruct;
|
|||||||
public enum InputProtocolEnum {
|
public enum InputProtocolEnum {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 连接终端
|
* 请求连接
|
||||||
*/
|
*/
|
||||||
CONNECT("co",
|
CONNECT("co",
|
||||||
TerminalConnectHandler.class,
|
TerminalConnectHandler.class,
|
||||||
@@ -74,7 +74,17 @@ public enum InputProtocolEnum {
|
|||||||
new String[]{"type", "width", "height"},
|
new String[]{"type", "width", "height"},
|
||||||
TerminalResizeRequest.class),
|
TerminalResizeRequest.class),
|
||||||
|
|
||||||
// ----------------------- SSH ----------------------
|
// ----------------------- guacd ----------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* guacd 指令
|
||||||
|
*/
|
||||||
|
GUACD_INSTRUCTION("gi",
|
||||||
|
GuacdInstructionHandler.class,
|
||||||
|
new String[]{"type", "instruction"},
|
||||||
|
GuacdInstructionRequest.class),
|
||||||
|
|
||||||
|
// ----------------------- ssh ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SSH 输入
|
* SSH 输入
|
||||||
@@ -84,7 +94,7 @@ public enum InputProtocolEnum {
|
|||||||
new String[]{"type", "command"},
|
new String[]{"type", "command"},
|
||||||
SshInputRequest.class),
|
SshInputRequest.class),
|
||||||
|
|
||||||
// ----------------------- SFTP ----------------------
|
// ----------------------- sftp ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SFTP 文件列表
|
* SFTP 文件列表
|
||||||
@@ -182,15 +192,15 @@ public enum InputProtocolEnum {
|
|||||||
new String[]{"type", "path"},
|
new String[]{"type", "path"},
|
||||||
SftpBaseRequest.class),
|
SftpBaseRequest.class),
|
||||||
|
|
||||||
// ----------------------- guacd ----------------------
|
// ----------------------- rdp ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* guacd 指令
|
* RDP 文件系统事件
|
||||||
*/
|
*/
|
||||||
GUACD_INSTRUCTION("gi",
|
RDP_FILE_SYSTEM_EVENT("fse",
|
||||||
GuacdInstructionHandler.class,
|
RdpFileSystemEventHandler.class,
|
||||||
new String[]{"type", "instruction"},
|
new String[]{"type", "event"},
|
||||||
GuacdInstructionRequest.class),
|
RdpFileSystemEventRequest.class),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ public enum OutputProtocolEnum {
|
|||||||
*/
|
*/
|
||||||
RESIZE("rs", "${type}|${width}|${height}"),
|
RESIZE("rs", "${type}|${width}|${height}"),
|
||||||
|
|
||||||
|
// ----------------------- guacd ----------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* guacd 指令
|
||||||
|
*/
|
||||||
|
GUACD_INSTRUCTION("gi", "${type}|${instruction}"),
|
||||||
|
|
||||||
// ----------------------- ssh ----------------------
|
// ----------------------- ssh ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,13 +150,6 @@ public enum OutputProtocolEnum {
|
|||||||
*/
|
*/
|
||||||
SFTP_SET_CONTENT("sc", "${type}|${result}|${msg}|${token}"),
|
SFTP_SET_CONTENT("sc", "${type}|${result}|${msg}|${token}"),
|
||||||
|
|
||||||
// ----------------------- guacd ----------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* guacd 指令
|
|
||||||
*/
|
|
||||||
GUACD_INSTRUCTION("gi", "${type}|${instruction}"),
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 - present Dromara, All rights reserved.
|
||||||
|
*
|
||||||
|
* https://visor.dromara.org
|
||||||
|
* https://visor.dromara.org.cn
|
||||||
|
* https://visor.orionsec.cn
|
||||||
|
*
|
||||||
|
* Members:
|
||||||
|
* Jiahang Li - ljh1553488six@139.com - author
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.dromara.visor.module.terminal.handler.terminal.handler;
|
||||||
|
|
||||||
|
import cn.orionsec.kit.lang.utils.collect.Maps;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||||
|
import org.dromara.visor.module.terminal.define.operator.TerminalOperatorType;
|
||||||
|
import org.dromara.visor.module.terminal.handler.terminal.model.TerminalChannelProps;
|
||||||
|
import org.dromara.visor.module.terminal.handler.terminal.model.request.RdpFileSystemEventRequest;
|
||||||
|
import org.dromara.visor.module.terminal.handler.terminal.model.transport.RdpFileSystemEvent;
|
||||||
|
import org.dromara.visor.module.terminal.handler.terminal.sender.IGuacdTerminalSender;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rdp 文件系统事件 处理器
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/2/19 11:13
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class RdpFileSystemEventHandler extends AbstractTerminalHandler<IGuacdTerminalSender, RdpFileSystemEventRequest> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(TerminalChannelProps props, IGuacdTerminalSender sender, RdpFileSystemEventRequest payload) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
String sessionId = props.getId();
|
||||||
|
// 获取会话
|
||||||
|
RdpFileSystemEvent fsEvent = JSON.parseObject(payload.getEvent(), RdpFileSystemEvent.class);
|
||||||
|
String event = fsEvent.getEvent();
|
||||||
|
String path = fsEvent.getPath();
|
||||||
|
log.info("RdpFileSystemEventHandler-handle start sessionId: {}, event: {}, path: {}", sessionId, event, path);
|
||||||
|
String operatorType;
|
||||||
|
if (TerminalOperatorType.RDP_UPLOAD.equals(event)) {
|
||||||
|
// 上传文件
|
||||||
|
operatorType = TerminalOperatorType.RDP_UPLOAD;
|
||||||
|
} else if (TerminalOperatorType.RDP_DOWNLOAD.equals(event)) {
|
||||||
|
// 下载文件
|
||||||
|
operatorType = TerminalOperatorType.RDP_DOWNLOAD;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 保存操作日志
|
||||||
|
Map<String, Object> extra = Maps.newMap();
|
||||||
|
extra.put(OperatorLogs.PATH, path);
|
||||||
|
this.saveOperatorLog(props, extra, operatorType, startTime, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 - present Dromara, All rights reserved.
|
||||||
|
*
|
||||||
|
* https://visor.dromara.org
|
||||||
|
* https://visor.dromara.org.cn
|
||||||
|
* https://visor.orionsec.cn
|
||||||
|
*
|
||||||
|
* Members:
|
||||||
|
* Jiahang Li - ljh1553488six@139.com - author
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.dromara.visor.module.terminal.handler.terminal.model.request;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import org.dromara.visor.module.terminal.handler.terminal.model.TerminalBasePayload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rdp 文件系统事件请求
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/2/6 13:31
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class RdpFileSystemEventRequest extends TerminalBasePayload {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件
|
||||||
|
*/
|
||||||
|
private String event;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 - present Dromara, All rights reserved.
|
||||||
|
*
|
||||||
|
* https://visor.dromara.org
|
||||||
|
* https://visor.dromara.org.cn
|
||||||
|
* https://visor.orionsec.cn
|
||||||
|
*
|
||||||
|
* Members:
|
||||||
|
* Jiahang Li - ljh1553488six@139.com - author
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.dromara.visor.module.terminal.handler.terminal.model.transport;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RDP 文件系统事件
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2025/6/30 22:33
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class RdpFileSystemEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件
|
||||||
|
*/
|
||||||
|
private String event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件路径
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
package org.dromara.visor.module.terminal.handler.transfer.session;
|
package org.dromara.visor.module.terminal.handler.transfer.session;
|
||||||
|
|
||||||
import cn.orionsec.kit.lang.exception.argument.InvalidArgumentException;
|
import cn.orionsec.kit.lang.exception.argument.InvalidArgumentException;
|
||||||
|
import cn.orionsec.kit.lang.utils.collect.Maps;
|
||||||
import cn.orionsec.kit.lang.utils.io.Streams;
|
import cn.orionsec.kit.lang.utils.io.Streams;
|
||||||
import cn.orionsec.kit.net.host.SessionStore;
|
import cn.orionsec.kit.net.host.SessionStore;
|
||||||
import cn.orionsec.kit.net.host.sftp.SftpExecutor;
|
import cn.orionsec.kit.net.host.sftp.SftpExecutor;
|
||||||
@@ -33,14 +34,18 @@ import org.dromara.visor.common.constant.Const;
|
|||||||
import org.dromara.visor.common.constant.FieldConst;
|
import org.dromara.visor.common.constant.FieldConst;
|
||||||
import org.dromara.visor.common.session.config.SshConnectConfig;
|
import org.dromara.visor.common.session.config.SshConnectConfig;
|
||||||
import org.dromara.visor.framework.biz.operator.log.core.model.OperatorLogModel;
|
import org.dromara.visor.framework.biz.operator.log.core.model.OperatorLogModel;
|
||||||
|
import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||||
import org.dromara.visor.framework.websocket.core.utils.WebSockets;
|
import org.dromara.visor.framework.websocket.core.utils.WebSockets;
|
||||||
|
import org.dromara.visor.module.terminal.handler.terminal.model.TerminalChannelProps;
|
||||||
import org.dromara.visor.module.terminal.handler.terminal.record.TerminalAsyncSaver;
|
import org.dromara.visor.module.terminal.handler.terminal.record.TerminalAsyncSaver;
|
||||||
|
import org.dromara.visor.module.terminal.handler.terminal.utils.TerminalUtils;
|
||||||
import org.dromara.visor.module.terminal.handler.transfer.enums.TransferReceiver;
|
import org.dromara.visor.module.terminal.handler.transfer.enums.TransferReceiver;
|
||||||
import org.dromara.visor.module.terminal.handler.transfer.model.TransferOperatorRequest;
|
import org.dromara.visor.module.terminal.handler.transfer.model.TransferOperatorRequest;
|
||||||
import org.dromara.visor.module.terminal.handler.transfer.utils.TransferUtils;
|
import org.dromara.visor.module.terminal.handler.transfer.utils.TransferUtils;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主机传输会话实现
|
* 主机传输会话实现
|
||||||
@@ -149,10 +154,19 @@ public abstract class TransferSession implements ITransferSession {
|
|||||||
* @param paths paths
|
* @param paths paths
|
||||||
*/
|
*/
|
||||||
protected void saveOperatorLog(Long logId, String type, List<String> paths) {
|
protected void saveOperatorLog(Long logId, String type, List<String> paths) {
|
||||||
|
TerminalChannelProps props = WebSockets.getAttr(channel, FieldConst.PROPS);
|
||||||
String path = String.join(Const.LF, paths);
|
String path = String.join(Const.LF, paths);
|
||||||
int count = paths.size();
|
int count = paths.size();
|
||||||
// 获取操作日志
|
// 获取操作日志
|
||||||
OperatorLogModel model = TransferUtils.getOperatorLogModel(type, path, count, connectConfig, WebSockets.getAttr(channel, FieldConst.PROPS));
|
Map<String, Object> extra = Maps.newMap();
|
||||||
|
extra.put(OperatorLogs.PATH, path);
|
||||||
|
extra.put(OperatorLogs.COUNT, count);
|
||||||
|
extra.put(OperatorLogs.HOST_ID, connectConfig.getHostId());
|
||||||
|
extra.put(OperatorLogs.HOST_NAME, connectConfig.getHostName());
|
||||||
|
extra.put(OperatorLogs.ADDRESS, connectConfig.getHostAddress());
|
||||||
|
OperatorLogModel model = TerminalUtils.getOperatorLogModel(props, extra, type, System.currentTimeMillis(), null);
|
||||||
|
// 保存操作日志
|
||||||
|
TerminalAsyncSaver.saveOperatorLog(model);
|
||||||
// 保存操作日志
|
// 保存操作日志
|
||||||
TerminalAsyncSaver.saveOperatorLog(model);
|
TerminalAsyncSaver.saveOperatorLog(model);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,21 +23,14 @@
|
|||||||
package org.dromara.visor.module.terminal.handler.transfer.utils;
|
package org.dromara.visor.module.terminal.handler.transfer.utils;
|
||||||
|
|
||||||
import cn.orionsec.kit.lang.utils.Strings;
|
import cn.orionsec.kit.lang.utils.Strings;
|
||||||
import cn.orionsec.kit.lang.utils.collect.Maps;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import org.apache.catalina.connector.ClientAbortException;
|
import org.apache.catalina.connector.ClientAbortException;
|
||||||
import org.dromara.visor.common.constant.ErrorMessage;
|
import org.dromara.visor.common.constant.ErrorMessage;
|
||||||
import org.dromara.visor.common.session.config.BaseConnectConfig;
|
|
||||||
import org.dromara.visor.framework.biz.operator.log.core.model.OperatorLogModel;
|
|
||||||
import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
|
||||||
import org.dromara.visor.framework.websocket.core.utils.WebSockets;
|
import org.dromara.visor.framework.websocket.core.utils.WebSockets;
|
||||||
import org.dromara.visor.module.terminal.handler.terminal.model.TerminalChannelProps;
|
|
||||||
import org.dromara.visor.module.terminal.handler.terminal.utils.TerminalUtils;
|
|
||||||
import org.dromara.visor.module.terminal.handler.transfer.enums.TransferReceiver;
|
import org.dromara.visor.module.terminal.handler.transfer.enums.TransferReceiver;
|
||||||
import org.dromara.visor.module.terminal.handler.transfer.model.TransferOperatorResponse;
|
import org.dromara.visor.module.terminal.handler.transfer.model.TransferOperatorResponse;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,30 +45,6 @@ public class TransferUtils {
|
|||||||
private TransferUtils() {
|
private TransferUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取传输操作日志
|
|
||||||
*
|
|
||||||
* @param type type
|
|
||||||
* @param path path
|
|
||||||
* @param count count
|
|
||||||
* @param config config
|
|
||||||
* @param props props
|
|
||||||
*/
|
|
||||||
public static OperatorLogModel getOperatorLogModel(String type,
|
|
||||||
String path, Integer count,
|
|
||||||
BaseConnectConfig config,
|
|
||||||
TerminalChannelProps props) {
|
|
||||||
// 设置参数
|
|
||||||
Map<String, Object> extra = Maps.newMap();
|
|
||||||
extra.put(OperatorLogs.PATH, path);
|
|
||||||
extra.put(OperatorLogs.COUNT, count);
|
|
||||||
extra.put(OperatorLogs.HOST_ID, config.getHostId());
|
|
||||||
extra.put(OperatorLogs.HOST_NAME, config.getHostName());
|
|
||||||
extra.put(OperatorLogs.ADDRESS, config.getHostAddress());
|
|
||||||
// 获取操作日志
|
|
||||||
return TerminalUtils.getOperatorLogModel(props, extra, type, System.currentTimeMillis(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送消息
|
* 发送消息
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -275,7 +275,11 @@
|
|||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
const uploadFile = () => {
|
const uploadFile = () => {
|
||||||
transferManager.rdp.addUpload(props.session, fileList.value[0].file as File);
|
const file = fileList.value[0].file as File;
|
||||||
|
// 记录事件
|
||||||
|
props.session.onFileSystemEvent({ event: 'terminal:rdp-upload', path: file.name });
|
||||||
|
// 上传文件
|
||||||
|
transferManager.rdp.addUpload(props.session, file);
|
||||||
fileList.value = [];
|
fileList.value = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,8 @@ export interface IRdpSession extends IGuacdSession {
|
|||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
init: (config: GuacdInitConfig) => Promise<void>;
|
init: (config: GuacdInitConfig) => Promise<void>;
|
||||||
|
// 文件系统事件
|
||||||
|
onFileSystemEvent: (event: Record<string, any>) => void;
|
||||||
// 发送键
|
// 发送键
|
||||||
sendKeys: (keys: Array<number>) => void;
|
sendKeys: (keys: Array<number>) => void;
|
||||||
// 粘贴
|
// 粘贴
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import type { OutputPayload } from '@/views/terminal/types/protocol';
|
|||||||
import { InputProtocol } from '@/views/terminal/types/protocol';
|
import { InputProtocol } from '@/views/terminal/types/protocol';
|
||||||
import { TerminalMessages, fitDisplayValue, TerminalCloseCode } from '@/views/terminal/types/const';
|
import { TerminalMessages, fitDisplayValue, TerminalCloseCode } from '@/views/terminal/types/const';
|
||||||
import { screenshot } from '@/views/terminal/types/utils';
|
import { screenshot } from '@/views/terminal/types/utils';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
import Guacamole from 'guacamole-common-js';
|
import Guacamole from 'guacamole-common-js';
|
||||||
import BaseSession from './base-session';
|
import BaseSession from './base-session';
|
||||||
@@ -105,6 +106,13 @@ export default class RdpSession extends BaseSession<GuacdReactiveSessionStatus,
|
|||||||
};
|
};
|
||||||
// 下载文件回调
|
// 下载文件回调
|
||||||
this.client.onfile = (stream, mimetype, filename) => {
|
this.client.onfile = (stream, mimetype, filename) => {
|
||||||
|
if (!this.isWriteable()) {
|
||||||
|
Message.error('无写入权限');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 记录事件
|
||||||
|
this.onFileSystemEvent({ event: 'terminal:rdp-download', path: filename });
|
||||||
|
// 下载文件
|
||||||
useTerminalStore().transferManager.rdp.addDownload(this, stream, mimetype, filename);
|
useTerminalStore().transferManager.rdp.addDownload(this, stream, mimetype, filename);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -160,6 +168,11 @@ export default class RdpSession extends BaseSession<GuacdReactiveSessionStatus,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 文件系统事件
|
||||||
|
onFileSystemEvent(event: Record<string, any>): void {
|
||||||
|
this.channel.send(InputProtocol.RDP_FILE_SYSTEM_EVENT, { event: JSON.stringify(event) });
|
||||||
|
}
|
||||||
|
|
||||||
// 发送键
|
// 发送键
|
||||||
sendKeys(keys: Array<number>): void {
|
sendKeys(keys: Array<number>): void {
|
||||||
if (!this.isWriteable()) {
|
if (!this.isWriteable()) {
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ export const InputProtocol = {
|
|||||||
type: 'rs',
|
type: 'rs',
|
||||||
template: ['type', 'width', 'height']
|
template: ['type', 'width', 'height']
|
||||||
},
|
},
|
||||||
|
// guacd 指令
|
||||||
|
GUACD_INSTRUCTION: {
|
||||||
|
type: 'gi',
|
||||||
|
template: ['type', 'instruction']
|
||||||
|
},
|
||||||
// SSH 输入
|
// SSH 输入
|
||||||
SSH_INPUT: {
|
SSH_INPUT: {
|
||||||
type: 'i',
|
type: 'i',
|
||||||
@@ -95,11 +100,11 @@ export const InputProtocol = {
|
|||||||
type: 'sc',
|
type: 'sc',
|
||||||
template: ['type', 'path']
|
template: ['type', 'path']
|
||||||
},
|
},
|
||||||
// guacd 指令
|
// RDP 文件系统事件
|
||||||
GUACD_INSTRUCTION: {
|
RDP_FILE_SYSTEM_EVENT: {
|
||||||
type: 'gi',
|
type: 'fse',
|
||||||
template: ['type', 'instruction']
|
template: ['type', 'event']
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 输出协议
|
// 输出协议
|
||||||
@@ -140,6 +145,12 @@ export const OutputProtocol = {
|
|||||||
template: ['type'],
|
template: ['type'],
|
||||||
processMethod: 'processPong'
|
processMethod: 'processPong'
|
||||||
},
|
},
|
||||||
|
// guacd 指令
|
||||||
|
GUACD_INSTRUCTION: {
|
||||||
|
type: 'gi',
|
||||||
|
template: ['type', 'instruction'],
|
||||||
|
processMethod: 'processInstruction'
|
||||||
|
},
|
||||||
// SSH 输出
|
// SSH 输出
|
||||||
SSH_OUTPUT: {
|
SSH_OUTPUT: {
|
||||||
type: 'o',
|
type: 'o',
|
||||||
@@ -200,12 +211,6 @@ export const OutputProtocol = {
|
|||||||
template: ['type', 'result', 'msg', 'token'],
|
template: ['type', 'result', 'msg', 'token'],
|
||||||
processMethod: 'processSftpSetContent'
|
processMethod: 'processSftpSetContent'
|
||||||
},
|
},
|
||||||
// guacd 指令
|
|
||||||
GUACD_INSTRUCTION: {
|
|
||||||
type: 'gi',
|
|
||||||
template: ['type', 'instruction'],
|
|
||||||
processMethod: 'processInstruction'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 解析参数
|
// 解析参数
|
||||||
|
|||||||
Reference in New Issue
Block a user