Refactored Protocol.Name -> Protocol.Type; added Encapsulation field Refactored TLS parsing; added support for ALPN
142 lines
3.0 KiB
Go
142 lines
3.0 KiB
Go
package protocol
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestDetectHTTPRequest(t *testing.T) {
|
|
atomicFormats.Store([]format{{Client, "", detectHTTPRequest}})
|
|
|
|
// A valid HTTP/1.0 GET request
|
|
http10Request := []byte("GET /old-page.html HTTP/1.0\r\nUser-Agent: NCSA_Mosaic/1.0\r\n\r\n")
|
|
|
|
// A valid HTTP/1.1 GET request
|
|
getRequest := []byte("GET /resource/item?id=123 HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
|
|
|
// An invalid HTTP request
|
|
sshBanner := []byte("SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4\r\n")
|
|
|
|
tests := []*testCase{
|
|
{
|
|
Name: "HTTP/1.0 GET",
|
|
Direction: Client,
|
|
Data: http10Request,
|
|
DstPort: 80,
|
|
WantType: TypeHTTP,
|
|
WantConfidence: .95,
|
|
},
|
|
{
|
|
Name: "HTTP/1.1 GET",
|
|
Direction: Client,
|
|
Data: getRequest,
|
|
DstPort: 80,
|
|
WantType: TypeHTTP,
|
|
WantConfidence: .95,
|
|
},
|
|
{
|
|
Name: "Invalid SSH",
|
|
Direction: Client,
|
|
Data: sshBanner,
|
|
DstPort: 80,
|
|
WantError: ErrUnknown,
|
|
},
|
|
}
|
|
|
|
defer func() { Strict = false }()
|
|
for _, strict := range []bool{false, true} {
|
|
Strict = strict
|
|
|
|
name := "loose"
|
|
if strict {
|
|
name = "strict"
|
|
}
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
testRunner(t, tests)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDetectHTTPResponse(t *testing.T) {
|
|
atomicFormats.Store([]format{{Server, "HTTP/?.? ", detectHTTPResponse}})
|
|
|
|
// A valid HTTP/1.0 403 Forbidden response
|
|
http10Response := []byte("HTTP/1.0 403 Forbidden\r\nServer: CERN/3.0\r\n\r\n")
|
|
|
|
// A valid HTTP/1.1 200 OK response
|
|
responseOK := []byte("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html>...</html>")
|
|
|
|
// A valid HTTP/1.1 404 Not Found response
|
|
responseNotFound := []byte("HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n")
|
|
|
|
// An invalid HTTP GET request
|
|
getRequest := []byte("GET /resource/item?id=123 HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
|
|
|
// An invalid banner (SSH)
|
|
sshBanner := []byte("SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4\r\n")
|
|
|
|
tests := []*testCase{
|
|
{
|
|
Name: "HTTP/1.0 403",
|
|
Direction: Server,
|
|
Data: http10Response,
|
|
SrcPort: 80,
|
|
WantType: TypeHTTP,
|
|
},
|
|
{
|
|
Name: "HTTP/1.1 200",
|
|
Direction: Server,
|
|
Data: responseOK,
|
|
SrcPort: 80,
|
|
WantType: TypeHTTP,
|
|
},
|
|
{
|
|
Name: "HTTP/1.1 404",
|
|
Direction: Server,
|
|
Data: responseNotFound,
|
|
SrcPort: 80,
|
|
WantType: TypeHTTP,
|
|
},
|
|
{
|
|
Name: "Invalid HTTP/1.1 GET",
|
|
Direction: Server,
|
|
Data: getRequest,
|
|
SrcPort: 80,
|
|
WantError: ErrUnknown,
|
|
},
|
|
{
|
|
Name: "Invalid SSH",
|
|
Direction: Server,
|
|
Data: sshBanner,
|
|
SrcPort: 80,
|
|
WantError: ErrUnknown,
|
|
},
|
|
}
|
|
|
|
defer func() { Strict = false }()
|
|
for _, strict := range []bool{false, true} {
|
|
Strict = strict
|
|
|
|
var name string
|
|
if strict {
|
|
name = "strict"
|
|
for _, test := range tests {
|
|
if test.WantError == nil {
|
|
test.WantConfidence = .95
|
|
}
|
|
}
|
|
} else {
|
|
name = "loose"
|
|
for _, test := range tests {
|
|
if test.WantError == nil {
|
|
test.WantConfidence = .85
|
|
}
|
|
}
|
|
}
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
testRunner(t, tests)
|
|
})
|
|
}
|
|
}
|