socks_test.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. package socks_test
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "net"
  7. "testing"
  8. "golang.org/x/net/proxy"
  9. "github.com/v2ray/v2ray-core/app"
  10. v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
  11. v2proxy "github.com/v2ray/v2ray-core/proxy"
  12. proxytesting "github.com/v2ray/v2ray-core/proxy/testing"
  13. proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
  14. "github.com/v2ray/v2ray-core/shell/point"
  15. "github.com/v2ray/v2ray-core/shell/point/testing/mocks"
  16. v2testing "github.com/v2ray/v2ray-core/testing"
  17. "github.com/v2ray/v2ray-core/testing/assert"
  18. )
  19. func TestSocksTcpConnect(t *testing.T) {
  20. v2testing.Current(t)
  21. port := v2nettesting.PickPort()
  22. connInput := []byte("The data to be returned to socks server.")
  23. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  24. och := &proxymocks.OutboundConnectionHandler{
  25. ConnOutput: connOutput,
  26. ConnInput: bytes.NewReader(connInput),
  27. }
  28. protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (v2proxy.OutboundConnectionHandler, error) {
  29. return och, nil
  30. })
  31. assert.Error(err).IsNil()
  32. config := mocks.Config{
  33. PortValue: port,
  34. InboundConfigValue: &mocks.ConnectionConfig{
  35. ProtocolValue: "socks",
  36. SettingsValue: []byte(`
  37. {
  38. "auth": "noauth"
  39. }`),
  40. },
  41. OutboundConfigValue: &mocks.ConnectionConfig{
  42. ProtocolValue: protocol,
  43. SettingsValue: nil,
  44. },
  45. }
  46. point, err := point.NewPoint(&config)
  47. assert.Error(err).IsNil()
  48. err = point.Start()
  49. assert.Error(err).IsNil()
  50. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), nil, proxy.Direct)
  51. assert.Error(err).IsNil()
  52. targetServer := "google.com:80"
  53. conn, err := socks5Client.Dial("tcp", targetServer)
  54. assert.Error(err).IsNil()
  55. data2Send := "The data to be sent to remote server."
  56. conn.Write([]byte(data2Send))
  57. if tcpConn, ok := conn.(*net.TCPConn); ok {
  58. tcpConn.CloseWrite()
  59. }
  60. dataReturned, err := ioutil.ReadAll(conn)
  61. assert.Error(err).IsNil()
  62. conn.Close()
  63. assert.Bytes([]byte(data2Send)).Equals(connOutput.Bytes())
  64. assert.Bytes(dataReturned).Equals(connInput)
  65. assert.StringLiteral(targetServer).Equals(och.Destination.NetAddr())
  66. }
  67. func TestSocksTcpConnectWithUserPass(t *testing.T) {
  68. v2testing.Current(t)
  69. port := v2nettesting.PickPort()
  70. connInput := []byte("The data to be returned to socks server.")
  71. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  72. och := &proxymocks.OutboundConnectionHandler{
  73. ConnInput: bytes.NewReader(connInput),
  74. ConnOutput: connOutput,
  75. }
  76. protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (v2proxy.OutboundConnectionHandler, error) {
  77. return och, nil
  78. })
  79. assert.Error(err).IsNil()
  80. config := mocks.Config{
  81. PortValue: port,
  82. InboundConfigValue: &mocks.ConnectionConfig{
  83. ProtocolValue: "socks",
  84. SettingsValue: []byte(`
  85. {
  86. "auth": "password",
  87. "accounts": [
  88. {"user": "userx", "pass": "passy"}
  89. ]
  90. }`),
  91. },
  92. OutboundConfigValue: &mocks.ConnectionConfig{
  93. ProtocolValue: protocol,
  94. SettingsValue: nil,
  95. },
  96. }
  97. point, err := point.NewPoint(&config)
  98. assert.Error(err).IsNil()
  99. err = point.Start()
  100. assert.Error(err).IsNil()
  101. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), &proxy.Auth{"userx", "passy"}, proxy.Direct)
  102. assert.Error(err).IsNil()
  103. targetServer := "1.2.3.4:443"
  104. conn, err := socks5Client.Dial("tcp", targetServer)
  105. assert.Error(err).IsNil()
  106. data2Send := "The data to be sent to remote server."
  107. conn.Write([]byte(data2Send))
  108. if tcpConn, ok := conn.(*net.TCPConn); ok {
  109. tcpConn.CloseWrite()
  110. }
  111. dataReturned, err := ioutil.ReadAll(conn)
  112. assert.Error(err).IsNil()
  113. conn.Close()
  114. assert.Bytes([]byte(data2Send)).Equals(connOutput.Bytes())
  115. assert.Bytes(dataReturned).Equals(connInput)
  116. assert.StringLiteral(targetServer).Equals(och.Destination.NetAddr())
  117. }
  118. func TestSocksTcpConnectWithWrongUserPass(t *testing.T) {
  119. v2testing.Current(t)
  120. port := v2nettesting.PickPort()
  121. connInput := []byte("The data to be returned to socks server.")
  122. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  123. och := &proxymocks.OutboundConnectionHandler{
  124. ConnInput: bytes.NewReader(connInput),
  125. ConnOutput: connOutput,
  126. }
  127. protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (v2proxy.OutboundConnectionHandler, error) {
  128. return och, nil
  129. })
  130. assert.Error(err).IsNil()
  131. config := mocks.Config{
  132. PortValue: port,
  133. InboundConfigValue: &mocks.ConnectionConfig{
  134. ProtocolValue: "socks",
  135. SettingsValue: []byte(`
  136. {
  137. "auth": "password",
  138. "accounts": [
  139. {"user": "userx", "pass": "passy"}
  140. ]
  141. }`),
  142. },
  143. OutboundConfigValue: &mocks.ConnectionConfig{
  144. ProtocolValue: protocol,
  145. SettingsValue: nil,
  146. },
  147. }
  148. point, err := point.NewPoint(&config)
  149. assert.Error(err).IsNil()
  150. err = point.Start()
  151. assert.Error(err).IsNil()
  152. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), &proxy.Auth{"userx", "passz"}, proxy.Direct)
  153. assert.Error(err).IsNil()
  154. targetServer := "1.2.3.4:443"
  155. _, err = socks5Client.Dial("tcp", targetServer)
  156. assert.Error(err).IsNotNil()
  157. }
  158. func TestSocksTcpConnectWithWrongAuthMethod(t *testing.T) {
  159. v2testing.Current(t)
  160. port := v2nettesting.PickPort()
  161. connInput := []byte("The data to be returned to socks server.")
  162. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  163. och := &proxymocks.OutboundConnectionHandler{
  164. ConnInput: bytes.NewReader(connInput),
  165. ConnOutput: connOutput,
  166. }
  167. protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och", func(space app.Space, config interface{}) (v2proxy.OutboundConnectionHandler, error) {
  168. return och, nil
  169. })
  170. assert.Error(err).IsNil()
  171. config := mocks.Config{
  172. PortValue: port,
  173. InboundConfigValue: &mocks.ConnectionConfig{
  174. ProtocolValue: "socks",
  175. SettingsValue: []byte(`
  176. {
  177. "auth": "password",
  178. "accounts": [
  179. {"user": "userx", "pass": "passy"}
  180. ]
  181. }`),
  182. },
  183. OutboundConfigValue: &mocks.ConnectionConfig{
  184. ProtocolValue: protocol,
  185. SettingsValue: nil,
  186. },
  187. }
  188. point, err := point.NewPoint(&config)
  189. assert.Error(err).IsNil()
  190. err = point.Start()
  191. assert.Error(err).IsNil()
  192. socks5Client, err := proxy.SOCKS5("tcp", fmt.Sprintf("127.0.0.1:%d", port), nil, proxy.Direct)
  193. assert.Error(err).IsNil()
  194. targetServer := "1.2.3.4:443"
  195. _, err = socks5Client.Dial("tcp", targetServer)
  196. assert.Error(err).IsNotNil()
  197. }
  198. func TestSocksUdpSend(t *testing.T) {
  199. v2testing.Current(t)
  200. port := v2nettesting.PickPort()
  201. connInput := []byte("The data to be returned to socks server.")
  202. connOutput := bytes.NewBuffer(make([]byte, 0, 1024))
  203. och := &proxymocks.OutboundConnectionHandler{
  204. ConnInput: bytes.NewReader(connInput),
  205. ConnOutput: connOutput,
  206. }
  207. protocol, err := proxytesting.RegisterOutboundConnectionHandlerCreator("mock_och",
  208. func(space app.Space, config interface{}) (v2proxy.OutboundConnectionHandler, error) {
  209. return och, nil
  210. })
  211. assert.Error(err).IsNil()
  212. config := mocks.Config{
  213. PortValue: port,
  214. InboundConfigValue: &mocks.ConnectionConfig{
  215. ProtocolValue: "socks",
  216. SettingsValue: []byte(`{"auth": "noauth", "udp": true}`),
  217. },
  218. OutboundConfigValue: &mocks.ConnectionConfig{
  219. ProtocolValue: protocol,
  220. SettingsValue: nil,
  221. },
  222. }
  223. point, err := point.NewPoint(&config)
  224. assert.Error(err).IsNil()
  225. err = point.Start()
  226. assert.Error(err).IsNil()
  227. conn, err := net.DialUDP("udp", nil, &net.UDPAddr{
  228. IP: []byte{127, 0, 0, 1},
  229. Port: int(port),
  230. Zone: "",
  231. })
  232. assert.Error(err).IsNil()
  233. data2Send := []byte("Fake DNS request")
  234. buffer := make([]byte, 0, 1024)
  235. buffer = append(buffer, 0, 0, 0)
  236. buffer = append(buffer, 1, 8, 8, 4, 4, 0, 53)
  237. buffer = append(buffer, data2Send...)
  238. conn.Write(buffer)
  239. response := make([]byte, 1024)
  240. nBytes, err := conn.Read(response)
  241. assert.Error(err).IsNil()
  242. assert.Bytes(response[10:nBytes]).Equals(connInput)
  243. assert.Bytes(data2Send).Equals(connOutput.Bytes())
  244. assert.StringLiteral(och.Destination.String()).Equals("udp:8.8.4.4:53")
  245. }