add some test

addon-dailer
lqqyt2423 3 years ago
parent 0cc735cfa3
commit c61db1bffb

@ -14,4 +14,4 @@ clean:
.PHONY: test .PHONY: test
test: test:
go test ./... go test ./... -v

@ -41,6 +41,64 @@ type CA struct {
cacheMu sync.Mutex cacheMu sync.Mutex
} }
func createCert() (*rsa.PrivateKey, *x509.Certificate, error) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, nil, err
}
template := &x509.Certificate{
SerialNumber: big.NewInt(time.Now().UnixNano() / 100000),
Subject: pkix.Name{
CommonName: "mitmproxy",
Organization: []string{"mitmproxy"},
},
NotBefore: time.Now().Add(-time.Hour * 48),
NotAfter: time.Now().Add(time.Hour * 24 * 365 * 3),
BasicConstraintsValid: true,
IsCA: true,
SignatureAlgorithm: x509.SHA256WithRSA,
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageEmailProtection,
x509.ExtKeyUsageTimeStamping,
x509.ExtKeyUsageCodeSigning,
x509.ExtKeyUsageMicrosoftCommercialCodeSigning,
x509.ExtKeyUsageMicrosoftServerGatedCrypto,
x509.ExtKeyUsageNetscapeServerGatedCrypto,
},
}
certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
if err != nil {
return nil, nil, err
}
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return nil, nil, err
}
return key, cert, nil
}
// Create new ca only live in memory, will change when process restart
func NewCAMemory() (*CA, error) {
key, cert, err := createCert()
if err != nil {
return nil, err
}
return &CA{
PrivateKey: *key,
RootCert: *cert,
StorePath: "",
cache: lru.New(100),
group: new(singleflight.Group),
}, nil
}
// Load ca from store path or create new ca then store
func NewCA(path string) (*CA, error) { func NewCA(path string) (*CA, error) {
storePath, err := getStorePath(path) storePath, err := getStorePath(path)
if err != nil { if err != nil {
@ -178,44 +236,12 @@ func (ca *CA) load() error {
} }
func (ca *CA) create() error { func (ca *CA) create() error {
key, err := rsa.GenerateKey(rand.Reader, 2048) key, cert, err := createCert()
if err != nil { if err != nil {
return err return err
} }
ca.PrivateKey = *key
template := &x509.Certificate{
SerialNumber: big.NewInt(time.Now().UnixNano() / 100000),
Subject: pkix.Name{
CommonName: "mitmproxy",
Organization: []string{"mitmproxy"},
},
NotBefore: time.Now().Add(-time.Hour * 48),
NotAfter: time.Now().Add(time.Hour * 24 * 365 * 3),
BasicConstraintsValid: true,
IsCA: true,
SignatureAlgorithm: x509.SHA256WithRSA,
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageEmailProtection,
x509.ExtKeyUsageTimeStamping,
x509.ExtKeyUsageCodeSigning,
x509.ExtKeyUsageMicrosoftCommercialCodeSigning,
x509.ExtKeyUsageMicrosoftServerGatedCrypto,
x509.ExtKeyUsageNetscapeServerGatedCrypto,
},
}
certBytes, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key) ca.PrivateKey = *key
if err != nil {
return err
}
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return err
}
ca.RootCert = *cert ca.RootCert = *cert
if err := ca.save(); err != nil { if err := ca.save(); err != nil {

@ -0,0 +1,143 @@
package proxy
import (
"crypto/tls"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"testing"
"time"
"github.com/lqqyt2423/go-mitmproxy/cert"
)
func handleError(t *testing.T, err error) {
t.Helper()
if err != nil {
t.Fatal(err)
}
}
func TestProxy(t *testing.T) {
// start http server
ln, err := net.Listen("tcp", "127.0.0.1:0")
handleError(t, err)
defer ln.Close()
go http.Serve(ln, nil)
// start https server
tlsLn, err := net.Listen("tcp", "127.0.0.1:0")
handleError(t, err)
defer tlsLn.Close()
ca, err := cert.NewCAMemory()
handleError(t, err)
cert, err := ca.GetCert("localhost")
handleError(t, err)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{*cert},
}
go http.Serve(tls.NewListener(tlsLn, tlsConfig), nil)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
httpEndpoint := "http://" + ln.Addr().String() + "/"
httpsPort := tlsLn.Addr().(*net.TCPAddr).Port
httpsEndpoint := "https://localhost:" + strconv.Itoa(httpsPort) + "/"
t.Run("test http server", func(t *testing.T) {
resp, err := http.Get(httpEndpoint)
handleError(t, err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
handleError(t, err)
if string(body) != "ok" {
t.Fatal("expected ok, bug got", string(body))
}
})
t.Run("test https server", func(t *testing.T) {
t.Run("should generate not trusted error", func(t *testing.T) {
_, err := http.Get(httpsEndpoint)
if err == nil {
t.Fatal("should have error")
}
if !strings.Contains(err.Error(), "certificate is not trusted") {
t.Fatal("should get not trusted error, but got", err.Error())
}
})
t.Run("should get ok when InsecureSkipVerify", func(t *testing.T) {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
req, err := http.NewRequest("GET", httpsEndpoint, nil)
handleError(t, err)
resp, err := client.Do(req)
handleError(t, err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
handleError(t, err)
if string(body) != "ok" {
t.Fatal("expected ok, bug got", string(body))
}
})
})
// start proxy
testProxy, err := NewProxy(&Options{
Addr: ":29080", // some random port
SslInsecure: true,
})
handleError(t, err)
testProxy.AddAddon(&LogAddon{})
go testProxy.Start()
time.Sleep(time.Millisecond * 10) // wait for test proxy startup
t.Run("test proxy", func(t *testing.T) {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
Proxy: func(r *http.Request) (*url.URL, error) {
return url.Parse("http://127.0.0.1:29080")
},
},
}
t.Run("can proxy http", func(t *testing.T) {
req, err := http.NewRequest("GET", httpEndpoint, nil)
handleError(t, err)
resp, err := client.Do(req)
handleError(t, err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
handleError(t, err)
if string(body) != "ok" {
t.Fatal("expected ok, bug got", string(body))
}
})
t.Run("can proxy https", func(t *testing.T) {
req, err := http.NewRequest("GET", httpsEndpoint, nil)
handleError(t, err)
resp, err := client.Do(req)
handleError(t, err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
handleError(t, err)
if string(body) != "ok" {
t.Fatal("expected ok, bug got", string(body))
}
})
})
}
Loading…
Cancel
Save