bibliogram/src/lib/utils/tor.js

87 lines
2.2 KiB
JavaScript
Raw Normal View History

2020-02-02 11:43:56 +00:00
const SocksProxyAgent = require("socks-proxy-agent")
const {connect} = require("net");
const constants = require("../constants")
const {request} = require("./request")
2020-11-17 05:30:18 +00:00
const {RequestCache} = require("../cache")
2020-02-02 11:43:56 +00:00
class TorManager {
/**
* @param {import("@deadcanaries/granax/lib/controller")} tor
* @param {number} port
*/
constructor(tor, port) {
this.tor = tor
this.port = port
this.agent = new SocksProxyAgent("socks5://localhost:"+this.port)
2020-11-17 05:30:18 +00:00
this.circuitManager = new RequestCache()
2020-02-02 11:43:56 +00:00
}
async request(url, test) {
2020-11-17 05:30:18 +00:00
let done = false
let g
2020-11-17 05:30:18 +00:00
while (!done) {
g = await request(url, {agent: this.agent}, {log: true, statusLine: "TOR"})
2020-02-02 11:43:56 +00:00
try {
await g.check(test)
break
2020-02-02 11:43:56 +00:00
} catch (e) {
await this.newCircuit()
}
}
return g
2020-02-02 11:43:56 +00:00
}
newCircuit() {
2020-11-17 05:30:18 +00:00
return this.circuitManager.getOrFetchPromise("circuit", () => {
console.log(" <> [TOR-CIR] Finding a new circuit...")
return new Promise(resolve => {
this.tor.cleanCircuits(() => resolve())
})
}).then(x => x.result)
2020-02-02 11:43:56 +00:00
}
}
try {
var granax = require("@deadcanaries/granax")
} catch (e) {}
/** @type {Promise<TorManager>} */
module.exports = new Promise(resolve => {
if (granax) {
/** @type {import("@deadcanaries/granax/lib/controller")} */
// @ts-ignore
let tor
2021-09-28 03:23:52 +00:00
if (constants.tor.password == null || constants.tor.port == null) {
2020-02-02 11:43:56 +00:00
// @ts-ignore
tor = new granax()
} else {
2021-09-28 03:23:52 +00:00
tor = new granax.TorController(connect(constants.tor.port), {authOnConnect: false})
2020-02-02 13:24:14 +00:00
tor.authenticate(`"${constants.tor.password}"`, err => {
2020-02-02 11:43:56 +00:00
if (err) console.log("Tor auth error:", err)
})
}
2020-02-18 02:56:26 +00:00
console.log("Starting Tor...")
2020-02-02 11:43:56 +00:00
tor.once("ready", () => {
tor.getInfo("net/listeners/socks", (err, result) => {
if (err) throw err
// result is string containing something like "127.0.0.1:36977"
// yes, the string contains double quotes!
const port = +result.match(/:(\d+)/)[1]
const torManager = new TorManager(tor, port)
console.log("Tor is ready, using SOCKS port "+port)
resolve(torManager)
})
})
tor.on("error", function() {
console.log("Tor error!")
console.log(...arguments)
})
} else {
2020-02-18 02:56:26 +00:00
console.log("Note: Tor functionality not installed. You may wish to run `npm install`. (78+ MB download required.)")
2020-02-02 11:43:56 +00:00
resolve(null)
}
})