|  | @@ -0,0 +1,87 @@
 | 
	
		
			
				|  |  | +package internet
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import (
 | 
	
		
			
				|  |  | +	"errors"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	"github.com/v2ray/v2ray-core/common/alloc"
 | 
	
		
			
				|  |  | +	"github.com/v2ray/v2ray-core/common/loader"
 | 
	
		
			
				|  |  | +)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type Authenticator interface {
 | 
	
		
			
				|  |  | +	Seal(*alloc.Buffer)
 | 
	
		
			
				|  |  | +	Open(*alloc.Buffer) bool
 | 
	
		
			
				|  |  | +	Overhead() int
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type AuthenticatorFactory interface {
 | 
	
		
			
				|  |  | +	Create(AuthenticatorConfig) Authenticator
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type AuthenticatorConfig interface {
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +var (
 | 
	
		
			
				|  |  | +	ErrDuplicatedAuthenticator = errors.New("Authenticator already registered.")
 | 
	
		
			
				|  |  | +	ErrAuthenticatorNotFound   = errors.New("Authenticator not found.")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	authenticatorCache = make(map[string]AuthenticatorFactory)
 | 
	
		
			
				|  |  | +	configCache        loader.ConfigLoader
 | 
	
		
			
				|  |  | +)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func RegisterAuthenticator(name string, factory AuthenticatorFactory, configCreator loader.ConfigCreator) error {
 | 
	
		
			
				|  |  | +	if _, found := authenticatorCache[name]; found {
 | 
	
		
			
				|  |  | +		return ErrDuplicatedAuthenticator
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	authenticatorCache[name] = factory
 | 
	
		
			
				|  |  | +	return configCache.RegisterCreator(name, configCreator)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func CreateAuthenticator(name string, config AuthenticatorConfig) (Authenticator, error) {
 | 
	
		
			
				|  |  | +	factory, found := authenticatorCache[name]
 | 
	
		
			
				|  |  | +	if !found {
 | 
	
		
			
				|  |  | +		return nil, ErrAuthenticatorNotFound
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return factory.Create(config.(AuthenticatorConfig)), nil
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func CreateAuthenticatorConfig(rawConfig []byte) (string, AuthenticatorConfig, error) {
 | 
	
		
			
				|  |  | +	config, name, err := configCache.Load(rawConfig)
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		return name, nil, err
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return name, config, nil
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type AuthenticatorChain struct {
 | 
	
		
			
				|  |  | +	authenticators []Authenticator
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func NewAuthenticatorChain(auths ...Authenticator) Authenticator {
 | 
	
		
			
				|  |  | +	return &AuthenticatorChain{
 | 
	
		
			
				|  |  | +		authenticators: auths,
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func (this *AuthenticatorChain) Overhead() int {
 | 
	
		
			
				|  |  | +	total := 0
 | 
	
		
			
				|  |  | +	for _, auth := range this.authenticators {
 | 
	
		
			
				|  |  | +		total += auth.Overhead()
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return total
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func (this *AuthenticatorChain) Open(payload *alloc.Buffer) bool {
 | 
	
		
			
				|  |  | +	for _, auth := range this.authenticators {
 | 
	
		
			
				|  |  | +		if !auth.Open(payload) {
 | 
	
		
			
				|  |  | +			return false
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return true
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func (this *AuthenticatorChain) Seal(payload *alloc.Buffer) {
 | 
	
		
			
				|  |  | +	for i := len(this.authenticators) - 1; i >= 0; i-- {
 | 
	
		
			
				|  |  | +		auth := this.authenticators[i]
 | 
	
		
			
				|  |  | +		auth.Seal(payload)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 |