handle Internet cookie addresses correctly. Fixes #121

This commit is contained in:
Andrey Sidorov 2016-01-15 16:01:54 +11:00
parent 0d7346fbac
commit 70519cbb38
3 changed files with 85 additions and 92 deletions

View file

@ -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( '', '' );
});
}; };

View file

@ -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();
}); });
} }

View file

@ -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);