An attempt at adding UDP support to aiosocks. Untested due to lack of server support.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

336 lines
12 KiB

  1. import unittest
  2. import aiohttp
  3. import aiosocks
  4. import asyncio
  5. from aiohttp import web
  6. from aiosocks.connector import SocksConnector
  7. try:
  8. from asyncio import ensure_future
  9. except ImportError:
  10. ensure_future = asyncio.async
  11. from .helpers import fake_socks_srv, find_unused_port
  12. class TestCreateSocks4Connection(unittest.TestCase):
  13. def setUp(self):
  14. self.loop = asyncio.new_event_loop()
  15. asyncio.set_event_loop(None)
  16. def tearDown(self):
  17. self.loop.close()
  18. def test_connect_success(self):
  19. server, port = self.loop.run_until_complete(
  20. fake_socks_srv(self.loop, b'\x00\x5a\x04W\x01\x01\x01\x01test')
  21. )
  22. addr = aiosocks.Socks4Addr('127.0.0.1', port)
  23. auth = aiosocks.Socks4Auth('usr')
  24. dst = ('python.org', 80)
  25. coro = aiosocks.create_connection(
  26. None, addr, auth, dst, loop=self.loop)
  27. transport, protocol = self.loop.run_until_complete(coro)
  28. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  29. data = self.loop.run_until_complete(protocol._stream_reader.read(4))
  30. self.assertEqual(data, b'test')
  31. transport.close()
  32. server.close()
  33. self.loop.run_until_complete(server.wait_closed())
  34. def test_invalid_data(self):
  35. server, port = self.loop.run_until_complete(
  36. fake_socks_srv(self.loop, b'\x01\x5a\x04W\x01\x01\x01\x01')
  37. )
  38. addr = aiosocks.Socks4Addr('127.0.0.1', port)
  39. auth = aiosocks.Socks4Auth('usr')
  40. dst = ('python.org', 80)
  41. with self.assertRaises(aiosocks.SocksError) as ct:
  42. coro = aiosocks.create_connection(
  43. None, addr, auth, dst, loop=self.loop)
  44. self.loop.run_until_complete(coro)
  45. self.assertIn('invalid data', str(ct.exception))
  46. server.close()
  47. self.loop.run_until_complete(server.wait_closed())
  48. def test_socks_srv_error(self):
  49. server, port = self.loop.run_until_complete(
  50. fake_socks_srv(self.loop, b'\x00\x5b\x04W\x01\x01\x01\x01')
  51. )
  52. addr = aiosocks.Socks4Addr('127.0.0.1', port)
  53. auth = aiosocks.Socks4Auth('usr')
  54. dst = ('python.org', 80)
  55. with self.assertRaises(aiosocks.SocksError) as ct:
  56. coro = aiosocks.create_connection(
  57. None, addr, auth, dst, loop=self.loop)
  58. self.loop.run_until_complete(coro)
  59. self.assertIn('0x5b', str(ct.exception))
  60. server.close()
  61. self.loop.run_until_complete(server.wait_closed())
  62. class TestCreateSocks5Connect(unittest.TestCase):
  63. def setUp(self):
  64. self.loop = asyncio.new_event_loop()
  65. asyncio.set_event_loop(None)
  66. def tearDown(self):
  67. self.loop.close()
  68. def test_connect_success_anonymous(self):
  69. server, port = self.loop.run_until_complete(
  70. fake_socks_srv(
  71. self.loop,
  72. b'\x05\x00\x05\x00\x00\x01\x01\x01\x01\x01\x04Wtest'
  73. )
  74. )
  75. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  76. auth = aiosocks.Socks5Auth('usr', 'pwd')
  77. dst = ('python.org', 80)
  78. coro = aiosocks.create_connection(
  79. None, addr, auth, dst, loop=self.loop)
  80. transport, protocol = self.loop.run_until_complete(coro)
  81. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  82. data = self.loop.run_until_complete(protocol._stream_reader.read(4))
  83. self.assertEqual(data, b'test')
  84. transport.close()
  85. server.close()
  86. self.loop.run_until_complete(server.wait_closed())
  87. def test_connect_success_usr_pwd(self):
  88. server, port = self.loop.run_until_complete(
  89. fake_socks_srv(
  90. self.loop,
  91. b'\x05\x02\x01\x00\x05\x00\x00\x01\x01\x01\x01\x01\x04Wtest'
  92. )
  93. )
  94. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  95. auth = aiosocks.Socks5Auth('usr', 'pwd')
  96. dst = ('python.org', 80)
  97. coro = aiosocks.create_connection(
  98. None, addr, auth, dst, loop=self.loop)
  99. transport, protocol = self.loop.run_until_complete(coro)
  100. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  101. data = self.loop.run_until_complete(protocol._stream_reader.read(4))
  102. self.assertEqual(data, b'test')
  103. transport.close()
  104. server.close()
  105. self.loop.run_until_complete(server.wait_closed())
  106. def test_auth_ver_err(self):
  107. server, port = self.loop.run_until_complete(
  108. fake_socks_srv(self.loop, b'\x04\x02')
  109. )
  110. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  111. auth = aiosocks.Socks5Auth('usr', 'pwd')
  112. dst = ('python.org', 80)
  113. with self.assertRaises(aiosocks.SocksError) as ct:
  114. coro = aiosocks.create_connection(
  115. None, addr, auth, dst, loop=self.loop)
  116. self.loop.run_until_complete(coro)
  117. self.assertIn('invalid version', str(ct.exception))
  118. server.close()
  119. self.loop.run_until_complete(server.wait_closed())
  120. def test_auth_method_rejected(self):
  121. server, port = self.loop.run_until_complete(
  122. fake_socks_srv(self.loop, b'\x05\xFF')
  123. )
  124. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  125. auth = aiosocks.Socks5Auth('usr', 'pwd')
  126. dst = ('python.org', 80)
  127. with self.assertRaises(aiosocks.SocksError) as ct:
  128. coro = aiosocks.create_connection(
  129. None, addr, auth, dst, loop=self.loop)
  130. self.loop.run_until_complete(coro)
  131. self.assertIn('authentication methods were rejected',
  132. str(ct.exception))
  133. server.close()
  134. self.loop.run_until_complete(server.wait_closed())
  135. def test_auth_status_invalid(self):
  136. server, port = self.loop.run_until_complete(
  137. fake_socks_srv(self.loop, b'\x05\xF0')
  138. )
  139. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  140. auth = aiosocks.Socks5Auth('usr', 'pwd')
  141. dst = ('python.org', 80)
  142. with self.assertRaises(aiosocks.SocksError) as ct:
  143. coro = aiosocks.create_connection(
  144. None, addr, auth, dst, loop=self.loop)
  145. self.loop.run_until_complete(coro)
  146. self.assertIn('invalid data', str(ct.exception))
  147. server.close()
  148. self.loop.run_until_complete(server.wait_closed())
  149. def test_auth_status_invalid2(self):
  150. server, port = self.loop.run_until_complete(
  151. fake_socks_srv(self.loop, b'\x05\x02\x02\x00')
  152. )
  153. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  154. auth = aiosocks.Socks5Auth('usr', 'pwd')
  155. dst = ('python.org', 80)
  156. with self.assertRaises(aiosocks.SocksError) as ct:
  157. coro = aiosocks.create_connection(
  158. None, addr, auth, dst, loop=self.loop)
  159. self.loop.run_until_complete(coro)
  160. self.assertIn('invalid data', str(ct.exception))
  161. server.close()
  162. self.loop.run_until_complete(server.wait_closed())
  163. def test_auth_failed(self):
  164. server, port = self.loop.run_until_complete(
  165. fake_socks_srv(self.loop, b'\x05\x02\x01\x01')
  166. )
  167. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  168. auth = aiosocks.Socks5Auth('usr', 'pwd')
  169. dst = ('python.org', 80)
  170. with self.assertRaises(aiosocks.SocksError) as ct:
  171. coro = aiosocks.create_connection(
  172. None, addr, auth, dst, loop=self.loop)
  173. self.loop.run_until_complete(coro)
  174. self.assertIn('authentication failed', str(ct.exception))
  175. server.close()
  176. self.loop.run_until_complete(server.wait_closed())
  177. def test_cmd_ver_err(self):
  178. server, port = self.loop.run_until_complete(
  179. fake_socks_srv(self.loop, b'\x05\x02\x01\x00\x04\x00\x00')
  180. )
  181. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  182. auth = aiosocks.Socks5Auth('usr', 'pwd')
  183. dst = ('python.org', 80)
  184. with self.assertRaises(aiosocks.SocksError) as ct:
  185. coro = aiosocks.create_connection(
  186. None, addr, auth, dst, loop=self.loop)
  187. self.loop.run_until_complete(coro)
  188. self.assertIn('invalid version', str(ct.exception))
  189. server.close()
  190. self.loop.run_until_complete(server.wait_closed())
  191. def test_cmd_not_granted(self):
  192. server, port = self.loop.run_until_complete(
  193. fake_socks_srv(self.loop, b'\x05\x02\x01\x00\x05\x01\x00')
  194. )
  195. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  196. auth = aiosocks.Socks5Auth('usr', 'pwd')
  197. dst = ('python.org', 80)
  198. with self.assertRaises(aiosocks.SocksError) as ct:
  199. coro = aiosocks.create_connection(
  200. None, addr, auth, dst, loop=self.loop)
  201. self.loop.run_until_complete(coro)
  202. self.assertIn('General SOCKS server failure', str(ct.exception))
  203. server.close()
  204. self.loop.run_until_complete(server.wait_closed())
  205. def test_invalid_address_type(self):
  206. server, port = self.loop.run_until_complete(
  207. fake_socks_srv(self.loop, b'\x05\x02\x01\x00\x05\x00\x00\xFF')
  208. )
  209. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  210. auth = aiosocks.Socks5Auth('usr', 'pwd')
  211. dst = ('python.org', 80)
  212. with self.assertRaises(aiosocks.SocksError) as ct:
  213. coro = aiosocks.create_connection(
  214. None, addr, auth, dst, loop=self.loop)
  215. self.loop.run_until_complete(coro)
  216. self.assertIn('invalid data', str(ct.exception))
  217. server.close()
  218. self.loop.run_until_complete(server.wait_closed())
  219. def test_atype_ipv4(self):
  220. server, port = self.loop.run_until_complete(
  221. fake_socks_srv(
  222. self.loop,
  223. b'\x05\x02\x01\x00\x05\x00\x00\x01\x01\x01\x01\x01\x04W'
  224. )
  225. )
  226. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  227. auth = aiosocks.Socks5Auth('usr', 'pwd')
  228. dst = ('python.org', 80)
  229. coro = aiosocks.create_connection(
  230. None, addr, auth, dst, loop=self.loop)
  231. transport, protocol = self.loop.run_until_complete(coro)
  232. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  233. transport.close()
  234. server.close()
  235. self.loop.run_until_complete(server.wait_closed())
  236. def test_atype_ipv6(self):
  237. server, port = self.loop.run_until_complete(
  238. fake_socks_srv(
  239. self.loop,
  240. b'\x05\x02\x01\x00\x05\x00\x00\x04\x00\x00\x00\x00'
  241. b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11\x04W')
  242. )
  243. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  244. auth = aiosocks.Socks5Auth('usr', 'pwd')
  245. dst = ('python.org', 80)
  246. coro = aiosocks.create_connection(
  247. None, addr, auth, dst, loop=self.loop)
  248. transport, protocol = self.loop.run_until_complete(coro)
  249. self.assertEqual(protocol.proxy_sockname, ('::111', 1111))
  250. transport.close()
  251. server.close()
  252. self.loop.run_until_complete(server.wait_closed())
  253. def test_atype_domain(self):
  254. server, port = self.loop.run_until_complete(
  255. fake_socks_srv(
  256. self.loop,
  257. b'\x05\x02\x01\x00\x05\x00\x00\x03\x0apython.org\x04W'
  258. )
  259. )
  260. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  261. auth = aiosocks.Socks5Auth('usr', 'pwd')
  262. dst = ('python.org', 80)
  263. coro = aiosocks.create_connection(
  264. None, addr, auth, dst, loop=self.loop)
  265. transport, protocol = self.loop.run_until_complete(coro)
  266. self.assertEqual(protocol.proxy_sockname, (b'python.org', 1111))
  267. transport.close()
  268. server.close()
  269. self.loop.run_until_complete(server.wait_closed())