socks.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // Package socks contains protocol definition and io lib for SOCKS5 protocol
  2. package socks
  3. import (
  4. "encoding/binary"
  5. "fmt"
  6. "io"
  7. )
  8. const (
  9. socksVersion = uint8(5)
  10. AuthNotRequired = byte(0x00)
  11. AuthGssApi = byte(0x01)
  12. AuthUserPass = byte(0x02)
  13. )
  14. // Authentication request header of Socks5 protocol
  15. type Socks5AuthenticationRequest struct {
  16. version byte
  17. nMethods byte
  18. authMethods [256]byte
  19. }
  20. func (request *Socks5AuthenticationRequest) HasAuthMethod(method byte) bool {
  21. for i := byte(0); i < request.nMethods; i++ {
  22. if request.authMethods[i] == method {
  23. return true
  24. }
  25. }
  26. return false
  27. }
  28. func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, err error) {
  29. buffer := make([]byte, 2)
  30. nBytes, err := reader.Read(buffer)
  31. if err != nil {
  32. return
  33. }
  34. if nBytes < 2 {
  35. err = fmt.Errorf("Expected 2 bytes read, but actaully %d bytes read", nBytes)
  36. return
  37. }
  38. auth.version = buffer[0]
  39. if auth.version != socksVersion {
  40. err = fmt.Errorf("Unknown SOCKS version %d", auth.version)
  41. return
  42. }
  43. auth.nMethods = buffer[1]
  44. if auth.nMethods <= 0 {
  45. err = fmt.Errorf("Zero length of authentication methods")
  46. return
  47. }
  48. buffer = make([]byte, auth.nMethods)
  49. nBytes, err = reader.Read(buffer)
  50. if err != nil {
  51. return
  52. }
  53. if nBytes != int(auth.nMethods) {
  54. err = fmt.Errorf("Unmatching number of auth methods, expecting %d, but got %d", auth.nMethods, nBytes)
  55. return
  56. }
  57. copy(auth.authMethods[:nBytes], buffer)
  58. return
  59. }
  60. type Socks5AuthenticationResponse struct {
  61. version byte
  62. authMethod byte
  63. }
  64. func NewAuthenticationResponse(authMethod byte) *Socks5AuthenticationResponse {
  65. response := new(Socks5AuthenticationResponse)
  66. response.version = socksVersion
  67. response.authMethod = authMethod
  68. return response
  69. }
  70. func (r *Socks5AuthenticationResponse) ToBytes() []byte {
  71. buffer := make([]byte, 2 /* size of Socks5AuthenticationResponse */)
  72. buffer[0] = r.version
  73. buffer[1] = r.authMethod
  74. return buffer
  75. }
  76. func WriteAuthentication(writer io.Writer, response *Socks5AuthenticationResponse) error {
  77. _, err := writer.Write(response.ToBytes())
  78. return err
  79. }
  80. const (
  81. AddrTypeIPv4 = byte(0x01)
  82. AddrTypeIPv6 = byte(0x04)
  83. AddrTypeDomain = byte(0x03)
  84. CmdConnect = byte(0x01)
  85. CmdBind = byte(0x02)
  86. CmdUdpAssociate = byte(0x03)
  87. )
  88. type Socks5Request struct {
  89. Version byte
  90. Command byte
  91. AddrType byte
  92. IPv4 [4]byte
  93. Domain string
  94. IPv6 [16]byte
  95. Port uint16
  96. }
  97. func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
  98. request = new(Socks5Request)
  99. buffer := make([]byte, 4)
  100. nBytes, err := reader.Read(buffer)
  101. if err != nil {
  102. return
  103. }
  104. if nBytes < len(buffer) {
  105. err = fmt.Errorf("Unable to read request.")
  106. return
  107. }
  108. request.Version = buffer[0]
  109. request.Command = buffer[1]
  110. // buffer[2] is a reserved field
  111. request.AddrType = buffer[3]
  112. switch request.AddrType {
  113. case 0x01:
  114. nBytes, err = reader.Read(request.IPv4[:])
  115. if err != nil {
  116. return
  117. }
  118. if nBytes != 4 {
  119. err = fmt.Errorf("Unable to read IPv4 address.")
  120. return
  121. }
  122. case 0x03:
  123. buffer = make([]byte, 257)
  124. nBytes, err = reader.Read(buffer)
  125. if err != nil {
  126. return
  127. }
  128. domainLength := buffer[0]
  129. if nBytes != int(domainLength)+1 {
  130. err = fmt.Errorf("Unable to read domain")
  131. return
  132. }
  133. request.Domain = string(buffer[1 : domainLength+1])
  134. case 0x04:
  135. nBytes, err = reader.Read(request.IPv6[:])
  136. if err != nil {
  137. return
  138. }
  139. if nBytes != 16 {
  140. err = fmt.Errorf("Unable to read IPv4 address.")
  141. return
  142. }
  143. default:
  144. err = fmt.Errorf("Unexpected address type %d", request.AddrType)
  145. return
  146. }
  147. buffer = make([]byte, 2)
  148. nBytes, err = reader.Read(buffer)
  149. if err != nil {
  150. return
  151. }
  152. if nBytes != 2 {
  153. err = fmt.Errorf("Unable to read port.")
  154. return
  155. }
  156. request.Port = binary.BigEndian.Uint16(buffer)
  157. return
  158. }
  159. const (
  160. ErrorSuccess = byte(0x00)
  161. ErrorGeneralFailure = byte(0x01)
  162. ErrorConnectionNotAllowed = byte(0x02)
  163. ErrorNetworkUnreachable = byte(0x03)
  164. ErrorHostUnUnreachable = byte(0x04)
  165. ErrorConnectionRefused = byte(0x05)
  166. ErrorTTLExpired = byte(0x06)
  167. ErrorCommandNotSupported = byte(0x07)
  168. ErrorAddressTypeNotSupported = byte(0x08)
  169. )
  170. type Socks5Response struct {
  171. Version byte
  172. Error byte
  173. AddrType byte
  174. IPv4 [4]byte
  175. Domain string
  176. IPv6 [16]byte
  177. Port uint16
  178. }
  179. func NewSocks5Response() *Socks5Response {
  180. response := new(Socks5Response)
  181. response.Version = socksVersion
  182. return response
  183. }
  184. func (r *Socks5Response) SetIPv4(ipv4 []byte) {
  185. r.AddrType = AddrTypeIPv4
  186. copy(r.IPv4[:], ipv4)
  187. }
  188. func (r *Socks5Response) SetIPv6(ipv6 []byte) {
  189. r.AddrType = AddrTypeIPv6
  190. copy(r.IPv6[:], ipv6)
  191. }
  192. func (r *Socks5Response) SetDomain(domain string) {
  193. r.AddrType = AddrTypeDomain
  194. r.Domain = domain
  195. }
  196. func (r *Socks5Response) toBytes() []byte {
  197. buffer := make([]byte, 0, 300)
  198. buffer = append(buffer, r.Version)
  199. buffer = append(buffer, r.Error)
  200. buffer = append(buffer, 0x00) // reserved
  201. buffer = append(buffer, r.AddrType)
  202. switch r.AddrType {
  203. case 0x01:
  204. buffer = append(buffer, r.IPv4[:]...)
  205. case 0x03:
  206. buffer = append(buffer, byte(len(r.Domain)))
  207. buffer = append(buffer, []byte(r.Domain)...)
  208. case 0x04:
  209. buffer = append(buffer, r.IPv6[:]...)
  210. }
  211. portBuffer := make([]byte, 2)
  212. binary.BigEndian.PutUint16(portBuffer, r.Port)
  213. buffer = append(buffer, portBuffer...)
  214. return buffer
  215. }
  216. func WriteResponse(writer io.Writer, response *Socks5Response) error {
  217. _, err := writer.Write(response.toBytes())
  218. return err
  219. }