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.
 
 

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