|
@@ -3,6 +3,7 @@ package sshd
|
|
|
import (
|
|
import (
|
|
|
"context"
|
|
"context"
|
|
|
"errors"
|
|
"errors"
|
|
|
|
|
+ "fmt"
|
|
|
"os"
|
|
"os"
|
|
|
"strings"
|
|
"strings"
|
|
|
"sync"
|
|
"sync"
|
|
@@ -291,24 +292,42 @@ func (c *MQTTCoupler) execOneCmd(msg mqtt.Message) {
|
|
|
goto retp
|
|
goto retp
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ cmd := params.Cmd
|
|
|
|
|
+ if strings.ContainsAny(cmd, "&") {
|
|
|
|
|
+ ce.mu.Unlock()
|
|
|
|
|
+ resp = jsonrpc2.BuildError(req, -32003, "prohibit the startup of background tasks")
|
|
|
|
|
+ goto retp
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if strings.ContainsAny(cmd, "|>;") || strings.Contains(cmd, "\n") {
|
|
|
|
|
+ safeCmd := strings.ReplaceAll(cmd, "'", "'\\''")
|
|
|
|
|
+ cmd = fmt.Sprintf("sh -c '%s'", safeCmd) // 包装成 shell 命令, 支持管道等高级功能
|
|
|
|
|
+ params.Cmd = cmd
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ hostID := params.HostFingerprint
|
|
|
|
|
+ if hostID == "" {
|
|
|
|
|
+ hostID = "unknown"
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
ce.state = execRunning
|
|
ce.state = execRunning
|
|
|
ce.mu.Unlock()
|
|
ce.mu.Unlock()
|
|
|
|
|
|
|
|
start := time.Now()
|
|
start := time.Now()
|
|
|
if true { //////// 记录执行日志-执行前
|
|
if true { //////// 记录执行日志-执行前
|
|
|
- baseapp.Logger.Infof("[%s][▷ EXEC] client=%s cmd=%q dir=%q timeout=%ds",
|
|
|
|
|
- MODULE_NAME, clientID, params.Cmd, params.Dir, params.Timeout)
|
|
|
|
|
|
|
+ baseapp.Logger.Infof("[%s][▷ EXEC] host=%s, cmd=%q, timeout=%ds",
|
|
|
|
|
+ MODULE_NAME, hostID, params.Cmd, params.Timeout)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
result, err := ce.executor.Exec(params) // 本地执行用户指令
|
|
result, err := ce.executor.Exec(params) // 本地执行用户指令
|
|
|
|
|
|
|
|
cost := time.Since(start)
|
|
cost := time.Since(start)
|
|
|
- if err != nil { // 记录执行日志-执行后
|
|
|
|
|
- baseapp.Logger.Warnf("[%s][✖ EXEC] client=%s cost=%v cmd=%q err=%v",
|
|
|
|
|
- MODULE_NAME, clientID, cost, params.Cmd, err)
|
|
|
|
|
- } else {
|
|
|
|
|
- baseapp.Logger.Infof("[%s][✔ EXEC] client=%s cost=%v cmd=%q",
|
|
|
|
|
- MODULE_NAME, clientID, cost, params.Cmd)
|
|
|
|
|
|
|
+ if err != nil { // 记录失败日志-执行后
|
|
|
|
|
+ baseapp.Logger.Warnf("[%s][✖ EXEC] host=%s, cmd=%q, err=%v, cost=%v",
|
|
|
|
|
+ MODULE_NAME, hostID, params.Cmd, err, cost)
|
|
|
|
|
+ } else { ///////// 记录成功日志-执行后
|
|
|
|
|
+ baseapp.Logger.Infof("[%s][✔ EXEC] host=%s, cmd=%q, cost=%v",
|
|
|
|
|
+ MODULE_NAME, hostID, params.Cmd, cost)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ce.mu.Lock()
|
|
ce.mu.Lock()
|
|
@@ -327,7 +346,7 @@ func (c *MQTTCoupler) execOneCmd(msg mqtt.Message) {
|
|
|
ce.mu.Unlock()
|
|
ce.mu.Unlock()
|
|
|
|
|
|
|
|
if !running {
|
|
if !running {
|
|
|
- resp = jsonrpc2.BuildError(req, -32003, "no running command")
|
|
|
|
|
|
|
+ resp = jsonrpc2.BuildError(req, -32004, "no running command")
|
|
|
goto retp
|
|
goto retp
|
|
|
}
|
|
}
|
|
|
|
|
|