Beispiel #1
0
func (server *SocksServer) HandleConnection(connection net.Conn) error {
	defer connection.Close()

	auth, err := socksio.ReadAuthentication(connection)
	if err != nil {
		log.Print(err)
		return err
	}
	log.Print(auth)

	if !auth.HasAuthMethod(socksio.AuthNotRequired) {
		// TODO send response with FF
		log.Print(ErrorAuthenticationFailed)
		return ErrorAuthenticationFailed
	}

	authResponse := socksio.NewAuthenticationResponse(socksio.AuthNotRequired)
	socksio.WriteAuthentication(connection, authResponse)

	request, err := socksio.ReadRequest(connection)
	if err != nil {
		log.Print(err)
		return err
	}

	response := socksio.NewSocks5Response()

	if request.Command == socksio.CmdBind || request.Command == socksio.CmdUdpAssociate {
		response := socksio.NewSocks5Response()
		response.Error = socksio.ErrorCommandNotSupported
		socksio.WriteResponse(connection, response)
		log.Print(ErrorCommandNotSupported)
		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
	}
	socksio.WriteResponse(connection, response)

	ray := server.vPoint.NewInboundConnectionAccepted(request.Destination())
	input := ray.InboundInput()
	output := ray.InboundOutput()
	finish := make(chan bool, 2)

	go server.dumpInput(connection, input, finish)
	go server.dumpOutput(connection, output, finish)
	server.waitForFinish(finish)

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

	reader := bufio.NewReader(connection)

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

	expectedAuthMethod := socksio.AuthNotRequired
	if server.config.AuthMethod == JsonAuthMethodUserPass {
		expectedAuthMethod = socksio.AuthUserPass
	}

	if !auth.HasAuthMethod(expectedAuthMethod) {
		authResponse := socksio.NewAuthenticationResponse(socksio.AuthNoMatchingMethod)
		socksio.WriteAuthentication(connection, authResponse)

		log.Warning("Client doesn't support allowed any auth methods.")
		return ErrorAuthenticationFailed
	}

	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 {
		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
		socksio.WriteResponse(connection, response)
		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
	}
	socksio.WriteResponse(connection, response)

	ray := server.vPoint.NewInboundConnectionAccepted(request.Destination())
	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 #3
0
func (server *SocksServer) HandleConnection(connection net.Conn) error {
	defer connection.Close()

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

	expectedAuthMethod := socksio.AuthNotRequired
	if server.config.AuthMethod == JsonAuthMethodUserPass {
		expectedAuthMethod = socksio.AuthUserPass
	}

	if !auth.HasAuthMethod(expectedAuthMethod) {
		authResponse := socksio.NewAuthenticationResponse(socksio.AuthNoMatchingMethod)
		socksio.WriteAuthentication(connection, authResponse)

		log.Info("Client doesn't support allowed any auth methods.")
		return ErrorAuthenticationFailed
	}

	log.Debug("Auth accepted, responding auth.")
	authResponse := socksio.NewAuthenticationResponse(socksio.AuthNotRequired)
	socksio.WriteAuthentication(connection, authResponse)

	request, err := socksio.ReadRequest(connection)
	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
		socksio.WriteResponse(connection, response)
		log.Info("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
	}
	log.Debug("Socks response port = %d", response.Port)
	socksio.WriteResponse(connection, response)

	ray := server.vPoint.NewInboundConnectionAccepted(request.Destination())
	input := ray.InboundInput()
	output := ray.InboundOutput()
	finish := make(chan bool, 2)

	go server.dumpInput(connection, input, finish)
	go server.dumpOutput(connection, output, finish)
	server.waitForFinish(finish)

	return nil
}