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.
 
 

266 lines
10 KiB

  1. import unittest
  2. import aiosocks
  3. import asyncio
  4. try:
  5. from asyncio import ensure_future
  6. except ImportError:
  7. ensure_future = asyncio.async
  8. from .helpers import fake_socks_srv
  9. class TestCreateSocks4Connection(unittest.TestCase):
  10. def setUp(self):
  11. self.loop = asyncio.new_event_loop()
  12. asyncio.set_event_loop(None)
  13. def tearDown(self):
  14. self.loop.close()
  15. def test_connect_success(self):
  16. with fake_socks_srv(self.loop,
  17. b'\x00\x5a\x04W\x01\x01\x01\x01test') as port:
  18. addr = aiosocks.Socks4Addr('127.0.0.1', port)
  19. auth = aiosocks.Socks4Auth('usr')
  20. dst = ('python.org', 80)
  21. coro = aiosocks.create_connection(
  22. None, addr, auth, dst, loop=self.loop)
  23. transport, protocol = self.loop.run_until_complete(coro)
  24. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  25. data = self.loop.run_until_complete(
  26. protocol._stream_reader.read(4))
  27. self.assertEqual(data, b'test')
  28. transport.close()
  29. def test_invalid_data(self):
  30. with fake_socks_srv(self.loop,
  31. b'\x01\x5a\x04W\x01\x01\x01\x01') as port:
  32. addr = aiosocks.Socks4Addr('127.0.0.1', port)
  33. auth = aiosocks.Socks4Auth('usr')
  34. dst = ('python.org', 80)
  35. with self.assertRaises(aiosocks.SocksError) as ct:
  36. coro = aiosocks.create_connection(
  37. None, addr, auth, dst, loop=self.loop)
  38. self.loop.run_until_complete(coro)
  39. self.assertIn('invalid data', str(ct.exception))
  40. def test_socks_srv_error(self):
  41. with fake_socks_srv(self.loop,
  42. b'\x00\x5b\x04W\x01\x01\x01\x01') as port:
  43. addr = aiosocks.Socks4Addr('127.0.0.1', port)
  44. auth = aiosocks.Socks4Auth('usr')
  45. dst = ('python.org', 80)
  46. with self.assertRaises(aiosocks.SocksError) as ct:
  47. coro = aiosocks.create_connection(
  48. None, addr, auth, dst, loop=self.loop)
  49. self.loop.run_until_complete(coro)
  50. self.assertIn('0x5b', str(ct.exception))
  51. class TestCreateSocks5Connect(unittest.TestCase):
  52. def setUp(self):
  53. self.loop = asyncio.new_event_loop()
  54. asyncio.set_event_loop(None)
  55. def tearDown(self):
  56. self.loop.close()
  57. def test_connect_success_anonymous(self):
  58. with fake_socks_srv(
  59. self.loop,
  60. b'\x05\x00\x05\x00\x00\x01\x01\x01\x01\x01\x04Wtest') as port:
  61. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  62. auth = aiosocks.Socks5Auth('usr', 'pwd')
  63. dst = ('python.org', 80)
  64. coro = aiosocks.create_connection(
  65. None, addr, auth, dst, loop=self.loop)
  66. transport, protocol = self.loop.run_until_complete(coro)
  67. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  68. data = self.loop.run_until_complete(
  69. protocol._stream_reader.read(4))
  70. self.assertEqual(data, b'test')
  71. transport.close()
  72. def test_connect_success_usr_pwd(self):
  73. with fake_socks_srv(
  74. self.loop,
  75. b'\x05\x02\x01\x00\x05\x00\x00\x01\x01\x01\x01\x01\x04Wtest'
  76. ) as port:
  77. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  78. auth = aiosocks.Socks5Auth('usr', 'pwd')
  79. dst = ('python.org', 80)
  80. coro = aiosocks.create_connection(
  81. None, addr, auth, dst, loop=self.loop)
  82. transport, protocol = self.loop.run_until_complete(coro)
  83. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  84. data = self.loop.run_until_complete(
  85. protocol._stream_reader.read(4))
  86. self.assertEqual(data, b'test')
  87. transport.close()
  88. def test_auth_ver_err(self):
  89. with fake_socks_srv(self.loop, b'\x04\x02') as port:
  90. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  91. auth = aiosocks.Socks5Auth('usr', 'pwd')
  92. dst = ('python.org', 80)
  93. with self.assertRaises(aiosocks.SocksError) as ct:
  94. coro = aiosocks.create_connection(
  95. None, addr, auth, dst, loop=self.loop)
  96. self.loop.run_until_complete(coro)
  97. self.assertIn('invalid version', str(ct.exception))
  98. def test_auth_method_rejected(self):
  99. with fake_socks_srv(self.loop, b'\x05\xFF') as port:
  100. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  101. auth = aiosocks.Socks5Auth('usr', 'pwd')
  102. dst = ('python.org', 80)
  103. with self.assertRaises(aiosocks.SocksError) as ct:
  104. coro = aiosocks.create_connection(
  105. None, addr, auth, dst, loop=self.loop)
  106. self.loop.run_until_complete(coro)
  107. self.assertIn('authentication methods were rejected',
  108. str(ct.exception))
  109. def test_auth_status_invalid(self):
  110. with fake_socks_srv(self.loop, b'\x05\xF0') as port:
  111. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  112. auth = aiosocks.Socks5Auth('usr', 'pwd')
  113. dst = ('python.org', 80)
  114. with self.assertRaises(aiosocks.SocksError) as ct:
  115. coro = aiosocks.create_connection(
  116. None, addr, auth, dst, loop=self.loop)
  117. self.loop.run_until_complete(coro)
  118. self.assertIn('invalid data', str(ct.exception))
  119. def test_auth_status_invalid2(self):
  120. with fake_socks_srv(self.loop, b'\x05\x02\x02\x00') as port:
  121. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  122. auth = aiosocks.Socks5Auth('usr', 'pwd')
  123. dst = ('python.org', 80)
  124. with self.assertRaises(aiosocks.SocksError) as ct:
  125. coro = aiosocks.create_connection(
  126. None, addr, auth, dst, loop=self.loop)
  127. self.loop.run_until_complete(coro)
  128. self.assertIn('invalid data', str(ct.exception))
  129. def test_auth_failed(self):
  130. with fake_socks_srv(self.loop, b'\x05\x02\x01\x01') as port:
  131. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  132. auth = aiosocks.Socks5Auth('usr', 'pwd')
  133. dst = ('python.org', 80)
  134. with self.assertRaises(aiosocks.SocksError) as ct:
  135. coro = aiosocks.create_connection(
  136. None, addr, auth, dst, loop=self.loop)
  137. self.loop.run_until_complete(coro)
  138. self.assertIn('authentication failed', str(ct.exception))
  139. def test_cmd_ver_err(self):
  140. with fake_socks_srv(self.loop,
  141. b'\x05\x02\x01\x00\x04\x00\x00') as port:
  142. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  143. auth = aiosocks.Socks5Auth('usr', 'pwd')
  144. dst = ('python.org', 80)
  145. with self.assertRaises(aiosocks.SocksError) as ct:
  146. coro = aiosocks.create_connection(
  147. None, addr, auth, dst, loop=self.loop)
  148. self.loop.run_until_complete(coro)
  149. self.assertIn('invalid version', str(ct.exception))
  150. def test_cmd_not_granted(self):
  151. with fake_socks_srv(self.loop,
  152. b'\x05\x02\x01\x00\x05\x01\x00') as port:
  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('General SOCKS server failure', str(ct.exception))
  161. def test_invalid_address_type(self):
  162. with fake_socks_srv(self.loop,
  163. b'\x05\x02\x01\x00\x05\x00\x00\xFF') as port:
  164. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  165. auth = aiosocks.Socks5Auth('usr', 'pwd')
  166. dst = ('python.org', 80)
  167. with self.assertRaises(aiosocks.SocksError) as ct:
  168. coro = aiosocks.create_connection(
  169. None, addr, auth, dst, loop=self.loop)
  170. self.loop.run_until_complete(coro)
  171. self.assertIn('invalid data', str(ct.exception))
  172. def test_atype_ipv4(self):
  173. with fake_socks_srv(
  174. self.loop,
  175. b'\x05\x02\x01\x00\x05\x00\x00\x01\x01\x01\x01\x01\x04W'
  176. ) as port:
  177. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  178. auth = aiosocks.Socks5Auth('usr', 'pwd')
  179. dst = ('python.org', 80)
  180. coro = aiosocks.create_connection(
  181. None, addr, auth, dst, loop=self.loop)
  182. transport, protocol = self.loop.run_until_complete(coro)
  183. self.assertEqual(protocol.proxy_sockname, ('1.1.1.1', 1111))
  184. transport.close()
  185. def test_atype_ipv6(self):
  186. with fake_socks_srv(
  187. self.loop,
  188. b'\x05\x02\x01\x00\x05\x00\x00\x04\x00\x00\x00\x00'
  189. b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11\x04W'
  190. ) as port:
  191. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  192. auth = aiosocks.Socks5Auth('usr', 'pwd')
  193. dst = ('python.org', 80)
  194. coro = aiosocks.create_connection(
  195. None, addr, auth, dst, loop=self.loop)
  196. transport, protocol = self.loop.run_until_complete(coro)
  197. self.assertEqual(protocol.proxy_sockname, ('::111', 1111))
  198. transport.close()
  199. def test_atype_domain(self):
  200. with fake_socks_srv(
  201. self.loop,
  202. b'\x05\x02\x01\x00\x05\x00\x00\x03\x0apython.org\x04W'
  203. ) as port:
  204. addr = aiosocks.Socks5Addr('127.0.0.1', port)
  205. auth = aiosocks.Socks5Auth('usr', 'pwd')
  206. dst = ('python.org', 80)
  207. coro = aiosocks.create_connection(
  208. None, addr, auth, dst, loop=self.loop)
  209. transport, protocol = self.loop.run_until_complete(coro)
  210. self.assertEqual(protocol.proxy_sockname, (b'python.org', 1111))
  211. transport.close()