1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-16 00:03:45 +00:00

1. Updated monitor-info, so it no longer assumes DISPLAY = :0

2. Updated user-sessions to have better uid and username helpers on linux
3. Updated Clipboard dispatching
This commit is contained in:
Bryan Roe
2019-03-12 22:25:56 -07:00
parent 429b645a54
commit 6a8b7de44c
4 changed files with 204 additions and 71 deletions

File diff suppressed because one or more lines are too long

View File

@@ -15,6 +15,12 @@ limitations under the License.
*/ */
var promise = require('promise'); var promise = require('promise');
var SelectionClear = 29;
var SelectionNotify = 31;
var SelectionRequest = 30;
var AnyPropertyType = 0;
var CurrentTime = 0;
function nativeAddModule(name) function nativeAddModule(name)
{ {
@@ -65,9 +71,16 @@ function dispatchRead(sid)
} }
else else
{ {
var childProperties = { sessionId: id };
if (process.platform == 'linux')
{
xinfo = require('monitor-info').getXInfo(id);
childProperties.env = { XAUTHORITY: xinfo.xauthority, DISPLAY: xinfo.display };
}
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
ret.success = false; ret.success = false;
ret.master = require('ScriptContainer').Create({ sessionId: id }); ret.master = require('ScriptContainer').Create(childProperties);
ret.master.promise = ret; ret.master.promise = ret;
ret.master.on('data', function (d) ret.master.on('data', function (d)
{ {
@@ -83,7 +96,7 @@ function dispatchRead(sid)
} }
delete this.promise.master; delete this.promise.master;
}); });
ret.master.ExecuteString("var parent = require('ScriptContainer'); require('clipboard').read().then(parent.send, function(){process.exit();});"); ret.master.ExecuteString("var parent = require('ScriptContainer'); require('clipboard').read().then(function(v){parent.send(v);}, function(e){console.error(e);process.exit();});");
return (ret); return (ret);
} }
} }
@@ -143,10 +156,9 @@ function lin_readtext()
} }
else else
{ {
var SelectionNotify = 31;
var AnyPropertyType = 0;
var GM = require('monitor-info')._gm; var GM = require('monitor-info')._gm;
ret._getInfoPromise = require('monitor-info').getInfo(); ret._getInfoPromise = require('monitor-info').getInfo();
ret._getInfoPromise._masterPromise = ret; ret._getInfoPromise._masterPromise = ret;
ret._getInfoPromise.then(function (mon) ret._getInfoPromise.then(function (mon)
@@ -163,9 +175,10 @@ function lin_readtext()
this._masterPromise.FAKEWIN = X11.XCreateSimpleWindow(mon[0].display, this._masterPromise.ROOTWIN, 0, 0, mon[0].right, 5, 0, white, white); this._masterPromise.FAKEWIN = X11.XCreateSimpleWindow(mon[0].display, this._masterPromise.ROOTWIN, 0, 0, mon[0].right, 5, 0, white, white);
X11.XSync(mon[0].display, 0); X11.XSync(mon[0].display, 0);
X11.XConvertSelection(mon[0].display, this._masterPromise.CLIPID, this._masterPromise.FMTID, this._masterPromise.PROPID, this._masterPromise.FAKEWIN, 0); X11.XConvertSelection(mon[0].display, this._masterPromise.CLIPID, this._masterPromise.FMTID, this._masterPromise.PROPID, this._masterPromise.FAKEWIN, CurrentTime);
X11.XSync(mon[0].display, 0); X11.XSync(mon[0].display, 0);
this._masterPromise.DescriptorEvent = require('DescriptorEvents').addDescriptor(X11.XConnectionNumber(mon[0].display).Val, { readset: true }); this._masterPromise.DescriptorEvent = require('DescriptorEvents').addDescriptor(X11.XConnectionNumber(mon[0].display).Val, { readset: true });
this._masterPromise.DescriptorEvent._masterPromise = this._masterPromise; this._masterPromise.DescriptorEvent._masterPromise = this._masterPromise;
this._masterPromise.DescriptorEvent._display = mon[0].display; this._masterPromise.DescriptorEvent._display = mon[0].display;
@@ -184,6 +197,7 @@ function lin_readtext()
var result = GM.CreatePointer(); var result = GM.CreatePointer();
X11.XGetWindowProperty(this._display, this._masterPromise.FAKEWIN, this._masterPromise.PROPID, 0, 65535, 0, AnyPropertyType, id, bits, sz, tail, result); X11.XGetWindowProperty(this._display, this._masterPromise.FAKEWIN, this._masterPromise.PROPID, 0, 65535, 0, AnyPropertyType, id, bits, sz, tail, result);
this._masterPromise._res(result.Deref().String); this._masterPromise._res(result.Deref().String);
X11.XFree(result.Deref()); X11.XFree(result.Deref());
X11.XDestroyWindow(this._display, this._masterPromise.FAKEWIN); X11.XDestroyWindow(this._display, this._masterPromise.FAKEWIN);
@@ -194,12 +208,74 @@ function lin_readtext()
} }
}); });
} }
}); }, console.error);
} }
return (ret); return (ret);
} }
function lin_copytext() function lin_copytext()
{ {
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
try
{
require('monitor-info')
}
catch(exc)
{
ret._rej(exc);
return (ret);
}
var X11 = require('monitor-info')._X11;
if (!X11)
{
ret._rej('X11 required for Clipboard Manipulation');
}
else
{
var GM = require('monitor-info')._gm;
ret._getInfoPromise = require('monitor-info').getInfo();
ret._getInfoPromise._masterPromise = ret;
ret._getInfoPromise.then(function (mon)
{
if (mon.length > 0)
{
var white = X11.XWhitePixel(mon[0].display, mon[0].screenId).Val;
this._masterPromise.CLIPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('CLIPBOARD'), 0);
this._masterPromise.ROOTWIN = X11.XRootWindow(mon[0].display, mon[0].screenId);
this._masterPromise.FAKEWIN = X11.XCreateSimpleWindow(mon[0].display, this._masterPromise.ROOTWIN, 0, 0, mon[0].right, 5, 0, white, white);
X11.XSetSelectionOwner(mon[0].display, this._masterPromise.CLIPID, this._masterPromise.FAKEWIN, CurrentTime);
X11.XSync(mon[0].display, 0);
this._masterPromise.DescriptorEvent = require('DescriptorEvents').addDescriptor(X11.XConnectionNumber(mon[0].display).Val, { readset: true });
this._masterPromise.DescriptorEvent._masterPromise = this._masterPromise;
this._masterPromise.DescriptorEvent._display = mon[0].display;
this._masterPromise.DescriptorEvent.on('readset', function (fd)
{
var XE = GM.CreateVariable(1024);
while (X11.XPending(this._display).Val)
{
X11.XNextEventSync(this._display, XE);
switch (XE.Deref(0, 4).toBuffer().readUInt32LE())
{
case SelectionClear:
console.log('Somebody else owns clipboard');
break;
case SelectionNotify:
console.log("Shouldn't really be getting this");
break;
case SelectionRequest:
console.log('Somebody wants us to send them data');
break;
}
}
});
}
});
}
return (ret);
} }
function win_readtext() function win_readtext()

