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.
 
 

642 lines
24 KiB

  1. import asyncio
  2. import aiosocks
  3. import unittest
  4. import socket
  5. import ssl as ssllib
  6. from unittest import mock
  7. from asyncio import coroutine as coro
  8. import aiosocks.constants as c
  9. from aiosocks.protocols import BaseSocksProtocol
  10. from .helpers import fake_coroutine
  11. try:
  12. from asyncio import ensure_future
  13. except ImportError:
  14. ensure_future = asyncio.async
  15. def make_base(loop, *, dst=None, waiter=None, ap_factory=None, ssl=None):
  16. dst = dst or ('python.org', 80)
  17. proto = BaseSocksProtocol(None, None, dst=dst, ssl=ssl,
  18. loop=loop, waiter=waiter,
  19. app_protocol_factory=ap_factory)
  20. return proto
  21. def make_socks4(loop, *, addr=None, auth=None, rr=True, dst=None, r=b'',
  22. ap_factory=None, whiter=None):
  23. addr = addr or aiosocks.Socks4Addr('localhost', 1080)
  24. auth = auth or aiosocks.Socks4Auth('user')
  25. dst = dst or ('python.org', 80)
  26. proto = aiosocks.Socks4Protocol(
  27. proxy=addr, proxy_auth=auth, dst=dst, remote_resolve=rr,
  28. loop=loop, app_protocol_factory=ap_factory, waiter=whiter)
  29. proto._stream_writer = mock.Mock()
  30. proto.read_response = mock.Mock(
  31. side_effect=coro(mock.Mock(return_value=r)))
  32. proto._get_dst_addr = mock.Mock(
  33. side_effect=coro(mock.Mock(return_value=(socket.AF_INET, '127.0.0.1')))
  34. )
  35. return proto
  36. def make_socks5(loop, *, addr=None, auth=None, rr=True, dst=None, r=None,
  37. ap_factory=None, whiter=None):
  38. addr = addr or aiosocks.Socks5Addr('localhost', 1080)
  39. auth = auth or aiosocks.Socks5Auth('user', 'pwd')
  40. dst = dst or ('python.org', 80)
  41. proto = aiosocks.Socks5Protocol(
  42. proxy=addr, proxy_auth=auth, dst=dst, remote_resolve=rr,
  43. loop=loop, app_protocol_factory=ap_factory, waiter=whiter)
  44. proto._stream_writer = mock.Mock()
  45. proto._stream_writer.drain = fake_coroutine(True)
  46. if not isinstance(r, (list, tuple)):
  47. proto.read_response = mock.Mock(
  48. side_effect=coro(mock.Mock(return_value=r)))
  49. else:
  50. proto.read_response = mock.Mock(
  51. side_effect=coro(mock.Mock(side_effect=r)))
  52. proto._get_dst_addr = mock.Mock(
  53. side_effect=coro(mock.Mock(return_value=(socket.AF_INET, '127.0.0.1')))
  54. )
  55. return proto
  56. class TestBaseSocksProtocol(unittest.TestCase):
  57. def setUp(self):
  58. self.loop = asyncio.new_event_loop()
  59. asyncio.set_event_loop(None)
  60. def tearDown(self):
  61. self.loop.close()
  62. def test_init(self):
  63. with self.assertRaises(ValueError):
  64. BaseSocksProtocol(None, None, None, loop=self.loop,
  65. waiter=None, app_protocol_factory=None)
  66. with self.assertRaises(ValueError):
  67. BaseSocksProtocol(None, None, 123, loop=self.loop,
  68. waiter=None, app_protocol_factory=None)
  69. with self.assertRaises(ValueError):
  70. BaseSocksProtocol(None, None, ('python.org',), loop=self.loop,
  71. waiter=None, app_protocol_factory=None)
  72. def test_write_request(self):
  73. proto = make_base(self.loop)
  74. proto._stream_writer = mock.Mock()
  75. proto.write_request([b'\x00', b'\x01\x02', 0x03])
  76. proto._stream_writer.write.assert_called_with(b'\x00\x01\x02\x03')
  77. with self.assertRaises(ValueError):
  78. proto.write_request(['\x00'])
  79. def test_negotiate_os_error(self):
  80. waiter = asyncio.Future(loop=self.loop)
  81. proto = make_base(self.loop, waiter=waiter)
  82. proto.socks_request = fake_coroutine(OSError('test'))
  83. self.loop.run_until_complete(proto.negotiate(None, None))
  84. self.assertIn('test', str(waiter.exception()))
  85. def test_negotiate_socks_err(self):
  86. waiter = asyncio.Future(loop=self.loop)
  87. proto = make_base(self.loop, waiter=waiter)
  88. proto.socks_request = fake_coroutine(aiosocks.SocksError('test'))
  89. self.loop.run_until_complete(proto.negotiate(None, None))
  90. self.assertIn('Can not connect to', str(waiter.exception()))
  91. def test_negotiate_without_app_proto(self):
  92. waiter = asyncio.Future(loop=self.loop)
  93. proto = make_base(self.loop, waiter=waiter)
  94. proto.socks_request = fake_coroutine((None, None))
  95. proto._transport = True
  96. self.loop.run_until_complete(proto.negotiate(None, None))
  97. self.assertTrue(waiter.done())
  98. def test_negotiate_with_app_proto(self):
  99. waiter = asyncio.Future(loop=self.loop)
  100. proto = make_base(self.loop, waiter=waiter,
  101. ap_factory=lambda: asyncio.Protocol())
  102. proto.socks_request = fake_coroutine((None, None))
  103. self.loop.run_until_complete(proto.negotiate(None, None))
  104. self.assertTrue(waiter.done())
  105. def test_connection_lost(self):
  106. loop_mock = mock.Mock()
  107. app_proto = mock.Mock()
  108. proto = make_base(loop_mock, ap_factory=lambda: app_proto)
  109. # negotiate not completed
  110. proto._negotiate_done = False
  111. proto.connection_lost(True)
  112. self.assertFalse(loop_mock.call_soon.called)
  113. # negotiate successfully competed
  114. loop_mock.reset_mock()
  115. proto._negotiate_done = True
  116. proto.connection_lost(True)
  117. self.assertTrue(loop_mock.call_soon.called)
  118. # don't call connect_lost, if app_protocol == self
  119. # otherwise recursion
  120. loop_mock.reset_mock()
  121. proto = make_base(loop_mock, ap_factory=None)
  122. proto._negotiate_done = True
  123. proto.connection_lost(True)
  124. self.assertFalse(loop_mock.call_soon.called)
  125. def test_pause_writing(self):
  126. loop_mock = mock.Mock()
  127. app_proto = mock.Mock()
  128. proto = make_base(loop_mock, ap_factory=lambda: app_proto)
  129. # negotiate not completed
  130. proto._negotiate_done = False
  131. proto.pause_writing()
  132. self.assertFalse(proto._app_protocol.pause_writing.called)
  133. # negotiate successfully competed
  134. app_proto.reset_mock()
  135. proto._negotiate_done = True
  136. proto.pause_writing()
  137. self.assertTrue(proto._app_protocol.pause_writing.called)
  138. # don't call pause_writing, if app_protocol == self
  139. # otherwise recursion
  140. app_proto.reset_mock()
  141. proto = make_base(loop_mock)
  142. proto._negotiate_done = True
  143. proto.pause_writing()
  144. def test_resume_writing(self):
  145. loop_mock = mock.Mock()
  146. app_proto = mock.Mock()
  147. proto = make_base(loop_mock, ap_factory=lambda: app_proto)
  148. # negotiate not completed
  149. proto._negotiate_done = False
  150. # negotiate not completed
  151. with self.assertRaises(AssertionError):
  152. proto.resume_writing()
  153. self.assertFalse(proto._app_protocol.resume_writing.called)
  154. # negotiate successfully competed
  155. loop_mock.reset_mock()
  156. proto._negotiate_done = True
  157. proto.resume_writing()
  158. self.assertTrue(proto._app_protocol.resume_writing.called)
  159. # don't call resume_writing, if app_protocol == self
  160. # otherwise recursion
  161. loop_mock.reset_mock()
  162. proto = make_base(loop_mock)
  163. proto._negotiate_done = True
  164. with self.assertRaises(AssertionError):
  165. proto.resume_writing()
  166. def test_data_received(self):
  167. loop_mock = mock.Mock()
  168. app_proto = mock.Mock()
  169. proto = make_base(loop_mock, ap_factory=lambda: app_proto)
  170. # negotiate not completed
  171. proto._negotiate_done = False
  172. proto.data_received(b'123')
  173. self.assertFalse(proto._app_protocol.data_received.called)
  174. # negotiate successfully competed
  175. app_proto.reset_mock()
  176. proto._negotiate_done = True
  177. proto.data_received(b'123')
  178. self.assertTrue(proto._app_protocol.data_received.called)
  179. # don't call data_received, if app_protocol == self
  180. # otherwise recursion
  181. loop_mock.reset_mock()
  182. proto = make_base(loop_mock)
  183. proto._negotiate_done = True
  184. proto.data_received(b'123')
  185. def test_eof_received(self):
  186. loop_mock = mock.Mock()
  187. app_proto = mock.Mock()
  188. proto = make_base(loop_mock, ap_factory=lambda: app_proto)
  189. # negotiate not completed
  190. proto._negotiate_done = False
  191. proto.eof_received()
  192. self.assertFalse(proto._app_protocol.eof_received.called)
  193. # negotiate successfully competed
  194. app_proto.reset_mock()
  195. proto._negotiate_done = True
  196. proto.eof_received()
  197. self.assertTrue(proto._app_protocol.eof_received.called)
  198. # don't call pause_writing, if app_protocol == self
  199. # otherwise recursion
  200. app_proto.reset_mock()
  201. proto = make_base(loop_mock)
  202. proto._negotiate_done = True
  203. proto.eof_received()
  204. def test_make_ssl_proto(self):
  205. loop_mock = mock.Mock()
  206. app_proto = mock.Mock()
  207. ssl_context = ssllib.create_default_context()
  208. proto = make_base(loop_mock,
  209. ap_factory=lambda: app_proto, ssl=ssl_context)
  210. proto.socks_request = fake_coroutine((None, None))
  211. proto._transport = mock.Mock()
  212. self.loop.run_until_complete(proto.negotiate(None, None))
  213. self.assertTrue(loop_mock._make_ssl_transport.called)
  214. self.assertIs(loop_mock._make_ssl_transport.call_args[1]['sslcontext'],
  215. ssl_context)
  216. @mock.patch('aiosocks.protocols.asyncio.Task')
  217. def test_func_negotiate_cb_call(self, task_mock):
  218. loop_mock = mock.Mock()
  219. waiter = mock.Mock()
  220. proto = make_base(loop_mock, waiter=waiter)
  221. proto.socks_request = fake_coroutine((None, None))
  222. proto._negotiate_done_cb = mock.Mock()
  223. self.loop.run_until_complete(proto.negotiate(None, None))
  224. self.assertTrue(proto._negotiate_done_cb.called)
  225. self.assertFalse(task_mock.called)
  226. @mock.patch('aiosocks.protocols.asyncio.Task')
  227. def test_coro_negotiate_cb_call(self, task_mock):
  228. loop_mock = mock.Mock()
  229. waiter = mock.Mock()
  230. proto = make_base(loop_mock, waiter=waiter)
  231. proto.socks_request = fake_coroutine((None, None))
  232. proto._negotiate_done_cb = fake_coroutine(None)
  233. self.loop.run_until_complete(proto.negotiate(None, None))
  234. self.assertTrue(proto._negotiate_done_cb.called)
  235. self.assertTrue(task_mock.called)
  236. def test_reader_limit(self):
  237. proto = BaseSocksProtocol(None, None, ('python.org', 80),
  238. None, None, reader_limit=10,
  239. loop=self.loop)
  240. self.assertEqual(proto.reader._limit, 10)
  241. proto = BaseSocksProtocol(None, None, ('python.org', 80),
  242. None, None, reader_limit=15,
  243. loop=self.loop)
  244. self.assertEqual(proto.reader._limit, 15)
  245. def test_incomplete_error(self):
  246. proto = BaseSocksProtocol(None, None, ('python.org', 80),
  247. None, None, reader_limit=10,
  248. loop=self.loop)
  249. proto._stream_reader.readexactly = fake_coroutine(
  250. asyncio.IncompleteReadError(b'part', 5))
  251. with self.assertRaises(aiosocks.InvalidServerReply):
  252. self.loop.run_until_complete(proto.read_response(4))
  253. class TestSocks4Protocol(unittest.TestCase):
  254. def setUp(self):
  255. self.loop = asyncio.new_event_loop()
  256. asyncio.set_event_loop(None)
  257. def tearDown(self):
  258. self.loop.close()
  259. def test_init(self):
  260. addr = aiosocks.Socks4Addr('localhost', 1080)
  261. auth = aiosocks.Socks4Auth('user')
  262. dst = ('python.org', 80)
  263. with self.assertRaises(ValueError):
  264. aiosocks.Socks4Protocol(None, None, dst, loop=self.loop,
  265. waiter=None, app_protocol_factory=None)
  266. with self.assertRaises(ValueError):
  267. aiosocks.Socks4Protocol(None, auth, dst, loop=self.loop,
  268. waiter=None, app_protocol_factory=None)
  269. with self.assertRaises(ValueError):
  270. aiosocks.Socks4Protocol(aiosocks.Socks5Addr('host'), auth, dst,
  271. loop=self.loop, waiter=None,
  272. app_protocol_factory=None)
  273. with self.assertRaises(ValueError):
  274. aiosocks.Socks4Protocol(addr, aiosocks.Socks5Auth('l', 'p'), dst,
  275. loop=self.loop, waiter=None,
  276. app_protocol_factory=None)
  277. aiosocks.Socks4Protocol(addr, None, dst, loop=self.loop,
  278. waiter=None, app_protocol_factory=None)
  279. aiosocks.Socks4Protocol(addr, auth, dst, loop=self.loop,
  280. waiter=None, app_protocol_factory=None)
  281. def test_dst_domain_with_remote_resolve(self):
  282. proto = make_socks4(self.loop, dst=('python.org', 80),
  283. r=b'\x00\x5a\x00P\x7f\x00\x00\x01')
  284. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  285. self.loop.run_until_complete(req)
  286. proto._stream_writer.write.assert_called_with(
  287. b'\x04\x01\x00P\x00\x00\x00\x01user\x00python.org\x00'
  288. )
  289. def test_dst_domain_with_local_resolve(self):
  290. proto = make_socks4(self.loop, dst=('python.org', 80),
  291. rr=False, r=b'\x00\x5a\x00P\x7f\x00\x00\x01')
  292. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  293. self.loop.run_until_complete(req)
  294. proto._stream_writer.write.assert_called_with(
  295. b'\x04\x01\x00P\x7f\x00\x00\x01user\x00'
  296. )
  297. def test_dst_ip_with_remote_resolve(self):
  298. proto = make_socks4(self.loop, dst=('127.0.0.1', 8800),
  299. r=b'\x00\x5a\x00P\x7f\x00\x00\x01')
  300. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  301. self.loop.run_until_complete(req)
  302. proto._stream_writer.write.assert_called_with(
  303. b'\x04\x01"`\x7f\x00\x00\x01user\x00'
  304. )
  305. def test_dst_ip_with_locale_resolve(self):
  306. proto = make_socks4(self.loop, dst=('127.0.0.1', 8800),
  307. rr=False, r=b'\x00\x5a\x00P\x7f\x00\x00\x01')
  308. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  309. self.loop.run_until_complete(req)
  310. proto._stream_writer.write.assert_called_with(
  311. b'\x04\x01"`\x7f\x00\x00\x01user\x00'
  312. )
  313. def test_dst_domain_without_user(self):
  314. proto = make_socks4(self.loop, auth=aiosocks.Socks4Auth(''),
  315. dst=('python.org', 80),
  316. r=b'\x00\x5a\x00P\x7f\x00\x00\x01')
  317. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  318. self.loop.run_until_complete(req)
  319. proto._stream_writer.write.assert_called_with(
  320. b'\x04\x01\x00P\x00\x00\x00\x01\x00python.org\x00'
  321. )
  322. def test_dst_ip_without_user(self):
  323. proto = make_socks4(self.loop, auth=aiosocks.Socks4Auth(''),
  324. dst=('127.0.0.1', 8800),
  325. r=b'\x00\x5a\x00P\x7f\x00\x00\x01')
  326. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  327. self.loop.run_until_complete(req)
  328. proto._stream_writer.write.assert_called_with(
  329. b'\x04\x01"`\x7f\x00\x00\x01\x00'
  330. )
  331. def test_valid_resp_handling(self):
  332. proto = make_socks4(self.loop, r=b'\x00\x5a\x00P\x7f\x00\x00\x01')
  333. req = ensure_future(
  334. proto.socks_request(c.SOCKS_CMD_CONNECT), loop=self.loop)
  335. self.loop.run_until_complete(req)
  336. self.assertEqual(req.result(), (('python.org', 80), ('127.0.0.1', 80)))
  337. def test_invalid_reply_resp_handling(self):
  338. proto = make_socks4(self.loop, r=b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF')
  339. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  340. with self.assertRaises(aiosocks.InvalidServerReply):
  341. self.loop.run_until_complete(req)
  342. def test_socks_err_resp_handling(self):
  343. proto = make_socks4(self.loop, r=b'\x00\x5b\x00P\x7f\x00\x00\x01')
  344. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  345. with self.assertRaises(aiosocks.SocksError) as cm:
  346. self.loop.run_until_complete(req)
  347. self.assertTrue('0x5b' in str(cm.exception))
  348. def test_unknown_err_resp_handling(self):
  349. proto = make_socks4(self.loop, r=b'\x00\x5e\x00P\x7f\x00\x00\x01')
  350. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  351. with self.assertRaises(aiosocks.SocksError) as cm:
  352. self.loop.run_until_complete(req)
  353. self.assertTrue('Unknown error' in str(cm.exception))
  354. class TestSocks5Protocol(unittest.TestCase):
  355. def setUp(self):
  356. self.loop = asyncio.new_event_loop()
  357. asyncio.set_event_loop(None)
  358. def tearDown(self):
  359. self.loop.close()
  360. def test_init(self):
  361. addr = aiosocks.Socks5Addr('localhost', 1080)
  362. auth = aiosocks.Socks5Auth('user', 'pwd')
  363. dst = ('python.org', 80)
  364. with self.assertRaises(ValueError):
  365. aiosocks.Socks5Protocol(None, None, dst, loop=self.loop,
  366. waiter=None, app_protocol_factory=None)
  367. with self.assertRaises(ValueError):
  368. aiosocks.Socks5Protocol(None, auth, dst, loop=self.loop,
  369. waiter=None, app_protocol_factory=None)
  370. with self.assertRaises(ValueError):
  371. aiosocks.Socks5Protocol(aiosocks.Socks4Addr('host'),
  372. auth, dst, loop=self.loop,
  373. waiter=None, app_protocol_factory=None)
  374. with self.assertRaises(ValueError):
  375. aiosocks.Socks5Protocol(addr, aiosocks.Socks4Auth('l'),
  376. dst, loop=self.loop,
  377. waiter=None, app_protocol_factory=None)
  378. aiosocks.Socks5Protocol(addr, None, dst, loop=self.loop,
  379. waiter=None, app_protocol_factory=None)
  380. aiosocks.Socks5Protocol(addr, auth, dst, loop=self.loop,
  381. waiter=None, app_protocol_factory=None)
  382. def test_auth_inv_srv_ver(self):
  383. proto = make_socks5(self.loop, r=b'\x00\x00')
  384. req = proto.authenticate()
  385. with self.assertRaises(aiosocks.InvalidServerVersion):
  386. self.loop.run_until_complete(req)
  387. def test_auth_no_acceptable_auth_methods(self):
  388. proto = make_socks5(self.loop, r=b'\x05\xFF')
  389. req = proto.authenticate()
  390. with self.assertRaises(aiosocks.NoAcceptableAuthMethods):
  391. self.loop.run_until_complete(req)
  392. def test_auth_unsupported_auth_method(self):
  393. proto = make_socks5(self.loop, r=b'\x05\xF0')
  394. req = proto.authenticate()
  395. with self.assertRaises(aiosocks.InvalidServerReply):
  396. self.loop.run_until_complete(req)
  397. def test_auth_usr_pwd_granted(self):
  398. proto = make_socks5(self.loop, r=(b'\x05\x02', b'\x01\x00',))
  399. self.loop.run_until_complete(proto.authenticate())
  400. proto._stream_writer.write.assert_has_calls([
  401. mock.call(b'\x05\x02\x00\x02'),
  402. mock.call(b'\x01\x04user\x03pwd')
  403. ])
  404. def test_auth_invalid_reply(self):
  405. proto = make_socks5(self.loop, r=(b'\x05\x02', b'\x00\x00',))
  406. req = proto.authenticate()
  407. with self.assertRaises(aiosocks.InvalidServerReply):
  408. self.loop.run_until_complete(req)
  409. def test_auth_access_denied(self):
  410. proto = make_socks5(self.loop, r=(b'\x05\x02', b'\x01\x01',))
  411. req = proto.authenticate()
  412. with self.assertRaises(aiosocks.LoginAuthenticationFailed):
  413. self.loop.run_until_complete(req)
  414. def test_auth_anonymous_granted(self):
  415. proto = make_socks5(self.loop, r=b'\x05\x00')
  416. req = proto.authenticate()
  417. self.loop.run_until_complete(req)
  418. def test_build_dst_addr_ipv4(self):
  419. proto = make_socks5(self.loop)
  420. c = proto.build_dst_address('127.0.0.1', 80)
  421. dst_req, resolved = self.loop.run_until_complete(c)
  422. self.assertEqual(dst_req, [0x01, b'\x7f\x00\x00\x01', b'\x00P'])
  423. self.assertEqual(resolved, ('127.0.0.1', 80))
  424. def test_build_dst_addr_ipv6(self):
  425. proto = make_socks5(self.loop)
  426. c = proto.build_dst_address(
  427. '2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d', 80)
  428. dst_req, resolved = self.loop.run_until_complete(c)
  429. self.assertEqual(dst_req, [
  430. 0x04, b' \x01\r\xb8\x11\xa3\t\xd7\x1f4\x8a.\x07\xa0v]', b'\x00P'])
  431. self.assertEqual(resolved,
  432. ('2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d', 80))
  433. def test_build_dst_addr_domain_with_remote_resolve(self):
  434. proto = make_socks5(self.loop)
  435. c = proto.build_dst_address('python.org', 80)
  436. dst_req, resolved = self.loop.run_until_complete(c)
  437. self.assertEqual(dst_req, [0x03, b'\n', b'python.org', b'\x00P'])
  438. self.assertEqual(resolved, ('python.org', 80))
  439. def test_build_dst_addr_domain_with_locale_resolve(self):
  440. proto = make_socks5(self.loop, rr=False)
  441. c = proto.build_dst_address('python.org', 80)
  442. dst_req, resolved = self.loop.run_until_complete(c)
  443. self.assertEqual(dst_req, [0x01, b'\x7f\x00\x00\x01', b'\x00P'])
  444. self.assertEqual(resolved, ('127.0.0.1', 80))
  445. def test_rd_addr_ipv4(self):
  446. proto = make_socks5(
  447. self.loop, r=[b'\x01', b'\x7f\x00\x00\x01', b'\x00P'])
  448. req = ensure_future(proto.read_address(), loop=self.loop)
  449. self.loop.run_until_complete(req)
  450. self.assertEqual(req.result(), ('127.0.0.1', 80))
  451. def test_rd_addr_ipv6(self):
  452. resp = [
  453. b'\x04',
  454. b' \x01\r\xb8\x11\xa3\t\xd7\x1f4\x8a.\x07\xa0v]',
  455. b'\x00P'
  456. ]
  457. proto = make_socks5(self.loop, r=resp)
  458. req = ensure_future(proto.read_address(), loop=self.loop)
  459. self.loop.run_until_complete(req)
  460. self.assertEqual(
  461. req.result(), ('2001:db8:11a3:9d7:1f34:8a2e:7a0:765d', 80))
  462. def test_rd_addr_domain(self):
  463. proto = make_socks5(
  464. self.loop, r=[b'\x03', b'\n', b'python.org', b'\x00P'])
  465. req = ensure_future(proto.read_address(), loop=self.loop)
  466. self.loop.run_until_complete(req)
  467. self.assertEqual(req.result(), (b'python.org', 80))
  468. def test_socks_req_inv_ver(self):
  469. proto = make_socks5(self.loop, r=[b'\x05\x00', b'\x04\x00\x00'])
  470. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  471. with self.assertRaises(aiosocks.InvalidServerVersion):
  472. self.loop.run_until_complete(req)
  473. def test_socks_req_socks_srv_err(self):
  474. proto = make_socks5(self.loop, r=[b'\x05\x00', b'\x05\x02\x00'])
  475. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  476. with self.assertRaises(aiosocks.SocksError) as ct:
  477. self.loop.run_until_complete(req)
  478. self.assertTrue(
  479. 'Connection not allowed by ruleset' in str(ct.exception))
  480. def test_socks_req_unknown_err(self):
  481. proto = make_socks5(self.loop, r=[b'\x05\x00', b'\x05\xFF\x00'])
  482. req = proto.socks_request(c.SOCKS_CMD_CONNECT)
  483. with self.assertRaises(aiosocks.SocksError) as ct:
  484. self.loop.run_until_complete(req)
  485. self.assertTrue('Unknown error' in str(ct.exception))
  486. def test_socks_req_cmd_granted(self):
  487. # cmd granted
  488. resp = [b'\x05\x00',
  489. b'\x05\x00\x00',
  490. b'\x01', b'\x7f\x00\x00\x01',
  491. b'\x00P']
  492. proto = make_socks5(self.loop, r=resp)
  493. req = ensure_future(proto.socks_request(c.SOCKS_CMD_CONNECT),
  494. loop=self.loop)
  495. self.loop.run_until_complete(req)
  496. self.assertEqual(req.result(), (('python.org', 80), ('127.0.0.1', 80)))
  497. proto._stream_writer.write.assert_has_calls([
  498. mock.call(b'\x05\x02\x00\x02'),
  499. mock.call(b'\x05\x01\x00\x03\npython.org\x00P')
  500. ])