SOCKSServer.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. const { Provider } = require('nconf');
  2. const nconf = new Provider();
  3. const getPort = require('get-port');
  4. const { HttpAgent, auth } = require('socksv5');
  5. const { assert } = require('chai');
  6. const SocksProxyAgent = require('socks-proxy-agent');
  7. const _ = require('lodash');
  8. const { TorPool, SOCKSServer, TorProcess } = require('../');
  9. const { WAIT_FOR_CREATE, PAGE_LOAD_TIME, RETRY_DELAY, RETRY_STRATEGY, MAX_ATTEMPTS } = require('./constants');
  10. const request = require('requestretry').defaults({
  11. promiseFactory: ((resolver) => new Promise(resolver)),
  12. maxAttempts: MAX_ATTEMPTS,
  13. retryStrategy: RETRY_STRATEGY,
  14. retryDelay: RETRY_DELAY
  15. });
  16. nconf.use('memory');
  17. require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
  18. nconf.defaults(require(`${__dirname}/../src/default_config.js`));
  19. describe('SOCKSServer', function () {
  20. describe('#handleConnection(socket)', function () {
  21. let socksPort;
  22. let socksServerTorPool;
  23. let socksServer;
  24. before('start up server', async function (){
  25. socksServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null);
  26. socksServer = new SOCKSServer(socksServerTorPool, null, false);
  27. this.timeout(WAIT_FOR_CREATE);
  28. await socksServerTorPool.create(1);
  29. socksPort = await getPort();
  30. await socksServer.listen(socksPort);
  31. });
  32. it('should service a request for example.com', async function () {
  33. this.timeout(PAGE_LOAD_TIME);
  34. await request({
  35. url: 'http://example.com',
  36. agent: new SocksProxyAgent(`socks5h://127.0.0.1:${socksPort}`)
  37. });
  38. });
  39. it('should emit the "instance_connection" event', function (done) {
  40. this.timeout(PAGE_LOAD_TIME);
  41. let connectionHandler = (instance, source) => {
  42. assert.instanceOf(instance, TorProcess);
  43. assert.isObject(source);
  44. socksServer.removeAllListeners('instance_connection');;
  45. done();
  46. };
  47. socksServer.on('instance_connection', connectionHandler);
  48. request({
  49. url: 'http://example.com',
  50. agent: new SocksProxyAgent(`socks5h://127.0.0.1:${socksPort}`)
  51. })
  52. .catch(done)
  53. });
  54. after('shutdown server and shutdown tor pool', async function () {
  55. socksServer.close();
  56. await socksServerTorPool.exit();
  57. });
  58. });
  59. describe('#authenticate_user(username, password)', function () {
  60. let socksPort;
  61. let socksServerTorPool;
  62. let socksServer;
  63. let instance_def = {
  64. Name: 'instance-3',
  65. Group: "foo"
  66. };
  67. before('start up server', async function (){
  68. socksServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null);
  69. socksServer = new SOCKSServer(socksServerTorPool, null, { deny_unidentified_users: true, mode: "individual" });
  70. this.timeout(WAIT_FOR_CREATE * 3);
  71. await socksServerTorPool.create(2);
  72. await socksServerTorPool.add(instance_def);
  73. socksPort = await getPort();
  74. await socksServer.listen(socksPort);
  75. });
  76. it(`should service a request for example.com through ${instance_def.Name}`, function (done) {
  77. this.timeout(PAGE_LOAD_TIME);
  78. let connectionHandler = (instance, source) => {
  79. assert.equal(instance.instance_name, instance_def.Name);
  80. assert.isTrue(source.by_name);
  81. socksServer.removeAllListeners('instance_connection');
  82. done();
  83. };
  84. socksServer.on('instance_connection', connectionHandler);
  85. request({
  86. url: 'http://example.com',
  87. agent: new SocksProxyAgent(`socks5h://${instance_def.Name}:doesnotmatter@127.0.0.1:${socksPort}`)
  88. })
  89. .catch(done);
  90. });
  91. return
  92. it(`four requests made to example.com through the group named "foo" should come from the instances in "foo"`, function (done) {
  93. (async () => {
  94. this.timeout(PAGE_LOAD_TIME + (WAIT_FOR_CREATE));
  95. await socksServerTorPool.add([
  96. {
  97. Name: 'instance-4',
  98. Group: 'foo'
  99. }
  100. ]);
  101. })()
  102. .then(async () => {
  103. socksServer.proxy_by_name.mode = "group";
  104. let names_requested = [];
  105. let connectionHandler = (instance, source) => {
  106. names_requested.push(instance.instance_name);
  107. if (names_requested.length === socksServerTorPool.instances.length) {
  108. names_requested = _.uniq(names_requested).sort();
  109. let names_in_group = socksServerTorPool.instances_by_group('foo').map((i) => i.instance_name).sort()
  110. assert.deepEqual(names_requested, names_in_group);
  111. socksServer.removeAllListeners('instance_connection');
  112. done();
  113. }
  114. };
  115. socksServer.on('instance_connection', connectionHandler);
  116. let i = 0;
  117. while (i < socksServerTorPool.instances.length) {
  118. await request({
  119. url: 'http://example.com',
  120. agent: new SocksProxyAgent(`socks5h://foo:doesnotmatter@127.0.0.1:${socksPort}`)
  121. });
  122. i++;
  123. }
  124. })
  125. .then(async () => {
  126. await socksServerTorPool.remove_by_name('instance-4');
  127. socksServer.proxy_by_name.mode = "individual";
  128. })
  129. .catch(done);
  130. });
  131. // it(`shouldn't be able to send a request without a username`, async function() {
  132. // let f = () => {};
  133. // try {
  134. // await request({
  135. // url: 'http://example.com',
  136. // agent: new HttpAgent({
  137. // proxyHost: '127.0.0.1',
  138. // proxyPort: socksPort,
  139. // localDNS: false,
  140. // auths: [ auth.None() ]
  141. // }),
  142. // timeout: PAGE_LOAD_TIME
  143. // });
  144. // } catch (error) {
  145. // f = () => { throw error };
  146. // } finally {
  147. // assert.throws(f);
  148. // }
  149. // });
  150. // it(`shouldn't be able to send a request with an incorrect username`, async function() {
  151. // let f = () => {};
  152. // try {
  153. // await request({
  154. // url: 'http://example.com',
  155. // agent: new HttpAgent({
  156. // proxyHost: '127.0.0.1',
  157. // proxyPort: socksPort,
  158. // localDNS: false,
  159. // auths: [ auth.UserPassword("foo", "bar") ]
  160. // }),
  161. // timeout: PAGE_LOAD_TIME
  162. // });
  163. // } catch (error) {
  164. // f = () => { throw error };
  165. // } finally {
  166. // assert.throws(f);
  167. // }
  168. // });
  169. after('shutdown server and shutdown tor pool', async function () {
  170. socksServer.close();
  171. await socksServerTorPool.exit();
  172. });
  173. });
  174. });