mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 17:46:58 -05:00
username/password support for socks proxy
This commit is contained in:
parent
0c1277c439
commit
4c963a51ed
@ -86,6 +86,57 @@ func WriteAuthentication(writer io.Writer, response *Socks5AuthenticationRespons
|
||||
return err
|
||||
}
|
||||
|
||||
type Socks5UserPassRequest struct {
|
||||
version byte
|
||||
username string
|
||||
password string
|
||||
}
|
||||
|
||||
func (request Socks5UserPassRequest) IsValid(username string, password string) bool {
|
||||
return request.username == username && request.password == password
|
||||
}
|
||||
|
||||
func ReadUserPassRequest(reader io.Reader) (request Socks5UserPassRequest, err error) {
|
||||
buffer := make([]byte, 256)
|
||||
_, err = reader.Read(buffer[0:2])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
request.version = buffer[0]
|
||||
nUsername := buffer[1]
|
||||
nBytes, err := reader.Read(buffer[:nUsername])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
request.username = string(buffer[:nBytes])
|
||||
|
||||
_, err = reader.Read(buffer[0:1])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
nPassword := buffer[0]
|
||||
nBytes, err = reader.Read(buffer[:nPassword])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
request.password = string(buffer[:nBytes])
|
||||
return
|
||||
}
|
||||
|
||||
type Socks5UserPassResponse struct {
|
||||
version byte
|
||||
status byte
|
||||
}
|
||||
|
||||
func NewSocks5UserPassResponse(status byte) Socks5UserPassResponse {
|
||||
return Socks5UserPassResponse{socksVersion, status}
|
||||
}
|
||||
|
||||
func WriteUserPassResponse(writer io.Writer, response Socks5UserPassResponse) error {
|
||||
_, err := writer.Write([]byte{response.version, response.status})
|
||||
return err
|
||||
}
|
||||
|
||||
const (
|
||||
AddrTypeIPv4 = byte(0x01)
|
||||
AddrTypeIPv6 = byte(0x04)
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
var (
|
||||
ErrorAuthenticationFailed = errors.New("None of the authentication methods is allowed.")
|
||||
ErrorCommandNotSupported = errors.New("Client requested an unsupported command.")
|
||||
ErrorInvalidUser = errors.New("Invalid username or password.")
|
||||
)
|
||||
|
||||
// SocksServer is a SOCKS 5 proxy server
|
||||
@ -84,8 +85,25 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
|
||||
return ErrorAuthenticationFailed
|
||||
}
|
||||
|
||||
authResponse := socksio.NewAuthenticationResponse(socksio.AuthNotRequired)
|
||||
authResponse := socksio.NewAuthenticationResponse(expectedAuthMethod)
|
||||
socksio.WriteAuthentication(connection, authResponse)
|
||||
|
||||
if server.config.AuthMethod == JsonAuthMethodUserPass {
|
||||
upRequest, err := socksio.ReadUserPassRequest(reader)
|
||||
if err != nil {
|
||||
log.Error("Failed to read username and password: %v", err)
|
||||
return err
|
||||
}
|
||||
status := byte(0)
|
||||
if ! upRequest.IsValid(server.config.Username, server.config.Password) {
|
||||
status = byte(0xFF)
|
||||
}
|
||||
upResponse := socksio.NewSocks5UserPassResponse(status)
|
||||
socksio.WriteUserPassResponse(connection, upResponse)
|
||||
if status != byte(0) {
|
||||
return ErrorInvalidUser
|
||||
}
|
||||
}
|
||||
|
||||
request, err := socksio.ReadRequest(reader)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user