github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/goptlib/socks.go (about)

     1  package pt
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"net"
     8  	"time"
     9  )
    10  
    11  const (
    12  	socks4Version = 0x04
    13  	socks5Version = 0x05
    14  
    15  	socksAuthNoneRequired        = 0x00
    16  	socksAuthUsernamePassword    = 0x02
    17  	socksAuthNoAcceptableMethods = 0xff
    18  
    19  	socksCmdConnect = 0x01
    20  	socksReserved   = 0x00
    21  
    22  	socksAtypeV4         = 0x01
    23  	socksAtypeDomainName = 0x03
    24  	socksAtypeV6         = 0x04
    25  
    26  	socksAuthRFC1929Ver     = 0x01
    27  	socksAuthRFC1929Success = 0x00
    28  	socksAuthRFC1929Fail    = 0x01
    29  
    30  	socksRepSucceeded = 0x00
    31  	// "general SOCKS server failure"
    32  	SocksRepGeneralFailure = 0x01
    33  	// "connection not allowed by ruleset"
    34  	SocksRepConnectionNotAllowed = 0x02
    35  	// "Network unreachable"
    36  	SocksRepNetworkUnreachable = 0x03
    37  	// "Host unreachable"
    38  	SocksRepHostUnreachable = 0x04
    39  	// "Connection refused"
    40  	SocksRepConnectionRefused = 0x05
    41  	// "TTL expired"
    42  	SocksRepTTLExpired = 0x06
    43  	// "Command not supported"
    44  	SocksRepCommandNotSupported = 0x07
    45  	// "Address type not supported"
    46  	SocksRepAddressNotSupported = 0x08
    47  
    48  	socks4ResponseVersion = 0x00
    49  	socks4RequestGranted  = 0x5a
    50  	socks4RequestRejected = 0x5b
    51  )
    52  
    53  // Put a sanity timeout on how long we wait for a SOCKS request.
    54  const socksRequestTimeout = 5 * time.Second
    55  
    56  // SocksRequest describes a SOCKS request.
    57  type SocksRequest struct {
    58  	// The endpoint requested by the client as a "host:port" string.
    59  	Target string
    60  	// The userid string sent by the client.
    61  	Username string
    62  	// The password string sent by the client.
    63  	Password string
    64  	// The parsed contents of Username as a key–value mapping.
    65  	Args Args
    66  }
    67  
    68  // SocksConn encapsulates a net.Conn and information associated with a SOCKS request.
    69  type SocksConn struct {
    70  	net.Conn
    71  	Req          SocksRequest
    72  	socksVersion byte
    73  }
    74  
    75  // Send a message to the proxy client that access to the given address is
    76  // granted.
    77  // For SOCKS5, Addr is ignored, and "0.0.0.0:0" is always sent back for
    78  // BND.ADDR/BND.PORT in the SOCKS response.
    79  // For SOCKS4a, if the IP field inside addr is not an IPv4 address, the IP
    80  // portion of the response will be four zero bytes.
    81  func (conn *SocksConn) Grant(addr *net.TCPAddr) error {
    82  	if conn.socksVersion == socks4Version {
    83  		return sendSocks4aResponseGranted(conn, addr)
    84  	}
    85  	return sendSocks5ResponseGranted(conn)
    86  }
    87  
    88  // Send a message to the proxy client that access was rejected or failed.  This
    89  // sends back a "General Failure" error code.  RejectReason should be used if
    90  // more specific error reporting is desired.
    91  func (conn *SocksConn) Reject() error {
    92  	if conn.socksVersion == socks4Version {
    93  		return sendSocks4aResponseRejected(conn)
    94  	}
    95  	return sendSocks5ResponseRejected(conn, SocksRepGeneralFailure)
    96  }
    97  
    98  // Send a message to the proxy client that access was rejected, with the
    99  // specific error code indicating the reason behind the rejection.
   100  // For SOCKS4a, the reason is ignored.
   101  func (conn *SocksConn) RejectReason(reason byte) error {
   102  	if conn.socksVersion == socks4Version {
   103  		return sendSocks4aResponseRejected(conn)
   104  	}
   105  	return sendSocks5ResponseRejected(conn, reason)
   106  }
   107  
   108  // SocksListener wraps a net.Listener in order to read a SOCKS request on Accept.
   109  //
   110  // 	func handleConn(conn *pt.SocksConn) error {
   111  // 		defer conn.Close()
   112  // 		remote, err := net.Dial("tcp", conn.Req.Target)
   113  // 		if err != nil {
   114  // 			conn.Reject()
   115  // 			return err
   116  // 		}
   117  // 		defer remote.Close()
   118  // 		err = conn.Grant(remote.RemoteAddr().(*net.TCPAddr))
   119  // 		if err != nil {
   120  // 			return err
   121  // 		}
   122  // 		// do something with conn and remote
   123  // 		return nil
   124  // 	}
   125  // 	...
   126  // 	ln, err := pt.ListenSocks("tcp", "127.0.0.1:0")
   127  // 	if err != nil {
   128  // 		panic(err.Error())
   129  // 	}
   130  // 	for {
   131  // 		conn, err := ln.AcceptSocks()
   132  // 		if err != nil {
   133  // 			log.Printf("accept error: %s", err)
   134  // 			if e, ok := err.(net.Error); !ok || !e.Temporary() {
   135  // 				break
   136  // 			}
   137  // 			continue
   138  // 		}
   139  // 		go handleConn(conn)
   140  // 	}
   141  type SocksListener struct {
   142  	net.Listener
   143  }
   144  
   145  // Open a net.Listener according to network and laddr, and return it as a
   146  // SocksListener.
   147  func ListenSocks(network, laddr string) (*SocksListener, error) {
   148  	ln, err := net.Listen(network, laddr)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	return NewSocksListener(ln), nil
   153  }
   154  
   155  // Create a new SocksListener wrapping the given net.Listener.
   156  func NewSocksListener(ln net.Listener) *SocksListener {
   157  	return &SocksListener{ln}
   158  }
   159  
   160  // Accept is the same as AcceptSocks, except that it returns a generic net.Conn.
   161  // It is present for the sake of satisfying the net.Listener interface.
   162  func (ln *SocksListener) Accept() (net.Conn, error) {
   163  	return ln.AcceptSocks()
   164  }
   165  
   166  // Call Accept on the wrapped net.Listener, do SOCKS negotiation, and return a
   167  // SocksConn. After accepting, you must call either conn.Grant or conn.Reject
   168  // (presumably after trying to connect to conn.Req.Target).
   169  //
   170  // Errors returned by AcceptSocks may be temporary (for example, EOF while
   171  // reading the request, or a badly formatted userid string), or permanent (e.g.,
   172  // the underlying socket is closed). You can determine whether an error is
   173  // temporary and take appropriate action with a type conversion to net.Error.
   174  // For example:
   175  //
   176  // 	for {
   177  // 		conn, err := ln.AcceptSocks()
   178  // 		if err != nil {
   179  // 			if e, ok := err.(net.Error); ok && e.Temporary() {
   180  // 				log.Printf("temporary accept error; trying again: %s", err)
   181  // 				continue
   182  // 			}
   183  // 			log.Printf("permanent accept error; giving up: %s", err)
   184  // 			break
   185  // 		}
   186  // 		go handleConn(conn)
   187  // 	}
   188  func (ln *SocksListener) AcceptSocks() (*SocksConn, error) {
   189  	c, err := ln.Listener.Accept()
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  	conn := new(SocksConn)
   194  	conn.Conn = c
   195  
   196  	err = conn.SetDeadline(time.Now().Add(socksRequestTimeout))
   197  	if err != nil {
   198  		conn.Close()
   199  		err = newTemporaryNetError("AcceptSocks: conn.SetDeadline() #1 failed: %s", err.Error())
   200  		return nil, err
   201  	}
   202  
   203  	rw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
   204  
   205  	// Determine which SOCKS version the client is using and branch on it.
   206  	if version, err := socksPeekByte(rw.Reader); err != nil {
   207  		conn.Close()
   208  		err = newTemporaryNetError("AcceptSocks: socksPeekByte() failed: %s", err.Error())
   209  		return nil, err
   210  	} else if version == socks4Version {
   211  		conn.socksVersion = socks4Version
   212  		conn.Req, err = readSocks4aConnect(rw.Reader)
   213  		if err != nil {
   214  			conn.Close()
   215  			return nil, err
   216  		}
   217  	} else if version == socks5Version {
   218  		conn.socksVersion = socks5Version
   219  		conn.Req, err = socks5Handshake(rw)
   220  		if err != nil {
   221  			conn.Close()
   222  			return nil, err
   223  		}
   224  	} else {
   225  		conn.Close()
   226  		err = newTemporaryNetError("AcceptSocks: Illegal SOCKS version: 0x%02x", version)
   227  		return nil, err
   228  	}
   229  
   230  	err = conn.SetDeadline(time.Time{})
   231  	if err != nil {
   232  		conn.Close()
   233  		err = newTemporaryNetError("AcceptSocks: conn.SetDeadline() #2 failed: %s", err.Error())
   234  		return nil, err
   235  
   236  	}
   237  	return conn, nil
   238  }
   239  
   240  // Returns "socks5", suitable to be included in a call to Cmethod.
   241  func (ln *SocksListener) Version() string {
   242  	return "socks5"
   243  }
   244  
   245  // socks5handshake conducts the SOCKS5 handshake up to the point where the
   246  // client command is read and the proxy must open the outgoing connection.
   247  // Returns a SocksRequest.
   248  func socks5Handshake(rw *bufio.ReadWriter) (req SocksRequest, err error) {
   249  	// Negotiate the authentication method.
   250  	var method byte
   251  	if method, err = socks5NegotiateAuth(rw); err != nil {
   252  		return
   253  	}
   254  
   255  	// Authenticate the client.
   256  	if err = socks5Authenticate(rw, method, &req); err != nil {
   257  		return
   258  	}
   259  
   260  	// Read the command.
   261  	err = socks5ReadCommand(rw, &req)
   262  	return
   263  }
   264  
   265  // socks5NegotiateAuth negotiates the authentication method and returns the
   266  // selected method as a byte.  On negotiation failures an error is returned.
   267  func socks5NegotiateAuth(rw *bufio.ReadWriter) (method byte, err error) {
   268  	// Validate the version.
   269  	if err = socksReadByteVerify(rw.Reader, "version", socks5Version); err != nil {
   270  		err = newTemporaryNetError("socks5NegotiateAuth: %s", err.Error())
   271  		return
   272  	}
   273  
   274  	// Read the number of methods.
   275  	var nmethods byte
   276  	if nmethods, err = socksReadByte(rw.Reader); err != nil {
   277  		err = newTemporaryNetError("socks5NegotiateAuth: Failed to read nmethods byte: %s", err.Error())
   278  		return
   279  	}
   280  
   281  	// Read the methods.
   282  	var methods []byte
   283  	if methods, err = socksReadBytes(rw.Reader, int(nmethods)); err != nil {
   284  		err = newTemporaryNetError("socks5NegotiateAuth: Failed to read methods bytes: %s", err.Error())
   285  		return
   286  	}
   287  
   288  	// Pick the most "suitable" method.
   289  	method = socksAuthNoAcceptableMethods
   290  	for _, m := range methods {
   291  		// [Psiphon]
   292  		// Some SOCKS5 clients send both None and Username/Password when in fact they are only
   293  		// able to auth with None. Since we don't need pluggable transport parameters and prefer
   294  		// enabling clients to proxy, we prefer None, which allows those clients to connect.
   295  		/*
   296  			switch m {
   297  			case socksAuthNoneRequired:
   298  				// Pick Username/Password over None if the client happens to
   299  				// send both.
   300  				if method == socksAuthNoAcceptableMethods {
   301  					method = m
   302  				}
   303  
   304  			case socksAuthUsernamePassword:
   305  				method = m
   306  			}
   307  		*/
   308  		switch m {
   309  		case socksAuthNoneRequired:
   310  			method = m
   311  
   312  		case socksAuthUsernamePassword:
   313  			if method == socksAuthNoAcceptableMethods {
   314  				method = m
   315  			}
   316  		}
   317  		// [Psiphon]
   318  	}
   319  
   320  	// Send the negotiated method.
   321  	var msg [2]byte
   322  	msg[0] = socks5Version
   323  	msg[1] = method
   324  	if _, err = rw.Writer.Write(msg[:]); err != nil {
   325  		err = newTemporaryNetError("socks5NegotiateAuth: Failed to write negotiated method: %s", err.Error())
   326  		return
   327  	}
   328  
   329  	if err = socksFlushBuffers(rw); err != nil {
   330  		err = newTemporaryNetError("socks5NegotiateAuth: Failed to flush buffers: %s", err.Error())
   331  		return
   332  	}
   333  	return
   334  }
   335  
   336  // socks5Authenticate authenticates the client via the chosen authentication
   337  // mechanism.
   338  func socks5Authenticate(rw *bufio.ReadWriter, method byte, req *SocksRequest) (err error) {
   339  	switch method {
   340  	case socksAuthNoneRequired:
   341  		// Straight into reading the connect.
   342  
   343  	case socksAuthUsernamePassword:
   344  		if err = socks5AuthRFC1929(rw, req); err != nil {
   345  			return
   346  		}
   347  
   348  	case socksAuthNoAcceptableMethods:
   349  		err = newTemporaryNetError("socks5Authenticate: SOCKS method select had no compatible methods")
   350  		return
   351  
   352  	default:
   353  		err = newTemporaryNetError("socks5Authenticate: SOCKS method select picked a unsupported method 0x%02x", method)
   354  		return
   355  	}
   356  
   357  	if err = socksFlushBuffers(rw); err != nil {
   358  		err = newTemporaryNetError("socks5Authenticate: Failed to flush buffers: %s", err)
   359  		return
   360  	}
   361  	return
   362  }
   363  
   364  // socks5AuthRFC1929 authenticates the client via RFC 1929 username/password
   365  // auth.  As a design decision any valid username/password is accepted as this
   366  // field is primarily used as an out-of-band argument passing mechanism for
   367  // pluggable transports.
   368  func socks5AuthRFC1929(rw *bufio.ReadWriter, req *SocksRequest) (err error) {
   369  	sendErrResp := func() {
   370  		// Swallow the write/flush error here, we are going to close the
   371  		// connection and the original failure is more useful.
   372  		resp := []byte{socksAuthRFC1929Ver, socksAuthRFC1929Fail}
   373  		rw.Write(resp[:])
   374  		socksFlushBuffers(rw)
   375  	}
   376  
   377  	// Validate the fixed parts of the command message.
   378  	if err = socksReadByteVerify(rw.Reader, "auth version", socksAuthRFC1929Ver); err != nil {
   379  		sendErrResp()
   380  		err = newTemporaryNetError("socks5AuthRFC1929: %s", err)
   381  		return
   382  	}
   383  
   384  	// Read the username.
   385  	var ulen byte
   386  	if ulen, err = socksReadByte(rw.Reader); err != nil {
   387  		err = newTemporaryNetError("socks5AuthRFC1929: Failed to read username length: %s", err)
   388  		return
   389  	}
   390  	if ulen < 1 {
   391  		sendErrResp()
   392  		err = newTemporaryNetError("socks5AuthRFC1929: username with 0 length")
   393  		return
   394  	}
   395  	var uname []byte
   396  	if uname, err = socksReadBytes(rw.Reader, int(ulen)); err != nil {
   397  		err = newTemporaryNetError("socks5AuthRFC1929: Failed to read username: %s", err)
   398  		return
   399  	}
   400  	req.Username = string(uname)
   401  
   402  	// Read the password.
   403  	var plen byte
   404  	if plen, err = socksReadByte(rw.Reader); err != nil {
   405  		err = newTemporaryNetError("socks5AuthRFC1929: Failed to read password length: %s", err)
   406  		return
   407  	}
   408  	if plen < 1 {
   409  		sendErrResp()
   410  		err = newTemporaryNetError("socks5AuthRFC1929: password with 0 length")
   411  		return
   412  	}
   413  	var passwd []byte
   414  	if passwd, err = socksReadBytes(rw.Reader, int(plen)); err != nil {
   415  		err = newTemporaryNetError("socks5AuthRFC1929: Failed to read password: %s", err)
   416  		return
   417  	}
   418  	if !(plen == 1 && passwd[0] == 0x00) {
   419  		// tor will set the password to 'NUL' if there are no arguments.
   420  		req.Password = string(passwd)
   421  	}
   422  
   423  	// [Psiphon]
   424  	// Since we don't need pluggable transport parameters and prefer enabling clients to proxy,
   425  	// don't parse or validate username/password as PT args.
   426  	/*
   427  		// Mash the username/password together and parse it as a pluggable
   428  		// transport argument string.
   429  		if req.Args, err = parseClientParameters(req.Username + req.Password); err != nil {
   430  			sendErrResp()
   431  			err = newTemporaryNetError("socks5AuthRFC1929: failed to parse client parameters: %s", err)
   432  			return
   433  		}
   434  	*/
   435  	// [Psiphon]
   436  
   437  	// Write success response
   438  	resp := []byte{socksAuthRFC1929Ver, socksAuthRFC1929Success}
   439  	if _, err = rw.Write(resp[:]); err != nil {
   440  		err = newTemporaryNetError("socks5AuthRFC1929: failed to write success response: %s", err)
   441  		return
   442  	}
   443  	return
   444  }
   445  
   446  // socks5ReadCommand reads a SOCKS5 client command and parses out the relevant
   447  // fields into a SocksRequest.  Only CMD_CONNECT is supported.
   448  func socks5ReadCommand(rw *bufio.ReadWriter, req *SocksRequest) (err error) {
   449  	sendErrResp := func(reason byte) {
   450  		// Swallow errors that occur when writing/flushing the response,
   451  		// connection will be closed anyway.
   452  		sendSocks5ResponseRejected(rw, reason)
   453  		socksFlushBuffers(rw)
   454  	}
   455  
   456  	// Validate the fixed parts of the command message.
   457  	if err = socksReadByteVerify(rw.Reader, "version", socks5Version); err != nil {
   458  		sendErrResp(SocksRepGeneralFailure)
   459  		err = newTemporaryNetError("socks5ReadCommand: %s", err)
   460  		return
   461  	}
   462  	if err = socksReadByteVerify(rw.Reader, "command", socksCmdConnect); err != nil {
   463  		sendErrResp(SocksRepCommandNotSupported)
   464  		err = newTemporaryNetError("socks5ReadCommand: %s", err)
   465  		return
   466  	}
   467  	if err = socksReadByteVerify(rw.Reader, "reserved", socksReserved); err != nil {
   468  		sendErrResp(SocksRepGeneralFailure)
   469  		err = newTemporaryNetError("socks5ReadCommand: %s", err)
   470  		return
   471  	}
   472  
   473  	// Read the destination address/port.
   474  	// XXX: This should probably eventually send socks 5 error messages instead
   475  	// of rudely closing connections on invalid addresses.
   476  	var atype byte
   477  	if atype, err = socksReadByte(rw.Reader); err != nil {
   478  		err = newTemporaryNetError("socks5ReadCommand: Failed to read address type: %s", err)
   479  		return
   480  	}
   481  	var host string
   482  	switch atype {
   483  	case socksAtypeV4:
   484  		var addr []byte
   485  		if addr, err = socksReadBytes(rw.Reader, net.IPv4len); err != nil {
   486  			err = newTemporaryNetError("socks5ReadCommand: Failed to read IPv4 address: %s", err)
   487  			return
   488  		}
   489  		host = net.IPv4(addr[0], addr[1], addr[2], addr[3]).String()
   490  
   491  	case socksAtypeDomainName:
   492  		var alen byte
   493  		if alen, err = socksReadByte(rw.Reader); err != nil {
   494  			err = newTemporaryNetError("socks5ReadCommand: Failed to read domain name length: %s", err)
   495  			return
   496  		}
   497  		if alen == 0 {
   498  			err = newTemporaryNetError("socks5ReadCommand: SOCKS request had domain name with 0 length")
   499  			return
   500  		}
   501  		var addr []byte
   502  		if addr, err = socksReadBytes(rw.Reader, int(alen)); err != nil {
   503  			err = newTemporaryNetError("socks5ReadCommand: Failed to read domain name: %s", err)
   504  			return
   505  		}
   506  		host = string(addr)
   507  
   508  	case socksAtypeV6:
   509  		var rawAddr []byte
   510  		if rawAddr, err = socksReadBytes(rw.Reader, net.IPv6len); err != nil {
   511  			err = newTemporaryNetError("socks5ReadCommand: Failed to read IPv6 address: %s", err)
   512  			return
   513  		}
   514  		addr := make(net.IP, net.IPv6len)
   515  		copy(addr[:], rawAddr[:])
   516  		host = fmt.Sprintf("[%s]", addr.String())
   517  
   518  	default:
   519  		sendErrResp(SocksRepAddressNotSupported)
   520  		err = newTemporaryNetError("socks5ReadCommand: SOCKS request had unsupported address type 0x%02x", atype)
   521  		return
   522  	}
   523  	var rawPort []byte
   524  	if rawPort, err = socksReadBytes(rw.Reader, 2); err != nil {
   525  		err = newTemporaryNetError("socks5ReadCommand: Failed to read port number: %s", err)
   526  		return
   527  	}
   528  	port := int(rawPort[0])<<8 | int(rawPort[1])<<0
   529  
   530  	if err = socksFlushBuffers(rw); err != nil {
   531  		err = newTemporaryNetError("socks5ReadCommand: Failed to flush buffers: %s", err)
   532  		return
   533  	}
   534  
   535  	req.Target = fmt.Sprintf("%s:%d", host, port)
   536  	return
   537  }
   538  
   539  // Send a SOCKS5 response with the given code. BND.ADDR/BND.PORT is always the
   540  // IPv4 address/port "0.0.0.0:0".
   541  func sendSocks5Response(w io.Writer, code byte) error {
   542  	resp := make([]byte, 4+4+2)
   543  	resp[0] = socks5Version
   544  	resp[1] = code
   545  	resp[2] = socksReserved
   546  	resp[3] = socksAtypeV4
   547  
   548  	// BND.ADDR/BND.PORT should be the address and port that the outgoing
   549  	// connection is bound to on the proxy, but Tor does not use this
   550  	// information, so all zeroes are sent.
   551  
   552  	if _, err := w.Write(resp[:]); err != nil {
   553  		err = newTemporaryNetError("sendSocks5Response: Failed write response: %s", err)
   554  		return err
   555  	}
   556  
   557  	return nil
   558  }
   559  
   560  // Send a SOCKS5 response code 0x00.
   561  func sendSocks5ResponseGranted(w io.Writer) error {
   562  	return sendSocks5Response(w, socksRepSucceeded)
   563  }
   564  
   565  // Send a SOCKS5 response with the provided failure reason.
   566  func sendSocks5ResponseRejected(w io.Writer, reason byte) error {
   567  	return sendSocks5Response(w, reason)
   568  }
   569  
   570  /*
   571   * Common helpers
   572   */
   573  
   574  func socksFlushBuffers(rw *bufio.ReadWriter) error {
   575  	if err := rw.Writer.Flush(); err != nil {
   576  		return err
   577  	}
   578  	if err := socksFlushReadBuffer(rw.Reader); err != nil {
   579  		return err
   580  	}
   581  	return nil
   582  }
   583  
   584  func socksFlushReadBuffer(r *bufio.Reader) error {
   585  	if r.Buffered() > 0 {
   586  		return fmt.Errorf("%d bytes left after SOCKS message", r.Buffered())
   587  	}
   588  	return nil
   589  }
   590  
   591  func socksReadByte(r *bufio.Reader) (byte, error) {
   592  	return r.ReadByte()
   593  }
   594  
   595  func socksReadBytes(r *bufio.Reader, n int) ([]byte, error) {
   596  	ret := make([]byte, n)
   597  	if _, err := io.ReadFull(r, ret); err != nil {
   598  		return nil, err
   599  	}
   600  	return ret, nil
   601  }
   602  
   603  func socksReadByteVerify(r *bufio.Reader, descr string, expected byte) error {
   604  	val, err := socksReadByte(r)
   605  	if err != nil {
   606  		return err
   607  	}
   608  	if val != expected {
   609  		return fmt.Errorf("SOCKS message field %s was 0x%02x, not 0x%02x", descr, val, expected)
   610  	}
   611  	return nil
   612  }
   613  
   614  func socksReadBytesUntil(r *bufio.Reader, end byte) ([]byte, error) {
   615  	val, err := r.ReadBytes(end)
   616  	if err != nil {
   617  		return nil, err
   618  	}
   619  	return val, nil
   620  }
   621  
   622  func socksPeekByte(r *bufio.Reader) (b byte, err error) {
   623  	var byteSlice []byte
   624  	if byteSlice, err = r.Peek(1); err != nil {
   625  		return
   626  	}
   627  	b = byteSlice[0]
   628  	return
   629  }
   630  
   631  // temporaryNetError is used for our custom errors. All such errors are "temporary";
   632  // that is, the listener doesn't need to be torn down when they occur. They also
   633  // need to implement the net.Error interface.
   634  type temporaryNetError struct {
   635  	error
   636  }
   637  
   638  // Ensure temporaryNetError implements net.Error
   639  var _ net.Error = temporaryNetError{}
   640  
   641  func newTemporaryNetError(errMsg string, args ...interface{}) *temporaryNetError {
   642  	return &temporaryNetError{
   643  		error: fmt.Errorf(errMsg, args...),
   644  	}
   645  }
   646  
   647  func (tne temporaryNetError) Timeout() bool {
   648  	return false
   649  }
   650  
   651  func (tne temporaryNetError) Temporary() bool {
   652  	return true
   653  }
   654  
   655  /*
   656   * SOCKS4a-specific code
   657   */
   658  
   659  // Read a SOCKS4a connect request. Returns a SocksRequest.
   660  func readSocks4aConnect(r *bufio.Reader) (req SocksRequest, err error) {
   661  	// Validate the version.
   662  	if err = socksReadByteVerify(r, "version", socks4Version); err != nil {
   663  		err = newTemporaryNetError("readSocks4aConnect: %s", err.Error())
   664  		return
   665  	}
   666  
   667  	var cmdConnect byte
   668  	if cmdConnect, err = socksReadByte(r); err != nil {
   669  		err = newTemporaryNetError("readSocks4aConnect: Failed to read connect command: %s", err.Error())
   670  		return
   671  	}
   672  	if cmdConnect != socksCmdConnect {
   673  		err = newTemporaryNetError("readSocks4aConnect: SOCKS header had command 0x%02x, not 0x%02x", cmdConnect, socksCmdConnect)
   674  		return
   675  	}
   676  
   677  	var rawPort []byte
   678  	if rawPort, err = socksReadBytes(r, 2); err != nil {
   679  		err = newTemporaryNetError("readSocks4aConnect: Failed to read port: %s", err.Error())
   680  		return
   681  	}
   682  	port := int(rawPort[0])<<8 | int(rawPort[1])<<0
   683  
   684  	var rawHostIP []byte
   685  	if rawHostIP, err = socksReadBytes(r, 4); err != nil {
   686  		err = newTemporaryNetError("readSocks4aConnect: Failed to read IP address: %s", err.Error())
   687  		return
   688  	}
   689  	// If there's a hostname, it comes after the username, so we'll wait a bit
   690  	// before we process the IP info.
   691  
   692  	var usernameBytes []byte
   693  	usernameBytes, err = socksReadBytesUntil(r, '\x00')
   694  	if err != nil {
   695  		err = newTemporaryNetError("readSocks4aConnect: Failed to read username: %s", err.Error())
   696  		return
   697  	}
   698  	req.Username = string(usernameBytes[:len(usernameBytes)-1])
   699  
   700  	// [Psiphon]
   701  	// Since we don't need pluggable transport parameters and prefer enabling clients to proxy,
   702  	// don't parse or validate username/password as PT args.
   703  	/*
   704  		req.Args, err = parseClientParameters(req.Username)
   705  		if err != nil {
   706  			err = newTemporaryNetError("readSocks4aConnect: Failed to parse client parameters: %s", err.Error())
   707  			return
   708  		}
   709  	*/
   710  	// [Psiphon]
   711  
   712  	var host string
   713  	if rawHostIP[0] == 0 && rawHostIP[1] == 0 && rawHostIP[2] == 0 && rawHostIP[3] != 0 {
   714  		// If the IP is of the form 0.0.0.x (with x nonzero), then a domain name is provided.
   715  		var hostBytes []byte
   716  		if hostBytes, err = socksReadBytesUntil(r, '\x00'); err != nil {
   717  			err = newTemporaryNetError("readSocks4aConnect: Failed to read domain name: %s", err.Error())
   718  			return
   719  		}
   720  		host = string(hostBytes[:len(hostBytes)-1])
   721  	} else {
   722  		host = net.IPv4(rawHostIP[0], rawHostIP[1], rawHostIP[2], rawHostIP[3]).String()
   723  	}
   724  
   725  	req.Target = fmt.Sprintf("%s:%d", host, port)
   726  
   727  	if err = socksFlushReadBuffer(r); err != nil {
   728  		err = newTemporaryNetError("readSocks4aConnect: Failed to flush buffers: %s", err.Error())
   729  		return
   730  	}
   731  
   732  	return
   733  }
   734  
   735  // Send a SOCKS4a response with the given code and address. If the IP field
   736  // inside addr is not an IPv4 address, the IP portion of the response will be
   737  // four zero bytes.
   738  func sendSocks4aResponse(w io.Writer, code byte, addr *net.TCPAddr) error {
   739  	var resp [8]byte
   740  	resp[0] = socks4ResponseVersion
   741  	resp[1] = code
   742  	resp[2] = byte((addr.Port >> 8) & 0xff)
   743  	resp[3] = byte((addr.Port >> 0) & 0xff)
   744  	ipv4 := addr.IP.To4()
   745  	if ipv4 != nil {
   746  		resp[4] = ipv4[0]
   747  		resp[5] = ipv4[1]
   748  		resp[6] = ipv4[2]
   749  		resp[7] = ipv4[3]
   750  	}
   751  
   752  	if _, err := w.Write(resp[:]); err != nil {
   753  		err = newTemporaryNetError("sendSocks4aResponse: Failed to write response: %s", err.Error())
   754  		return err
   755  	}
   756  
   757  	return nil
   758  }
   759  
   760  // Send a SOCKS4a response code 0x5a.
   761  func sendSocks4aResponseGranted(w io.Writer, addr *net.TCPAddr) error {
   762  	return sendSocks4aResponse(w, socks4RequestGranted, addr)
   763  }
   764  
   765  // Send a SOCKS4a response code 0x5b (with an all-zero address).
   766  func sendSocks4aResponseRejected(w io.Writer) error {
   767  	emptyAddr := net.TCPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 0}
   768  	return sendSocks4aResponse(w, socks4RequestRejected, &emptyAddr)
   769  }