🔨 记录 RDP 传输日志.
This commit is contained in:
@@ -43,7 +43,7 @@ import javax.annotation.PostConstruct;
|
||||
public enum InputProtocolEnum {
|
||||
|
||||
/**
|
||||
* 连接终端
|
||||
* 请求连接
|
||||
*/
|
||||
CONNECT("co",
|
||||
TerminalConnectHandler.class,
|
||||
@@ -74,7 +74,17 @@ public enum InputProtocolEnum {
|
||||
new String[]{"type", "width", "height"},
|
||||
TerminalResizeRequest.class),
|
||||
|
||||
// ----------------------- SSH ----------------------
|
||||
// ----------------------- guacd ----------------------
|
||||
|
||||
/**
|
||||
* guacd 指令
|
||||
*/
|
||||
GUACD_INSTRUCTION("gi",
|
||||
GuacdInstructionHandler.class,
|
||||
new String[]{"type", "instruction"},
|
||||
GuacdInstructionRequest.class),
|
||||
|
||||
// ----------------------- ssh ----------------------
|
||||
|
||||
/**
|
||||
* SSH 输入
|
||||
@@ -84,7 +94,7 @@ public enum InputProtocolEnum {
|
||||
new String[]{"type", "command"},
|
||||
SshInputRequest.class),
|
||||
|
||||
// ----------------------- SFTP ----------------------
|
||||
// ----------------------- sftp ----------------------
|
||||
|
||||
/**
|
||||
* SFTP 文件列表
|
||||
@@ -182,15 +192,15 @@ public enum InputProtocolEnum {
|
||||
new String[]{"type", "path"},
|
||||
SftpBaseRequest.class),
|
||||
|
||||
// ----------------------- guacd ----------------------
|
||||
// ----------------------- rdp ----------------------
|
||||
|
||||
/**
|
||||
* guacd 指令
|
||||
* RDP 文件系统事件
|
||||
*/
|
||||
GUACD_INSTRUCTION("gi",
|
||||
GuacdInstructionHandler.class,
|
||||
new String[]{"type", "instruction"},
|
||||
GuacdInstructionRequest.class),
|
||||
RDP_FILE_SYSTEM_EVENT("fse",
|
||||
RdpFileSystemEventHandler.class,
|
||||
new String[]{"type", "event"},
|
||||
RdpFileSystemEventRequest.class),
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -69,6 +69,13 @@ public enum OutputProtocolEnum {
|
||||
*/
|
||||
RESIZE("rs", "${type}|${width}|${height}"),
|
||||
|
||||
// ----------------------- guacd ----------------------
|
||||
|
||||
/**
|
||||
* guacd 指令
|
||||
*/
|
||||
GUACD_INSTRUCTION("gi", "${type}|${instruction}"),
|
||||
|
||||
// ----------------------- ssh ----------------------
|
||||
|
||||
/**
|
||||
@@ -143,13 +150,6 @@ public enum OutputProtocolEnum {
|
||||
*/
|
||||
SFTP_SET_CONTENT("sc", "${type}|${result}|${msg}|${token}"),
|
||||
|
||||
// ----------------------- guacd ----------------------
|
||||
|
||||
/**
|
||||
* guacd 指令
|
||||
*/
|
||||
GUACD_INSTRUCTION("gi", "${type}|${instruction}"),
|
||||
|
||||
;
|
||||
|
||||
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;
|
||||
|
||||
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.net.host.SessionStore;
|
||||
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.session.config.SshConnectConfig;
|
||||
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.module.terminal.handler.terminal.model.TerminalChannelProps;
|
||||
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.model.TransferOperatorRequest;
|
||||
import org.dromara.visor.module.terminal.handler.transfer.utils.TransferUtils;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 主机传输会话实现
|
||||
@@ -149,10 +154,19 @@ public abstract class TransferSession implements ITransferSession {
|
||||
* @param paths 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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -23,21 +23,14 @@
|
||||
package org.dromara.visor.module.terminal.handler.transfer.utils;
|
||||
|
||||
import cn.orionsec.kit.lang.utils.Strings;
|
||||
import cn.orionsec.kit.lang.utils.collect.Maps;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.catalina.connector.ClientAbortException;
|
||||
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.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.model.TransferOperatorResponse;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -52,30 +45,6 @@ public class 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user