feature: Adds basic data command support.
This commit is contained in:
parent
ede4d528aa
commit
17e1491f96
14 changed files with 2241 additions and 195 deletions
103
backend/sshappbackend/datacommands/constants.go
Normal file
103
backend/sshappbackend/datacommands/constants.go
Normal file
|
@ -0,0 +1,103 @@
|
|||
package datacommands
|
||||
|
||||
type ProxyStatusRequest struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
}
|
||||
|
||||
type ProxyStatusResponse struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
type RemoveProxy struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
}
|
||||
|
||||
type ProxyInstanceResponse struct {
|
||||
Type string
|
||||
Proxies []uint16
|
||||
}
|
||||
|
||||
type ProxyConnectionsRequest struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
}
|
||||
|
||||
type ProxyConnectionsResponse struct {
|
||||
Type string
|
||||
Connections []uint16
|
||||
}
|
||||
|
||||
type TCPConnectionOpened struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
ConnectionID uint16
|
||||
}
|
||||
|
||||
type TCPConnectionClosed struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
ConnectionID uint16
|
||||
}
|
||||
|
||||
type TCPProxyData struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
ConnectionID uint16
|
||||
DataLength uint16
|
||||
}
|
||||
|
||||
type UDPProxyData struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
ClientIP string
|
||||
ClientPort uint16
|
||||
DataLength uint16
|
||||
}
|
||||
|
||||
type ProxyInformationRequest struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
}
|
||||
|
||||
type ProxyInformationResponse struct {
|
||||
Type string
|
||||
Exists bool
|
||||
SourceIP string
|
||||
SourcePort uint16
|
||||
DestPort uint16
|
||||
Protocol string // Will be either 'tcp' or 'udp'
|
||||
}
|
||||
|
||||
type ProxyConnectionInformationRequest struct {
|
||||
Type string
|
||||
ProxyID uint16
|
||||
ConnectionID uint16
|
||||
}
|
||||
|
||||
type ProxyConnectionInformationResponse struct {
|
||||
Type string
|
||||
Exists bool
|
||||
ClientIP string
|
||||
ClientPort uint16
|
||||
}
|
||||
|
||||
const (
|
||||
ProxyStatusRequestID = iota + 100
|
||||
ProxyStatusResponseID
|
||||
RemoveProxyID
|
||||
ProxyInstanceResponseID
|
||||
ProxyConnectionsRequestID
|
||||
ProxyConnectionsResponseID
|
||||
TCPConnectionOpenedID
|
||||
TCPConnectionClosedID
|
||||
TCPProxyDataID
|
||||
UDPProxyDataID
|
||||
ProxyInformationRequestID
|
||||
ProxyInformationResponseID
|
||||
ProxyConnectionInformationRequestID
|
||||
ProxyConnectionInformationResponseID
|
||||
)
|
323
backend/sshappbackend/datacommands/marshal.go
Normal file
323
backend/sshappbackend/datacommands/marshal.go
Normal file
|
@ -0,0 +1,323 @@
|
|||
package datacommands
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
// Example size and protocol constants — adjust as needed.
|
||||
const (
|
||||
IPv4Size = 4
|
||||
IPv6Size = 16
|
||||
|
||||
TCP = 1
|
||||
UDP = 2
|
||||
)
|
||||
|
||||
// Marshal takes a command (pointer to one of our structs) and converts it to a byte slice.
|
||||
func Marshal(_ string, command interface{}) ([]byte, error) {
|
||||
switch cmd := command.(type) {
|
||||
// ProxyStatusRequest: 1 byte for the command ID + 2 bytes for the ProxyID.
|
||||
case *ProxyStatusRequest:
|
||||
buf := make([]byte, 1+2)
|
||||
|
||||
buf[0] = ProxyStatusRequestID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// ProxyStatusResponse: 1 byte for the command ID, 2 bytes for ProxyID, and 1 byte for IsActive.
|
||||
case *ProxyStatusResponse:
|
||||
buf := make([]byte, 1+2+1)
|
||||
|
||||
buf[0] = ProxyStatusResponseID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
|
||||
if cmd.IsActive {
|
||||
buf[3] = 1
|
||||
} else {
|
||||
buf[3] = 0
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
|
||||
// RemoveProxy: 1 byte for the command ID + 2 bytes for the ProxyID.
|
||||
case *RemoveProxy:
|
||||
buf := make([]byte, 1+2)
|
||||
|
||||
buf[0] = RemoveProxyID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// ProxyConnectionsRequest: 1 byte for the command ID + 2 bytes for the ProxyID.
|
||||
case *ProxyConnectionsRequest:
|
||||
buf := make([]byte, 1+2)
|
||||
|
||||
buf[0] = ProxyConnectionsRequestID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// ProxyConnectionsResponse: 1 byte for the command ID + 2 bytes length of the Connections + 2 bytes for each
|
||||
// number in the Connection array.
|
||||
case *ProxyConnectionsResponse:
|
||||
buf := make([]byte, 1+((len(cmd.Connections)+1)*2))
|
||||
|
||||
buf[0] = ProxyConnectionsResponseID
|
||||
binary.BigEndian.PutUint16(buf[1:], uint16(len(cmd.Connections)))
|
||||
|
||||
for connectionIndex, connection := range cmd.Connections {
|
||||
binary.BigEndian.PutUint16(buf[3+(connectionIndex*2):], connection)
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
|
||||
// ProxyConnectionsResponse: 1 byte for the command ID + 2 bytes length of the Proxies + 2 bytes for each
|
||||
// number in the Proxies array.
|
||||
case *ProxyInstanceResponse:
|
||||
buf := make([]byte, 1+((len(cmd.Proxies)+1)*2))
|
||||
|
||||
buf[0] = ProxyInstanceResponseID
|
||||
binary.BigEndian.PutUint16(buf[1:], uint16(len(cmd.Proxies)))
|
||||
|
||||
for connectionIndex, connection := range cmd.Proxies {
|
||||
binary.BigEndian.PutUint16(buf[3+(connectionIndex*2):], connection)
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
|
||||
// TCPConnectionOpened: 1 byte for the command ID + 2 bytes ProxyID + 2 bytes ConnectionID.
|
||||
case *TCPConnectionOpened:
|
||||
buf := make([]byte, 1+2+2)
|
||||
|
||||
buf[0] = TCPConnectionOpenedID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
binary.BigEndian.PutUint16(buf[3:], cmd.ConnectionID)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// TCPConnectionClosed: 1 byte for the command ID + 2 bytes ProxyID + 2 bytes ConnectionID.
|
||||
case *TCPConnectionClosed:
|
||||
buf := make([]byte, 1+2+2)
|
||||
|
||||
buf[0] = TCPConnectionClosedID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
binary.BigEndian.PutUint16(buf[3:], cmd.ConnectionID)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// TCPProxyData: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID + 2 bytes DataLength.
|
||||
case *TCPProxyData:
|
||||
buf := make([]byte, 1+2+2+2)
|
||||
|
||||
buf[0] = TCPProxyDataID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
binary.BigEndian.PutUint16(buf[3:], cmd.ConnectionID)
|
||||
binary.BigEndian.PutUint16(buf[5:], cmd.DataLength)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// UDPProxyData:
|
||||
// Format: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID +
|
||||
// 1 byte IP version + IP bytes + 2 bytes ClientPort + 2 bytes DataLength.
|
||||
case *UDPProxyData:
|
||||
ip := net.ParseIP(cmd.ClientIP)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid client IP: %v", cmd.ClientIP)
|
||||
}
|
||||
|
||||
var ipVer uint8
|
||||
var ipBytes []byte
|
||||
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
ipBytes = ip4
|
||||
ipVer = 4
|
||||
} else if ip16 := ip.To16(); ip16 != nil {
|
||||
ipBytes = ip16
|
||||
ipVer = 6
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to detect IP version for: %v", cmd.ClientIP)
|
||||
}
|
||||
|
||||
totalSize := 1 + // id
|
||||
2 + // ProxyID
|
||||
1 + // IP version
|
||||
len(ipBytes) + // client IP bytes
|
||||
2 + // ClientPort
|
||||
2 // DataLength
|
||||
|
||||
buf := make([]byte, totalSize)
|
||||
offset := 0
|
||||
buf[offset] = UDPProxyDataID
|
||||
offset++
|
||||
|
||||
binary.BigEndian.PutUint16(buf[offset:], cmd.ProxyID)
|
||||
offset += 2
|
||||
|
||||
buf[offset] = ipVer
|
||||
offset++
|
||||
|
||||
copy(buf[offset:], ipBytes)
|
||||
offset += len(ipBytes)
|
||||
|
||||
binary.BigEndian.PutUint16(buf[offset:], cmd.ClientPort)
|
||||
offset += 2
|
||||
|
||||
binary.BigEndian.PutUint16(buf[offset:], cmd.DataLength)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// ProxyInformationRequest: 1 byte ID + 2 bytes ProxyID.
|
||||
case *ProxyInformationRequest:
|
||||
buf := make([]byte, 1+2)
|
||||
buf[0] = ProxyInformationRequestID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
return buf, nil
|
||||
|
||||
// ProxyInformationResponse:
|
||||
// Format: 1 byte ID + 1 byte Exists + (if exists:)
|
||||
// 1 byte IP version + IP bytes + 2 bytes SourcePort + 2 bytes DestPort + 1 byte Protocol.
|
||||
// (For simplicity, this marshaller always writes the IP and port info even if !Exists.)
|
||||
case *ProxyInformationResponse:
|
||||
if !cmd.Exists {
|
||||
buf := make([]byte, 1+1)
|
||||
buf[0] = ProxyInformationResponseID
|
||||
buf[1] = 0 /* false */
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
ip := net.ParseIP(cmd.SourceIP)
|
||||
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid source IP: %v", cmd.SourceIP)
|
||||
}
|
||||
|
||||
var ipVer uint8
|
||||
var ipBytes []byte
|
||||
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
ipBytes = ip4
|
||||
ipVer = 4
|
||||
} else if ip16 := ip.To16(); ip16 != nil {
|
||||
ipBytes = ip16
|
||||
ipVer = 6
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to detect IP version for: %v", cmd.SourceIP)
|
||||
}
|
||||
|
||||
totalSize := 1 + // id
|
||||
1 + // Exists flag
|
||||
1 + // IP version
|
||||
len(ipBytes) +
|
||||
2 + // SourcePort
|
||||
2 + // DestPort
|
||||
1 // Protocol
|
||||
|
||||
buf := make([]byte, totalSize)
|
||||
|
||||
offset := 0
|
||||
buf[offset] = ProxyInformationResponseID
|
||||
offset++
|
||||
|
||||
// We already handle this above
|
||||
buf[offset] = 1 /* true */
|
||||
offset++
|
||||
|
||||
buf[offset] = ipVer
|
||||
offset++
|
||||
|
||||
copy(buf[offset:], ipBytes)
|
||||
offset += len(ipBytes)
|
||||
|
||||
binary.BigEndian.PutUint16(buf[offset:], cmd.SourcePort)
|
||||
offset += 2
|
||||
|
||||
binary.BigEndian.PutUint16(buf[offset:], cmd.DestPort)
|
||||
offset += 2
|
||||
|
||||
// Encode protocol as 1 byte.
|
||||
switch cmd.Protocol {
|
||||
case "tcp":
|
||||
buf[offset] = TCP
|
||||
case "udp":
|
||||
buf[offset] = UDP
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid protocol: %v", cmd.Protocol)
|
||||
}
|
||||
|
||||
// offset++ (not needed since we are at the end)
|
||||
return buf, nil
|
||||
|
||||
// ProxyConnectionInformationRequest: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID.
|
||||
case *ProxyConnectionInformationRequest:
|
||||
buf := make([]byte, 1+2+2)
|
||||
|
||||
buf[0] = ProxyConnectionInformationRequestID
|
||||
binary.BigEndian.PutUint16(buf[1:], cmd.ProxyID)
|
||||
binary.BigEndian.PutUint16(buf[3:], cmd.ConnectionID)
|
||||
|
||||
return buf, nil
|
||||
|
||||
// ProxyConnectionInformationResponse:
|
||||
// Format: 1 byte ID + 1 byte Exists + (if exists:)
|
||||
// 1 byte IP version + IP bytes + 2 bytes ClientPort.
|
||||
// This marshaller only writes the rest of the data if Exists.
|
||||
case *ProxyConnectionInformationResponse:
|
||||
if !cmd.Exists {
|
||||
buf := make([]byte, 1+1)
|
||||
buf[0] = ProxyConnectionInformationResponseID
|
||||
buf[1] = 0 /* false */
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
ip := net.ParseIP(cmd.ClientIP)
|
||||
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid client IP: %v", cmd.ClientIP)
|
||||
}
|
||||
|
||||
var ipVer uint8
|
||||
var ipBytes []byte
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
ipBytes = ip4
|
||||
ipVer = 4
|
||||
} else if ip16 := ip.To16(); ip16 != nil {
|
||||
ipBytes = ip16
|
||||
ipVer = 6
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to detect IP version for: %v", cmd.ClientIP)
|
||||
}
|
||||
|
||||
totalSize := 1 + // id
|
||||
1 + // Exists flag
|
||||
1 + // IP version
|
||||
len(ipBytes) +
|
||||
2 // ClientPort
|
||||
|
||||
buf := make([]byte, totalSize)
|
||||
offset := 0
|
||||
buf[offset] = ProxyConnectionInformationResponseID
|
||||
offset++
|
||||
|
||||
// We already handle this above
|
||||
buf[offset] = 1 /* true */
|
||||
offset++
|
||||
|
||||
buf[offset] = ipVer
|
||||
offset++
|
||||
|
||||
copy(buf[offset:], ipBytes)
|
||||
offset += len(ipBytes)
|
||||
|
||||
binary.BigEndian.PutUint16(buf[offset:], cmd.ClientPort)
|
||||
|
||||
return buf, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported command type")
|
||||
}
|
||||
}
|
828
backend/sshappbackend/datacommands/marshalling_test.go
Normal file
828
backend/sshappbackend/datacommands/marshalling_test.go
Normal file
|
@ -0,0 +1,828 @@
|
|||
package datacommands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var logLevel = os.Getenv("HERMES_LOG_LEVEL")
|
||||
|
||||
func TestProxyStatusRequest(t *testing.T) {
|
||||
commandInput := &ProxyStatusRequest{
|
||||
Type: "proxyStatusRequest",
|
||||
ProxyID: 19132,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyStatusRequest)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyStatusResponse(t *testing.T) {
|
||||
commandInput := &ProxyStatusResponse{
|
||||
Type: "proxyStatusResponse",
|
||||
ProxyID: 19132,
|
||||
IsActive: true,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyStatusResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
|
||||
if commandInput.IsActive != commandUnmarshalled.IsActive {
|
||||
t.Fail()
|
||||
log.Printf("IsActive's are not equal (orig: '%t', unmsh: '%t')", commandInput.IsActive, commandUnmarshalled.IsActive)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveProxy(t *testing.T) {
|
||||
commandInput := &RemoveProxy{
|
||||
Type: "removeProxy",
|
||||
ProxyID: 19132,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*RemoveProxy)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyConnectionsRequest(t *testing.T) {
|
||||
commandInput := &ProxyConnectionsRequest{
|
||||
Type: "proxyConnectionsRequest",
|
||||
ProxyID: 19132,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyConnectionsRequest)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyConnectionsResponse(t *testing.T) {
|
||||
commandInput := &ProxyConnectionsResponse{
|
||||
Type: "proxyConnectionsResponse",
|
||||
Connections: []uint16{12831, 9455, 64219, 12, 32},
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyConnectionsResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
for connectionIndex, originalConnection := range commandInput.Connections {
|
||||
remoteConnection := commandUnmarshalled.Connections[connectionIndex]
|
||||
|
||||
if originalConnection != remoteConnection {
|
||||
t.Fail()
|
||||
log.Printf("(in #%d) SourceIP's are not equal (orig: %d, unmsh: %d)", connectionIndex, originalConnection, connectionIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyInstanceResponse(t *testing.T) {
|
||||
commandInput := &ProxyInstanceResponse{
|
||||
Type: "proxyInstanceResponse",
|
||||
Proxies: []uint16{12831, 9455, 64219, 12, 32},
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyInstanceResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
for proxyIndex, originalProxy := range commandInput.Proxies {
|
||||
remoteProxy := commandUnmarshalled.Proxies[proxyIndex]
|
||||
|
||||
if originalProxy != remoteProxy {
|
||||
t.Fail()
|
||||
log.Printf("(in #%d) Proxy IDs are not equal (orig: %d, unmsh: %d)", proxyIndex, originalProxy, remoteProxy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCPConnectionOpened(t *testing.T) {
|
||||
commandInput := &TCPConnectionOpened{
|
||||
Type: "tcpConnectionOpened",
|
||||
ProxyID: 19132,
|
||||
ConnectionID: 25565,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*TCPConnectionOpened)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
|
||||
if commandInput.ConnectionID != commandUnmarshalled.ConnectionID {
|
||||
t.Fail()
|
||||
log.Printf("ConnectionID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ConnectionID, commandUnmarshalled.ConnectionID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCPConnectionClosed(t *testing.T) {
|
||||
commandInput := &TCPConnectionClosed{
|
||||
Type: "tcpConnectionClosed",
|
||||
ProxyID: 19132,
|
||||
ConnectionID: 25565,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*TCPConnectionClosed)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
|
||||
if commandInput.ConnectionID != commandUnmarshalled.ConnectionID {
|
||||
t.Fail()
|
||||
log.Printf("ConnectionID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ConnectionID, commandUnmarshalled.ConnectionID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCPProxyData(t *testing.T) {
|
||||
commandInput := &TCPProxyData{
|
||||
Type: "tcpProxyData",
|
||||
ProxyID: 19132,
|
||||
ConnectionID: 25565,
|
||||
DataLength: 1234,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*TCPProxyData)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
|
||||
if commandInput.ConnectionID != commandUnmarshalled.ConnectionID {
|
||||
t.Fail()
|
||||
log.Printf("ConnectionID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ConnectionID, commandUnmarshalled.ConnectionID)
|
||||
}
|
||||
|
||||
if commandInput.DataLength != commandUnmarshalled.DataLength {
|
||||
t.Fail()
|
||||
log.Printf("DataLength's are not equal (orig: '%d', unmsh: '%d')", commandInput.DataLength, commandUnmarshalled.DataLength)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUDPProxyData(t *testing.T) {
|
||||
commandInput := &UDPProxyData{
|
||||
Type: "udpProxyData",
|
||||
ProxyID: 19132,
|
||||
ClientIP: "68.51.23.54",
|
||||
ClientPort: 28173,
|
||||
DataLength: 1234,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*UDPProxyData)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
|
||||
if commandInput.ClientIP != commandUnmarshalled.ClientIP {
|
||||
t.Fail()
|
||||
log.Printf("ClientIP's are not equal (orig: '%s', unmsh: '%s')", commandInput.ClientIP, commandUnmarshalled.ClientIP)
|
||||
}
|
||||
|
||||
if commandInput.ClientPort != commandUnmarshalled.ClientPort {
|
||||
t.Fail()
|
||||
log.Printf("ClientPort's are not equal (orig: '%d', unmsh: '%d')", commandInput.ClientPort, commandUnmarshalled.ClientPort)
|
||||
}
|
||||
|
||||
if commandInput.DataLength != commandUnmarshalled.DataLength {
|
||||
t.Fail()
|
||||
log.Printf("DataLength's are not equal (orig: '%d', unmsh: '%d')", commandInput.DataLength, commandUnmarshalled.DataLength)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyInformationRequest(t *testing.T) {
|
||||
commandInput := &ProxyInformationRequest{
|
||||
Type: "proxyInformationRequest",
|
||||
ProxyID: 19132,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyInformationRequest)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyInformationResponseExists(t *testing.T) {
|
||||
commandInput := &ProxyInformationResponse{
|
||||
Type: "proxyInformationResponse",
|
||||
Exists: true,
|
||||
SourceIP: "192.168.0.139",
|
||||
SourcePort: 19132,
|
||||
DestPort: 19132,
|
||||
Protocol: "tcp",
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyInformationResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.Exists != commandUnmarshalled.Exists {
|
||||
t.Fail()
|
||||
log.Printf("Exists's are not equal (orig: '%t', unmsh: '%t')", commandInput.Exists, commandUnmarshalled.Exists)
|
||||
}
|
||||
|
||||
if commandInput.SourceIP != commandUnmarshalled.SourceIP {
|
||||
t.Fail()
|
||||
log.Printf("SourceIP's are not equal (orig: %s, unmsh: %s)", commandInput.SourceIP, commandUnmarshalled.SourceIP)
|
||||
}
|
||||
|
||||
if commandInput.SourcePort != commandUnmarshalled.SourcePort {
|
||||
t.Fail()
|
||||
log.Printf("SourcePort's are not equal (orig: %d, unmsh: %d)", commandInput.SourcePort, commandUnmarshalled.SourcePort)
|
||||
}
|
||||
|
||||
if commandInput.DestPort != commandUnmarshalled.DestPort {
|
||||
t.Fail()
|
||||
log.Printf("DestPort's are not equal (orig: %d, unmsh: %d)", commandInput.DestPort, commandUnmarshalled.DestPort)
|
||||
}
|
||||
|
||||
if commandInput.Protocol != commandUnmarshalled.Protocol {
|
||||
t.Fail()
|
||||
log.Printf("Protocols are not equal (orig: %s, unmsh: %s)", commandInput.Protocol, commandUnmarshalled.Protocol)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyInformationResponseNoExist(t *testing.T) {
|
||||
commandInput := &ProxyInformationResponse{
|
||||
Type: "proxyInformationResponse",
|
||||
Exists: false,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyInformationResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.Exists != commandUnmarshalled.Exists {
|
||||
t.Fail()
|
||||
log.Printf("Exists's are not equal (orig: '%t', unmsh: '%t')", commandInput.Exists, commandUnmarshalled.Exists)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyConnectionInformationRequest(t *testing.T) {
|
||||
commandInput := &ProxyConnectionInformationRequest{
|
||||
Type: "proxyConnectionInformationRequest",
|
||||
ProxyID: 19132,
|
||||
ConnectionID: 25565,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyConnectionInformationRequest)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.ProxyID != commandUnmarshalled.ProxyID {
|
||||
t.Fail()
|
||||
log.Printf("ProxyID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ProxyID, commandUnmarshalled.ProxyID)
|
||||
}
|
||||
|
||||
if commandInput.ConnectionID != commandUnmarshalled.ConnectionID {
|
||||
t.Fail()
|
||||
log.Printf("ConnectionID's are not equal (orig: '%d', unmsh: '%d')", commandInput.ConnectionID, commandUnmarshalled.ConnectionID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyConnectionInformationResponseExists(t *testing.T) {
|
||||
commandInput := &ProxyConnectionInformationResponse{
|
||||
Type: "proxyConnectionInformationResponse",
|
||||
Exists: true,
|
||||
ClientIP: "192.168.0.139",
|
||||
ClientPort: 19132,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyConnectionInformationResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.Exists != commandUnmarshalled.Exists {
|
||||
t.Fail()
|
||||
log.Printf("Exists's are not equal (orig: '%t', unmsh: '%t')", commandInput.Exists, commandUnmarshalled.Exists)
|
||||
}
|
||||
|
||||
if commandInput.ClientIP != commandUnmarshalled.ClientIP {
|
||||
t.Fail()
|
||||
log.Printf("SourceIP's are not equal (orig: %s, unmsh: %s)", commandInput.ClientIP, commandUnmarshalled.ClientIP)
|
||||
}
|
||||
|
||||
if commandInput.ClientPort != commandUnmarshalled.ClientPort {
|
||||
t.Fail()
|
||||
log.Printf("ClientPort's are not equal (orig: %d, unmsh: %d)", commandInput.ClientPort, commandUnmarshalled.ClientPort)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProxyConnectionInformationResponseNoExists(t *testing.T) {
|
||||
commandInput := &ProxyConnectionInformationResponse{
|
||||
Type: "proxyConnectionInformationResponse",
|
||||
Exists: false,
|
||||
}
|
||||
|
||||
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if logLevel == "debug" {
|
||||
log.Printf("Generated array contents: %v", commandMarshalled)
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(commandMarshalled)
|
||||
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if commandType != commandInput.Type {
|
||||
t.Fail()
|
||||
log.Print("command type does not match up!")
|
||||
}
|
||||
|
||||
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyConnectionInformationResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("failed typecast")
|
||||
}
|
||||
|
||||
if commandInput.Type != commandUnmarshalled.Type {
|
||||
t.Fail()
|
||||
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
|
||||
}
|
||||
|
||||
if commandInput.Exists != commandUnmarshalled.Exists {
|
||||
t.Fail()
|
||||
log.Printf("Exists's are not equal (orig: '%t', unmsh: '%t')", commandInput.Exists, commandUnmarshalled.Exists)
|
||||
}
|
||||
}
|
435
backend/sshappbackend/datacommands/unmarshal.go
Normal file
435
backend/sshappbackend/datacommands/unmarshal.go
Normal file
|
@ -0,0 +1,435 @@
|
|||
package datacommands
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
)
|
||||
|
||||
// Unmarshal reads from the provided connection and returns
|
||||
// the message type (as a string), the unmarshalled struct, or an error.
|
||||
func Unmarshal(conn io.Reader) (string, interface{}, error) {
|
||||
// Every command starts with a 1-byte command ID.
|
||||
header := make([]byte, 1)
|
||||
if _, err := io.ReadFull(conn, header); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read command ID: %w", err)
|
||||
}
|
||||
|
||||
cmdID := header[0]
|
||||
switch cmdID {
|
||||
// ProxyStatusRequest: 1 byte ID + 2 bytes ProxyID.
|
||||
case ProxyStatusRequestID:
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyStatusRequest ProxyID: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf)
|
||||
|
||||
return "proxyStatusRequest", &ProxyStatusRequest{
|
||||
Type: "proxyStatusRequest",
|
||||
ProxyID: proxyID,
|
||||
}, nil
|
||||
|
||||
// ProxyStatusResponse: 1 byte ID + 2 bytes ProxyID + 1 byte IsActive.
|
||||
case ProxyStatusResponseID:
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyStatusResponse ProxyID: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf)
|
||||
boolBuf := make([]byte, 1)
|
||||
|
||||
if _, err := io.ReadFull(conn, boolBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyStatusResponse IsActive: %w", err)
|
||||
}
|
||||
|
||||
isActive := boolBuf[0] != 0
|
||||
|
||||
return "proxyStatusResponse", &ProxyStatusResponse{
|
||||
Type: "proxyStatusResponse",
|
||||
ProxyID: proxyID,
|
||||
IsActive: isActive,
|
||||
}, nil
|
||||
|
||||
// RemoveProxy: 1 byte ID + 2 bytes ProxyID.
|
||||
case RemoveProxyID:
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read RemoveProxy ProxyID: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf)
|
||||
|
||||
return "removeProxy", &RemoveProxy{
|
||||
Type: "removeProxy",
|
||||
ProxyID: proxyID,
|
||||
}, nil
|
||||
|
||||
// ProxyConnectionsRequest: 1 byte ID + 2 bytes ProxyID.
|
||||
case ProxyConnectionsRequestID:
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionsRequest ProxyID: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf)
|
||||
|
||||
return "proxyConnectionsRequest", &ProxyConnectionsRequest{
|
||||
Type: "proxyConnectionsRequest",
|
||||
ProxyID: proxyID,
|
||||
}, nil
|
||||
|
||||
// ProxyConnectionsResponse: 1 byte ID + 2 bytes Connections length + 2 bytes for each Connection in Connections.
|
||||
case ProxyConnectionsResponseID:
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionsResponse length: %w", err)
|
||||
}
|
||||
|
||||
length := binary.BigEndian.Uint16(buf)
|
||||
connections := make([]uint16, length)
|
||||
|
||||
var failedDuringReading error
|
||||
|
||||
for connectionIndex := range connections {
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
failedDuringReading = fmt.Errorf("couldn't read ProxyConnectionsResponse with position of %d: %w", connectionIndex, err)
|
||||
break
|
||||
}
|
||||
|
||||
connections[connectionIndex] = binary.BigEndian.Uint16(buf)
|
||||
}
|
||||
|
||||
return "proxyConnectionsResponse", &ProxyConnectionsResponse{
|
||||
Type: "proxyConnectionsResponse",
|
||||
Connections: connections,
|
||||
}, failedDuringReading
|
||||
|
||||
// ProxyInstanceResponse: 1 byte ID + 2 bytes Proxies length + 2 bytes for each Proxy in Proxies.
|
||||
case ProxyInstanceResponseID:
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionsResponse length: %w", err)
|
||||
}
|
||||
|
||||
length := binary.BigEndian.Uint16(buf)
|
||||
proxies := make([]uint16, length)
|
||||
|
||||
var failedDuringReading error
|
||||
|
||||
for connectionIndex := range proxies {
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
failedDuringReading = fmt.Errorf("couldn't read ProxyConnectionsResponse with position of %d: %w", connectionIndex, err)
|
||||
break
|
||||
}
|
||||
|
||||
proxies[connectionIndex] = binary.BigEndian.Uint16(buf)
|
||||
}
|
||||
|
||||
return "proxyInstanceResponse", &ProxyInstanceResponse{
|
||||
Type: "proxyInstanceResponse",
|
||||
Proxies: proxies,
|
||||
}, failedDuringReading
|
||||
|
||||
// TCPConnectionOpened: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID.
|
||||
case TCPConnectionOpenedID:
|
||||
buf := make([]byte, 2+2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read TCPConnectionOpened fields: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf[0:2])
|
||||
connectionID := binary.BigEndian.Uint16(buf[2:4])
|
||||
|
||||
return "tcpConnectionOpened", &TCPConnectionOpened{
|
||||
Type: "tcpConnectionOpened",
|
||||
ProxyID: proxyID,
|
||||
ConnectionID: connectionID,
|
||||
}, nil
|
||||
|
||||
// TCPConnectionClosed: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID.
|
||||
case TCPConnectionClosedID:
|
||||
buf := make([]byte, 2+2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read TCPConnectionClosed fields: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf[0:2])
|
||||
connectionID := binary.BigEndian.Uint16(buf[2:4])
|
||||
|
||||
return "tcpConnectionClosed", &TCPConnectionClosed{
|
||||
Type: "tcpConnectionClosed",
|
||||
ProxyID: proxyID,
|
||||
ConnectionID: connectionID,
|
||||
}, nil
|
||||
|
||||
// TCPProxyData: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID + 2 bytes DataLength.
|
||||
case TCPProxyDataID:
|
||||
buf := make([]byte, 2+2+2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read TCPProxyData fields: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf[0:2])
|
||||
connectionID := binary.BigEndian.Uint16(buf[2:4])
|
||||
dataLength := binary.BigEndian.Uint16(buf[4:6])
|
||||
|
||||
return "tcpProxyData", &TCPProxyData{
|
||||
Type: "tcpProxyData",
|
||||
ProxyID: proxyID,
|
||||
ConnectionID: connectionID,
|
||||
DataLength: dataLength,
|
||||
}, nil
|
||||
|
||||
// UDPProxyData:
|
||||
// Format: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID +
|
||||
// 1 byte IP version + IP bytes + 2 bytes ClientPort + 2 bytes DataLength.
|
||||
case UDPProxyDataID:
|
||||
// Read 2 bytes ProxyID + 2 bytes ConnectionID.
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read UDPProxyData ProxyID/ConnectionID: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf)
|
||||
|
||||
// Read IP version.
|
||||
ipVerBuf := make([]byte, 1)
|
||||
|
||||
if _, err := io.ReadFull(conn, ipVerBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read UDPProxyData IP version: %w", err)
|
||||
}
|
||||
|
||||
var ipSize int
|
||||
|
||||
if ipVerBuf[0] == 4 {
|
||||
ipSize = IPv4Size
|
||||
} else if ipVerBuf[0] == 6 {
|
||||
ipSize = IPv6Size
|
||||
} else {
|
||||
return "", nil, fmt.Errorf("invalid IP version received: %v", ipVerBuf[0])
|
||||
}
|
||||
|
||||
// Read the IP bytes.
|
||||
ipBytes := make([]byte, ipSize)
|
||||
if _, err := io.ReadFull(conn, ipBytes); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read UDPProxyData IP bytes: %w", err)
|
||||
}
|
||||
clientIP := net.IP(ipBytes).String()
|
||||
|
||||
// Read ClientPort.
|
||||
portBuf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, portBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read UDPProxyData ClientPort: %w", err)
|
||||
}
|
||||
|
||||
clientPort := binary.BigEndian.Uint16(portBuf)
|
||||
|
||||
// Read DataLength.
|
||||
dataLengthBuf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, dataLengthBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read UDPProxyData DataLength: %w", err)
|
||||
}
|
||||
|
||||
dataLength := binary.BigEndian.Uint16(dataLengthBuf)
|
||||
|
||||
return "udpProxyData", &UDPProxyData{
|
||||
Type: "udpProxyData",
|
||||
ProxyID: proxyID,
|
||||
ClientIP: clientIP,
|
||||
ClientPort: clientPort,
|
||||
DataLength: dataLength,
|
||||
}, nil
|
||||
|
||||
// ProxyInformationRequest: 1 byte ID + 2 bytes ProxyID.
|
||||
case ProxyInformationRequestID:
|
||||
buf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyInformationRequest ProxyID: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf)
|
||||
|
||||
return "proxyInformationRequest", &ProxyInformationRequest{
|
||||
Type: "proxyInformationRequest",
|
||||
ProxyID: proxyID,
|
||||
}, nil
|
||||
|
||||
// ProxyInformationResponse:
|
||||
// Format: 1 byte ID + 1 byte Exists +
|
||||
// 1 byte IP version + IP bytes + 2 bytes SourcePort + 2 bytes DestPort + 1 byte Protocol.
|
||||
case ProxyInformationResponseID:
|
||||
// Read Exists flag.
|
||||
boolBuf := make([]byte, 1)
|
||||
|
||||
if _, err := io.ReadFull(conn, boolBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyInformationResponse Exists flag: %w", err)
|
||||
}
|
||||
|
||||
exists := boolBuf[0] != 0
|
||||
|
||||
if !exists {
|
||||
return "proxyInformationResponse", &ProxyInformationResponse{
|
||||
Type: "proxyInformationResponse",
|
||||
Exists: exists,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Read IP version.
|
||||
ipVerBuf := make([]byte, 1)
|
||||
|
||||
if _, err := io.ReadFull(conn, ipVerBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyInformationResponse IP version: %w", err)
|
||||
}
|
||||
|
||||
var ipSize int
|
||||
|
||||
if ipVerBuf[0] == 4 {
|
||||
ipSize = IPv4Size
|
||||
} else if ipVerBuf[0] == 6 {
|
||||
ipSize = IPv6Size
|
||||
} else {
|
||||
return "", nil, fmt.Errorf("invalid IP version in ProxyInformationResponse: %v", ipVerBuf[0])
|
||||
}
|
||||
|
||||
// Read the source IP bytes.
|
||||
ipBytes := make([]byte, ipSize)
|
||||
|
||||
if _, err := io.ReadFull(conn, ipBytes); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyInformationResponse IP bytes: %w", err)
|
||||
}
|
||||
|
||||
sourceIP := net.IP(ipBytes).String()
|
||||
|
||||
// Read SourcePort and DestPort.
|
||||
portsBuf := make([]byte, 2+2)
|
||||
|
||||
if _, err := io.ReadFull(conn, portsBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyInformationResponse ports: %w", err)
|
||||
}
|
||||
|
||||
sourcePort := binary.BigEndian.Uint16(portsBuf[0:2])
|
||||
destPort := binary.BigEndian.Uint16(portsBuf[2:4])
|
||||
|
||||
// Read protocol.
|
||||
protoBuf := make([]byte, 1)
|
||||
|
||||
if _, err := io.ReadFull(conn, protoBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyInformationResponse protocol: %w", err)
|
||||
}
|
||||
var protocol string
|
||||
if protoBuf[0] == TCP {
|
||||
protocol = "tcp"
|
||||
} else if protoBuf[0] == UDP {
|
||||
protocol = "udp"
|
||||
} else {
|
||||
return "", nil, fmt.Errorf("invalid protocol value in ProxyInformationResponse: %d", protoBuf[0])
|
||||
}
|
||||
|
||||
return "proxyInformationResponse", &ProxyInformationResponse{
|
||||
Type: "proxyInformationResponse",
|
||||
Exists: exists,
|
||||
SourceIP: sourceIP,
|
||||
SourcePort: sourcePort,
|
||||
DestPort: destPort,
|
||||
Protocol: protocol,
|
||||
}, nil
|
||||
|
||||
// ProxyConnectionInformationRequest: 1 byte ID + 2 bytes ProxyID + 2 bytes ConnectionID.
|
||||
case ProxyConnectionInformationRequestID:
|
||||
buf := make([]byte, 2+2)
|
||||
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionInformationRequest fields: %w", err)
|
||||
}
|
||||
|
||||
proxyID := binary.BigEndian.Uint16(buf[0:2])
|
||||
connectionID := binary.BigEndian.Uint16(buf[2:4])
|
||||
|
||||
return "proxyConnectionInformationRequest", &ProxyConnectionInformationRequest{
|
||||
Type: "proxyConnectionInformationRequest",
|
||||
ProxyID: proxyID,
|
||||
ConnectionID: connectionID,
|
||||
}, nil
|
||||
|
||||
// ProxyConnectionInformationResponse:
|
||||
// Format: 1 byte ID + 1 byte Exists + 1 byte IP version + IP bytes + 2 bytes ClientPort.
|
||||
case ProxyConnectionInformationResponseID:
|
||||
// Read Exists flag.
|
||||
boolBuf := make([]byte, 1)
|
||||
if _, err := io.ReadFull(conn, boolBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionInformationResponse Exists flag: %w", err)
|
||||
}
|
||||
|
||||
exists := boolBuf[0] != 0
|
||||
|
||||
if !exists {
|
||||
return "proxyConnectionInformationResponse", &ProxyConnectionInformationResponse{
|
||||
Type: "proxyConnectionInformationResponse",
|
||||
Exists: exists,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Read IP version.
|
||||
ipVerBuf := make([]byte, 1)
|
||||
|
||||
if _, err := io.ReadFull(conn, ipVerBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionInformationResponse IP version: %w", err)
|
||||
}
|
||||
|
||||
if ipVerBuf[0] != 4 && ipVerBuf[0] != 6 {
|
||||
return "", nil, fmt.Errorf("invalid IP version in ProxyConnectionInformationResponse: %v", ipVerBuf[0])
|
||||
}
|
||||
|
||||
var ipSize int
|
||||
|
||||
if ipVerBuf[0] == 4 {
|
||||
ipSize = IPv4Size
|
||||
} else {
|
||||
ipSize = IPv6Size
|
||||
}
|
||||
|
||||
// Read IP bytes.
|
||||
ipBytes := make([]byte, ipSize)
|
||||
|
||||
if _, err := io.ReadFull(conn, ipBytes); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionInformationResponse IP bytes: %w", err)
|
||||
}
|
||||
|
||||
clientIP := net.IP(ipBytes).String()
|
||||
|
||||
// Read ClientPort.
|
||||
portBuf := make([]byte, 2)
|
||||
|
||||
if _, err := io.ReadFull(conn, portBuf); err != nil {
|
||||
return "", nil, fmt.Errorf("couldn't read ProxyConnectionInformationResponse ClientPort: %w", err)
|
||||
}
|
||||
|
||||
clientPort := binary.BigEndian.Uint16(portBuf)
|
||||
|
||||
return "proxyConnectionInformationResponse", &ProxyConnectionInformationResponse{
|
||||
Type: "proxyConnectionInformationResponse",
|
||||
Exists: exists,
|
||||
ClientIP: clientIP,
|
||||
ClientPort: clientPort,
|
||||
}, nil
|
||||
default:
|
||||
return "", nil, fmt.Errorf("unknown command id: %v", cmdID)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue