Beispiel #1
0
func forward(conn net.Conn, arg Args) (net.Conn, error) {
	var err error
	if glog.V(LINFO) {
		proto := arg.Protocol
		if proto == "default" {
			proto = "http" // default is http
		}
		glog.Infof("forward: %s/%s %s", proto, arg.Transport, arg.Addr)
	}
	switch arg.Transport {
	case "ws": // websocket connection
		conn, err = wsClient(conn, arg.Addr)
		if err != nil {
			return nil, err
		}
	case "tls": // tls connection
		conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
	case "tcp":
		fallthrough
	default:
	}

	switch arg.Protocol {
	case "socks", "socks5":
		selector := &clientSelector{
			methods: []uint8{
				gosocks5.MethodNoAuth,
				gosocks5.MethodUserPass,
				MethodTLS,
			},
			arg: arg,
		}
		c := gosocks5.ClientConn(conn, selector)
		if err := c.Handleshake(); err != nil {
			return nil, err
		}
		conn = c
	case "ss": // shadowsocks
		if arg.User != nil {
			method := arg.User.Username()
			password, _ := arg.User.Password()
			cipher, err := shadowsocks.NewCipher(method, password)
			if err != nil {
				return nil, err
			}
			conn = shadowsocks.NewConn(conn, cipher)
		}
	case "http":
		fallthrough
	default:
	}

	return conn, nil
}
Beispiel #2
0
func connectSocks5Proxy(addr string) (conn net.Conn, err error) {
	conn, err = dial(proxyURL.Host)
	if err != nil {
		return
	}

	conf := &gosocks5.Config{
		// Methods:        []uint8{gosocks5.MethodNoAuth, gosocks5.MethodUserPass},
		MethodSelected: proxyMethodSelected,
	}
	if proxyURL.User != nil {
		conf.Methods = []uint8{gosocks5.MethodUserPass}
	}

	c := gosocks5.ClientConn(conn, conf)
	if err := c.Handleshake(); err != nil {
		conn.Close()
		return nil, err
	}
	conn = c

	s := strings.Split(addr, ":")
	host := s[0]
	port := 80
	if len(s) == 2 {
		n, _ := strconv.ParseUint(s[1], 10, 16)
		port = int(n)
	}
	a := &gosocks5.Addr{
		Type: gosocks5.AddrDomain,
		Host: host,
		Port: uint16(port),
	}
	if err := gosocks5.NewRequest(gosocks5.CmdConnect, a).Write(conn); err != nil {
		conn.Close()
		return nil, err
	}
	rep, err := gosocks5.ReadReply(conn)
	if err != nil {
		conn.Close()
		return nil, err
	}
	if rep.Rep != gosocks5.Succeeded {
		conn.Close()
		return nil, errors.New("Socks Failture")
	}

	return conn, nil
}
Beispiel #3
0
func makeTunnel() (c net.Conn, err error) {
	if UseTLS || UseWebsocket || !UseHttp {
		c, err = connect(Saddr)
	} else {
		addr := Saddr
		if proxyURL != nil {
			addr = proxyURL.Host
		}
		c, err = dial(addr)
	}
	if err != nil {
		return
	}

	if UseTLS {
		config := &tls.Config{InsecureSkipVerify: true}
		c = tls.Client(c, config)
	} else if UseWebsocket {
		ws, resp, err := websocket.NewClient(c, &url.URL{Host: Saddr}, nil, 8192, 8192)
		if err != nil {
			c.Close()
			return nil, err
		}
		resp.Body.Close()

		c = NewWSConn(ws)
	} else if UseHttp {
		httpcli := NewHttpClientConn(c)
		if err = httpcli.Handshake(); err != nil {
			c.Close()
			return nil, err
		}
		c = httpcli
		//defer httpcli.Close()
	}

	sc := gosocks5.ClientConn(c, clientConfig)
	if err = sc.Handleshake(); err != nil {
		c.Close()
		return nil, err
	}
	c = sc

	return
}
Beispiel #4
0
func forward(conn net.Conn, arg Args) (net.Conn, error) {
	var err error

	switch arg.Transport {
	case "ws": // websocket connection
		conn, err = wsClient(conn, arg.Addr)
		if err != nil {
			return nil, err
		}
	case "tls": // tls connection
		conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
	case "tcp":
		fallthrough
	default:
	}

	switch arg.Protocol {
	case "ss": // shadowsocks
		return nil, errors.New("Not implemented")
	case "socks", "socks5":
		selector := &clientSelector{
			methods: []uint8{
				gosocks5.MethodNoAuth,
				gosocks5.MethodUserPass,
				MethodTLS,
			},
			arg: arg,
		}
		c := gosocks5.ClientConn(conn, selector)
		if err := c.Handleshake(); err != nil {
			return nil, err
		}
		conn = c
	case "http":
		fallthrough
	default:
	}

	return conn, nil
}
Beispiel #5
0
func (c *ProxyConn) handshake() error {
	var tlsUsed bool

	switch c.Node.Transport {
	case "ws": // websocket connection
		u := url.URL{Scheme: "ws", Host: c.Node.Addr, Path: "/ws"}
		conn, err := WebsocketClientConn(u.String(), c.conn, nil)
		if err != nil {
			return err
		}
		c.conn = conn
	case "wss": // websocket security
		tlsUsed = true
		u := url.URL{Scheme: "wss", Host: c.Node.Addr, Path: "/ws"}
		config := &tls.Config{
			InsecureSkipVerify: c.Node.insecureSkipVerify(),
			ServerName:         c.Node.serverName,
		}
		conn, err := WebsocketClientConn(u.String(), c.conn, config)
		if err != nil {
			return err
		}
		c.conn = conn
	case "tls", "http2": // tls connection
		tlsUsed = true
		cfg := &tls.Config{
			InsecureSkipVerify: c.Node.insecureSkipVerify(),
			ServerName:         c.Node.serverName,
		}
		c.conn = tls.Client(c.conn, cfg)
	case "h2": // same as http2, but just set a flag for later using.
		tlsUsed = true
	case "kcp": // kcp connection
		tlsUsed = true
	default:
	}

	switch c.Node.Protocol {
	case "socks", "socks5": // socks5 handshake with auth and tls supported
		selector := &clientSelector{
			methods: []uint8{
				gosocks5.MethodNoAuth,
				gosocks5.MethodUserPass,
				//MethodTLS,
			},
			user: c.Node.User,
		}

		if !tlsUsed { // if transport is not security, enable security socks5
			selector.methods = append(selector.methods, MethodTLS)
			selector.tlsConfig = &tls.Config{
				InsecureSkipVerify: c.Node.insecureSkipVerify(),
				ServerName:         c.Node.serverName,
			}
		}

		conn := gosocks5.ClientConn(c.conn, selector)
		if err := conn.Handleshake(); err != nil {
			return err
		}
		c.conn = conn
	case "ss": // shadowsocks
		if c.Node.User != nil {
			method := c.Node.User.Username()
			password, _ := c.Node.User.Password()
			cipher, err := shadowsocks.NewCipher(method, password)
			if err != nil {
				return err
			}
			c.conn = &shadowConn{conn: shadowsocks.NewConn(c.conn, cipher)}
		}
	case "http", "http2":
		fallthrough
	default:
	}

	c.handshaked = true

	return nil
}