Beispiel #1
0
func (request *Socks5Request) Destination() v2net.VAddress {
	switch request.AddrType {
	case AddrTypeIPv4:
		return v2net.IPAddress(request.IPv4[:], request.Port)
	case AddrTypeIPv6:
		return v2net.IPAddress(request.IPv6[:], request.Port)
	case AddrTypeDomain:
		return v2net.DomainAddress(request.Domain, request.Port)
	default:
		panic("Unknown address type")
	}
}
Beispiel #2
0
func (config VNextConfig) ToVNextServer() VNextServer {
	users := make([]core.User, 0, len(config.Users))
	for _, user := range config.Users {
		vuser, err := user.ToUser()
		if err != nil {
			panic(log.Error("Failed to convert %v to User.", user))
		}
		users = append(users, vuser)
	}
	ip := net.ParseIP(config.Address)
	if ip == nil {
		panic(log.Error("Unable to parse VNext IP: %s", config.Address))
	}
	return VNextServer{
		v2net.IPAddress(ip, config.Port),
		users}
}
Beispiel #3
0
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
	buffer := make([]byte, 256)

	nBytes, err := reader.Read(buffer[:core.IDBytesLen])
	if err != nil {
		return nil, err
	}

	log.Debug("Read user hash: %v", buffer[:nBytes])

	userId, timeSec, valid := r.vUserSet.GetUser(buffer[:nBytes])
	if !valid {
		return nil, ErrorInvalidUser
	}

	aesCipher, err := aes.NewCipher(userId.CmdKey())
	if err != nil {
		return nil, err
	}
	aesStream := cipher.NewCFBDecrypter(aesCipher, v2hash.Int64Hash(timeSec))
	decryptor := v2io.NewCryptionReader(aesStream, reader)

	if err != nil {
		return nil, err
	}

	nBytes, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}

	randomLength := buffer[0]
	if randomLength <= 0 || randomLength > 32 {
		return nil, fmt.Errorf("Unexpected random length %d", randomLength)
	}
	_, err = decryptor.Read(buffer[:randomLength])
	if err != nil {
		return nil, err
	}

	nBytes, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}

	request := &VMessRequest{
		UserId:  *userId,
		Version: buffer[0],
	}

	if request.Version != Version {
		log.Error("Unknown VMess version %d", request.Version)
		return nil, ErrorInvalidVerion
	}

	// TODO: check number of bytes returned
	_, err = decryptor.Read(request.RequestIV[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(request.RequestKey[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(request.ResponseHeader[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	request.Command = buffer[0]

	_, err = decryptor.Read(buffer[0:2])
	if err != nil {
		return nil, err
	}
	port := binary.BigEndian.Uint16(buffer[0:2])

	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	switch buffer[0] {
	case addrTypeIPv4:
		_, err = decryptor.Read(buffer[1:5])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[1:5], port)
	case addrTypeIPv6:
		_, err = decryptor.Read(buffer[1:17])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[1:17], port)
	case addrTypeDomain:
		_, err = decryptor.Read(buffer[1:2])
		if err != nil {
			return nil, err
		}
		domainLength := buffer[1]
		_, err = decryptor.Read(buffer[2 : 2+domainLength])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.DomainAddress(string(buffer[2:2+domainLength]), port)
	}
	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	randomLength = buffer[0]
	_, err = decryptor.Read(buffer[:randomLength])
	if err != nil {
		return nil, err
	}

	return request, nil
}
Beispiel #4
0
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
	request := new(VMessRequest)

	buffer := make([]byte, 256)
	nBytes, err := reader.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	// TODO: verify version number
	request.Version = buffer[0]

	nBytes, err = reader.Read(buffer[:len(request.UserId)])
	if err != nil {
		return nil, err
	}

	userId, valid := r.vUserSet.IsValidUserId(buffer[:nBytes])
	if !valid {
		return nil, ErrorInvalidUser
	}
	request.UserId = *userId

	decryptor, err := NewDecryptionReader(reader, userId.Hash([]byte("PWD")), make([]byte, blockSize))
	if err != nil {
		return nil, err
	}

	nBytes, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}

	randomLength := buffer[0]
	if randomLength <= 0 || randomLength > 32 {
		return nil, fmt.Errorf("Unexpected random length %d", randomLength)
	}
	_, err = decryptor.Read(buffer[:randomLength])
	if err != nil {
		return nil, err
	}

	// TODO: check number of bytes returned
	_, err = decryptor.Read(request.RequestIV[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(request.RequestKey[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(request.ResponseHeader[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	request.Command = buffer[0]

	_, err = decryptor.Read(buffer[0:2])
	if err != nil {
		return nil, err
	}
	port := binary.BigEndian.Uint16(buffer[0:2])

	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	switch buffer[0] {
	case addrTypeIPv4:
		_, err = decryptor.Read(buffer[1:5])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[1:5], port)
	case addrTypeIPv6:
		_, err = decryptor.Read(buffer[1:17])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[1:17], port)
	case addrTypeDomain:
		_, err = decryptor.Read(buffer[1:2])
		if err != nil {
			return nil, err
		}
		domainLength := buffer[1]
		_, err = decryptor.Read(buffer[2 : 2+domainLength])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.DomainAddress(string(buffer[2:2+domainLength]), port)
	}
	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	randomLength = buffer[0]
	_, err = decryptor.Read(buffer[:randomLength])
	if err != nil {
		return nil, err
	}

	return request, nil
}
Beispiel #5
0
func (server *SocksServer) HandleConnection(connection net.Conn) error {
	defer connection.Close()

	reader := connection.(io.Reader)

	auth, auth4, err := socksio.ReadAuthentication(reader)
	if err != nil && err != socksio.ErrorSocksVersion4 {
		log.Error("Error on reading authentication: %v", err)
		return err
	}

	var dest v2net.Address

	// TODO refactor this part
	if err == socksio.ErrorSocksVersion4 {
		result := socksio.Socks4RequestGranted
		if auth4.Command == socksio.CmdBind {
			result = socksio.Socks4RequestRejected
		}
		socks4Response := socksio.NewSocks4AuthenticationResponse(result, auth4.Port, auth4.IP[:])
		socksio.WriteSocks4AuthenticationResponse(connection, socks4Response)

		if result == socksio.Socks4RequestRejected {
			return ErrorCommandNotSupported
		}

		dest = v2net.IPAddress(auth4.IP[:], auth4.Port)
	} else {
		expectedAuthMethod := socksio.AuthNotRequired
		if server.config.AuthMethod == JsonAuthMethodUserPass {
			expectedAuthMethod = socksio.AuthUserPass
		}

		if !auth.HasAuthMethod(expectedAuthMethod) {
			authResponse := socksio.NewAuthenticationResponse(socksio.AuthNoMatchingMethod)
			err = socksio.WriteAuthentication(connection, authResponse)
			if err != nil {
				log.Error("Error on socksio write authentication: %v", err)
				return err
			}
			log.Warning("Client doesn't support allowed any auth methods.")
			return ErrorAuthenticationFailed
		}

		authResponse := socksio.NewAuthenticationResponse(expectedAuthMethod)
		err = socksio.WriteAuthentication(connection, authResponse)
		if err != nil {
			log.Error("Error on socksio write authentication: %v", err)
			return err
		}
		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)
			err = socksio.WriteUserPassResponse(connection, upResponse)
			if err != nil {
				log.Error("Error on socksio write user pass response: %v", err)
				return err
			}
			if status != byte(0) {
				return ErrorInvalidUser
			}
		}

		request, err := socksio.ReadRequest(reader)
		if err != nil {
			log.Error("Error on reading socks request: %v", err)
			return err
		}

		response := socksio.NewSocks5Response()

		if request.Command == socksio.CmdBind || request.Command == socksio.CmdUdpAssociate {
			response := socksio.NewSocks5Response()
			response.Error = socksio.ErrorCommandNotSupported
			err = socksio.WriteResponse(connection, response)
			if err != nil {
				log.Error("Error on socksio write response: %v", err)
				return err
			}
			log.Warning("Unsupported socks command %d", request.Command)
			return ErrorCommandNotSupported
		}

		response.Error = socksio.ErrorSuccess
		response.Port = request.Port
		response.AddrType = request.AddrType
		switch response.AddrType {
		case socksio.AddrTypeIPv4:
			copy(response.IPv4[:], request.IPv4[:])
		case socksio.AddrTypeIPv6:
			copy(response.IPv6[:], request.IPv6[:])
		case socksio.AddrTypeDomain:
			response.Domain = request.Domain
		}
		err = socksio.WriteResponse(connection, response)
		if err != nil {
			log.Error("Error on socksio write response: %v", err)
			return err
		}

		dest = request.Destination()
	}

	ray := server.vPoint.NewInboundConnectionAccepted(dest)
	input := ray.InboundInput()
	output := ray.InboundOutput()
	readFinish := make(chan bool)
	writeFinish := make(chan bool)

	go server.dumpInput(reader, input, readFinish)
	go server.dumpOutput(connection, output, writeFinish)
	<-writeFinish

	return nil
}
Beispiel #6
0
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
	request := new(VMessRequest)

	buffer := make([]byte, 256)
	nBytes, err := reader.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	// TODO: verify version number
	request.Version = buffer[0]

	nBytes, err = reader.Read(buffer[:core.IDBytesLen])
	if err != nil {
		return nil, err
	}

	userId, valid := r.vUserSet.GetUser(buffer[:nBytes])
	if !valid {
		return nil, ErrorInvalidUser
	}
	request.UserId = *userId

	aesCipher, err := aes.NewCipher(userId.Hash([]byte(CryptoMessage)))
	if err != nil {
		return nil, err
	}
	aesStream := cipher.NewCFBDecrypter(aesCipher, emptyIV)
	decryptor := v2io.NewCryptionReader(aesStream, reader)

	if err != nil {
		return nil, err
	}

	nBytes, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}

	randomLength := buffer[0]
	if randomLength <= 0 || randomLength > 32 {
		return nil, fmt.Errorf("Unexpected random length %d", randomLength)
	}
	_, err = decryptor.Read(buffer[:randomLength])
	if err != nil {
		return nil, err
	}

	// TODO: check number of bytes returned
	_, err = decryptor.Read(request.RequestIV[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(request.RequestKey[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(request.ResponseHeader[:])
	if err != nil {
		return nil, err
	}
	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	request.Command = buffer[0]

	_, err = decryptor.Read(buffer[0:2])
	if err != nil {
		return nil, err
	}
	port := binary.BigEndian.Uint16(buffer[0:2])

	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	switch buffer[0] {
	case addrTypeIPv4:
		_, err = decryptor.Read(buffer[1:5])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[1:5], port)
	case addrTypeIPv6:
		_, err = decryptor.Read(buffer[1:17])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.IPAddress(buffer[1:17], port)
	case addrTypeDomain:
		_, err = decryptor.Read(buffer[1:2])
		if err != nil {
			return nil, err
		}
		domainLength := buffer[1]
		_, err = decryptor.Read(buffer[2 : 2+domainLength])
		if err != nil {
			return nil, err
		}
		request.Address = v2net.DomainAddress(string(buffer[2:2+domainLength]), port)
	}
	_, err = decryptor.Read(buffer[0:1])
	if err != nil {
		return nil, err
	}
	randomLength = buffer[0]
	_, err = decryptor.Read(buffer[:randomLength])
	if err != nil {
		return nil, err
	}

	return request, nil
}