mirror of
https://github.com/danbulant/node-x11
synced 2026-06-05 07:41:34 +00:00
Fix auth for remote hosts and handle different auth families
- Use the remote address to find the auth cookie instead of the local hostname - Read family type as big endian in Xauthority file - Don't upgrade 127.0.0.1 TCP connections to unix domain socket (libX11 and xcb don't do this) - Don't error if no auth cookie is found; continue without auth
This commit is contained in:
parent
edbe678f84
commit
e8883275bf
3 changed files with 30 additions and 15 deletions
26
lib/auth.js
26
lib/auth.js
|
|
@ -1,4 +1,5 @@
|
||||||
// TODO: http://en.wikipedia.org/wiki/X_Window_authorization
|
// TODO: differentiate between auth types (i.e., MIT-MAGIC-COOKIE-1 and XDM-AUTHORIZATION-1)
|
||||||
|
// and choose the best based on the algorithm in libXau's XauGetBestAuthByAddr
|
||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var Buffer = require('buffer').Buffer;
|
var Buffer = require('buffer').Buffer;
|
||||||
|
|
@ -15,7 +16,7 @@ var typeToName = {
|
||||||
1: 'DECnet',
|
1: 'DECnet',
|
||||||
2: 'Chaos',
|
2: 'Chaos',
|
||||||
5: 'ServerInterpreted',
|
5: 'ServerInterpreted',
|
||||||
6: 'InternetV6'
|
6: 'Internet6'
|
||||||
};
|
};
|
||||||
|
|
||||||
function parseXauth( buf )
|
function parseXauth( buf )
|
||||||
|
|
@ -27,7 +28,7 @@ function parseXauth( buf )
|
||||||
while (offset < buf.length)
|
while (offset < buf.length)
|
||||||
{
|
{
|
||||||
var cookie = {};
|
var cookie = {};
|
||||||
cookie.type = buf.readUInt16LE(offset);
|
cookie.type = buf.readUInt16BE(offset);
|
||||||
if (!typeToName[cookie.type]) {
|
if (!typeToName[cookie.type]) {
|
||||||
console.warn('Unknown address type');
|
console.warn('Unknown address type');
|
||||||
}
|
}
|
||||||
|
|
@ -73,8 +74,16 @@ function readXauthority(cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function( display, host, cb )
|
module.exports = function( display, host, socketFamily, cb )
|
||||||
{
|
{
|
||||||
|
var family;
|
||||||
|
if (socketFamily === 'IPv4') {
|
||||||
|
family = 0; // Internet
|
||||||
|
} else if (socketFamily === 'IPv6') {
|
||||||
|
family = 6; // Internet6
|
||||||
|
} else {
|
||||||
|
family = 256; // Local
|
||||||
|
}
|
||||||
readXauthority(function(err, data) {
|
readXauthority(function(err, data) {
|
||||||
if(err) return cb(err);
|
if(err) return cb(err);
|
||||||
|
|
||||||
|
|
@ -84,15 +93,18 @@ module.exports = function( display, host, cb )
|
||||||
authData: ''
|
authData: ''
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var auth = parseXauth(data);
|
var auth = parseXauth(data);
|
||||||
for (var cookieNum in auth)
|
for (var cookieNum in auth)
|
||||||
{
|
{
|
||||||
var cookie = auth[cookieNum];
|
var cookie = auth[cookieNum];
|
||||||
if ((typeToName[cookie.family] === 'Wild' || cookie.address === host) &&
|
if ((typeToName[cookie.family] === 'Wild' || (cookie.type === family && cookie.address === host)) &&
|
||||||
(cookie.display.length === 0 || cookie.display === display))
|
(cookie.display.length === 0 || cookie.display === display))
|
||||||
return cb( null, cookie );
|
return cb( null, cookie );
|
||||||
}
|
}
|
||||||
cb(new Error('No auth cookie matching display=' + display + ' and host=' + host));
|
// If no cookie is found, proceed without authentication
|
||||||
|
cb(null, {
|
||||||
|
authName: '',
|
||||||
|
authData: ''
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -189,9 +189,9 @@ function getByteOrder() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeClientHello(stream, displayNum, authHost)
|
function writeClientHello(stream, displayNum, authHost, authFamily)
|
||||||
{
|
{
|
||||||
getAuthString( displayNum, authHost, function( err, cookie ) {
|
getAuthString( displayNum, authHost, authFamily, function( err, cookie ) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
lib/xcore.js
15
lib/xcore.js
|
|
@ -31,7 +31,6 @@ function XClient(displayNum, screenNum, options)
|
||||||
|
|
||||||
this.displayNum = displayNum;
|
this.displayNum = displayNum;
|
||||||
this.screenNum = screenNum;
|
this.screenNum = screenNum;
|
||||||
this.authHost = os.hostname();
|
|
||||||
}
|
}
|
||||||
util.inherits(XClient, EventEmitter);
|
util.inherits(XClient, EventEmitter);
|
||||||
|
|
||||||
|
|
@ -39,6 +38,13 @@ XClient.prototype.init = function(stream)
|
||||||
{
|
{
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
|
|
||||||
|
this.authHost = stream.remoteAddress;
|
||||||
|
this.authFamily = stream.remoteFamily;
|
||||||
|
if (!this.authHost || this.authHost === '127.0.0.1' || this.authHost === '::1') {
|
||||||
|
this.authHost = os.hostname();
|
||||||
|
this.authFamily = null;
|
||||||
|
}
|
||||||
|
|
||||||
var pack_stream = new PackStream();
|
var pack_stream = new PackStream();
|
||||||
|
|
||||||
// data received from stream is dispached to
|
// data received from stream is dispached to
|
||||||
|
|
@ -524,7 +530,7 @@ XClient.prototype.expectReplyHeader = function()
|
||||||
XClient.prototype.startHandshake = function() {
|
XClient.prototype.startHandshake = function() {
|
||||||
var client = this;
|
var client = this;
|
||||||
|
|
||||||
handshake.writeClientHello(this.pack_stream, this.displayNum, this.authHost);
|
handshake.writeClientHello(this.pack_stream, this.displayNum, this.authHost, this.authFamily);
|
||||||
handshake.readServerHello(this.pack_stream, function(display)
|
handshake.readServerHello(this.pack_stream, function(display)
|
||||||
{
|
{
|
||||||
// TODO: readServerHello can set error state in display
|
// TODO: readServerHello can set error state in display
|
||||||
|
|
@ -560,8 +566,6 @@ module.exports.createClient = function(options, initCb)
|
||||||
throw new Error("Cannot parse display");
|
throw new Error("Cannot parse display");
|
||||||
|
|
||||||
var host = displayMatch[1];
|
var host = displayMatch[1];
|
||||||
if (!host)
|
|
||||||
host = '127.0.0.1';
|
|
||||||
|
|
||||||
var displayNum = displayMatch[2];
|
var displayNum = displayMatch[2];
|
||||||
if (!displayNum)
|
if (!displayNum)
|
||||||
|
|
@ -586,10 +590,9 @@ module.exports.createClient = function(options, initCb)
|
||||||
{
|
{
|
||||||
socketPath = display;
|
socketPath = display;
|
||||||
}
|
}
|
||||||
} else if(host == '127.0.0.1') //TODO check if it's consistent with xlib (DISPLAY=127.0.0.1:0 -> local unix socket or port 6000?)
|
} else if(!host)
|
||||||
socketPath = '/tmp/.X11-unix/X' + displayNum;
|
socketPath = '/tmp/.X11-unix/X' + displayNum;
|
||||||
}
|
}
|
||||||
//socketPath = '/tmp/.X11-unix/X' + displayNum;
|
|
||||||
var client = new XClient(displayNum, screenNum, options);
|
var client = new XClient(displayNum, screenNum, options);
|
||||||
|
|
||||||
var connectStream = function() {
|
var connectStream = function() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue