socks_test.go 8.0 KB

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