socks_test.go 7.3 KB

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