upstreamproxy

package
v2.0.0+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 21, 2018 License: GPL-3.0 Imports: 17 Imported by: 0

README

upstreamproxy Package

This provides upstream proxy support by extending golang.org/x/net/proxy package.

Currently supported protocols:

  • SOCKS4 via socks4a URI scheme
  • SOCKS5 via socks5 URI scheme
  • HTTP 'CONNECT' with Basic, Digest and NTLM Authentication via http URI scheme

Usage

Note: NewProxyDialFunc returns ForwardDialFunc if ProxyURIString is empty

/* 
   Proxy URI examples:
   "http://proxyhost:8080"
   "socks5://user:password@proxyhost:1080"
   "http://NTDOMAIN\NTUser:password@proxyhost:3375"
*/

//Plain HTTP transport via HTTP proxy
func doAuthenticatedHTTP() {
	proxyUrl, err := url.Parse("http://user:password@172.16.1.1:8080")
	transport := &http.Transport{Proxy: http.ProxyURL(proxyUrl)}
	customHeader := http.Header{"Test" :{"test"}}

	authHttpTransport, err := upstreamproxy.NewProxyAuthTransport(transport, customHeader)
	if err != nil {
		fmt.Println("Error: ", err)
		return
	}
	r, err := http.NewRequest("GET", "http://www.reddit.com", bytes.NewReader(data))
	if err != nil {
		fmt.Println("Error: ", err)
		return
	}
	resp, err := authHttpTransport.RoundTrip(r)
	if err != nil {
		fmt.Println("RoundTrip Error: ", err)
		return
	}
	ioutil.ReadAll(resp.Body)
	fmt.Println(string(resp.Status))
}

//HTTPS transport via HTTP proxy
func doAuthenticatedHTTPS() {
	dialTlsFn := func(netw, addr string) (net.Conn, error) {
		config := &upstreamproxy.UpstreamProxyConfig{
			ForwardDialFunc: net.Dial,
			ProxyURIString:  "http://user:password@172.16.1.1:8080",
		}

		proxyDialFunc := upstreamproxy.NewProxyDialFunc(config)

		conn, err := proxyDialFunc(netw, addr)
		if err != nil {
			return nil, err
		}
		tlsconfig := &tls.Config{InsecureSkipVerify: false}
		tlsConn := tls.Client(conn, tlsconfig)

		return tlsConn, tlsConn.Handshake()
	}

	r, err := http.NewRequest("GET", "https://www.reddit.com", bytes.NewReader(data))
	transport = &http.Transport{DialTLS: dialTlsFn}
	resp, err := transport.RoundTrip(r)
	if err != nil {
		log.Println("RoundTrip Error: ", err)
		return
	}
	ioutil.ReadAll(resp.Body)
	fmt.Println(string(resp.Status))
}

