From 7c2bbde75bdf44d96b0fb63c7bede59bf3a975ea Mon Sep 17 00:00:00 2001 From: yv1ing Date: Mon, 31 Mar 2025 10:40:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E7=BF=BB=E9=A1=B9=E7=9B=AE=EF=BC=8C?= =?UTF-8?q?=E8=AE=A1=E5=88=92=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 +- protocol/core/transport/transport.go | 6 - protocol/fastpath/fastpath.go | 68 ----- protocol/fastpath/fastpath_test.go | 66 ----- protocol/tpkt/tpkt.go | 86 ------ protocol/tpkt/tpkt_test.go | 68 ----- protocol/x224/x224.go | 393 --------------------------- protocol/x224/x224_test.go | 64 ----- 8 files changed, 1 insertion(+), 752 deletions(-) delete mode 100644 protocol/core/transport/transport.go delete mode 100644 protocol/fastpath/fastpath.go delete mode 100644 protocol/fastpath/fastpath_test.go delete mode 100644 protocol/tpkt/tpkt.go delete mode 100644 protocol/tpkt/tpkt_test.go delete mode 100644 protocol/x224/x224.go delete mode 100644 protocol/x224/x224_test.go diff --git a/go.mod b/go.mod index 44cc41c..374ba17 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module rdp_channel -go 1.24 +go 1.24 \ No newline at end of file diff --git a/protocol/core/transport/transport.go b/protocol/core/transport/transport.go deleted file mode 100644 index 114339f..0000000 --- a/protocol/core/transport/transport.go +++ /dev/null @@ -1,6 +0,0 @@ -package transport - -type Transport interface { - Read() (int, []byte, error) - Write([]byte) (int, error) -} diff --git a/protocol/fastpath/fastpath.go b/protocol/fastpath/fastpath.go deleted file mode 100644 index 70754b7..0000000 --- a/protocol/fastpath/fastpath.go +++ /dev/null @@ -1,68 +0,0 @@ -package fastpath - -import ( - "encoding/binary" - "errors" - "rdp_channel/protocol/core/transport" -) - -// 协议常量 -const ( - FASTPATH_PDU_HEADER_LENGTH = 0x4 // updateHeader(1 bytes) + compressionFlags(1 bytes) + size(2 bytes) - FASTPATH__MAX_PACKET_LENGTH = 0xffff - - FASTPATH_UPDATETYPE_ORDERS uint32 = 0x0 - FASTPATH_UPDATETYPE_BITMAP uint32 = 0x1 -) - -const ( - // update header: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/a1c4caa8-00ed-45bb-a06e-5177473766d3 - FASTPATH_UPDATE_HEADER uint8 = 0x8 - FASTPATH_COMPRESSION_FLAGS uint8 = 0x0 -) - -var ( - FASTPATH_INVALID_PACKET_LENGTH = errors.New("[FASTPATH] invalid packet length") -) - -type FastPath struct { - transport transport.Transport -} - -func New(transport transport.Transport) *FastPath { - return &FastPath{ - transport: transport, - } -} - -func (fp *FastPath) Write(data []byte) (int, error) { - /* - 构造PDU - 格式参考:https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/0ae3c114-1439-4465-8d3f-6585227eff7d - */ - dataLen := len(data) - if dataLen > FASTPATH__MAX_PACKET_LENGTH { - return dataLen, FASTPATH_INVALID_PACKET_LENGTH - } - - size := uint16(FASTPATH_PDU_HEADER_LENGTH + dataLen) - pdu := make([]byte, size) - - pdu[0] = FASTPATH_UPDATE_HEADER - pdu[1] = FASTPATH_COMPRESSION_FLAGS - binary.LittleEndian.PutUint16(pdu[2:4], size) - - copy(pdu[4:], data) - - return fp.transport.Write(pdu) -} - -func (fp *FastPath) Read() (int, []byte, error) { - _, packet, err := fp.transport.Read() - if err != nil { - return 0, nil, err - } - - data := packet[FASTPATH_PDU_HEADER_LENGTH:] - return len(data), data, nil -} diff --git a/protocol/fastpath/fastpath_test.go b/protocol/fastpath/fastpath_test.go deleted file mode 100644 index 0f18486..0000000 --- a/protocol/fastpath/fastpath_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package fastpath - -import ( - "net" - "rdp_channel/protocol/tpkt" - "testing" -) - -func TestFastPath(t *testing.T) { - go runServer(t) - runClient(t) -} - -func runServer(t *testing.T) { - listener, err := net.Listen("tcp", "127.0.0.1:3388") - if err != nil { - t.Fatal(err) - } - defer listener.Close() - - for { - conn, err := listener.Accept() - if err != nil { - continue - } - - go func(conn net.Conn) { - defer conn.Close() - - tpkt := tpkt.New(conn) - fp := New(tpkt) - - dataLen, data, err := fp.Read() - if err != nil { - return - } - - t.Logf("fp server read data(%d bytes): %q\n", dataLen, data) - - _, err = fp.Write([]byte("fp server hello")) - }(conn) - } -} - -func runClient(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:3388") - if err != nil { - t.Fatal(err) - } - defer conn.Close() - - tpkt := tpkt.New(conn) - fp := New(tpkt) - - _, err = fp.Write([]byte("fp client hello")) - if err != nil { - t.Logf("fp client write error: %s\n", err) - } - - dataLen, data, err := fp.Read() - if err != nil { - t.Fatal(err) - } - - t.Logf("fp client read data(%d bytes): %q\n", dataLen, data) -} diff --git a/protocol/tpkt/tpkt.go b/protocol/tpkt/tpkt.go deleted file mode 100644 index f7551ad..0000000 --- a/protocol/tpkt/tpkt.go +++ /dev/null @@ -1,86 +0,0 @@ -package tpkt - -import ( - "bufio" - "encoding/binary" - "errors" - "io" - "net" -) - -// 协议常量 -const ( - TPKT_VERSION = 0x03 - TPKT_RESERVED = 0x00 - TPKT_HEADER_LENGTH = 0x04 - TPKT_MAX_PACKET_LENGTH = 0xffff -) - -var ( - TPKT_INVALID_VERSION = errors.New("[TPKT] invalid version") - TPKT_INVALID_PACKET_LENGTH = errors.New("[TPKT] invalid packet length") -) - -// TPKT 协议封装 -type TPKT struct { - connection net.Conn - readBuff *bufio.Reader -} - -func New(conn net.Conn) *TPKT { - tpkt := &TPKT{ - connection: conn, - readBuff: bufio.NewReader(conn), - } - - return tpkt -} - -// Write 发送TPKT包 -func (tpkt *TPKT) Write(data []byte) (int, error) { - dataLen := len(data) - if dataLen > (TPKT_MAX_PACKET_LENGTH - TPKT_HEADER_LENGTH) { - return 0, TPKT_INVALID_PACKET_LENGTH - } - - // TPKT封包 - packet := make([]byte, TPKT_HEADER_LENGTH+dataLen) - packet[0] = TPKT_VERSION - packet[1] = TPKT_RESERVED - binary.BigEndian.PutUint16(packet[2:4], uint16(TPKT_HEADER_LENGTH+dataLen)) // 第2、3字节为tpkt包的长度 - - // 装填载荷 - copy(packet[TPKT_HEADER_LENGTH:], data) - - // 发送TPKT包 - return tpkt.connection.Write(packet) -} - -func (tpkt *TPKT) Read() (int, []byte, error) { - // 验证TPKT头 - header := make([]byte, TPKT_HEADER_LENGTH) - _, err := io.ReadFull(tpkt.readBuff, header) - if err != nil { - return 0, nil, err - } - - // 验证TPKT版本 - if header[0] != TPKT_VERSION { - return 0, nil, TPKT_INVALID_VERSION - } - - // 验证载荷长度 - length := binary.BigEndian.Uint16(header[2:4]) - if length > TPKT_MAX_PACKET_LENGTH { - return 0, nil, TPKT_INVALID_PACKET_LENGTH - } - - // 读取载荷数据 - dataLen := length - TPKT_HEADER_LENGTH - data := make([]byte, dataLen) - if _, err := io.ReadFull(tpkt.readBuff, data); err != nil { - return 0, nil, err - } - - return int(dataLen), data, nil -} diff --git a/protocol/tpkt/tpkt_test.go b/protocol/tpkt/tpkt_test.go deleted file mode 100644 index a683958..0000000 --- a/protocol/tpkt/tpkt_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package tpkt - -import ( - "net" - "testing" -) - -func TestTpkt(t *testing.T) { - go runServer(t) - runClient(t) -} - -func runServer(t *testing.T) { - listener, err := net.Listen("tcp", "127.0.0.1:3388") - if err != nil { - t.Fatal(err) - } - defer listener.Close() - t.Logf("tpkt server listening at %s\n", listener.Addr()) - - for { - conn, err := listener.Accept() - if err != nil { - t.Logf("tpkt server accept error: %s\n", err) - continue - } - - t.Logf("tpkt server accepted connection from %s\n", conn.RemoteAddr()) - go func(conn net.Conn) { - defer conn.Close() - - tpkt := New(conn) - dataLen, data, err := tpkt.Read() - if err != nil { - t.Logf("tpkt server read error: %s\n", err) - return - } - - t.Logf("tpkt server read data(%d): %q\n", dataLen, data) - - _, err = tpkt.Write([]byte("tpkt server hello")) - if err != nil { - t.Logf("tpkt server write error: %s\n", err) - } - }(conn) - } -} - -func runClient(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:3388") - if err != nil { - t.Fatal(err) - } - defer conn.Close() - - tpkt := New(conn) - - _, err = tpkt.Write([]byte("tpkt client hello")) - if err != nil { - t.Logf("tpkt client write error: %s\n", err) - } - - dataLen, data, err := tpkt.Read() - if err != nil { - t.Logf("tpkt client read error: %s\n", err) - } - t.Logf("tpkt client read data(%d): %q\n", dataLen, data) -} diff --git a/protocol/x224/x224.go b/protocol/x224/x224.go deleted file mode 100644 index c4f1acc..0000000 --- a/protocol/x224/x224.go +++ /dev/null @@ -1,393 +0,0 @@ -package x224 - -import ( - "bytes" - "encoding/binary" - "errors" - "io" - "log" - "rdp_channel/protocol/core/transport" -) - -/* 协议常量 */ -const ( - X224_HEADER_LENGTH = 0x06 - RDP_NEG_LENGTH = 0x08 -) - -// X224消息类型字段标识 -const ( - X224_CONNECTION_REQUEST byte = 0xE0 - X224_CONNECTION_CONFIRM byte = 0xD0 - X224_DISCONNECT_REQUEST byte = 0x80 - X224_DATA byte = 0xF0 - X224_ERROR byte = 0x70 -) - -// 安全协议协商状态字段标识 -const ( - RDP_NEG_REQ byte = 0x01 - RDP_NEG_RSP byte = 0x02 - RDP_NEG_FAIL byte = 0x03 -) - -// 可选协议 -const ( - PROTOCOL_RDP uint32 = 0x0000 - PROTOCOL_SSL uint32 = 0x0001 -) - -// Negotiation 安全协议协商结构体 -type Negotiation struct { - Type byte - Flags uint8 - Length uint16 - Payload uint32 -} - -func (neg *Negotiation) parseNegotiation(reader *bytes.Reader) error { - var err error - - err = binary.Read(reader, binary.LittleEndian, &neg.Type) - if err != nil { - return errors.New("[X224] failed to read pdu neg type: " + err.Error()) - } - - err = binary.Read(reader, binary.LittleEndian, &neg.Flags) - if err != nil { - return errors.New("[X224] failed to read pdu neg flags: " + err.Error()) - } - - err = binary.Read(reader, binary.LittleEndian, &neg.Length) - if err != nil { - return errors.New("[X224] failed to read pdu neg length: " + err.Error()) - } - - err = binary.Read(reader, binary.LittleEndian, &neg.Payload) - if err != nil { - return errors.New("[X224] failed to read pdu neg payload: " + err.Error()) - } - - return nil -} - -// X224 协议封装 -type X224 struct { - transport transport.Transport - reqProtocol uint32 - selProtocol uint32 - - dataHandlers []func([]byte) - errorHandlers []func(error) -} - -type X224PDU struct { - Len uint8 - Type byte - DstRef uint16 // 大端序 - SrcRef uint16 // 大端序 - ClsOpt uint8 - Cookie []byte - Payload []byte - NegMsg *Negotiation -} - -func New(transport transport.Transport) *X224 { - return &X224{ - transport: transport, - reqProtocol: PROTOCOL_SSL, - } -} - -/* 注册事件回调函数 */ - -// OnData 数据回调 -func (x *X224) OnData(handler func([]byte)) { - x.dataHandlers = append(x.dataHandlers, handler) -} - -// OnError 错误回调 -func (x *X224) OnError(handler func(error)) { - x.errorHandlers = append(x.errorHandlers, handler) -} - -// 从字节流中解析PDU头部 -func (x *X224) parsePduHeader(reader *bytes.Reader, pdu *X224PDU) error { - var err error - - // 读取Len字段 - err = binary.Read(reader, binary.LittleEndian, &pdu.Len) - if err != nil { - return errors.New("[X224] failed to read pdu length: " + err.Error()) - } - - // 读取Type字段 - err = binary.Read(reader, binary.LittleEndian, &pdu.Type) - if err != nil { - return errors.New("[X224] failed to read pdu type: " + err.Error()) - } - - // 读取DstRef(大端序) - err = binary.Read(reader, binary.BigEndian, &pdu.DstRef) - if err != nil { - return errors.New("[X224] failed to read pdu dstref: " + err.Error()) - } - - // 读取SrcRef(大端序) - err = binary.Read(reader, binary.BigEndian, &pdu.SrcRef) - if err != nil { - return errors.New("[X224] failed to read pdu srcref: " + err.Error()) - } - - // 读取ClsOpt - err = binary.Read(reader, binary.LittleEndian, &pdu.ClsOpt) - if err != nil { - return errors.New("[X224] failed to read pdu clsopt: " + err.Error()) - } - - return nil -} - -// 序列化X224PDU -func (x *X224) serialize(pdu *X224PDU) []byte { - buff := bytes.NewBuffer(nil) - _ = binary.Write(buff, binary.LittleEndian, pdu.Len) - _ = binary.Write(buff, binary.LittleEndian, pdu.Type) - _ = binary.Write(buff, binary.BigEndian, pdu.DstRef) - _ = binary.Write(buff, binary.BigEndian, pdu.SrcRef) - _ = binary.Write(buff, binary.LittleEndian, pdu.ClsOpt) - - // 仅连接相关PDU包含Cookie和协商负载 - switch pdu.Type { - case X224_CONNECTION_REQUEST, X224_CONNECTION_CONFIRM: - if len(pdu.Cookie) > 0 { - _ = binary.Write(buff, binary.LittleEndian, pdu.Cookie) - _ = binary.Write(buff, binary.LittleEndian, []byte{0x0D, 0x0A}) - } - - if pdu.NegMsg != nil { - _ = binary.Write(buff, binary.LittleEndian, pdu.NegMsg.Type) - _ = binary.Write(buff, binary.LittleEndian, pdu.NegMsg.Flags) - _ = binary.Write(buff, binary.LittleEndian, pdu.NegMsg.Length) - _ = binary.Write(buff, binary.LittleEndian, pdu.NegMsg.Payload) - } - case X224_DATA: - buff.Write(pdu.Payload) - } - - return buff.Bytes() -} - -// 处理数据消息 -func (x *X224) handleData(reader *bytes.Reader) { - buff, err := io.ReadAll(reader) - if err != nil { - x.handleError(err) - return - } - - for _, handler := range x.dataHandlers { - handler(buff) - } -} - -// 处理错误消息 -func (x *X224) handleError(err error) { - log.Println(err.Error()) - - for _, handler := range x.errorHandlers { - handler(err) - } -} - -// Write 发送数据消息 -func (x *X224) Write(data []byte) { - // 构造pdu - reqPdu := &X224PDU{ - Len: X224_HEADER_LENGTH + uint8(len(data)), // 头部长度 + 数据长度 - Type: X224_DATA, - DstRef: 0x00, - SrcRef: 0x00, - ClsOpt: 0x0, - Payload: data, - } - - // 序列化pdu - payload := x.serialize(reqPdu) - - // 写入传输层 - _, err := x.transport.Write(payload) - if err != nil { - x.handleError(err) - } -} - -/* - X224客户端相关实现 -*/ - -// ConnectToServer 客户端向服务端发起连接请求 -func (x *X224) ConnectToServer() { - cookie := []byte("Cookie: mstshash=yv1ing") - - /* 构造pdu */ - reqPdu := &X224PDU{ - Len: X224_HEADER_LENGTH + uint8(len(cookie)+0x02+RDP_NEG_LENGTH), // 头部长度 + Cookie长度 + CRLF + Neg字段 - Type: X224_CONNECTION_REQUEST, - DstRef: 0x00, - SrcRef: 0x00, - ClsOpt: 0x0, - Cookie: cookie, - NegMsg: &Negotiation{ - Type: RDP_NEG_RSP, - Flags: 0x00, - Length: RDP_NEG_LENGTH, - Payload: x.reqProtocol, - }, - } - - /* 序列化pdu */ - payload := x.serialize(reqPdu) - - /* 写入传输层 */ - _, err := x.transport.Write(payload) - if err != nil { - x.handleError(errors.New("[X224] failed to write pdu: " + err.Error())) - return - } - - /* 等待处理服务端对连接请求的响应 */ - go x.clientHandleServerMessage() -} - -// 客户端处理服务端的消息 -func (x *X224) clientHandleServerMessage() { - for { - li, packet, err := x.transport.Read() - if err != nil { - continue - } - - if li < 0x07 { - x.handleError(errors.New("[X224] invalid packet")) - return - } - - resPdu := &X224PDU{} - reader := bytes.NewReader(packet) - - err = x.parsePduHeader(reader, resPdu) - if err != nil { - x.handleError(errors.New("[X224] failed to parse pdu header: " + err.Error())) - return - } - - switch resPdu.Type { - case X224_CONNECTION_CONFIRM: - x.clientHandleConnectionConfirm(resPdu, reader) - case X224_DATA: - x.handleData(reader) - } - } -} - -// handleConnectionConfirm 客户端处理服务端对连接请求的响应 -func (x *X224) clientHandleConnectionConfirm(resPdu *X224PDU, reader *bytes.Reader) { - // 读取安全协议协商结果 - neg := &Negotiation{} - err := neg.parseNegotiation(reader) - if err != nil { - x.handleError(errors.New("[X224] failed to parse negotiation: " + err.Error())) - } - - resPdu.NegMsg = neg -} - -/* - X224服务端相关实现 -*/ - -// 服务端向客户端发送响应 -func (x *X224) serverResponseToClient(reqPdu *X224PDU) { - var err error - - // 构造协商响应 - resPdu := &X224PDU{ - Len: X224_HEADER_LENGTH + RDP_NEG_LENGTH, // 头部长度 + Neg字段 - Type: X224_CONNECTION_CONFIRM, - DstRef: reqPdu.SrcRef, - SrcRef: reqPdu.DstRef, - ClsOpt: reqPdu.ClsOpt, - NegMsg: &Negotiation{ - Type: RDP_NEG_RSP, - Flags: 0x00, - Length: RDP_NEG_LENGTH, - Payload: x.selProtocol, - }, - } - - payload := x.serialize(resPdu) - _, err = x.transport.Write(payload) - if err != nil { - x.handleError(errors.New("[X224] failed to write response: " + err.Error())) - } -} - -// 服务端处理客户端消息 -func (x *X224) serverHandleClientMessage() { - for { - _, packet, err := x.transport.Read() - if err != nil { - continue - } - - reqPdu := &X224PDU{} - reader := bytes.NewReader(packet) - - err = x.parsePduHeader(reader, reqPdu) - if err != nil { - x.handleError(errors.New("[X224] failed to parse pdu header: " + err.Error())) - return - } - - switch reqPdu.Type { - case X224_CONNECTION_REQUEST: - x.serverHandleConnectionRequest(reqPdu, reader) - case X224_DATA: - x.handleData(reader) - } - } -} - -// 服务端处理客户端发来的连接请求 -func (x *X224) serverHandleConnectionRequest(reqPdu *X224PDU, reader *bytes.Reader) { - - // 解析Cookie - cookieBuff := make([]byte, 0, 32) - for { - b, err := reader.ReadByte() - if err != nil { - x.handleError(errors.New("[X224] failed to read cookie: " + err.Error())) - return - } - cookieBuff = append(cookieBuff, b) - if len(cookieBuff) >= 2 && bytes.Equal(cookieBuff[len(cookieBuff)-2:], []byte{0x0D, 0x0A}) { - break - } - } - reqPdu.Cookie = cookieBuff[:len(cookieBuff)-2] // 去掉结尾CRLF - - // 解析协商请求 - reqNeg := &Negotiation{} - if err := reqNeg.parseNegotiation(reader); err != nil { - x.handleError(errors.New("[X224] failed to parse negotiation: " + err.Error())) - return - } - reqPdu.NegMsg = reqNeg - - // 确定使用协议 - x.selProtocol = PROTOCOL_SSL - - // 响应请求 - x.serverResponseToClient(reqPdu) -} diff --git a/protocol/x224/x224_test.go b/protocol/x224/x224_test.go deleted file mode 100644 index 1ad13cb..0000000 --- a/protocol/x224/x224_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package x224 - -import ( - "fmt" - "net" - "rdp_channel/protocol/tpkt" - "testing" - "time" -) - -func TestX224(t *testing.T) { - go runServer(t) - runClient(t) -} - -func runServer(t *testing.T) { - listener, err := net.Listen("tcp", "127.0.0.1:3388") - if err != nil { - t.Fatal(err) - } - defer listener.Close() - - for { - conn, err := listener.Accept() - if err != nil { - t.Fatal(err) - } - - go func(conn net.Conn) { - defer conn.Close() - - tpkt := tpkt.New(conn) - x224 := New(tpkt) - - x224.OnData(func(bytes []byte) { - fmt.Printf("server received: %s\n", string(bytes)) - x224.Write([]byte("yes! server hear!")) - }) - - x224.serverHandleClientMessage() - }(conn) - } -} - -func runClient(t *testing.T) { - conn, err := net.Dial("tcp", "127.0.0.1:3388") - if err != nil { - t.Fatal(err) - } - defer conn.Close() - - tpkt := tpkt.New(conn) - x224 := New(tpkt) - - x224.ConnectToServer() - x224.OnData(func(bytes []byte) { - fmt.Printf("client received: %s\n", string(bytes)) - }) - - for { - time.Sleep(1 * time.Second) - x224.Write([]byte("this is client!")) - } -}