mirror of
https://github.com/danbulant/node-x11
synced 2026-06-24 17:21:47 +00:00
handle Internet cookie addresses correctly. Fixes #121
This commit is contained in:
parent
0d7346fbac
commit
70519cbb38
3 changed files with 85 additions and 92 deletions
101
lib/auth.js
101
lib/auth.js
|
|
@ -11,81 +11,74 @@ function parseXauth( buf )
|
||||||
var auth = [];
|
var auth = [];
|
||||||
var cookieProperties = ['address', 'display', 'authName', 'authData'];
|
var cookieProperties = ['address', 'display', 'authName', 'authData'];
|
||||||
|
|
||||||
function handleCookieProperty(property) {
|
|
||||||
var length = buf.unpack('n', offset)[0];
|
|
||||||
offset += 2;
|
|
||||||
cookie[property] = buf.unpackString(length, offset);
|
|
||||||
offset += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (offset < buf.length)
|
while (offset < buf.length)
|
||||||
{
|
{
|
||||||
var cookie = {};
|
var cookie = {};
|
||||||
var typeToName = {
|
var typeToName = {
|
||||||
256: 'Local',
|
256: 'Local',
|
||||||
65535: 'Wild',
|
65535: 'Wild',
|
||||||
254: 'Netname',
|
254: 'Netname',
|
||||||
253: 'Krb5Principal',
|
253: 'Krb5Principal',
|
||||||
252: 'LocalHost',
|
252: 'LocalHost',
|
||||||
0: 'Internet',
|
0: 'Internet',
|
||||||
1: 'DECnet',
|
1: 'DECnet',
|
||||||
2: 'Chaos',
|
2: 'Chaos',
|
||||||
5: 'ServerInterpreted',
|
5: 'ServerInterpreted',
|
||||||
6: 'InternetV6'
|
6: 'InternetV6'
|
||||||
};
|
};
|
||||||
cookie.type = buf.unpack('n')[0];
|
cookie.type = buf.readUInt16LE(offset);
|
||||||
|
console.log('Cookie type: ');
|
||||||
if (!typeToName[cookie.type]) {
|
if (!typeToName[cookie.type]) {
|
||||||
console.warn('Unknown address type');
|
console.warn('Unknown address type');
|
||||||
}
|
}
|
||||||
offset += 2;
|
offset += 2;
|
||||||
//JSHint becomes angry when handleCookieProperty is declared inside loop
|
cookieProperties.forEach(function(property) {
|
||||||
cookieProperties.forEach(handleCookieProperty);
|
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);
|
auth.push(cookie);
|
||||||
}
|
}
|
||||||
return auth;
|
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 )
|
module.exports = function( display, host, cb )
|
||||||
{
|
{
|
||||||
var XAuthorityFile = process.env.XAUTHORITY;
|
readXauthority(function(err, data) {
|
||||||
if (!XAuthorityFile)
|
if(err) return cb(err);
|
||||||
|
|
||||||
|
var auth = parseXauth(data);
|
||||||
|
for (var cookieNum in auth)
|
||||||
{
|
{
|
||||||
if ( process.platform.match(/win/) ) {
|
var cookie = auth[cookieNum];
|
||||||
// http://www.straightrunning.com/XmingNotes/trouble.php
|
if (cookie.display === display && cookie.address === host)
|
||||||
//
|
return cb( null, cookie );
|
||||||
// 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';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
cb(new Error('No auth cookie matching display=' + display + ' and host=' + host));
|
||||||
fs.readFile(XAuthorityFile, function (err, data) {
|
});
|
||||||
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
if (err.code == 'ENOENT')
|
|
||||||
{
|
|
||||||
cb('','');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
var auth = parseXauth(data);
|
|
||||||
for (var 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;
|
|
||||||
cb( '', '' );
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,15 @@ function readVisuals(bl, visuals, n_visuals, cb)
|
||||||
var visual = {};
|
var visual = {};
|
||||||
bl.unpackTo( visual,
|
bl.unpackTo( visual,
|
||||||
[
|
[
|
||||||
'L vid',
|
'L vid',
|
||||||
'C class',
|
'C class',
|
||||||
'C bits_per_rgb',
|
'C bits_per_rgb',
|
||||||
'S map_ent',
|
'S map_ent',
|
||||||
'L red_mask',
|
'L red_mask',
|
||||||
'L green_mask',
|
'L green_mask',
|
||||||
'L blue_mask',
|
'L blue_mask',
|
||||||
'xxxx'
|
'xxxx'
|
||||||
],
|
],
|
||||||
function() {
|
function() {
|
||||||
var vid = visual.vid;
|
var vid = visual.vid;
|
||||||
// delete visual.vid;
|
// delete visual.vid;
|
||||||
|
|
@ -28,7 +28,7 @@ function readVisuals(bl, visuals, n_visuals, cb)
|
||||||
if (Object.keys(visuals).length == n_visuals)
|
if (Object.keys(visuals).length == n_visuals)
|
||||||
cb()
|
cb()
|
||||||
else
|
else
|
||||||
readVisuals(bl, visuals, n_visuals, cb);
|
readVisuals(bl, visuals, n_visuals, cb);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ function readDepths(bl, display, depths, n_depths, cb)
|
||||||
cb();
|
cb();
|
||||||
else
|
else
|
||||||
readDepths(bl, display, depths, n_depths, cb);
|
readDepths(bl, display, depths, n_depths, cb);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,23 +62,23 @@ function readScreens(bl, display, cbDisplayReady)
|
||||||
var scr = {};
|
var scr = {};
|
||||||
bl.unpackTo( scr,
|
bl.unpackTo( scr,
|
||||||
[
|
[
|
||||||
'L root',
|
'L root',
|
||||||
'L default_colormap',
|
'L default_colormap',
|
||||||
'L white_pixel',
|
'L white_pixel',
|
||||||
'L black_pixel',
|
'L black_pixel',
|
||||||
'L input_masks',
|
'L input_masks',
|
||||||
'S pixel_width',
|
'S pixel_width',
|
||||||
'S pixel_height',
|
'S pixel_height',
|
||||||
'S mm_width',
|
'S mm_width',
|
||||||
'S mm_height',
|
'S mm_height',
|
||||||
'S min_installed_maps',
|
'S min_installed_maps',
|
||||||
'S max_installed_maps',
|
'S max_installed_maps',
|
||||||
'L root_visual',
|
'L root_visual',
|
||||||
'C root_depth',
|
'C root_depth',
|
||||||
'C backing_stores',
|
'C backing_stores',
|
||||||
'C root_depth',
|
'C root_depth',
|
||||||
'C num_depths'
|
'C num_depths'
|
||||||
],
|
],
|
||||||
function () {
|
function () {
|
||||||
var depths = {};
|
var depths = {};
|
||||||
readDepths(bl, display, depths, scr.num_depths, function() {
|
readDepths(bl, display, depths, scr.num_depths, function() {
|
||||||
|
|
@ -86,7 +86,7 @@ function readScreens(bl, display, cbDisplayReady)
|
||||||
scr.depths = depths;
|
scr.depths = depths;
|
||||||
delete scr.num_depths;
|
delete scr.num_depths;
|
||||||
display.screen.push(scr);
|
display.screen.push(scr);
|
||||||
|
|
||||||
if (display.screen.length == display.screen_num)
|
if (display.screen.length == display.screen_num)
|
||||||
{
|
{
|
||||||
delete display.screen_num;
|
delete display.screen_num;
|
||||||
|
|
@ -96,7 +96,7 @@ function readScreens(bl, display, cbDisplayReady)
|
||||||
readScreens(bl, display, cbDisplayReady);
|
readScreens(bl, display, cbDisplayReady);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ function readServerHello(bl, cb)
|
||||||
{
|
{
|
||||||
|
|
||||||
bl.unpack('C', function(res) {
|
bl.unpack('C', function(res) {
|
||||||
|
|
||||||
if (res[0] == 0)
|
if (res[0] == 0)
|
||||||
{
|
{
|
||||||
// conection time error
|
// conection time error
|
||||||
|
|
@ -124,10 +124,10 @@ bl.unpack('C', function(res) {
|
||||||
'S major',
|
'S major',
|
||||||
'S minor',
|
'S minor',
|
||||||
'S xlen',
|
'S xlen',
|
||||||
'L release',
|
'L release',
|
||||||
'L resource_base',
|
'L resource_base',
|
||||||
'L resource_mask',
|
'L resource_mask',
|
||||||
'L motion_buffer_size',
|
'L motion_buffer_size',
|
||||||
'S vlen',
|
'S vlen',
|
||||||
'S max_request_length',
|
'S max_request_length',
|
||||||
'C screen_num',
|
'C screen_num',
|
||||||
|
|
@ -139,8 +139,8 @@ bl.unpack('C', function(res) {
|
||||||
'C min_keycode',
|
'C min_keycode',
|
||||||
'C max_keycode',
|
'C max_keycode',
|
||||||
'xxxx'
|
'xxxx'
|
||||||
],
|
],
|
||||||
|
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
var pvlen = xutil.padded_length(display.vlen);
|
var pvlen = xutil.padded_length(display.vlen);
|
||||||
|
|
@ -148,12 +148,12 @@ bl.unpack('C', function(res) {
|
||||||
// setup data to generate resource id
|
// setup data to generate resource id
|
||||||
// TODO: cleaunup code here
|
// TODO: cleaunup code here
|
||||||
var mask = display.resource_mask;
|
var mask = display.resource_mask;
|
||||||
display.rsrc_shift = 0;
|
display.rsrc_shift = 0;
|
||||||
while (!( (mask >> display.rsrc_shift) & 1) )
|
while (!( (mask >> display.rsrc_shift) & 1) )
|
||||||
display.rsrc_shift++;
|
display.rsrc_shift++;
|
||||||
display.rsrc_id = 0;
|
display.rsrc_id = 0;
|
||||||
|
|
||||||
bl.get(pvlen, function(vendor)
|
bl.get(pvlen, function(vendor)
|
||||||
{
|
{
|
||||||
display.vendor = vendor.toString().substr(0, display.vlen); // utf8 by default?
|
display.vendor = vendor.toString().substr(0, display.vlen); // utf8 by default?
|
||||||
|
|
||||||
|
|
@ -172,7 +172,7 @@ bl.unpack('C', function(res) {
|
||||||
readScreens(bl, display, cb);
|
readScreens(bl, display, cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -191,23 +191,24 @@ function getByteOrder() {
|
||||||
|
|
||||||
function writeClientHello(stream, displayNum, authHost)
|
function writeClientHello(stream, displayNum, authHost)
|
||||||
{
|
{
|
||||||
getAuthString( displayNum, authHost, function( authType, authData ) {
|
getAuthString( displayNum, authHost, function( err, cookie ) {
|
||||||
|
debugger;
|
||||||
var byte_order = getByteOrder();
|
var byte_order = getByteOrder();
|
||||||
var protocol_major = 11; // TODO: config? env?
|
var protocol_major = 11; // TODO: config? env?
|
||||||
var protocol_minor = 0;
|
var protocol_minor = 0;
|
||||||
stream.pack(
|
stream.pack(
|
||||||
'CxSSSSxxpp',
|
'CxSSSSxxpp',
|
||||||
[
|
[
|
||||||
byte_order,
|
byte_order,
|
||||||
protocol_major,
|
protocol_major,
|
||||||
protocol_minor,
|
protocol_minor,
|
||||||
authType.length,
|
cookie.authName.length,
|
||||||
authData.length,
|
cookie.authData.length,
|
||||||
authType,
|
cookie.authName,
|
||||||
authData
|
cookie.authData
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
stream.flush();
|
stream.flush();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -520,8 +520,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);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue