mirror of
https://github.com/danbulant/node-x11
synced 2026-06-18 06:01:31 +00:00
.Xauth-based authorisation
This commit is contained in:
parent
660c308527
commit
0a81b9fdf8
4 changed files with 123 additions and 19 deletions
|
|
@ -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;
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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!!!
|
||||
|
|
|
|||
|
|
@ -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++];
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue