github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/v4/transport_authenticators.go (about)

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