Skip to content

Instantly share code, notes, and snippets.

@markis
Created August 1, 2017 17:55
Show Gist options
  • Save markis/7ccba4285655e087022277b0d6196195 to your computer and use it in GitHub Desktop.
Save markis/7ccba4285655e087022277b0d6196195 to your computer and use it in GitHub Desktop.
Automatic vpn using openconnect
#!/usr/bin/env node
const proc = require('child_process');
const crypto = require('crypto');
const config = require('./config');
connect()
function connect() {
var step = 0;
const ps = proc.spawn('sudo', ['-S', 'openconnect', config.host, '-u', config.user]);
ps.stdout.on('data', listener);
ps.stderr.on('data', listener);
function listener(chunk) {
process.stdout.write(chunk.toString('utf8').trim() + '\n');
if (step === 0 && chunk.indexOf('sudo') > -1) {
ps.stdin.write(config.sudopass + '\n');
step = 1;
}
else if ((step === 0 || step === 1) && chunk.indexOf('Password:') > -1) {
ps.stdin.write(config.pass + '\n');
step = 2;
}
else if (step === 2 && chunk.indexOf('Response:') > -1) {
const googleAuth = getGoogleAuthenticatorCode(config.authenticatorSecret);
ps.stdin.write(googleAuth + '\n');
step = 0;
}
else if (chunk.indexOf('dead peer') > -1) {
try { ps.kill(); } catch(e) {}
ps = null;
connect();
}
};
}
function getGoogleAuthenticatorCode(secret) {
const byteTable = [
0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff
];
var plainChar;
var shiftIndex = 0;
var encodedByte = 0;
var pos = 0;
const encoded = new Buffer(secret);
const decoded = new Buffer(Math.ceil(5 * encoded.length / 8));
for (var i = 0; i < encoded.length && 0x3d !== encoded[i]; i++) {
encodedByte = byteTable[encoded[i] - 0x30];
shiftIndex > 3 ?
(decoded[pos] = plainChar |= 0xff & encodedByte >>> (shiftIndex = (shiftIndex + 5) % 8), pos++, plainChar = 0xff & encodedByte << 8 - shiftIndex) :
shiftIndex = (shiftIndex + 5) % 8, 0 === shiftIndex ?
(decoded[pos] = plainChar |= encodedByte, pos++, plainChar = 0) :
plainChar |= 0xff & encodedByte << 8 - shiftIndex
}
var counter = Math.floor(Date.now() / 30000);
const res = [];
while (res.length < 8) {
res.unshift(counter & 0xFF);
counter = counter >> 8;
}
const u64Counter = new Buffer(res);
const sha1hmac = crypto.createHmac('sha1', new Buffer(decoded.slice(0, pos)));
const counterHex = sha1hmac.update(u64Counter).digest('hex');
const hmac = new Buffer(counterHex, 'hex');
const offset = hmac[19] & 0xf;
const code = String((hmac[offset] & 0x7f) << 24 | (hmac[offset + 1] & 0xff) << 16 | (hmac[offset + 2] & 0xff) << 8 | (hmac[offset + 3] & 0xff));
return ('000000' + code).slice(-6);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment