// TODO: http://en.wikipedia.org/wiki/X_Window_authorization var fs = require('fs'); var Buffer = require('buffer').Buffer; // add 'unpack' method for buffer require('./unpackbuffer').addUnpack(Buffer); function parseXauth( buf ) { var offset = 0; var auth = []; var cookieProperties = ['address', 'display', 'authName', 'authData']; while (offset < buf.length) { var cookie = {}; var typeToName = { 256: 'Local', 65535: 'Wild', 254: 'Netname', 253: 'Krb5Principal', 252: 'LocalHost', 0: 'Internet', 1: 'DECnet', 2: 'Chaos', 5: 'ServerInterpreted', 6: 'InternetV6' }; cookie.type = buf.readUInt16LE(offset); console.log('Cookie type: '); if (!typeToName[cookie.type]) { console.warn('Unknown address type'); } offset += 2; cookieProperties.forEach(function(property) { var length = buf.unpack('n', offset)[0]; offset += 2; if (cookie.type === 0 && property == 'address') { // Internet // 4 bytes of ip addess, convert to w.x.y.z string cookie.address = [ buf[offset], buf[offset+1], buf[offset+2], buf[offset+3]] .map(function(octet) { return octet.toString(10) }).join('.'); } else { cookie[property] = buf.unpackString(length, offset); } offset += length; }); auth.push(cookie); } return auth; } var os = require('os'); var path = require('path'); function readXauthority(cb) { var filename = process.env.XAUTHORITY || path.join(os.homedir(), '.Xauthority'); fs.readFile(filename, function(err, data) { if (!err) return cb(null, data); if(err.code == 'ENOENT') { // Xming/windows uses %HOME%/Xauthority ( .Xauthority with no dot ) - try with this name filename = process.env.XAUTHORITY || path.join(os.homedir(), 'Xauthority'); return fs.readFile(filename, cb); } else { cb(err); } }); } module.exports = function( display, host, cb ) { readXauthority(function(err, data) { if(err) return cb(err); var auth = parseXauth(data); for (var cookieNum in auth) { var cookie = auth[cookieNum]; if (cookie.display === display && cookie.address === host) return cb( null, cookie ); } cb(new Error('No auth cookie matching display=' + display + ' and host=' + host)); }); };