feat(rdp): 新增 RDP 远程桌面/SMB/账单同步能力 + 清理编译产物

主要变更:
- RDP 远程桌面:新增 backend/pkg/rdp(RDP 引擎 + credssp/display/rle/trace)、
  backend/controller/rdp*(连接/凭证/文件/会话/实时)、frontend RDP 组件与 API
- Windows SMB 文件传输:backend/pkg/winsmb
- 云账单同步:backend/pkg/billingsync + billing_sync/aliyun_billing,前端账单详情
- Agent CLI Kubernetes 工具:kubernetes_action/get、pod_execute/logs
- 服务器导入助手:server_import_helpers、ImportCredentialSettings
- 国际化与组件重构(cloud/deploy/monitor/server/system 等多模块)
- 清理编译产物二进制:移除 backend/server、backend/agent/bin/aiops-agent-*
- .gitignore:新增 backend/agent/ 与 .cache/(避免 334MB go-build 缓存误入库)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
LoganandClaude committed 2026-07-04 01:50:36 +08:00
1 parent 777d9e4e71
commit 76ec9387f0
202 files changed
+16555 -2543

No files matched your search

+119
View File
@@ -0,0 +1,119 @@
package transport
import (
"encoding/binary"
"fmt"
"io"
)
const (
x224TypeConnectionRequest = 0xE0
x224TypeConnectionConfirm = 0xD0
x224TypeData = 0xF0
negTypeRequest = 0x01
negTypeResponse = 0x02
negTypeFailure = 0x03
protocolSSL = 0x00000001
protocolCredSSP = 0x00000002
)
const (
ProtocolStandard uint32 = 0
ProtocolTLS uint32 = protocolSSL
ProtocolCredSSP uint32 = protocolCredSSP
)
// NegotiationResult 是 X.224 阶段的 RDP 安全协议协商结果 // Logan.Li
type NegotiationResult struct {
SelectedProtocol uint32
FailureCode uint32
}
func (r NegotiationResult) ProtocolName() string {
switch r.SelectedProtocol {
case ProtocolCredSSP:
return "CredSSP/NLA"
case ProtocolTLS:
return "TLS"
case ProtocolStandard:
return "Standard RDP"
default:
return fmt.Sprintf("unknown(0x%x)", r.SelectedProtocol)
}
}
// BuildConnectionRequest 构造 X.224 Connection Request,并请求 NLA/TLS 协商 // Logan.Li
func BuildConnectionRequest() []byte {
return BuildConnectionRequestWithCookie("aiops")
}
// BuildConnectionRequestWithCookie 按 MS-RDPBCGR 2.2.1.1.1 构造包含 mstshash 的请求 // Logan.Li
func BuildConnectionRequestWithCookie(username string) []byte {
if username == "" {
username = "aiops"
}
if len(username) > 9 {
username = username[:9]
}
cookie := []byte("Cookie: mstshash=" + username + "\r\n")
neg := make([]byte, 8)
neg[0] = negTypeRequest
neg[1] = 0
binary.LittleEndian.PutUint16(neg[2:4], uint16(len(neg)))
binary.LittleEndian.PutUint32(neg[4:8], protocolSSL|protocolCredSSP)
length := 7 + len(cookie) + len(neg)
pdu := make([]byte, 0, length)
pdu = append(pdu, byte(length-1))
pdu = append(pdu, x224TypeConnectionRequest)
pdu = append(pdu, 0x00, 0x00) // dst-ref // Logan.Li
pdu = append(pdu, 0x00, 0x00) // src-ref // Logan.Li
pdu = append(pdu, 0x00) // class/options // Logan.Li
pdu = append(pdu, cookie...)
pdu = append(pdu, neg...)
return pdu
}
// ParseConnectionConfirm 解析 X.224 Connection Confirm 与 RDP Negotiation Response // Logan.Li
func ParseConnectionConfirm(payload []byte) (NegotiationResult, error) {
if len(payload) < 7 {
return NegotiationResult{}, fmt.Errorf("short X.224 confirm: %d", len(payload))
}
if payload[1] != x224TypeConnectionConfirm {
return NegotiationResult{}, fmt.Errorf("unexpected X.224 pdu type: 0x%x", payload[1])
}
for i := 7; i+8 <= len(payload); i++ {
switch payload[i] {
case negTypeResponse:
return NegotiationResult{SelectedProtocol: binary.LittleEndian.Uint32(payload[i+4 : i+8])}, nil
case negTypeFailure:
return NegotiationResult{FailureCode: binary.LittleEndian.Uint32(payload[i+4 : i+8])}, fmt.Errorf("RDP negotiation failure: 0x%x", binary.LittleEndian.Uint32(payload[i+4:i+8]))
}
}
return NegotiationResult{SelectedProtocol: 0}, nil
}
// WriteX224Data 写入 X.224 Data TPDU,NLA 后的 MCS/GCC 数据仍经由该层承载 // Logan.Li
func WriteX224Data(w io.Writer, payload []byte) error {
data := make([]byte, 0, len(payload)+3)
data = append(data, 0x02, x224TypeData, 0x80)
data = append(data, payload...)
return WriteTPKT(w, data)
}
// ReadX224Data 读取并剥离 X.224 Data TPDU 头,返回上层 MCS 负载 // Logan.Li
func ReadX224Data(r io.Reader) ([]byte, error) {
payload, err := ReadTPKT(r)
if err != nil {
return nil, err
}
if len(payload) < 3 {
return nil, fmt.Errorf("X.224 data too short: %d", len(payload))
}
if payload[1] != x224TypeData {
return nil, fmt.Errorf("unexpected X.224 type: 0x%x", payload[1])
}
return payload[3:], nil
}