mirror of
https://github.com/yv1ing/rdp_channel.git
synced 2025-09-16 14:59:08 +08:00
推翻项目,计划重构
This commit is contained in:
@@ -1,6 +0,0 @@
|
|||||||
package transport
|
|
||||||
|
|
||||||
type Transport interface {
|
|
||||||
Read() (int, []byte, error)
|
|
||||||
Write([]byte) (int, error)
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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!"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user