Completed the Show Self Events Only feature.
Ylian Saint-Hilaire committed
Sep 19, 2019 at 11:21 UTC
0b7452abd817e4bc9ba402423498e89691a795d3
4 files changed
+86
-4
agents/meshcore.min.js
+64
-1
@@ -306,6 +306,7 @@ function createMeshCore(agent)
306
var amtscanner = null;
307
var nextTunnelIndex = 1;
308
var amtPolicy = null;
309
+ var apftunnel = null;
310
311
// Add to the server event log
312
function MeshServerLog(msg, state) {
@@ -1667,7 +1668,7 @@ function createMeshCore(agent)
1668
var response = null;
1669
switch (cmd) {
1670
case 'help': { // Displays available commands
1670
- response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtacm,\r\namtdeactivate, amtpolicy, getscript, getclip, setclip, log, av, cpuinfo, sysinfo.';
1671
+ response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtacm,\r\namtdeactivate, amtpolicy, getscript, getclip, setclip, log, av, cpuinfo, sysinfo, apf.';
1672
break;
1673
}
1674
/*
@@ -1853,6 +1854,25 @@ function createMeshCore(agent)
1854
}
1855
break;
1856
}
1857
+ case 'uninstallagent':
1858
+ var agentName = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent';
1859
+ if (!require('service-manager').manager.getService(agentName).isMe())
1860
+ {
1861
+ response = 'Uininstall failed, this instance is not the service instance';
1862
+ }
1863
+ else
1864
+ {
1865
+ try
1866
+ {
1867
+ diagnosticAgent_uninstall();
1868
+ }
1869
+ catch(x)
1870
+ {
1871
+ }
1872
+ var js = "require('service-manager').manager.getService('" + agentName + "').stop(); require('service-manager').manager.uninstallService('" + agentName + "'); process.exit();";
1873
+ this.child = require('child_process').execFile(process.execPath, [process.platform == 'win32' ? (process.execPath.split('\\').pop()) : (process.execPath.split('/').pop()), '-b64exec', Buffer.from(js).toString('base64')], { type: 4, detached: true });
1874
+ }
1875
+ break;
1876
case 'notify': { // Send a notification message to the mesh
1877
if (args['_'].length != 1) {
1878
response = 'Proper usage: notify "message" [--session]'; // Display correct command usage
@@ -2271,6 +2291,49 @@ function createMeshCore(agent)
2291
if (diag) { diag.close(); diag = null; }
2292
break;
2293
}
2294
+ case 'apf': {
2295
+ if (meshCoreObj.intelamt!==null) {
2296
+ if (args['_'].length == 1) {
2297
+ if (args['_'][0] == 'on') {
2298
+ response = 'Starting APF tunnel'
2299
+ var apfarg = {
2300
+ mpsurl: mesh.ServerUrl.replace('agent.ashx','apf.ashx'),
2301
+ mpsuser: Buffer.from(mesh.ServerInfo.MeshID,'hex').toString('base64').substring(0,16),
2302
+ mpspass: Buffer.from(mesh.ServerInfo.MeshID,'hex').toString('base64').substring(0,16),
2303
+ mpskeepalive: 60000,
2304
+ clientname: require('os').hostname(),
2305
+ clientaddress: '127.0.0.1',
2306
+ clientuuid: meshCoreObj.intelamt.uuid
2307
+ };
2308
+ var tobj = { debug: false }; //
2309
+ apftunnel= require('apfclient')(tobj,apfarg);
2310
+ try {
2311
+ apftunnel.connect();
2312
+ response += "..success";
2313
+ } catch (e) {
2314
+ response += JSON.stringify(e);
2315
+ }
2316
+ } else if (args['_'][0] == 'off') {
2317
+ response = 'Stopping APF tunnel';
2318
+ try {
2319
+ apftunnel.disconnect();
2320
+ response += "..success";
2321
+ } catch (e) {
2322
+ response += JSON.stringify(e);
2323
+ }
2324
+ apftunnel=null;
2325
+ } else {
2326
+ response = 'Invalid command.\r\nCmd syntax: apf on|off';
2327
+ }
2328
+ } else {
2329
+ response = 'APF tunnel is '+ (apftunnel == null ? 'off': 'on' );
2330
+ }
2331
+
2332
+ } else {
2333
+ response = 'APF tunnel requires Intel AMT';
2334
+ }
2335
+ break;
2336
+ }
2337
default: { // This is an unknown command, return an error message
2338
response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
2339
break;
agents/modules_meshcore_min/apfclient.min.js
new
+1
@@ -0,0 +1 @@
1
+function CreateAPFClient(q,e){var o={};o.parent=q;o.args=e;o.http=require("http");o.net=require("net");o.forwardClient=null;o.downlinks={};o.pfwd_idx=0;o.timer=null;function u(K,J){return(K.charCodeAt(J)*16777216)+(K.charCodeAt(J+1)<<16)+(K.charCodeAt(J+2)<<8)+K.charCodeAt(J+3)}function n(J){return String.fromCharCode((J>>24)&255,(J>>16)&255,(J>>8)&255,J&255)}function m(J){var L="",K=(""+J).match(/../g),M;while(M=K.shift()){L+=String.fromCharCode("0x"+M)}return L}function h(J){return(J+256).toString(16).substr(-2).toUpperCase()}function w(K){var L="",J;for(J=0;J<K.length;J++){L+=h(K.charCodeAt(J))}return L}function j(J){return(J/256+1/512).toString(16).substring(2,4)}function g(K){var L="",J;for(J=0;J<K.length;J++){L+=j(K[J])}return L}function k(J){if(o.parent.debug){console.log(J)}}var i={INITIAL:0,PROTOCOL_VERSION_SENT:1,AUTH_SERVICE_REQUEST_SENT:2,AUTH_REQUEST_SENT:3,PFWD_SERVICE_REQUEST_SENT:4,GLOBAL_REQUEST_SENT:5,FAILED:-1};o.cirastate=i.INITIAL;var v={REDIR_UNKNOWN:0,REDIR_SOL:1,REDIR_KVM:2,REDIR_IDER:3};o.RedirectStartSol=String.fromCharCode(16,0,0,0,83,79,76,32);o.RedirectStartKvm=String.fromCharCode(16,1,0,0,75,86,77,82);o.RedirectStartIder=String.fromCharCode(16,0,0,0,73,68,69,82);var s=[16992,623,16994,5900];var d={UNKNOWN:0,DISCONNECT:1,SERVICE_REQUEST:5,SERVICE_ACCEPT:6,USERAUTH_REQUEST:50,USERAUTH_FAILURE:51,USERAUTH_SUCCESS:52,GLOBAL_REQUEST:80,REQUEST_SUCCESS:81,REQUEST_FAILURE:82,CHANNEL_OPEN:90,CHANNEL_OPEN_CONFIRMATION:91,CHANNEL_OPEN_FAILURE:92,CHANNEL_WINDOW_ADJUST:93,CHANNEL_DATA:94,CHANNEL_CLOSE:97,PROTOCOLVERSION:192,KEEPALIVE_REQUEST:208,KEEPALIVE_REPLY:209,KEEPALIVE_OPTIONS_REQUEST:210,KEEPALIVE_OPTIONS_REPLY:211};var c={HOST_NOT_ALLOWED_TO_CONNECT:1,PROTOCOL_ERROR:2,KEY_EXCHANGE_FAILED:3,RESERVED:4,MAC_ERROR:5,COMPRESSION_ERROR:6,SERVICE_NOT_AVAILABLE:7,PROTOCOL_VERSION_NOT_SUPPORTED:8,HOST_KEY_NOT_VERIFIABLE:9,CONNECTION_LOST:10,BY_APPLICATION:11,TOO_MANY_CONNECTIONS:12,AUTH_CANCELLED_BY_USER:13,NO_MORE_AUTH_METHODS_AVAILABLE:14,INVALID_CREDENTIALS:15,CONNECTION_TIMED_OUT:16,BY_POLICY:17,TEMPORARILY_UNAVAILABLE:18};var a={ADMINISTRATIVELY_PROHIBITED:1,CONNECT_FAILED:2,UNKNOWN_CHANNEL_TYPE:3,RESOURCE_SHORTAGE:4,};var b={AdministrativelyProhibited:1,ConnectFailed:2,UnknownChannelType:3,ResourceShortage:4,};o.onSecureConnect=function p(K,L,J){k("APF Secure WebSocket connected.");o.forwardClient.tag={accumulator:[]};o.forwardClient.ws=L;o.forwardClient.ws.on("end",function(){k("APF: Connection is closing.");if(o.timer!=null){clearInterval(o.timer);o.timer=null}});o.forwardClient.ws.on("data",function(M){o.forwardClient.tag.accumulator+=m(g(M));try{var O=0;do{O=t(o.forwardClient);if(O>0){o.forwardClient.tag.accumulator=o.forwardClient.tag.accumulator.slice(O)}if(o.cirastate==i.FAILED){k("APF: in a failed state, destroying socket.");o.forwardClient.ws.end()}}while(O>0)}catch(N){k(N)}});o.forwardClient.ws.on("error",function(M){k("APF: Connection error, ending connecting.");if(o.timer!=null){clearInterval(o.timer);o.timer=null}});o.state=i.INITIAL;F(o.forwardClient.ws,o.args.clientuuid);G(o.forwardClient.ws,"auth@amt.intel.com")};function l(J){return J.substring(6,8)+J.substring(4,6)+J.substring(2,4)+J.substring(0,2)+"-"+J.substring(10,12)+J.substring(8,10)+"-"+J.substring(14,16)+J.substring(12,14)+"-"+J.substring(16,20)+"-"+J.substring(20)}function I(K){K=K.replace(/-/g,"");var J=K.substring(6,8)+K.substring(4,6)+K.substring(2,4)+K.substring(0,2);J+=K.substring(10,12)+K.substring(8,10)+K.substring(14,16)+K.substring(12,14)+K.substring(16,20)+K.substring(20);return J}function f(K){var L="";for(var J=0;J<K;J++){L+=String.fromCharCode(0&255)}return L}function F(L,M){var J=I(M);var K=String.fromCharCode(d.PROTOCOLVERSION)+""+n(1)+n(0)+n(0)+m(J)+f(64);L.write(K);k("APF: Send protocol version 1 0 "+M);o.cirastate=i.PROTOCOL_VERSION_SENT}function G(L,K){var J=String.fromCharCode(d.SERVICE_REQUEST)+n(K.length)+K;L.write(J);k("APF: Send service request "+K);if(K=="auth@amt.intel.com"){o.cirastate=i.AUTH_SERVICE_REQUEST_SENT}else{if(K=="pfwd@amt.intel.com"){o.cirastate=i.PFWD_SERVICE_REQUEST_SENT}}}function H(M,N,K){var L="pfwd@amt.intel.com";var J=String.fromCharCode(d.USERAUTH_REQUEST)+n(N.length)+N+n(L.length)+L;J+=n(8)+"password";J+=f(1)+n(K.length)+K;M.write(J);k("APF: Send username password authentication to MPS");o.cirastate=i.AUTH_REQUEST_SENT}function C(M,J,K){var N="tcpip-forward";var L=String.fromCharCode(d.GLOBAL_REQUEST)+n(N.length)+N+f(1,1);L+=n(J.length)+J+n(K);M.write(L);k("APF: Send tcpip-forward "+J+":"+K);o.cirastate=i.GLOBAL_REQUEST_SENT}function E(K){var J=String.fromCharCode(d.KEEPALIVE_REQUEST)+n(255);K.write(J);k("APF: Send keepalive request")}function D(L,J){var K=String.fromCharCode(d.KEEPALIVE_REPLY)+n(J);L.write(K);k("APF: Send keepalive reply")}function t(U){var L=U.tag.accumulator.charCodeAt(0);var O=U.tag.accumulator.length;var M=U.tag.accumulator;if(O==0){return 0}switch(L){case d.SERVICE_ACCEPT:var T=u(M,1);var S=M.substring(5,6+T);k("APF: Service request to "+S+" accepted.");if(S=="auth@amt.intel.com"){if(o.cirastate>=i.AUTH_SERVICE_REQUEST_SENT){H(U.ws,o.args.mpsuser,o.args.mpspass)}}else{if(S=="pfwd@amt.intel.com"){if(o.cirastate>=i.PFWD_SERVICE_REQUEST_SENT){C(U.ws,o.args.clientname,s[o.pfwd_idx++])}}}return 5+T;case d.REQUEST_SUCCESS:if(O>=5){var Q=u(M,1);k("APF: Request to port forward "+Q+" successful.");if(o.pfwd_idx<s.length){C(U.ws,o.args.clientname,s[o.pfwd_idx++])}else{k("APF: Start keep alive for every "+o.args.mpskeepalive+" ms.");o.timer=setInterval(function(){E(o.forwardClient.ws)},o.args.mpskeepalive)}return 5}k("APF: Request successful.");return 1;case d.USERAUTH_SUCCESS:k("APF: User Authentication successful");G(U.ws,"pfwd@amt.intel.com");return 1;case d.USERAUTH_FAILURE:k("APF: User Authentication failed");o.cirastate=i.FAILED;return 14;case d.KEEPALIVE_REQUEST:k("APF: Keep Alive Request with cookie: "+u(M,1));D(U.ws,u(M,1));return 5;case d.KEEPALIVE_REPLY:k("APF: Keep Alive Reply with cookie: "+u(M,1));return 5;case d.CHANNEL_OPEN:var P=r(M);k("APF: CHANNEL_OPEN request: "+JSON.stringify(P));if(s.indexOf(P.target_port)>=0){o.downlinks[P.sender_chan]=o.net.createConnection({host:o.args.clientaddress,port:P.target_port},function(){o.downlinks[P.sender_chan].setEncoding("binary");z(U.ws,P)});o.downlinks[P.sender_chan].on("data",function(V){y(U.ws,P.sender_chan,V.length,V)});o.downlinks[P.sender_chan].on("error",function(V){k("Downlink connection error: "+V)});o.downlinks[P.sender_chan].on("end",function(){if(o.downlinks[P.sender_chan]){try{x(U.ws,P.sender_chan);delete o.downlinks[P.sender_chan]}catch(V){k("Downlink connection exception: "+V)}}})}else{A(U.ws,P)}return P.len;case d.CHANNEL_OPEN_CONFIRMATION:k("APF: CHANNEL_OPEN_CONFIRMATION");return 17;case d.CHANNEL_CLOSE:var R=u(M,1);k("APF: CHANNEL_CLOSE: "+R);x(U.ws,R);try{o.downlinks[R].end();delete o.downlinks[R]}catch(N){}return 5;case d.CHANNEL_DATA:k("APF: CHANNEL_DATA: "+JSON.stringify(w(M)));var R=u(M,1);var K=u(M,5);var J=M.substring(9,9+K);if(o.downlinks[R]){try{o.downlinks[R].write(J,"binary",function(){k("Write completed.");B(U.ws,R,K)})}catch(N){k("Cannot forward data to downlink socket.")}}return 9+K;case d.CHANNEL_WINDOW_ADJUST:k("APF: CHANNEL_WINDOW_ADJUST ");return 9;default:k("CMD: "+L+" is not implemented.");o.cirastate=i.FAILED;return 0}}function r(L){var N={len:0,cmd:d.CHANNEL_OPEN,chan_type:"",sender_chan:0,window_size:0,target_address:"",target_port:0,origin_address:"",origin_port:0,};var K=u(L,1);N.chan_type=L.substring(5,5+K);N.sender_chan=u(L,5+K);N.window_size=u(L,9+K);var J=u(L,17+K);N.target_address=L.substring(21+K,21+K+J);N.target_port=u(L,21+K+J);var M=u(L,25+K+J);N.origin_address=L.substring(29+K+J,29+K+J+M);N.origin_port=u(L,29+K+J+M);N.len=33+K+J+M;return N}function A(L,J){var K=String.fromCharCode(d.CHANNEL_OPEN_FAILURE)+n(J.sender_chan)+n(2)+n(0)+n(0);L.write(K);k("APF: Send ChannelOpenFailure")}function z(L,J){var K=String.fromCharCode(d.CHANNEL_OPEN_CONFIRMATION)+n(J.sender_chan)+n(J.sender_chan)+n(J.window_size)+n(4294967295);L.write(K);k("APF: Send ChannelOpenConfirmation")}function B(M,J,L){var K=String.fromCharCode(d.CHANNEL_WINDOW_ADJUST)+n(J)+n(L);M.write(K);k("APF: Send ChannelWindowAdjust: "+w(K))}function y(N,K,M,L){var J=String.fromCharCode(d.CHANNEL_DATA)+n(K)+n(M)+L;N.write(Buffer.from(J,"binary"));k("APF: Send ChannelData: "+w(J))}function x(L,K){var J=String.fromCharCode(d.CHANNEL_CLOSE)+n(K);L.write(Buffer.from(J,"binary"));k("APF: Send ChannelClose: "+w(J))}o.connect=function(){if(o.forwardClient!=null){try{o.forwardClient.ws.end()}catch(J){k(J)}}o.cirastate=i.INITIAL;o.pfwd_idx=0;var K=o.http.parseUri(o.args.mpsurl);K.rejectUnauthorized=0;o.forwardClient=o.http.request(K);o.forwardClient.upgrade=o.onSecureConnect;o.forwardClient.end()};o.disconnect=function(){try{o.forwardClient.ws.end()}catch(J){k(J)}};return o}module.exports=CreateAPFClient;
\ No newline at end of file
meshcentral.js
+1
-1
@@ -1024,7 +1024,7 @@ function CreateMeshCentralServer(config, args) {
1024
for (var i in obj.eventsDispatch[id]) {
1025
if (targets.indexOf(obj.eventsDispatch[id][i]) == -1) { // Check if we already displatched to this target
1026
targets.push(obj.eventsDispatch[id][i]);
1027
- try { obj.eventsDispatch[id][i].HandleEvent(source, event); } catch (ex) {
1027
+ try { obj.eventsDispatch[id][i].HandleEvent(source, event, ids, id); } catch (ex) {
1028
console.log(ex, obj.eventsDispatch[id][i]);
1029
}
1030
}
meshuser.js
+20
-2
@@ -230,13 +230,31 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
230
if (parent.parent.multiServer != null) { parent.parent.multiServer.DispatchMessage({ action: 'sessionStart', sessionid: ws.sessionId }); }
231
232
// Handle events
233
- ws.HandleEvent = function (source, event) {
233
+ ws.HandleEvent = function (source, event, ids, id) {
234
if (!event.domain || event.domain == domain.id) {
235
try {
236
if (event == 'close') { try { delete req.session; } catch (ex) { } obj.close(); }
237
else if (event == 'resubscribe') { user.subscriptions = parent.subscribe(user._id, ws); }
238
else if (event == 'updatefiles') { updateUserFiles(user, ws, domain); }
239
- else { ws.send(JSON.stringify({ action: 'event', event: event })); }
239
+ else {
240
+ // Because of the device group "Show Self Events Only", we need to do more checks here.
241
+ if (id.startsWith('mesh/')) {
242
+ // Check if we have rights to get this message. If we have limited events on this mesh, don't send the event to the user.
243
+ var meshlink = obj.user.links[id];
244
+ if ((meshlink != null) && ((meshlink.rights == 0xFFFFFFFF) || ((meshlink.rights & 8192) == 0) || (ids.indexOf(user._id) >= 0))) {
245
+ // We have the device group rights to see this event or we are directly targetted by the event
246
+ ws.send(JSON.stringify({ action: 'event', event: event }));
247
+ } else {
248
+ // Check if no other users are targeted by the event, if not, we can get this event.
249
+ var userTarget = false;
250
+ for (var i in ids) { if (ids[i].startsWith('user/')) { userTarget = true; } }
251
+ if (userTarget == false) { ws.send(JSON.stringify({ action: 'event', event: event })); }
252
+ }
253
+ } else {
254
+ // This is not a device group event, we can get this event.
255
+ ws.send(JSON.stringify({ action: 'event', event: event }));
256
+ }
257
+ }
258
} catch (e) { }
259
}
260
};