Added terminal start command option
Ylian Saint-Hilaire committed
Aug 19, 2021 at 14:10 UTC
adae944146da0630be05b0573068565662ee6b5a
5 files changed
+45
-24
agents/meshcore.js
+11
-19
@@ -87,7 +87,7 @@ if (require('MeshAgent').ARCHID == null) {
87
}
88
if (id != null) { Object.defineProperty(require('MeshAgent'), 'ARCHID', { value: id }); }
89
}
90
-var obj = {};
90
+var obj = { serverInfo: {} };
91
var agentFileHttpRequests = {}; // Currently active agent HTTPS GET requests from the server.
92
var agentFileHttpPendingRequests = []; // Pending HTTPS GET requests from the server.
93
var debugConsole = (global._MSH && (_MSH().debugConsole == 1));
@@ -1375,6 +1375,10 @@ function handleServerCommand(data) {
1375
agentFileHttpPendingRequests.push(data);
1376
serverFetchFile();
1377
break;
1378
+ case 'serverInfo': // Server information
1379
+ obj.serverInfo = data;
1380
+ delete obj.serverInfo.action;
1381
+ break;
1382
case 'errorlog': // Return agent error log
1383
try { mesh.SendCommand(JSON.stringify({ action: 'errorlog', log: require('util-agentlog').read(data.startTime) })); } catch (ex) { }
1384
break;
@@ -1922,14 +1926,7 @@ function onTunnelData(data) {
1926
// The above line is commented out, because there is a bug with ClosePseudoConsole() API, so this is the workaround
1927
this.httprequest._dispatcher = require('win-dispatcher').dispatch({ modules: [{ name: 'win-virtual-terminal', script: getJSModule('win-virtual-terminal') }], launch: { module: 'win-virtual-terminal', method: (this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'), args: [cols, rows] } });
1928
this.httprequest._dispatcher.httprequest = this.httprequest;
1925
- this.httprequest._dispatcher.on('connection', function (c) {
1926
- if (this.httprequest.connectionPromise.completed) {
1927
- c.end();
1928
- }
1929
- else {
1930
- this.httprequest.connectionPromise._res(c);
1931
- }
1932
- });
1929
+ this.httprequest._dispatcher.on('connection', function (c) { if (this.httprequest.connectionPromise.completed) { c.end(); } else { this.httprequest.connectionPromise._res(c); } });
1930
}
1931
else {
1932
// Legacy Terminal
@@ -1954,14 +1951,7 @@ function onTunnelData(data) {
1951
that.httprequest._dispatcher = require('win-dispatcher').dispatch({ user: username, modules: [{ name: 'win-terminal', script: getJSModule('win-terminal') }], launch: { module: 'win-terminal', method: (that.httprequest.protocol == 9 ? 'StartPowerShell' : 'Start'), args: [cols, rows] } });
1952
}
1953
that.httprequest._dispatcher.ws = that;
1957
- that.httprequest._dispatcher.on('connection', function (c) {
1958
- if (this.ws.httprequest.connectionPromise.completed) {
1959
- c.end();
1960
- }
1961
- else {
1962
- this.ws.httprequest.connectionPromise._res(c);
1963
- }
1964
- });
1954
+ that.httprequest._dispatcher.on('connection', function (c) { if (this.ws.httprequest.connectionPromise.completed) { c.end(); } else { this.ws.httprequest.connectionPromise._res(c); } });
1955
}
1956
});
1957
}
@@ -1992,13 +1982,15 @@ function onTunnelData(data) {
1982
else if (bash) {
1983
var p = childProcess.execFile(bash, ['bash'], options); // Start bash
1984
// Spaces at the beginning of lines are needed to hide commands from the command history
1995
- if (process.platform == 'linux') { p.stdin.write(' alias ls=\'ls --color=auto\';clear\n'); }
1985
+ if ((obj.serverInfo.termlaunchcommand != null) && (typeof obj.serverInfo.termlaunchcommand[process.platform] == 'string')) { p.stdin.write(obj.serverInfo.termlaunchcommand[process.platform]); }
1986
+ else if (process.platform == 'linux') { p.stdin.write(' alias ls=\'ls --color=auto\';clear\n'); }
1987
this.httprequest.connectionPromise._res(p);
1988
}
1989
else if (sh) {
1990
var p = childProcess.execFile(sh, ['sh'], options); // Start sh
1991
// Spaces at the beginning of lines are needed to hide commands from the command history
2001
- if (process.platform == 'linux') { p.stdin.write(' alias ls=\'ls --color=auto\';clear\n'); }
1992
+ if ((obj.serverInfo.termlaunchcommand != null) && (typeof obj.serverInfo.termlaunchcommand[process.platform] == 'string')) { p.stdin.write(obj.serverInfo.termlaunchcommand[process.platform]); }
1993
+ else if (process.platform == 'linux') { p.stdin.write(' alias ls=\'ls --color=auto\';clear\n'); }
1994
this.httprequest.connectionPromise._res(p);
1995
}
1996
else {
db.js
+3
-3
@@ -1970,7 +1970,7 @@ module.exports.CreateDB = function (parent, func) {
1970
var output = parent.fs.createWriteStream(newAutoBackupPath + '.zip');
1971
var archive = null;
1972
if (parent.config.settings.autobackup && (typeof parent.config.settings.autobackup.zippassword == 'string')) {
1973
- try { archiver.registerFormat('zip-encrypted', require("archiver-zip-encrypted")); } catch (ex) { }
1973
+ try { archiver.registerFormat('zip-encrypted', require('archiver-zip-encrypted')); } catch (ex) { }
1974
archive = archiver.create('zip-encrypted', { zlib: { level: 9 }, encryptionMethod: 'aes256', password: parent.config.settings.autobackup.zippassword });
1975
} else {
1976
archive = archiver('zip', { zlib: { level: 9 } });
@@ -2009,7 +2009,7 @@ module.exports.CreateDB = function (parent, func) {
2009
var output = parent.fs.createWriteStream(newAutoBackupPath + '.zip');
2010
var archive = null;
2011
if (parent.config.settings.autobackup && (typeof parent.config.settings.autobackup.zippassword == 'string')) {
2012
- try { archiver.registerFormat('zip-encrypted', require("archiver-zip-encrypted")); } catch (ex) { }
2012
+ try { archiver.registerFormat('zip-encrypted', require('archiver-zip-encrypted')); } catch (ex) { }
2013
archive = archiver.create('zip-encrypted', { zlib: { level: 9 }, encryptionMethod: 'aes256', password: parent.config.settings.autobackup.zippassword });
2014
} else {
2015
archive = archiver('zip', { zlib: { level: 9 } });
@@ -2036,7 +2036,7 @@ module.exports.CreateDB = function (parent, func) {
2036
var output = parent.fs.createWriteStream(newAutoBackupPath + '.zip');
2037
var archive = null;
2038
if (parent.config.settings.autobackup && (typeof parent.config.settings.autobackup.zippassword == 'string')) {
2039
- try { archiver.registerFormat('zip-encrypted', require("archiver-zip-encrypted")); } catch (ex) { }
2039
+ try { archiver.registerFormat('zip-encrypted', require('archiver-zip-encrypted')); } catch (ex) { }
2040
archive = archiver.create('zip-encrypted', { zlib: { level: 9 }, encryptionMethod: 'aes256', password: parent.config.settings.autobackup.zippassword });
2041
} else {
2042
archive = archiver('zip', { zlib: { level: 9 } });
meshagent.js
+13
@@ -1076,6 +1076,19 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1076
}
1077
});
1078
}
1079
+
1080
+ // Indicate server information to the agent.
1081
+ var serverInfo = { action: 'serverInfo' };
1082
+ if ((typeof domain.terminal == 'object') && (typeof domain.terminal.launchcommand == 'object')) {
1083
+ // Send terminal starting command
1084
+ serverInfo.termlaunchcommand = {};
1085
+ if (typeof domain.terminal.launchcommand.linux == 'string') { serverInfo.termlaunchcommand.linux = domain.terminal.launchcommand.linux; }
1086
+ if (typeof domain.terminal.launchcommand.darwin == 'string') { serverInfo.termlaunchcommand.darwin = domain.terminal.launchcommand.darwin; }
1087
+ if (typeof domain.terminal.launchcommand.freebsd == 'string') { serverInfo.termlaunchcommand.freebsd = domain.terminal.launchcommand.freebsd; }
1088
+ }
1089
+ obj.send(JSON.stringify(serverInfo));
1090
+
1091
+ // Plug in handler
1092
if (parent.parent.pluginHandler != null) {
1093
parent.parent.pluginHandler.callHook('hook_agentCoreIsStable', obj, parent);
1094
}
meshcentral-config-schema.json
+10
-2
@@ -507,10 +507,18 @@
507
"type": "object",
508
"description": "Values that affect the terminal feature",
509
"properties": {
510
- "linuxshell": {
510
+ "linuxShell": {
511
"type": "string",
512
"enum": [ "any", "root", "user", "login" ],
513
- "default": "any"
513
+ "default": "any",
514
+ "description": "Indicate what terminal options are available when the user clicks the right mouse button on the terminal connect button."
515
+ },
516
+ "launchCommand": {
517
+ "type": "object",
518
+ "description": "Indicate what string the agent must write to the shell after starting a terminal session",
519
+ "linux": { "type": "string", "default": " alias ls=\\'ls --color=auto\\';clear\\n", "description": "String to write after opening a Linux terminal." },
520
+ "darwin": { "type": "string", "default": null, "description": "String to write after opening a macOS terminal." },
521
+ "freebsd": { "type": "string", "default": null, "description": "String to write after opening a FreeBSD terminal." },
522
}
523
}
524
},
sample-config-advanced.json
+8
@@ -262,6 +262,14 @@
262
"_maxAgentSessions": 100,
263
"maxSingleUserSessions": 10
264
},
265
+ "_terminal": {
266
+ "_linuxshell": "login",
267
+ "launchCommand": {
268
+ "linux": "clear\necho \"Hello Linux\"\n",
269
+ "darwin": "clear\necho \"Hello MacOS\"\n",
270
+ "freebsd": "clear\necho \"Hello FreeBSD\"\n"
271
+ }
272
+ },
273
"_amtScanOptions": [
274
"LabNetwork 192.168.15.0/23",
275
"SalesNetwork 192.168.8.0/24"