mirror of https://github.com/ginuerzh/gost
7 changed files with 1332 additions and 66 deletions
@ -0,0 +1,105 @@ |
|||
package gost |
|||
|
|||
import ( |
|||
"bufio" |
|||
"bytes" |
|||
"crypto/rand" |
|||
"crypto/tls" |
|||
"errors" |
|||
"net/http" |
|||
"net/http/httptest" |
|||
"net/url" |
|||
"testing" |
|||
"time" |
|||
) |
|||
|
|||
func sniRoundtrip(client *Client, server *Server, targetURL string, data []byte) (err error) { |
|||
conn, err := client.Dial(server.Addr().String()) |
|||
if err != nil { |
|||
return |
|||
} |
|||
defer conn.Close() |
|||
|
|||
conn.SetDeadline(time.Now().Add(3 * time.Second)) |
|||
|
|||
conn, err = client.Handshake(conn) |
|||
if err != nil { |
|||
return |
|||
} |
|||
u, err := url.Parse(targetURL) |
|||
if err != nil { |
|||
return |
|||
} |
|||
conn, err = client.Connect(conn, u.Host) |
|||
if err != nil { |
|||
return |
|||
} |
|||
|
|||
if u.Scheme == "https" { |
|||
conn = tls.Client(conn, |
|||
&tls.Config{ |
|||
InsecureSkipVerify: false, |
|||
ServerName: u.Hostname(), |
|||
}) |
|||
u.Scheme = "http" |
|||
} |
|||
req, err := http.NewRequest( |
|||
http.MethodGet, |
|||
u.String(), |
|||
bytes.NewReader(data), |
|||
) |
|||
if err != nil { |
|||
return |
|||
} |
|||
if err = req.Write(conn); err != nil { |
|||
return |
|||
} |
|||
resp, err := http.ReadResponse(bufio.NewReader(conn), req) |
|||
if err != nil { |
|||
return |
|||
} |
|||
defer resp.Body.Close() |
|||
|
|||
if resp.StatusCode != http.StatusOK { |
|||
return errors.New(resp.Status) |
|||
} |
|||
|
|||
return |
|||
} |
|||
|
|||
func sniProxyRoundtrip(targetURL string, data []byte, host string) error { |
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SNIConnector(host), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Listener: ln, |
|||
Handler: SNIHandler(), |
|||
} |
|||
|
|||
go server.Run() |
|||
defer server.Close() |
|||
|
|||
return sniRoundtrip(client, server, targetURL, data) |
|||
} |
|||
|
|||
func TestSNIProxy(t *testing.T) { |
|||
// SetLogger(&LogLogger{})
|
|||
// Debug = true
|
|||
httpSrv := httptest.NewTLSServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
err := sniProxyRoundtrip("https://github.com", sendData, "google.com") |
|||
if err != nil { |
|||
t.Errorf("got error: %v", err) |
|||
} |
|||
} |
|||
@ -0,0 +1,371 @@ |
|||
package gost |
|||
|
|||
import ( |
|||
"crypto/rand" |
|||
"crypto/tls" |
|||
"fmt" |
|||
"net/http/httptest" |
|||
"net/url" |
|||
"testing" |
|||
) |
|||
|
|||
var socks5ProxyTests = []struct { |
|||
cliUser *url.Userinfo |
|||
srvUsers []*url.Userinfo |
|||
pass bool |
|||
}{ |
|||
{nil, nil, true}, |
|||
{nil, []*url.Userinfo{url.User("admin")}, false}, |
|||
{nil, []*url.Userinfo{url.UserPassword("", "123456")}, false}, |
|||
{url.User("admin"), []*url.Userinfo{url.User("test")}, false}, |
|||
{url.User("admin"), []*url.Userinfo{url.UserPassword("admin", "123456")}, false}, |
|||
{url.User("admin"), []*url.Userinfo{url.User("admin")}, true}, |
|||
{url.User("admin"), []*url.Userinfo{url.UserPassword("admin", "")}, true}, |
|||
{url.UserPassword("admin", "123456"), nil, true}, |
|||
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.User("admin")}, true}, |
|||
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("", "123456")}, true}, |
|||
{url.UserPassword("", "123456"), []*url.Userinfo{url.UserPassword("", "123456")}, true}, |
|||
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("admin", "123456")}, true}, |
|||
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("user", "pass"), url.UserPassword("admin", "123456")}, true}, |
|||
} |
|||
|
|||
func socks5ProxyRoundtrip(targetURL string, data []byte, clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error { |
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS5Connector(clientInfo), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: SOCKS5Handler(UsersHandlerOption(serverInfo...)), |
|||
Listener: ln, |
|||
} |
|||
|
|||
go server.Run() |
|||
defer server.Close() |
|||
|
|||
return proxyRoundtrip(client, server, targetURL, data) |
|||
} |
|||
|
|||
func TestSOCKS5Proxy(t *testing.T) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
DefaultTLSConfig = &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
for i, tc := range socks5ProxyTests { |
|||
tc := tc |
|||
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { |
|||
err := socks5ProxyRoundtrip(httpSrv.URL, sendData, |
|||
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 BenchmarkSOCKS5Proxy(b *testing.B) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
DefaultTLSConfig = &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS5Connector(url.UserPassword("admin", "123456")), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))), |
|||
Listener: ln, |
|||
} |
|||
|
|||
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 BenchmarkSOCKS5ProxyParallel(b *testing.B) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
DefaultTLSConfig = &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS5Connector(url.UserPassword("admin", "123456")), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))), |
|||
Listener: ln, |
|||
} |
|||
|
|||
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 socks4ProxyRoundtrip(targetURL string, data []byte) error { |
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS4Connector(), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Listener: ln, |
|||
Handler: SOCKS4Handler(), |
|||
} |
|||
go server.Run() |
|||
defer server.Close() |
|||
|
|||
return proxyRoundtrip(client, server, targetURL, data) |
|||
} |
|||
|
|||
func TestSOCKS4Proxy(t *testing.T) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
err := socks4ProxyRoundtrip(httpSrv.URL, sendData) |
|||
// t.Logf("#%d %v", i, err)
|
|||
if err != nil { |
|||
t.Errorf("got error: %v", err) |
|||
} |
|||
} |
|||
|
|||
func BenchmarkSOCKS4Proxy(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS4Connector(), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Listener: ln, |
|||
Handler: SOCKS4Handler(), |
|||
} |
|||
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 BenchmarkSOCKS4ProxyParallel(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS4Connector(), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Listener: ln, |
|||
Handler: SOCKS4Handler(), |
|||
} |
|||
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 socks4aProxyRoundtrip(targetURL string, data []byte) error { |
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS4AConnector(), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Listener: ln, |
|||
Handler: SOCKS4Handler(), |
|||
} |
|||
|
|||
go server.Run() |
|||
defer server.Close() |
|||
|
|||
return proxyRoundtrip(client, server, targetURL, data) |
|||
} |
|||
|
|||
func TestSOCKS4AProxy(t *testing.T) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
err := socks4aProxyRoundtrip(httpSrv.URL, sendData) |
|||
// t.Logf("#%d %v", i, err)
|
|||
if err != nil { |
|||
t.Errorf("got error: %v", err) |
|||
} |
|||
} |
|||
|
|||
func BenchmarkSOCKS4AProxy(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS4AConnector(), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Listener: ln, |
|||
Handler: SOCKS4Handler(), |
|||
} |
|||
|
|||
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 BenchmarkSOCKS4AProxyParallel(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: SOCKS4AConnector(), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Listener: ln, |
|||
Handler: SOCKS4Handler(), |
|||
} |
|||
|
|||
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) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
@ -0,0 +1,314 @@ |
|||
package gost |
|||
|
|||
import ( |
|||
"crypto/rand" |
|||
"fmt" |
|||
"net/http/httptest" |
|||
"net/url" |
|||
"testing" |
|||
) |
|||
|
|||
var ssProxyTests = []struct { |
|||
clientCipher *url.Userinfo |
|||
serverCipher *url.Userinfo |
|||
pass bool |
|||
}{ |
|||
{nil, nil, false}, |
|||
{&url.Userinfo{}, &url.Userinfo{}, false}, |
|||
{url.User("abc"), url.User("abc"), false}, |
|||
{url.UserPassword("abc", "def"), url.UserPassword("abc", "def"), false}, |
|||
|
|||
{url.User("aes-128-cfb"), url.User("aes-128-cfb"), false}, |
|||
{url.User("aes-128-cfb"), url.UserPassword("aes-128-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.User("aes-128-cfb"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "abc"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), true}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("chacha20", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false}, |
|||
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("salsa20", "123456"), false}, |
|||
|
|||
{url.User("aes-192-cfb"), url.User("aes-192-cfb"), false}, |
|||
{url.User("aes-192-cfb"), url.UserPassword("aes-192-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.User("aes-192-cfb"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-192-cfb", "abc"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), true}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("chacha20", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false}, |
|||
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("salsa20", "123456"), false}, |
|||
|
|||
{url.User("aes-256-cfb"), url.User("aes-256-cfb"), false}, |
|||
{url.User("aes-256-cfb"), url.UserPassword("aes-256-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.User("aes-256-cfb"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-256-cfb", "abc"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), true}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("chacha20", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false}, |
|||
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("salsa20", "123456"), false}, |
|||
|
|||
{url.User("aes-128-ctr"), url.User("aes-128-ctr"), false}, |
|||
{url.User("aes-128-ctr"), url.UserPassword("aes-128-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-128-ctr", "123456"), url.User("aes-128-ctr"), false}, |
|||
{url.UserPassword("aes-128-ctr", "123456"), url.UserPassword("aes-128-ctr", "abc"), false}, |
|||
{url.UserPassword("aes-128-ctr", "123456"), url.UserPassword("aes-128-ctr", "123456"), true}, |
|||
|
|||
{url.User("aes-192-ctr"), url.User("aes-192-ctr"), false}, |
|||
{url.User("aes-192-ctr"), url.UserPassword("aes-192-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-192-ctr", "123456"), url.User("aes-192-ctr"), false}, |
|||
{url.UserPassword("aes-192-ctr", "123456"), url.UserPassword("aes-192-ctr", "abc"), false}, |
|||
{url.UserPassword("aes-192-ctr", "123456"), url.UserPassword("aes-192-ctr", "123456"), true}, |
|||
|
|||
{url.User("aes-256-ctr"), url.User("aes-256-ctr"), false}, |
|||
{url.User("aes-256-ctr"), url.UserPassword("aes-256-ctr", "123456"), false}, |
|||
{url.UserPassword("aes-256-ctr", "123456"), url.User("aes-256-ctr"), false}, |
|||
{url.UserPassword("aes-256-ctr", "123456"), url.UserPassword("aes-256-ctr", "abc"), false}, |
|||
{url.UserPassword("aes-256-ctr", "123456"), url.UserPassword("aes-256-ctr", "123456"), true}, |
|||
|
|||
{url.User("des-cfb"), url.User("des-cfb"), false}, |
|||
{url.User("des-cfb"), url.UserPassword("des-cfb", "123456"), false}, |
|||
{url.UserPassword("des-cfb", "123456"), url.User("des-cfb"), false}, |
|||
{url.UserPassword("des-cfb", "123456"), url.UserPassword("des-cfb", "abc"), false}, |
|||
{url.UserPassword("des-cfb", "123456"), url.UserPassword("des-cfb", "123456"), true}, |
|||
|
|||
{url.User("bf-cfb"), url.User("bf-cfb"), false}, |
|||
{url.User("bf-cfb"), url.UserPassword("bf-cfb", "123456"), false}, |
|||
{url.UserPassword("bf-cfb", "123456"), url.User("bf-cfb"), false}, |
|||
{url.UserPassword("bf-cfb", "123456"), url.UserPassword("bf-cfb", "abc"), false}, |
|||
{url.UserPassword("bf-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), true}, |
|||
|
|||
{url.User("cast5-cfb"), url.User("cast5-cfb"), false}, |
|||
{url.User("cast5-cfb"), url.UserPassword("cast5-cfb", "123456"), false}, |
|||
{url.UserPassword("cast5-cfb", "123456"), url.User("cast5-cfb"), false}, |
|||
{url.UserPassword("cast5-cfb", "123456"), url.UserPassword("cast5-cfb", "abc"), false}, |
|||
{url.UserPassword("cast5-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), true}, |
|||
|
|||
{url.User("rc4-md5"), url.User("rc4-md5"), false}, |
|||
{url.User("rc4-md5"), url.UserPassword("rc4-md5", "123456"), false}, |
|||
{url.UserPassword("rc4-md5", "123456"), url.User("rc4-md5"), false}, |
|||
{url.UserPassword("rc4-md5", "123456"), url.UserPassword("rc4-md5", "abc"), false}, |
|||
{url.UserPassword("rc4-md5", "123456"), url.UserPassword("rc4-md5", "123456"), true}, |
|||
|
|||
{url.User("chacha20"), url.User("chacha20"), false}, |
|||
{url.User("chacha20"), url.UserPassword("chacha20", "123456"), false}, |
|||
{url.UserPassword("chacha20", "123456"), url.User("chacha20"), false}, |
|||
{url.UserPassword("chacha20", "123456"), url.UserPassword("chacha20", "abc"), false}, |
|||
{url.UserPassword("chacha20", "123456"), url.UserPassword("chacha20", "123456"), true}, |
|||
|
|||
{url.User("chacha20-ietf"), url.User("chacha20-ietf"), false}, |
|||
{url.User("chacha20-ietf"), url.UserPassword("chacha20-ietf", "123456"), false}, |
|||
{url.UserPassword("chacha20-ietf", "123456"), url.User("chacha20-ietf"), false}, |
|||
{url.UserPassword("chacha20-ietf", "123456"), url.UserPassword("chacha20-ietf", "abc"), false}, |
|||
{url.UserPassword("chacha20-ietf", "123456"), url.UserPassword("chacha20-ietf", "123456"), true}, |
|||
|
|||
{url.User("salsa20"), url.User("salsa20"), false}, |
|||
{url.User("salsa20"), url.UserPassword("salsa20", "123456"), false}, |
|||
{url.UserPassword("salsa20", "123456"), url.User("salsa20"), false}, |
|||
{url.UserPassword("salsa20", "123456"), url.UserPassword("salsa20", "abc"), false}, |
|||
{url.UserPassword("salsa20", "123456"), url.UserPassword("salsa20", "123456"), true}, |
|||
} |
|||
|
|||
func ssProxyRoundtrip(targetURL string, data []byte, clientInfo *url.Userinfo, serverInfo *url.Userinfo) error { |
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: ShadowConnector(clientInfo), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: ShadowHandler(UsersHandlerOption(serverInfo)), |
|||
Listener: ln, |
|||
} |
|||
|
|||
go server.Run() |
|||
defer server.Close() |
|||
|
|||
return proxyRoundtrip(client, server, targetURL, data) |
|||
} |
|||
|
|||
func TestSSProxy(t *testing.T) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
for i, tc := range ssProxyTests { |
|||
tc := tc |
|||
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { |
|||
err := ssProxyRoundtrip(httpSrv.URL, sendData, |
|||
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 BenchmarkSSProxy_AES256(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: ShadowConnector(url.UserPassword("aes-256-cfb", "123456")), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: ShadowHandler(UsersHandlerOption(url.UserPassword("aes-256-cfb", "123456"))), |
|||
Listener: ln, |
|||
} |
|||
|
|||
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 BenchmarkSSProxy_Chacha20(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: ShadowConnector(url.UserPassword("chacha20", "123456")), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: ShadowHandler(UsersHandlerOption(url.UserPassword("chacha20", "123456"))), |
|||
Listener: ln, |
|||
} |
|||
|
|||
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 BenchmarkSSProxy_Chacha20_ietf(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: ShadowConnector(url.UserPassword("chacha20-ietf", "123456")), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: ShadowHandler(UsersHandlerOption(url.UserPassword("chacha20-ietf", "123456"))), |
|||
Listener: ln, |
|||
} |
|||
|
|||
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 BenchmarkSSProxyParallel(b *testing.B) { |
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
ln, err := TCPListener("") |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
|
|||
client := &Client{ |
|||
Connector: ShadowConnector(url.UserPassword("chacha20-ietf", "123456")), |
|||
Transporter: TCPTransporter(), |
|||
} |
|||
|
|||
server := &Server{ |
|||
Handler: ShadowHandler(UsersHandlerOption(url.UserPassword("chacha20-ietf", "123456"))), |
|||
Listener: ln, |
|||
} |
|||
|
|||
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) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
@ -0,0 +1,371 @@ |
|||
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) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
t.Error(err) |
|||
} |
|||
tlsConfig := &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
for i, tc := range httpProxyTests { |
|||
tc := tc |
|||
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { |
|||
err := httpOverTLSRoundtrip(httpSrv.URL, sendData, tlsConfig, 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) |
|||
|
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
tlsConfig := &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
ln, err := TLSListener("", tlsConfig) |
|||
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) |
|||
|
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
b.Error(err) |
|||
} |
|||
tlsConfig := &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
ln, err := TLSListener("", tlsConfig) |
|||
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) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
t.Error(err) |
|||
} |
|||
tlsConfig := &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
DefaultTLSConfig = tlsConfig |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
for i, tc := range socks5ProxyTests { |
|||
tc := tc |
|||
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { |
|||
err := socks5OverTLSRoundtrip(httpSrv.URL, sendData, |
|||
tlsConfig, |
|||
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) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
t.Error(err) |
|||
} |
|||
tlsConfig := &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
err = socks4OverTLSRoundtrip(httpSrv.URL, sendData, tlsConfig) |
|||
// 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) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
t.Error(err) |
|||
} |
|||
tlsConfig := &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
err = socks4aOverTLSRoundtrip(httpSrv.URL, sendData, tlsConfig) |
|||
// 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) { |
|||
cert, err := GenCertificate() |
|||
if err != nil { |
|||
t.Error(err) |
|||
} |
|||
tlsConfig := &tls.Config{ |
|||
Certificates: []tls.Certificate{cert}, |
|||
} |
|||
DefaultTLSConfig = tlsConfig |
|||
|
|||
httpSrv := httptest.NewServer(httpTestHandler) |
|||
defer httpSrv.Close() |
|||
|
|||
sendData := make([]byte, 128) |
|||
rand.Read(sendData) |
|||
|
|||
for i, tc := range ssProxyTests { |
|||
tc := tc |
|||
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { |
|||
err := ssOverTLSRoundtrip(httpSrv.URL, sendData, |
|||
tlsConfig, |
|||
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) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
Loading…
Reference in new issue