Connects to the Tor instance via the control port when the instance starts
This commit is contained in:
parent
b3700e0202
commit
4bc4c15dd7
36
package-lock.json
generated
36
package-lock.json
generated
|
@ -770,6 +770,11 @@
|
|||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
},
|
||||
"interpret": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
|
||||
"integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ="
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
||||
|
@ -5825,6 +5830,11 @@
|
|||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
|
||||
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
|
@ -5890,6 +5900,14 @@
|
|||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
"rechoir": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
|
||||
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
|
||||
"requires": {
|
||||
"resolve": "1.7.1"
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.85.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
|
||||
|
@ -5930,6 +5948,14 @@
|
|||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
|
||||
"integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
|
||||
"requires": {
|
||||
"path-parse": "1.0.5"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
|
||||
|
@ -5968,6 +5994,16 @@
|
|||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
|
||||
},
|
||||
"shelljs": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz",
|
||||
"integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==",
|
||||
"requires": {
|
||||
"glob": "7.1.2",
|
||||
"interpret": "1.1.0",
|
||||
"rechoir": "0.6.2"
|
||||
}
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"nanoid": "^1.0.2",
|
||||
"native-dns": "git+https://github.com/znetstar/node-dns.git",
|
||||
"nconf": "^0.10.0",
|
||||
"shelljs": "^0.8.2",
|
||||
"socks-proxy-agent": "^3.0.1",
|
||||
"socksv5": "git+https://github.com/lee-elenbaas/socksv5.git",
|
||||
"temp": "^0.8.3",
|
||||
|
|
|
@ -6,15 +6,21 @@ const getPort = require('get-port');
|
|||
const del = require('del');
|
||||
const EventEmitter = require('eventemitter2').EventEmitter2;
|
||||
const temp = require('temp');
|
||||
const { TorController } = require('granax');
|
||||
const { connect } = require('net');
|
||||
const shell = require('shelljs');
|
||||
const crypto = require('crypto');
|
||||
temp.track();
|
||||
|
||||
class TorProcess extends EventEmitter {
|
||||
constructor(tor_path, config, logger, nconf) {
|
||||
constructor(tor_path, config, logger, nconf, granax_options) {
|
||||
super();
|
||||
|
||||
this.tor_path = tor_path || nconf.get('torPath');
|
||||
this.nconf = nconf;
|
||||
this.logger = logger;
|
||||
this.granax_options = granax_options || nconf.get('granaxOptions');
|
||||
this.control_password = crypto.randomBytes(128).toString('base64');
|
||||
|
||||
config.DataDirectory = config.DataDirectory || temp.mkdirSync();
|
||||
|
||||
|
@ -45,14 +51,25 @@ class TorProcess extends EventEmitter {
|
|||
return this._socks_port || null;
|
||||
}
|
||||
|
||||
get control_port() {
|
||||
return this._control_port || null;
|
||||
}
|
||||
|
||||
get controller() {
|
||||
return this._controller;
|
||||
}
|
||||
|
||||
create(callback) {
|
||||
async.auto({
|
||||
dnsPort: (callback) => getPort().then(port => callback(null, port)),
|
||||
socksPort: (callback) => getPort().then(port => callback(null, port)),
|
||||
configPath: ['dnsPort', 'socksPort', (context, callback) => {
|
||||
controlPort: (callback) => getPort().then(port => callback(null, port)),
|
||||
configPath: ['dnsPort', 'socksPort', 'controlPort', (context, callback) => {
|
||||
let options = {
|
||||
DNSPort: `127.0.0.1:${context.dnsPort}`,
|
||||
SocksPort: `127.0.0.1:${context.socksPort}`,
|
||||
ControlPort: `127.0.0.1:${context.controlPort}`,
|
||||
HashedControlPassword: shell.exec(`${this.tor_path} --hash-password "${this.control_password}"`, { async: false, silent: true }).stdout.trim()
|
||||
};
|
||||
let config = _.extend(_.extend({}, this.tor_config), options);
|
||||
let text = Object.keys(config).map((key) => `${key} ${config[key]}`).join("\n");
|
||||
|
@ -70,13 +87,14 @@ class TorProcess extends EventEmitter {
|
|||
|
||||
this._dns_port = context.dnsPort;
|
||||
this._socks_port = context.socksPort;
|
||||
this._control_port = context.controlPort;
|
||||
|
||||
let tor = spawn(this.tor_path, ['-f', context.configPath], {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
detached: false,
|
||||
shell: '/bin/bash'
|
||||
detached: false
|
||||
});
|
||||
|
||||
|
||||
tor.on('close', (code) => {
|
||||
this.emit('process_exit', code);
|
||||
if (this.definition && !this.definition.Name) {
|
||||
|
@ -95,6 +113,22 @@ class TorProcess extends EventEmitter {
|
|||
this.logger && this.logger.info(`[tor-${this.instance_name}]: tor is ready`);
|
||||
});
|
||||
|
||||
this.on('control_listen', () => {
|
||||
this._controller = new TorController(connect(this._control_port), _.extend({ authOnConnect: false }, this.granax_options));
|
||||
this.controller.on('ready', () => {
|
||||
this.logger && this.logger.debug(`[tor-${this.instance_name}]: connected to tor control port`);
|
||||
this.controller.authenticate(`"${this.control_password}"`, (err) => {
|
||||
if (err) {
|
||||
this.logger && this.logger.error(`[tor-${this.instance_name}]: ${err.stack}`);
|
||||
this.emit('error', err);
|
||||
} else {
|
||||
this.logger && this.logger.debug(`[tor-${this.instance_name}]: authenticated with tor instance via the control port`);
|
||||
this.emit('controller_ready');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
tor.stdout.on('data', (data) => {
|
||||
let text = Buffer.from(data).toString('utf8');
|
||||
let msg = text.split('] ').pop();
|
||||
|
@ -102,17 +136,29 @@ class TorProcess extends EventEmitter {
|
|||
this.emit('ready');
|
||||
}
|
||||
|
||||
if (text.indexOf('Opening Control listener on') !== -1) {
|
||||
this.emit('control_listen');
|
||||
}
|
||||
|
||||
if (text.indexOf('Opening Socks listener on') !== -1) {
|
||||
this.emit('socks_listen');
|
||||
}
|
||||
|
||||
if (text.indexOf('Opening DNS listener on') !== -1) {
|
||||
this.emit('dns_listen');
|
||||
}
|
||||
|
||||
if (text.indexOf('[err]') !== -1) {
|
||||
this.emit('error', new Error(msg));
|
||||
this.logger && this.logger.error(`[tor-${tor.pid}]: ${msg}`);
|
||||
this.logger && this.logger.error(`[tor-${this.instance_name}]: ${msg}`);
|
||||
}
|
||||
|
||||
else if (text.indexOf('[notice]') !== -1) {
|
||||
this.logger && this.logger.debug(`[tor-${tor.pid}]: ${msg}`);
|
||||
this.logger && this.logger.debug(`[tor-${this.instance_name}]: ${msg}`);
|
||||
}
|
||||
|
||||
else if (text.indexOf('[warn]') !== -1) {
|
||||
this.logger && this.logger.warn(`[tor-${tor.pid}]: ${msg}`);
|
||||
this.logger && this.logger.warn(`[tor-${this.instance_name}]: ${msg}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -40,4 +40,5 @@ module.exports = {
|
|||
"options": {},
|
||||
"timeout": null
|
||||
},
|
||||
"granaxOptions": null
|
||||
};
|
Loading…
Reference in a new issue