socks.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. package protocol
  2. import (
  3. "encoding/binary"
  4. "io"
  5. "github.com/v2ray/v2ray-core/common/alloc"
  6. "github.com/v2ray/v2ray-core/common/errors"
  7. "github.com/v2ray/v2ray-core/common/log"
  8. v2net "github.com/v2ray/v2ray-core/common/net"
  9. )
  10. const (
  11. socksVersion = byte(0x05)
  12. socks4Version = byte(0x04)
  13. AuthNotRequired = byte(0x00)
  14. AuthGssApi = byte(0x01)
  15. AuthUserPass = byte(0x02)
  16. AuthNoMatchingMethod = byte(0xFF)
  17. Socks4RequestGranted = byte(90)
  18. Socks4RequestRejected = byte(91)
  19. )
  20. // Authentication request header of Socks5 protocol
  21. type Socks5AuthenticationRequest struct {
  22. version byte
  23. nMethods byte
  24. authMethods [256]byte
  25. }
  26. func (request *Socks5AuthenticationRequest) HasAuthMethod(method byte) bool {
  27. for i := 0; i < int(request.nMethods); i++ {
  28. if request.authMethods[i] == method {
  29. return true
  30. }
  31. }
  32. return false
  33. }
  34. func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, auth4 Socks4AuthenticationRequest, err error) {
  35. buffer := alloc.NewSmallBuffer()
  36. defer buffer.Release()
  37. nBytes, err := reader.Read(buffer.Value)
  38. if err != nil {
  39. return
  40. }
  41. if nBytes < 2 {
  42. log.Info("Socks expected 2 bytes read, but only %d bytes read", nBytes)
  43. err = errors.NewCorruptedPacketError()
  44. return
  45. }
  46. if buffer.Value[0] == socks4Version {
  47. auth4.Version = buffer.Value[0]
  48. auth4.Command = buffer.Value[1]
  49. auth4.Port = binary.BigEndian.Uint16(buffer.Value[2:4])
  50. copy(auth4.IP[:], buffer.Value[4:8])
  51. err = NewSocksVersion4Error()
  52. return
  53. }
  54. auth.version = buffer.Value[0]
  55. if auth.version != socksVersion {
  56. err = errors.NewProtocolVersionError(int(auth.version))
  57. return
  58. }
  59. auth.nMethods = buffer.Value[1]
  60. if auth.nMethods <= 0 {
  61. log.Info("Zero length of authentication methods")
  62. err = errors.NewCorruptedPacketError()
  63. return
  64. }
  65. if nBytes-2 != int(auth.nMethods) {
  66. log.Info("Unmatching number of auth methods, expecting %d, but got %d", auth.nMethods, nBytes)
  67. err = errors.NewCorruptedPacketError()
  68. return
  69. }
  70. copy(auth.authMethods[:], buffer.Value[2:nBytes])
  71. return
  72. }
  73. type Socks5AuthenticationResponse struct {
  74. version byte
  75. authMethod byte
  76. }
  77. func NewAuthenticationResponse(authMethod byte) *Socks5AuthenticationResponse {
  78. return &Socks5AuthenticationResponse{
  79. version: socksVersion,
  80. authMethod: authMethod,
  81. }
  82. }
  83. func WriteAuthentication(writer io.Writer, r *Socks5AuthenticationResponse) error {
  84. _, err := writer.Write([]byte{r.version, r.authMethod})
  85. return err
  86. }
  87. type Socks5UserPassRequest struct {
  88. version byte
  89. username string
  90. password string
  91. }
  92. func (request Socks5UserPassRequest) Username() string {
  93. return request.username
  94. }
  95. func (request Socks5UserPassRequest) Password() string {
  96. return request.password
  97. }
  98. func (request Socks5UserPassRequest) AuthDetail() string {
  99. return request.username + ":" + request.password
  100. }
  101. func ReadUserPassRequest(reader io.Reader) (request Socks5UserPassRequest, err error) {
  102. buffer := alloc.NewSmallBuffer()
  103. defer buffer.Release()
  104. _, err = reader.Read(buffer.Value[0:2])
  105. if err != nil {
  106. return
  107. }
  108. request.version = buffer.Value[0]
  109. nUsername := buffer.Value[1]
  110. nBytes, err := reader.Read(buffer.Value[:nUsername])
  111. if err != nil {
  112. return
  113. }
  114. request.username = string(buffer.Value[:nBytes])
  115. _, err = reader.Read(buffer.Value[0:1])
  116. if err != nil {
  117. return
  118. }
  119. nPassword := buffer.Value[0]
  120. nBytes, err = reader.Read(buffer.Value[:nPassword])
  121. if err != nil {
  122. return
  123. }
  124. request.password = string(buffer.Value[:nBytes])
  125. return
  126. }
  127. type Socks5UserPassResponse struct {
  128. version byte
  129. status byte
  130. }
  131. func NewSocks5UserPassResponse(status byte) Socks5UserPassResponse {
  132. return Socks5UserPassResponse{
  133. version: socksVersion,
  134. status: status,
  135. }
  136. }
  137. func WriteUserPassResponse(writer io.Writer, response Socks5UserPassResponse) error {
  138. _, err := writer.Write([]byte{response.version, response.status})
  139. return err
  140. }
  141. const (
  142. AddrTypeIPv4 = byte(0x01)
  143. AddrTypeIPv6 = byte(0x04)
  144. AddrTypeDomain = byte(0x03)
  145. CmdConnect = byte(0x01)
  146. CmdBind = byte(0x02)
  147. CmdUdpAssociate = byte(0x03)
  148. )
  149. type Socks5Request struct {
  150. Version byte
  151. Command byte
  152. AddrType byte
  153. IPv4 [4]byte
  154. Domain string
  155. IPv6 [16]byte
  156. Port uint16
  157. }
  158. func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
  159. buffer := alloc.NewSmallBuffer()
  160. defer buffer.Release()
  161. nBytes, err := reader.Read(buffer.Value[:4])
  162. if err != nil {
  163. return
  164. }
  165. if nBytes < 4 {
  166. err = errors.NewCorruptedPacketError()
  167. return
  168. }
  169. request = &Socks5Request{
  170. Version: buffer.Value[0],
  171. Command: buffer.Value[1],
  172. // buffer[2] is a reserved field
  173. AddrType: buffer.Value[3],
  174. }
  175. switch request.AddrType {
  176. case AddrTypeIPv4:
  177. nBytes, err = reader.Read(request.IPv4[:])
  178. if err != nil {
  179. return
  180. }
  181. if nBytes != 4 {
  182. err = errors.NewCorruptedPacketError()
  183. return
  184. }
  185. case AddrTypeDomain:
  186. nBytes, err = reader.Read(buffer.Value[0:1])
  187. if err != nil {
  188. return
  189. }
  190. domainLength := buffer.Value[0]
  191. nBytes, err = reader.Read(buffer.Value[:domainLength])
  192. if err != nil {
  193. return
  194. }
  195. if nBytes != int(domainLength) {
  196. log.Info("Unable to read domain with %d bytes, expecting %d bytes", nBytes, domainLength)
  197. err = errors.NewCorruptedPacketError()
  198. return
  199. }
  200. request.Domain = string(buffer.Value[:domainLength])
  201. case AddrTypeIPv6:
  202. nBytes, err = reader.Read(request.IPv6[:])
  203. if err != nil {
  204. return
  205. }
  206. if nBytes != 16 {
  207. err = errors.NewCorruptedPacketError()
  208. return
  209. }
  210. default:
  211. log.Info("Unexpected address type %d", request.AddrType)
  212. err = errors.NewCorruptedPacketError()
  213. return
  214. }
  215. nBytes, err = reader.Read(buffer.Value[:2])
  216. if err != nil {
  217. return
  218. }
  219. if nBytes != 2 {
  220. err = errors.NewCorruptedPacketError()
  221. return
  222. }
  223. request.Port = binary.BigEndian.Uint16(buffer.Value[:2])
  224. return
  225. }
  226. func (request *Socks5Request) Destination() v2net.Destination {
  227. var address v2net.Address
  228. switch request.AddrType {
  229. case AddrTypeIPv4:
  230. address = v2net.IPAddress(request.IPv4[:], request.Port)
  231. case AddrTypeIPv6:
  232. address = v2net.IPAddress(request.IPv6[:], request.Port)
  233. case AddrTypeDomain:
  234. address = v2net.DomainAddress(request.Domain, request.Port)
  235. default:
  236. panic("Unknown address type")
  237. }
  238. return v2net.NewTCPDestination(address)
  239. }
  240. const (
  241. ErrorSuccess = byte(0x00)
  242. ErrorGeneralFailure = byte(0x01)
  243. ErrorConnectionNotAllowed = byte(0x02)
  244. ErrorNetworkUnreachable = byte(0x03)
  245. ErrorHostUnUnreachable = byte(0x04)
  246. ErrorConnectionRefused = byte(0x05)
  247. ErrorTTLExpired = byte(0x06)
  248. ErrorCommandNotSupported = byte(0x07)
  249. ErrorAddressTypeNotSupported = byte(0x08)
  250. )
  251. type Socks5Response struct {
  252. Version byte
  253. Error byte
  254. AddrType byte
  255. IPv4 [4]byte
  256. Domain string
  257. IPv6 [16]byte
  258. Port uint16
  259. }
  260. func NewSocks5Response() *Socks5Response {
  261. return &Socks5Response{
  262. Version: socksVersion,
  263. }
  264. }
  265. func (r *Socks5Response) SetIPv4(ipv4 []byte) {
  266. r.AddrType = AddrTypeIPv4
  267. copy(r.IPv4[:], ipv4)
  268. }
  269. func (r *Socks5Response) SetIPv6(ipv6 []byte) {
  270. r.AddrType = AddrTypeIPv6
  271. copy(r.IPv6[:], ipv6)
  272. }
  273. func (r *Socks5Response) SetDomain(domain string) {
  274. r.AddrType = AddrTypeDomain
  275. r.Domain = domain
  276. }
  277. func (r *Socks5Response) Write(buffer *alloc.Buffer) {
  278. buffer.AppendBytes(r.Version, r.Error, 0x00 /* reserved */, r.AddrType)
  279. switch r.AddrType {
  280. case 0x01:
  281. buffer.Append(r.IPv4[:])
  282. case 0x03:
  283. buffer.AppendBytes(byte(len(r.Domain)))
  284. buffer.Append([]byte(r.Domain))
  285. case 0x04:
  286. buffer.Append(r.IPv6[:])
  287. }
  288. buffer.AppendBytes(byte(r.Port>>8), byte(r.Port))
  289. }