gost/tls_test.go
2022-08-03 10:04:41 +08:00

811 lines
16 KiB
Go

package gost
import (
"crypto/rand"
"crypto/tls"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func httpOverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := TLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
err := httpOverTLSRoundtrip(httpSrv.URL, sendData, nil, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
}
}
func BenchmarkHTTPOverTLS(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := TLSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
go server.Run()
defer server.Close()
for i := 0; i < b.N; i++ {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
}
func BenchmarkHTTPOverTLSParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := TLSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
go server.Run()
defer server.Close()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
})
}
func socks5OverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := TLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
err := socks5OverTLSRoundtrip(httpSrv.URL, sendData,
nil,
tc.cliUser,
tc.srvUsers,
)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
}
}
func socks4OverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := TLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := TLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := TLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
err := ssOverTLSRoundtrip(httpSrv.URL, sendData,
nil,
tc.clientCipher,
tc.serverCipher,
)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
}
}
func sniOverTLSRoundtrip(targetURL string, data []byte, host string) error {
ln, err := TLSListener("", nil)
if err != nil {
return err
}
u, err := url.Parse(targetURL)
if err != nil {
return err
}
client := &Client{
Connector: SNIConnector(host),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SNIHandler(HostHandlerOption(u.Host)),
}
go server.Run()
defer server.Close()
return sniRoundtrip(client, server, targetURL, data)
}
func TestSNIOverTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
httpsSrv := httptest.NewTLSServer(httpTestHandler)
defer httpsSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
var sniProxyTests = []struct {
targetURL string
host string
pass bool
}{
{httpSrv.URL, "", true},
{httpSrv.URL, "example.com", true},
{httpsSrv.URL, "", true},
{httpsSrv.URL, "example.com", true},
}
for i, tc := range sniProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := sniOverTLSRoundtrip(tc.targetURL, sendData, tc.host)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
})
}
}
func tlsForwardTunnelRoundtrip(targetURL string, data []byte) error {
ln, err := TLSListener("", nil)
if err != nil {
return err
}
u, err := url.Parse(targetURL)
if err != nil {
return err
}
client := &Client{
Connector: ForwardConnector(),
Transporter: TLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: TCPDirectForwardHandler(u.Host),
}
server.Handler.Init()
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestTLSForwardTunnel(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := tlsForwardTunnelRoundtrip(httpSrv.URL, sendData)
if err != nil {
t.Error(err)
}
}
func httpOverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
err := httpOverMTLSRoundtrip(httpSrv.URL, sendData, nil, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
}
}
func BenchmarkHTTPOverMTLS(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MTLSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
go server.Run()
defer server.Close()
for i := 0; i < b.N; i++ {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
}
func BenchmarkHTTPOverMTLSParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MTLSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
go server.Run()
defer server.Close()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
b.Error(err)
}
}
})
}
func socks5OverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
err := socks5OverMTLSRoundtrip(httpSrv.URL, sendData,
nil,
tc.cliUser,
tc.srvUsers,
)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
}
}
func socks4OverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverMTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverMTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
err := ssOverMTLSRoundtrip(httpSrv.URL, sendData,
nil,
tc.clientCipher,
tc.serverCipher,
)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
}
}
func sniOverMTLSRoundtrip(targetURL string, data []byte, host string) error {
ln, err := MTLSListener("", nil)
if err != nil {
return err
}
u, err := url.Parse(targetURL)
if err != nil {
return err
}
client := &Client{
Connector: SNIConnector(host),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SNIHandler(HostHandlerOption(u.Host)),
}
go server.Run()
defer server.Close()
return sniRoundtrip(client, server, targetURL, data)
}
func TestSNIOverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
httpsSrv := httptest.NewTLSServer(httpTestHandler)
defer httpsSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
var sniProxyTests = []struct {
targetURL string
host string
pass bool
}{
{httpSrv.URL, "", true},
{httpSrv.URL, "example.com", true},
{httpsSrv.URL, "", true},
{httpsSrv.URL, "example.com", true},
}
for i, tc := range sniProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := sniOverMTLSRoundtrip(tc.targetURL, sendData, tc.host)
if err == nil {
if !tc.pass {
t.Errorf("#%d should failed", i)
}
} else {
// t.Logf("#%d %v", i, err)
if tc.pass {
t.Errorf("#%d got error: %v", i, err)
}
}
})
}
}
func mtlsForwardTunnelRoundtrip(targetURL string, data []byte) error {
ln, err := MTLSListener("", nil)
if err != nil {
return err
}
u, err := url.Parse(targetURL)
if err != nil {
return err
}
client := &Client{
Connector: ForwardConnector(),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: TCPDirectForwardHandler(u.Host),
}
server.Handler.Init()
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestMTLSForwardTunnel(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := mtlsForwardTunnelRoundtrip(httpSrv.URL, sendData)
if err != nil {
t.Error(err)
}
}