torControl.js
1 import fs from 'fs' 2 import net from 'net' 3 const PORT = process.env.PORT || 8003 4 5 if (process.env.ONESHOT) { 6 ogre((err, onion) => { 7 if (err) return console.log(err); 8 console.log(onion) 9 }) 10 } 11 12 function ogre(callback){ 13 var i = -1 14 let hiddenServicePortSplit, hiddenServiceDirSplit, onion 15 try { 16 var cookieBuff = fs.readFileSync(process.env.HOME + '/.tor/control_auth_cookie') 17 var cookie = Buffer.from(cookieBuff).toString('hex') 18 } catch { 19 console.log("Couldn't access", process.env.HOME + '/.tor/control_auth_cookie') 20 return callback("ERR: failed to access cookie") 21 } 22 let controlClient = net.connect({host: '127.0.0.1', port: 9061}, () => { 23 controlClient.write('AUTHENTICATE ' + cookie + '\r\n'); 24 }); 25 controlClient.on('data', (x) => { 26 i ++ 27 if (i ===0){ 28 controlClient.write("GETCONF HiddenServicePort \r\n") 29 } else if (i === 1) { 30 hiddenServicePortSplit = splitFromBuffer(x) 31 hiddenServicePortSplit = hiddenServicePortSplit.filter(x => x !== 'HiddenServicePort') 32 controlClient.write("GETCONF HiddenServiceDir \r\n") 33 } else if (i === 2){ 34 hiddenServiceDirSplit = splitFromBuffer(x) 35 hiddenServiceDirSplit = hiddenServiceDirSplit.filter(x => x !== 'HiddenServiceDir') 36 onion = checkCurrentPortHasConfigAndReturnOnion(hiddenServicePortSplit, hiddenServiceDirSplit, PORT) 37 if (!onion){ 38 let newConf = buildNewConfString(hiddenServicePortSplit, hiddenServiceDirSplit, PORT) 39 controlClient.write("SETCONF " + newConf + " \r\n") 40 } else { 41 controlClient.write("QUIT \r\n" ) 42 callback(null, onion) 43 } 44 } else if (i === 3){ 45 controlClient.write("SAVECONF \r\n" ) 46 } else if (i === 4){ 47 controlClient.write("GETCONF HiddenServicePort \r\n") 48 } else if (i === 5) { 49 hiddenServicePortSplit = splitFromBuffer(x) 50 controlClient.write("GETCONF HiddenServiceDir \r\n") 51 } else if (i === 6){ 52 hiddenServiceDirSplit = splitFromBuffer(x) 53 onion = checkCurrentPortHasConfigAndReturnOnion(hiddenServicePortSplit, hiddenServiceDirSplit, PORT) 54 if (!onion){ 55 console.log('guess we failed') 56 callback('sorry') 57 } else { 58 controlClient.write("QUIT \r\n" ) 59 callback(null, onion) 60 } 61 } 62 }) 63 64 } 65 66 function splitFromBuffer(x){ 67 return Buffer.from(x) 68 .toString() 69 .split(/\r?\n/) 70 .filter(x => x) 71 .map(x => x.slice(4)); 72 } 73 74 function buildNewConfString(hiddenServicePortSplit, hiddenServiceDirSplit, port){ 75 let targetDir = process.env.HOME + '/.tor/' + crypto.randomUUID() 76 try { 77 fs.mkdirSync(targetDir, '0700') 78 } catch (err){ 79 console.log(err) 80 } 81 82 hiddenServicePortSplit = hiddenServicePortSplit.map(noQuotes => { 83 return noQuotes.slice(0, 18) + "\"" + noQuotes.slice(18) + "\"" 84 }) 85 86 let alternate = [] 87 hiddenServiceDirSplit.forEach((x, i) => { 88 alternate.push(x) 89 alternate.push(hiddenServicePortSplit[i]) 90 }) 91 let conffy = '' 92 conffy += alternate.join(' ') 93 conffy += " HiddenServiceDir=" + targetDir + " " 94 conffy += " HiddenServicePort=\"80 127.0.0.1:" + port + "\"" 95 return conffy 96 } 97 98 function checkCurrentPortHasConfigAndReturnOnion(hiddenServicePortSplit, hiddenServiceDirSplit, port=8003){ 99 let onion = false 100 101 hiddenServicePortSplit.forEach((x, i) => { 102 if (x.indexOf(port) > -1){ 103 let directory = hiddenServiceDirSplit[i].slice(17) 104 onion = fs.readFileSync(directory + '/hostname', {encoding:'utf8'}) 105 } 106 }) 107 108 return onion 109 } 110 111 export default ogre