//HTTP transport via SOCKS5 proxy
func doAuthenticatedHttpSocks() {
	dialFn := func(netw, addr string) (net.Conn, error) {
		config := &upstreamproxy.UpstreamProxyConfig{
			ForwardDialFunc: net.Dial,
			ProxyURIString:  "socks5://user:password@172.16.1.1:5555",
		}

		proxyDialFunc := upstreamproxy.NewProxyDialFunc(config)

		return proxyDialFunc(netw, addr)
	}

	r, err := http.NewRequest("GET", "https://www.reddit.com", bytes.NewReader(data))
	transport = &http.Transport{Dial: dialFn}
	resp, err := transport.RoundTrip(r)
	if err != nil {
		log.Println("RoundTrip Error: ", err)
		return
	}
	ioutil.ReadAll(resp.Body)
	fmt.Println(string(resp.Status))
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BasicHttpAuthState

type BasicHttpAuthState int
const (
	BASIC_HTTP_AUTH_STATE_CHALLENGE_RECEIVED BasicHttpAuthState = iota
	BASIC_HTTP_AUTH_STATE_RESPONSE_GENERATED
)

type BasicHttpAuthenticator

type BasicHttpAuthenticator struct {
	// contains filtered or unexported fields
}

func (*BasicHttpAuthenticator) Authenticate

func (a *BasicHttpAuthenticator) Authenticate(req *http.Request, resp *http.Response) error

func (*BasicHttpAuthenticator) IsComplete

func (a *BasicHttpAuthenticator) IsComplete() bool

func (*BasicHttpAuthenticator) IsConnectionBased

func (a *BasicHttpAuthenticator) IsConnectionBased() bool

func (*BasicHttpAuthenticator) PreAuthenticate

func (a *BasicHttpAuthenticator) PreAuthenticate(req *http.Request) error

func (*BasicHttpAuthenticator) Reset

func (a *BasicHttpAuthenticator) Reset()

type DialFunc

type DialFunc func(string, string) (net.Conn, error)

func NewProxyDialFunc

func NewProxyDialFunc(config *UpstreamProxyConfig) DialFunc

type DigestHeaders

type DigestHeaders struct {
	Realm     string
	Qop       string
	Method    string
	Nonce     string
	Opaque    string
	Algorithm string
	HA1       string
	HA2       string
	Cnonce    string
	Uri       string
	Nc        int16
	Username  string
	Password  string
}

func (*DigestHeaders) ApplyAuth

func (d *DigestHeaders) ApplyAuth(req *http.Request)

ApplyAuth adds proper auth header to the passed request

type DigestHttpAuthState

type DigestHttpAuthState int
const (
	DIGEST_HTTP_AUTH_STATE_CHALLENGE_RECEIVED DigestHttpAuthState = iota
	DIGEST_HTTP_AUTH_STATE_RESPONSE_GENERATED
)

type DigestHttpAuthenticator

type DigestHttpAuthenticator struct {
	// contains filtered or unexported fields
}

func (*DigestHttpAuthenticator) Authenticate

func (a *DigestHttpAuthenticator) Authenticate(req *http.Request, resp *http.Response) error

func (*DigestHttpAuthenticator) IsComplete

func (a *DigestHttpAuthenticator) IsComplete() bool

func (*DigestHttpAuthenticator) IsConnectionBased

func (a *DigestHttpAuthenticator) IsConnectionBased() bool

func (*DigestHttpAuthenticator) PreAuthenticate

func (a *DigestHttpAuthenticator) PreAuthenticate(req *http.Request) error

func (*DigestHttpAuthenticator) Reset

func (a *DigestHttpAuthenticator) Reset()

type Error

type Error struct {
	// contains filtered or unexported fields
}

type HttpAuthState

type HttpAuthState int
const (
	HTTP_AUTH_STATE_UNCHALLENGED HttpAuthState = iota
	HTTP_AUTH_STATE_CHALLENGED
	HTTP_AUTH_STATE_FAILURE
	HTTP_AUTH_STATE_SUCCESS
)

type HttpAuthenticator

type HttpAuthenticator interface {
	PreAuthenticate(req *http.Request) error
	Authenticate(req *http.Request, resp *http.Response) error
	IsConnectionBased() bool
	IsComplete() bool
	Reset()
}

func NewHttpAuthenticator

func NewHttpAuthenticator(resp *http.Response, username, password string) (HttpAuthenticator, error)

type NTLMHttpAuthState

type NTLMHttpAuthState int
const (
	NTLM_HTTP_AUTH_STATE_CHALLENGE_RECEIVED NTLMHttpAuthState = iota
	NTLM_HTTP_AUTH_STATE_RESPONSE_TYPE1_GENERATED
	NTLM_HTTP_AUTH_STATE_RESPONSE_TYPE3_GENERATED
)

type NTLMHttpAuthenticator

type NTLMHttpAuthenticator struct {
	// contains filtered or unexported fields
}

func (*NTLMHttpAuthenticator) Authenticate

func (a *NTLMHttpAuthenticator) Authenticate(req *http.Request, resp *http.Response) error

func (*NTLMHttpAuthenticator) IsComplete

func (a *NTLMHttpAuthenticator) IsComplete() bool

func (*NTLMHttpAuthenticator) IsConnectionBased

func (a *NTLMHttpAuthenticator) IsConnectionBased() bool

func (*NTLMHttpAuthenticator) PreAuthenticate

func (a *NTLMHttpAuthenticator) PreAuthenticate(req *http.Request) error

func (*NTLMHttpAuthenticator) Reset

func (a *NTLMHttpAuthenticator) Reset()

type ProxyAuthTransport

type ProxyAuthTransport struct {
	*http.Transport
	// contains filtered or unexported fields
}

ProxyAuthTransport provides support for proxy authentication when doing plain HTTP by tapping into HTTP conversation and adding authentication headers to the requests when requested by server

Limitation: in violation of https://golang.org/pkg/net/http/#RoundTripper, ProxyAuthTransport is _not_ safe for concurrent RoundTrip calls. This is acceptable for its use in Psiphon to provide upstream proxy support for meek, which makes only serial RoundTrip calls. Concurrent RoundTrip calls will result in data race conditions and undefined behavior during an authentication handshake.

func NewProxyAuthTransport

func NewProxyAuthTransport(
	rawTransport *http.Transport,
	customHeaders http.Header) (*ProxyAuthTransport, error)

func (*ProxyAuthTransport) RoundTrip

func (tr *ProxyAuthTransport) RoundTrip(request *http.Request) (*http.Response, error)

type UpstreamProxyConfig

type UpstreamProxyConfig struct {
	ForwardDialFunc DialFunc
	ProxyURIString  string
	CustomHeaders   http.Header
}

func (*UpstreamProxyConfig) Dial

func (u *UpstreamProxyConfig) Dial(network, addr string) (net.Conn, error)

Dial implements the proxy.Dialer interface, allowing a UpstreamProxyConfig to be passed to proxy.FromURL.

Directories

Path Synopsis
go-ntlm
ntlm
Package NTLM implements the interfaces used for interacting with NTLMv1 and NTLMv2.
Package NTLM implements the interfaces used for interacting with NTLMv1 and NTLMv2.
ntlm/md4
Package md4 implements the MD4 hash algorithm as defined in RFC 1320.
Package md4 implements the MD4 hash algorithm as defined in RFC 1320.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL