Exemplo n.º 1
0
func TestWithBrowser(t *testing.T) {
	// an easy way to check if auth works with webserver
	// to test, run with
	// $ go test -run TestWithBrowser -- server
	// configure a browser to use the printed proxy address, use the proxy
	// and exit with Ctrl-C. It will throw error if your haven't acutally used the proxy
	if os.Args[len(os.Args)-1] != "server" {
		return
	}
	proxy := goproxy.NewProxyHttpServer()
	println("proxy localhost port 8082")
	access := int32(0)
	proxy.OnRequest().Do(auth.Basic("my_realm", func(user, passwd string) bool {
		atomic.AddInt32(&access, 1)
		return user == "user" && passwd == "1234"
	}))
	l, err := net.Listen("tcp", "localhost:8082")
	if err != nil {
		t.Fatal(err)
	}
	ch := make(chan os.Signal)
	signal.Notify(ch, os.Interrupt)
	go func() {
		<-ch
		l.Close()
	}()
	http.Serve(l, proxy)
	if access <= 0 {
		t.Error("No one accessed the proxy")
	}
}
Exemplo n.º 2
0
func TestBasicAuthWithCurl(t *testing.T) {
	expected := ":c>"
	background := httptest.NewServer(ConstantHanlder(expected))
	defer background.Close()
	proxy := goproxy.NewProxyHttpServer()
	proxy.OnRequest().Do(auth.Basic("my_realm", func(user, passwd string) bool {
		return user == "user" && passwd == "open sesame"
	}))
	_, proxyserver := oneShotProxy(proxy)
	defer proxyserver.Close()

	cmd := exec.Command("curl",
		"--silent", "--show-error",
		"-x", proxyserver.URL,
		"-U", "user:open sesame",
		"--url", background.URL+"/[1-3]",
	)
	out, err := cmd.CombinedOutput() // if curl got error, it'll show up in stderr
	if err != nil {
		t.Fatal(err, string(out))
	}
	finalexpected := times(3, expected)
	if string(out) != finalexpected {
		t.Error("Expected", finalexpected, "got", string(out))
	}
}
Exemplo n.º 3
0
func TestBasicAuth(t *testing.T) {
	expected := "hello"
	background := httptest.NewServer(ConstantHanlder(expected))
	defer background.Close()
	proxy := goproxy.NewProxyHttpServer()
	proxy.OnRequest().Do(auth.Basic("my_realm", func(user, passwd string) bool {
		return user == "user" && passwd == "open sesame"
	}))
	client, proxyserver := oneShotProxy(proxy)
	defer proxyserver.Close()

	// without auth
	resp, err := client.Get(background.URL)
	if err != nil {
		t.Fatal(err)
	}
	if resp.Header.Get("Proxy-Authenticate") != "Basic realm=my_realm" {
		t.Error("Expected Proxy-Authenticate header got", resp.Header.Get("Proxy-Authenticate"))
	}
	if resp.StatusCode != 407 {
		t.Error("Expected status 407 Proxy Authentication Required, got", resp.Status)
	}

	// with auth
	req, err := http.NewRequest("GET", background.URL, nil)
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set("Proxy-Authorization",
		"Basic "+base64.StdEncoding.EncodeToString([]byte("user:open sesame")))
	resp, err = client.Do(req)
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != 200 {
		t.Error("Expected status 200 OK, got", resp.Status)
	}
	msg, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal(err)
	}
	if string(msg) != "hello" {
		t.Errorf("Expected '%s', actual '%s'", expected, string(msg))
	}
}
Exemplo n.º 4
0
func TestCharset(t *testing.T) {
	s := httptest.NewServer(ConstantServer(1))
	defer s.Close()

	ch := make(chan string, 2)
	proxy := goproxy.NewProxyHttpServer()
	proxy.OnResponse().Do(goproxy_html.HandleString(
		func(s string, ctx *goproxy.ProxyCtx) string {
			ch <- s
			return s
		}))
	proxyServer := httptest.NewServer(proxy)
	defer proxyServer.Close()

	proxyUrl, _ := url.Parse(proxyServer.URL)
	client := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}

	resp, err := client.Get(s.URL + "/cp1255.txt")
	if err != nil {
		t.Fatal("GET:", err)
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal("readAll:", err)
	}
	resp.Body.Close()

	inHandleString := ""
	select {
	case inHandleString = <-ch:
	default:
	}

	if len(b) != 2 || b[0] != 0xe3 || b[1] != 0xf3 {
		t.Error("Did not translate back to 0xe3,0xf3, instead", b)
	}
	if inHandleString != "דף" {
		t.Error("HandleString did not convert DALET & PEH SOFIT (דף) from ISO-8859-8 to utf-8, got", []byte(inHandleString))
	}
}
Exemplo n.º 5
0
Arquivo: main.go Projeto: toorop/pure
//  Main
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
	/*login := flag.String("login", "", "proxy login")
	password := flag.String("password", "", "proxy passwd")*/
	addr := flag.String("addr", ":8080", "proxy listen address")
	flag.Parse()

	// Yara
	c, err := yara.NewCompiler()
	handleErr(err)
	// Load & compile rules
	err = filepath.Walk("rules/yara", func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		return c.AddFile("", "rules/yara/"+info.Name())
	})
	handleErr(err)

	engine, err := c.Rules()
	handleErr(err)
	c.Destroy()

	// HTML cleaners
	htmlCleaner := NewHTMLCleaner()
	err = htmlCleaner.LoadRulesFromFile("rules/HTMLCleaner.txt")
	handleErr(err)

	// CSS injector
	cssInjector := NewCSSInjector()
	err = cssInjector.LoadRulesFromFile("rules/filters/css2inject.txt")
	handleErr(err)

	// launch proxy
	goproxy.CertOrganisation = "Pure proxy"
	// Cache for certs
	TLSConfigCache, err = lru.New(TLSCacheSize)
	//goproxy.GoproxyCa, err = tls.X509KeyPair(CaCert, CaKey)
	ca, err := tls.X509KeyPair(CaCert, CaKey)
	handleErr(err)
	proxy := goproxy.NewProxyHttpServer()
	proxy.Verbose = *verbose

	MitmConnect := &goproxy.ConnectAction{
		Action: goproxy.ConnectMitm,
		TLSConfig: func(host string, ctx *goproxy.ProxyCtx) (*tls.Config, error) {
			return TLSGetConfig(host, ctx, &ca)
		},
	}
	var AlwaysMitm goproxy.FuncHttpsHandler = func(host string, ctx *goproxy.ProxyCtx) (
		*goproxy.ConnectAction, string) {
		return MitmConnect, host
	}

	proxy.OnRequest().HandleConnect(AlwaysMitm)

	/*auth.ProxyBasic(proxy, "my_realm", func(user, passwd string) bool {
		return user == *login && passwd == *password
	})*/

	/*
		proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
			log.Println(host)
			name := ""
			err = engine.ScanMemory([]byte(host), func(rule *yara.Rule) yara.CallbackStatus {
				name = rule.Identifier
				return yara.Abort
			})
			if name != "" {
				log.Println("REJECTED", name, host)
				return goproxy.RejectConnect, host
			}
			return goproxy.OkConnect, host
		})
	*/

	// POC websocket
	/*proxy.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
		log.Println(host)
		if host == "live.toorop.fr:80" {
			msg := "---------------------------------------------------------\n"
			for k, v := range ctx.Req.Header {
				msg += string(k) + ":" + v[0] + "\n"
			}
			msg += "---------------------------------------------------------\n\n"
			log.Println(msg)
		}
		return goproxy.OkConnect, host
	})*/

	/*proxy.OnRequest(IsWebsocket).
		HijackConnect(func(req *http.Request, client net.Conn, ctx *goproxy.ProxyCtx) {
		defer func() {
			if e := recover(); e != nil {
				ctx.Logf("error connecting to remote: %v", e)
				client.Write([]byte("HTTP/1.1 500 Cannot reach destination\r\n\r\n"))
			}
			client.Close()
		}()
		log.Println("Requete versTHE  websocket")
		clientBuf := bufio.NewReadWriter(bufio.NewReader(client), bufio.NewWriter(client))
		remote, err := connectDial(proxy, "tcp", req.URL.Host)
		orPanic(err)
		remoteBuf := bufio.NewReadWriter(bufio.NewReader(remote), bufio.NewWriter(remote))
		for {
			req, err := http.ReadRequest(clientBuf.Reader)
			orPanic(err)
			orPanic(req.Write(remoteBuf))
			orPanic(remoteBuf.Flush())
			resp, err := http.ReadResponse(remoteBuf.Reader, req)
			orPanic(err)
			orPanic(resp.Write(clientBuf.Writer))
			orPanic(clientBuf.Flush())
		}
	})*/

	/*proxy.OnRequest(IsWebsocket).DoFunc(func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
		log.Println("Requete vers websocket")
		return r, nil
	})*/

	proxy.OnRequest().DoFunc(
		func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
			name := ""
			err = engine.ScanMemory([]byte(r.Host), func(rule *yara.Rule) yara.CallbackStatus {
				name = rule.Identifier
				return yara.Abort
			})
			if name == "" {
				err = engine.ScanMemory([]byte(r.RequestURI), func(rule *yara.Rule) yara.CallbackStatus {
					name = rule.Identifier
					return yara.Abort
				})
			}
			if name != "" {
				log.Println("BLOCKED", name, r.RequestURI)
				return r, goproxy.NewResponse(r,
					goproxy.ContentTypeText, http.StatusForbidden,
					"I'm sorry, Dave. I'm afraid I can't do that.")
			}
			return r, nil
		})

	// Scan response - POC
	// TODO: refactoring
	proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
		if resp == nil {
			return nil
		}
		contentType := resp.Header.Get("content-type")

		// http
		if strings.HasPrefix(contentType, "text/html") {
			resp.Body = htmlCleaner.Clean(resp.Body, ctx.Req.Host)
		} else if strings.HasPrefix(contentType, "text/css") {
			resp.Body = cssInjector.Inject(resp.Body, ctx.Req.Host)
		} else if strings.HasPrefix(contentType, "application/json") {
			// POC remove google ads on search
			if ctx.Req.Host == "www.google.fr" {
				// read body
				body, err := ioutil.ReadAll(resp.Body)
				if err != nil {
					ctx.Warnf("Pure - ERROR while reading body: %s", err)
					return resp
				}
				bodyPart := strings.Split(string(body), `/*""*/`)
				t := ""
				for _, p := range bodyPart {
					if strings.Contains(p, "commercial-unit") || strings.Contains(p, "tadsb") {
						continue
					}
					t = t + p + `/*""*/`
				}
				body = []byte(t)
				resp.Body = ioutil.NopCloser(bytes.NewBuffer(body))
			}
		}

		return resp
	})
	log.Fatal(http.ListenAndServe(*addr, proxy))
}