.Xauth-based authorisation

This commit is contained in:
sidorares 2011-08-01 16:13:44 +10:00
parent 660c308527
commit 0a81b9fdf8
4 changed files with 123 additions and 19 deletions

View file

@ -1,11 +1,91 @@
// TODO: http://en.wikipedia.org/wiki/X_Window_authorization
module.exports = function( cb )
var fs = require('fs');
var Buffer = require('buffer').Buffer;
// add 'unpack' method for buffer
require('./unpackbuffer').addUnpack(Buffer);
function parseXauth( buf )
{
// empty yet
var authType = '';
var authData = '';
cb( authType, authData );
var offset = 0;
var auth = [];
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.unpack('n')[0];
offset += 2;
console.log(cookie.type);
// TODO: rewrite following using loop (16bits length + string data)
var addressLen = buf.unpack('n', offset)[0];
offset += 2;
console.log(addressLen);
cookie.address = buf.unpackString(addressLen, offset);
offset += addressLen;
var displayNumLen = buf.unpack('n', offset)[0];
console.log(displayNumLen);
offset += 2;
cookie.display = buf.unpackString(displayNumLen, offset);
offset += displayNumLen;
var authNameLen = buf.unpack('n', offset)[0];
offset += 2;
console.log(authNameLen);
cookie.authName = buf.unpackString(authNameLen, offset);
offset += authNameLen;
var authDataLen = buf.unpack('n', offset)[0];
offset += 2;
console.log(authDataLen);
cookie.authData = buf.unpackString(authDataLen, offset);
offset += authDataLen;
auth.push(cookie);
}
return auth;
}
// TODO: rewrite to allow negotiation of auth type with server
module.exports = function( display, host, cb )
{
var XAuthorityFile = process.env.XAUTHORITY;
if (!XAuthorityFile)
{
if ( process.platform.match(/win/) ) {
// http://www.straightrunning.com/XmingNotes/trouble.php
//
// The Xming magic cookie program, xauth (user-based), uses an
// Xauthority file (not the traditional .Xauthority file) in
// the %HOME% directory. To use xauth from Command Processor
// e.g. on Windows machine 192.168.0.2 with user colin...
XAuthorityFile = process.env.USERPROFILE + '\\Xauthority';
} else {
XAuthorityFile = process.env.HOME + '/.Xauthority';
}
fs.readFile(XAuthorityFile, function (err, data) {
if (err) throw err;
var auth = parseXauth(data);
for (cookieNum in auth)
{
var cookie = auth[cookieNum];
if (cookie.display == display && cookie.address == host)
{
cb( cookie.authName, cookie.authData );
return;
}
}
throw 'No auth cookie matching display=' + display + ' and host=' + host;
});
}
}

View file

@ -180,9 +180,9 @@ bl.unpack('C', function(res) {
}
function writeClientHello(stream)
function writeClientHello(stream, displayNum, authHost)
{
getAuthString( function( authType, authData ) {
getAuthString( displayNum, authHost, function( authType, authData ) {
authType = xutil.padded_string( authType );
authData = xutil.padded_string( authData );
var byte_order = 'l'.charCodeAt(0); // TODO: byteorder!!!

View file

@ -30,6 +30,11 @@ module.exports.addUnpack = function(Buffer)
var b2 = this[offset++];
data.push(b2*256+b1);
break;
case 'n':
var b1 = this[offset++];
var b2 = this[offset++];
data.push(b1*256+b2);
break;
case 'L':
var b1 = this[offset++];
var b2 = this[offset++];

View file

@ -13,6 +13,8 @@ var Buffer = require('buffer').Buffer;
// add 'unpack' method for buffer
require('./unpackbuffer').addUnpack(Buffer);
var os = require('os');
var xerrors = require('./xerrors');
var coreRequests = require('./corereqs');
var stdatoms = require('./stdatoms');
@ -281,7 +283,7 @@ XClient.prototype.startHandshake = function()
{
var client = this;
handshake.writeClientHello(this.pack_stream);
handshake.writeClientHello(this.pack_stream, this.displayNum, this.authHost);
handshake.readServerHello(this.pack_stream, function(display)
{
// TODO: readServerHello can set erro state in display
@ -300,20 +302,37 @@ var platformDefaultTransport = {
// TODO: check process.platform on SmartMachine solaris box
}
module.exports.createClient = function(initCb)
module.exports.createClient = function(initCb, display)
{
// TODO: parse $DISPLAY
if (!display)
display = process.env.DISPLAY;
if (!display)
display = ':0';
var displayMatch = display.match(/^(?:[^:]*?\/)?(.*):(\d+)(?:.(\d+))?$/);
var host = displayMatch[1];
if (!host)
host = '127.0.0.1';
var displayNum = displayMatch[2];
if (!displayNum)
displayNum = 0;
var screenNum = displayMatch[3];
if (!screenNum)
screenNum = 0;
// open stream
var stream;
var defaultTransportName = platformDefaultTransport[process.platform];
// use tcp if stated explicitly or if not defined at all
if (!defaultTransportName || defaultTransportName == 'tcp')
stream = net.createConnection(6000);
if (defaultTransportName == 'unix')
stream = net.createConnection('/tmp/.X11-unix/X0');
// open stream
var stream;
var defaultTransportName = platformDefaultTransport[process.platform];
// use tcp if stated explicitly or if not defined at all
if (!defaultTransportName || defaultTransportName == 'tcp' || host != '127.0.0.1')
stream = net.createConnection(6000 + displayNum, host);
if (defaultTransportName == 'unix' && host == '127.0.0.1')
stream = net.createConnection('/tmp/.X11-unix/X' + displayNum);
var client = new XClient(stream);
client.displayNum = displayNum;
client.screenNum = screenNum;
client.authHost = os.hostname();
if (initCb)
{
client.on('connect', function(display) {