weisk
3/26/2018 - 2:43 PM

sending a request over tor and renew ip

sending a request over tor and renew ip

var Https = require('socks5-https-client/lib/Agent');
var Http = require('socks5-http-client/lib/Agent');
var openports = require('openports');
var net = require('net');
var tmp = require('tmp');
var request  = require('request');
const { spawn } = require('child_process');

function spawnTor(port, port2) {
  const tmpobj = tmp.dirSync();
  const process = spawn("tor", [
    `--CookieAuthentication 0`, 
    `--DataDirectory "${tmpobj.name}"`,
    `--ControlPort ${port2}`,
    `--SocksPort ${port}`], {shell:true});


  return new Promise( (done, reject) => {
    process.stderr.on('end', reject);

    process.stdout.on('data', data=> {
      if (data.toString('utf8').indexOf('Done')>-1)
        return done(process);   
    });

  })
}



const getOverSocks = (url, headers, port) => {
  const Agent = url.slice(0,5) == 'https' ? Https : Http;
  return new Promise( (done, reject) => request({
    url,
    agentClass: Agent,
    headers,
    agentOptions: {
      socksHost: 'localhost', // Host set in config file.
      socksPort: port  // Port set in config file.
    }}, (e, res) => {
      if (e) return reject(e);
      return done(res)
    }
  ));
};

const torRoulette = function(n, password) {
  const ports = new Promise( done => openports(n*2, (e, ports) => {
    done(ports);
  }));

  const agents = ports.then(
    ports=> {
      const socks = ports.slice(0,n);
      const controls = ports.slice(n);
      const agents = Array.from({length:n}, (_,i) => ({
        sock: socks[i],
        control: controls[i],
        process: spawnTor(socks[i], controls[i]),
      }))

      return agents;
    })

  function get(i, url, headers={}) {
    return agents.then(a=> a[i%n])
    .then(a=>a.process.then(p=>a.sock))
    .then(port=> getOverSocks(url, headers, port))
    .catch(e=>console.log(e))
  }

  function renew(i) {
    return agents.then(a=> a[i%n])
    .then(a=>a.process.then(p => a.control))
    .then(port => new Promise( done => {
      const socket = net.connect({
        host: 'localhost',
        port
      }, () => {
        const command = [
          `authenticate "${password}"`, 
          'signal newnym', 
          'quit',
          ''
        ].join('\n');
        socket.write(command);
        socket.on('data', x=>console.log(x.toString()));
        socket.on('end', done);
      })
    }));
  }


  let i = 0;

  return {
    get,
    renew, // change ip
    roulleteGet(url, headers={}) {
      let j = i;
      ++i;
      return get(j, headers)
        .catch(e=> renew(j)
          .then(get(j, headers)))
    }
  }
}


const {get, renew} = torRoulette(10, 'password'); //create 10 tor demons; password defined in /etc/tor/torrc
const url = 'http://api.ipify.org';

get(0, url).then(
  x=>console.log(x.body)||renew(0)
).then(x=>get(0,url)).then(x=>console.log(x.body))