View File

@@ -288,38 +288,51 @@ function monitorinfo()
this.getInfo = function getInfo() this.getInfo = function getInfo()
{ {
var info = this; var info = this;
return (new promise(function (resolver, rejector) var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
ret.parent = this;
if (!process.env.XAUTHORITY || !process.env.DISPLAY)
{ {
var display = info._X11.XOpenDisplay(info._gm.CreateVariable(':0')); var xinfo = this.getXInfo(require('user-sessions').getUid(require('user-sessions').whoami()));
var screenCount = info._X11.XScreenCount(display).Val; process.setenv('XAUTHORITY', xinfo.xauthority);
var ret = []; process.setenv('DISPLAY', xinfo.display);
for(var i=0;i<screenCount;++i) }
{
var screen = info._X11.XScreenOfDisplay(display, i); var display = info._X11.XOpenDisplay(info._gm.CreateVariable(process.env.DISPLAY));
ret.push({ left: 0, top: 0, right: info._X11.XDisplayWidth(display, i).Val, bottom: info._X11.XDisplayHeight(display, i).Val, screen: screen, screenId: i, display: display }); if (display.Val == 0)
} {
resolver(ret); require('fs').writeFileSync('/var/tmp/agentSlave', 'XOpenDisplay Failed', { flags: 'a' });
})); ret._rej('XOpenDisplay Failed');
return (ret);
}
var screenCount = info._X11.XScreenCount(display).Val;
var ifo = [];
for(var i=0;i<screenCount;++i)
{
var screen = info._X11.XScreenOfDisplay(display, i);
ifo.push({ left: 0, top: 0, right: info._X11.XDisplayWidth(display, i).Val, bottom: info._X11.XDisplayHeight(display, i).Val, screen: screen, screenId: i, display: display });
}
ret._res(ifo);
return (ret);
} }
this.getXInfo = function getXInfo(consoleuid) this.getXInfo = function getXInfo(consoleuid)
{ {
var ret = null;
var uname = require('user-sessions').getUsername(consoleuid);
var child = require('child_process').execFile('/bin/sh', ['sh']); var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("ps -e -o user:999 -o tty -o command | grep X | awk '{ printf \"%s,%s,\",$1,$2;split($0, a, \"-auth\");split(a[2], b, \" \");print b[1];}'\nexit\n"); child.stdin.write("ps -e -o user:999 -o tty -o command | grep X | awk '{ split($0, a, \"-auth\"); split(a[2], b, \" \"); if($1==\"" + uname + "\" && b[1]!=\"\") { printf \"%s,%s,%s\",$1,$2,b[1] } }'\nexit\n");
child.waitExit(); child.waitExit();
var lines = child.stdout.str.split('\n'); var tokens = child.stdout.str.trim().split(',');
var uname = require('user-sessions')._uids()[consoleuid]; if (tokens.length == 3)
var ret = null;
for(var i in lines)
{ {
var tokens = lines[i].split(','); ret = { tty: tokens[1], xauthority: tokens[2] };
if(tokens.length == 3 && tokens[0] == uname)
{
ret = { tty: tokens[1], xauthority: tokens[2] };
break;
}
} }
if(ret!=null) if(ret!=null)
{ {
child = require('child_process').execFile('/bin/sh', ['sh']); child = require('child_process').execFile('/bin/sh', ['sh']);
@@ -334,7 +347,14 @@ function monitorinfo()
{ {
if(lines[x].trim().length>0) if(lines[x].trim().length>0)
{ {
ps = require('fs').readFileSync('/proc/' + lines[x].trim() + '/environ'); try
{
ps = require('fs').readFileSync('/proc/' + lines[x].trim() + '/environ');
}
catch(pse)
{
continue;
}
vs = 0; vs = 0;
for(psx=0;psx<ps.length;++psx) for(psx=0;psx<ps.length;++psx)
{ {

View File

@@ -40,6 +40,18 @@ var GUID_ACDC_POWER_SOURCE;
var GUID_BATTERY_PERCENTAGE_REMAINING; var GUID_BATTERY_PERCENTAGE_REMAINING;
var GUID_CONSOLE_DISPLAY_STATE; var GUID_CONSOLE_DISPLAY_STATE;
function columnParse(data, delimiter)
{
var tokens = data.split(delimiter);
var ret = [];
for(var i in tokens)
{
if (tokens[i].length > 0) { ret.push(tokens[i]); }
}
return (ret);
}
function UserSessions() function UserSessions()
{ {
this._ObjectID = 'user-sessions'; this._ObjectID = 'user-sessions';
@@ -372,34 +384,6 @@ function UserSessions()
} }
return (ret); return (ret);
} }
this.Self = function Self()
{
var promise = require('promise');
var p = new promise(function (res, rej)
{
this.__resolver = res; this.__rejector = rej;
this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
this.__child.promise = this;
this.__child.stdout._txt = '';
this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
this.__child.on('exit', function (code)
{
try
{
parseInt(this.stdout._txt);
}
catch (e)
{
this.promise.__rejector('invalid uid');
return;
}
var id = parseInt(this.stdout._txt);
this.promise.__resolver(id);
});
});
return (p);
};
this.Current = function Current(cb) this.Current = function Current(cb)
{ {
var retVal = {}; var retVal = {};
@@ -558,6 +542,52 @@ function UserSessions()
}); });
}; };
this.getUidConfig = function getUidConfig()
{
var ret = {};
var cfg = require('fs').readFileSync('/etc/login.defs').toString().split('\n');
var tokens;
for (var i in cfg)
{
tokens = columnParse(cfg[i], '\t'); //console.log(tokens);
if (tokens[0] == 'UID_MIN') { ret.MIN = parseInt(tokens[1]); }
if (tokens[0] == 'UID_MAX') { ret.MAX = parseInt(tokens[1]); }
if (ret.MIN != null && ret.MAX != null) { break; }
}
return (ret);
};
this.getUid = function getUid(username)
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("cat /etc/passwd | awk -F: '($1==\"" + username + "\"){print $3}'\nexit\n");
child.waitExit();
var ret = parseInt(child.stdout.str);
if (ret >= 0) { return (ret); }
throw ('username: ' + username + ' NOT FOUND');
};
this.getUsername = function getUsername(uid)
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("cat /etc/passwd | awk -F: '($3==" + uid + "){print $1}'\nexit\n");
child.waitExit();
if (child.stdout.str.length > 0) { return (child.stdout.str.trim()); }
throw ('uid: ' + uid + ' NOT FOUND');
};
this.whoami = function whoami()
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("whoami\nexit\n");
child.waitExit();
return (child.stdout.str.trim());
};
this.on('changed', this._recheckLoggedInUsers); // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID. this.on('changed', this._recheckLoggedInUsers); // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID.
@@ -664,7 +694,7 @@ function UserSessions()
if(process.platform == 'linux' || process.platform == 'darwin') if(process.platform == 'linux' || process.platform == 'darwin')
{ {
this._self = function _self() this.Self = function Self()
{ {
var child = require('child_process').execFile('/usr/bin/id', ['id', '-u']); var child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
child.stdout.str = ''; child.stdout.str = '';
@@ -674,7 +704,7 @@ function UserSessions()
} }
this.isRoot = function isRoot() this.isRoot = function isRoot()
{ {
return (this._self() == 0); return (this.Self() == 0);
} }
this.consoleUid = function consoleUid() this.consoleUid = function consoleUid()
{ {