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