github.com/EagleQL/Xray-core@v1.4.3/infra/conf/transport_authenticators.go (about)

     1  package conf
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/golang/protobuf/proto"
     7  
     8  	"github.com/xtls/xray-core/transport/internet/headers/http"
     9  	"github.com/xtls/xray-core/transport/internet/headers/noop"
    10  	"github.com/xtls/xray-core/transport/internet/headers/srtp"
    11  	"github.com/xtls/xray-core/transport/internet/headers/tls"
    12  	"github.com/xtls/xray-core/transport/internet/headers/utp"
    13  	"github.com/xtls/xray-core/transport/internet/headers/wechat"
    14  	"github.com/xtls/xray-core/transport/internet/headers/wireguard"
    15  )
    16  
    17  type NoOpAuthenticator struct{}
    18  
    19  func (NoOpAuthenticator) Build() (proto.Message, error) {
    20  	return new(noop.Config), nil
    21  }
    22  
    23  type NoOpConnectionAuthenticator struct{}
    24  
    25  func (NoOpConnectionAuthenticator) Build() (proto.Message, error) {
    26  	return new(noop.ConnectionConfig), nil
    27  }
    28  
    29  type SRTPAuthenticator struct{}
    30  
    31  func (SRTPAuthenticator) Build() (proto.Message, error) {
    32  	return new(srtp.Config), nil
    33  }
    34  
    35  type UTPAuthenticator struct{}
    36  
    37  func (UTPAuthenticator) Build() (proto.Message, error) {
    38  	return new(utp.Config), nil
    39  }
    40  
    41  type WechatVideoAuthenticator struct{}
    42  
    43  func (WechatVideoAuthenticator) Build() (proto.Message, error) {
    44  	return new(wechat.VideoConfig), nil
    45  }
    46  
    47  type WireguardAuthenticator struct{}
    48  
    49  func (WireguardAuthenticator) Build() (proto.Message, error) {
    50  	return new(wireguard.WireguardConfig), nil
    51  }
    52  
    53  type DTLSAuthenticator struct{}
    54  
    55  func (DTLSAuthenticator) Build() (proto.Message, error) {
    56  	return new(tls.PacketConfig), nil
    57  }
    58  
    59  type AuthenticatorRequest struct {
    60  	Version string                 `json:"version"`
    61  	Method  string                 `json:"method"`
    62  	Path    StringList             `json:"path"`
    63  	Headers map[string]*StringList `json:"headers"`
    64  }
    65  
    66  func sortMapKeys(m map[string]*StringList) []string {
    67  	var keys []string
    68  	for key := range m {
    69  		keys = append(keys, key)
    70  	}
    71  	sort.Strings(keys)
    72  	return keys
    73  }
    74  
    75  func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) {
    76  	config := &http.RequestConfig{
    77  		Uri: []string{"/"},
    78  		Header: []*http.Header{
    79  			{
    80  				Name:  "Host",
    81  				Value: []string{"www.baidu.com", "www.bing.com"},
    82  			},
    83  			{
    84  				Name: "User-Agent",
    85  				Value: []string{
    86  					"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    87  					"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46",
    88  				},
    89  			},
    90  			{
    91  				Name:  "Accept-Encoding",
    92  				Value: []string{"gzip, deflate"},
    93  			},
    94  			{
    95  				Name:  "Connection",
    96  				Value: []string{"keep-alive"},
    97  			},
    98  			{
    99  				Name:  "Pragma",
   100  				Value: []string{"no-cache"},
   101  			},
   102  		},
   103  	}
   104  
   105  	if len(v.Version) > 0 {
   106  		config.Version = &http.Version{Value: v.Version}
   107  	}
   108  
   109  	if len(v.Method) > 0 {
   110  		config.Method = &http.Method{Value: v.Method}
   111  	}
   112  
   113  	if len(v.Path) > 0 {
   114  		config.Uri = append([]string(nil), (v.Path)...)
   115  	}
   116  
   117  	if len(v.Headers) > 0 {
   118  		config.Header = make([]*http.Header, 0, len(v.Headers))
   119  		headerNames := sortMapKeys(v.Headers)
   120  		for _, key := range headerNames {
   121  			value := v.Headers[key]
   122  			if value == nil {
   123  				return nil, newError("empty HTTP header value: " + key).AtError()
   124  			}
   125  			config.Header = append(config.Header, &http.Header{
   126  				Name:  key,
   127  				Value: append([]string(nil), (*value)...),
   128  			})
   129  		}
   130  	}
   131  
   132  	return config, nil
   133  }
   134  
   135  type AuthenticatorResponse struct {
   136  	Version string                 `json:"version"`
   137  	Status  string                 `json:"status"`
   138  	Reason  string                 `json:"reason"`
   139  	Headers map[string]*StringList `json:"headers"`
   140  }
   141  
   142  func (v *AuthenticatorResponse) Build() (*http.ResponseConfig, error) {
   143  	config := &http.ResponseConfig{
   144  		Header: []*http.Header{
   145  			{
   146  				Name:  "Content-Type",
   147  				Value: []string{"application/octet-stream", "video/mpeg"},
   148  			},
   149  			{
   150  				Name:  "Transfer-Encoding",
   151  				Value: []string{"chunked"},
   152  			},
   153  			{
   154  				Name:  "Connection",
   155  				Value: []string{"keep-alive"},
   156  			},
   157  			{
   158  				Name:  "Pragma",
   159  				Value: []string{"no-cache"},
   160  			},
   161  			{
   162  				Name:  "Cache-Control",
   163  				Value: []string{"private", "no-cache"},
   164  			},
   165  		},
   166  	}
   167  
   168  	if len(v.Version) > 0 {
   169  		config.Version = &http.Version{Value: v.Version}
   170  	}
   171  
   172  	if len(v.Status) > 0 || len(v.Reason) > 0 {
   173  		config.Status = &http.Status{
   174  			Code:   "200",
   175  			Reason: "OK",
   176  		}
   177  		if len(v.Status) > 0 {
   178  			config.Status.Code = v.Status
   179  		}
   180  		if len(v.Reason) > 0 {
   181  			config.Status.Reason = v.Reason
   182  		}
   183  	}
   184  
   185  	if len(v.Headers) > 0 {
   186  		config.Header = make([]*http.Header, 0, len(v.Headers))
   187  		headerNames := sortMapKeys(v.Headers)
   188  		for _, key := range headerNames {
   189  			value := v.Headers[key]
   190  			if value == nil {
   191  				return nil, newError("empty HTTP header value: " + key).AtError()
   192  			}
   193  			config.Header = append(config.Header, &http.Header{
   194  				Name:  key,
   195  				Value: append([]string(nil), (*value)...),
   196  			})
   197  		}
   198  	}
   199  
   200  	return config, nil
   201  }
   202  
   203  type Authenticator struct {
   204  	Request  AuthenticatorRequest  `json:"request"`
   205  	Response AuthenticatorResponse `json:"response"`
   206  }
   207  
   208  func (v *Authenticator) Build() (proto.Message, error) {
   209  	config := new(http.Config)
   210  	requestConfig, err := v.Request.Build()
   211  	if err != nil {
   212  		return nil, err
   213  	}
   214  	config.Request = requestConfig
   215  
   216  	responseConfig, err := v.Response.Build()
   217  	if err != nil {
   218  		return nil, err
   219  	}
   220  	config.Response = responseConfig
   221  
   222  	return config, nil
   223  }