Updated terminal for windows, to workaround PseudoConsole process leak
Bryan Roe committed
Jan 7, 2020 at 15:05 UTC
f350350fc60c6f13ce920b5b983a93def506c518
1 file changed
+42
-20
agents/meshcore.js
+42
-20
@@ -1131,48 +1131,67 @@ function createMeshCore(agent) {
1131
};
1132
1133
// Remote terminal using native pipes
1134
- if (process.platform == 'win32') {
1135
- try {
1134
+ if (process.platform == 'win32')
1135
+ {
1136
+ try
1137
+ {
1138
if (!require('win-terminal').PowerShellCapable() && (this.httprequest.protocol == 6 || this.httprequest.protocol == 9)) { throw ('PowerShell is not supported on this version of windows'); }
1137
- if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6)) {
1139
+ if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6))
1140
+ {
1141
// Admin Terminal
1139
- if (require('win-virtual-terminal').supported) {
1142
+ if (require('win-virtual-terminal').supported)
1143
+ {
1144
// ConPTY PseudoTerminal
1141
- this.httprequest._term = require('win-virtual-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](80, 25);
1145
+ // this.httprequest._term = require('win-virtual-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](80, 25);
1146
+
1147
+ // The above line is commented out, because there is a bug with ClosePseudoConsole() API, so this is the workaround
1148
+ 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 == 9 ? 'StartPowerShell' : 'Start'), args: [80, 25] } });
1149
+ this.httprequest._dispatcher.ws = this;
1150
+ this.httprequest._dispatcher.on('connection', function (c)
1151
+ {
1152
+ console.log('client connected');
1153
+ this.ws._term = c;
1154
+ c.pipe(this.ws, { dataTypeSkip: 1 });
1155
+ this.ws.pipe(c, { dataTypeSkip: 1 });
1156
+ });
1157
}
1143
- else {
1158
+ else
1159
+ {
1160
// Legacy Terminal
1161
this.httprequest._term = require('win-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](80, 25);
1162
}
1163
}
1148
- else {
1164
+ else
1165
+ {
1166
// Logged in user
1167
var userPromise = require('user-sessions').enumerateUsers();
1168
userPromise.that = this;
1152
- userPromise.then(function (u) {
1169
+ userPromise.then(function (u)
1170
+ {
1171
var that = this.that;
1154
- if (u.Active.length > 0) {
1172
+ if (u.Active.length > 0)
1173
+ {
1174
var username = u.Active[0].Username;
1156
- if (require('win-virtual-terminal').supported) {
1175
+ if (require('win-virtual-terminal').supported)
1176
+ {
1177
// ConPTY PseudoTerminal
1178
that.httprequest._dispatcher = require('win-dispatcher').dispatch({ user: username, modules: [{ name: 'win-virtual-terminal', script: getJSModule('win-virtual-terminal') }], launch: { module: 'win-virtual-terminal', method: (that.httprequest.protocol == 9 ? 'StartPowerShell' : 'Start'), args: [80, 25] } });
1179
}
1160
- else {
1180
+ else
1181
+ {
1182
// Legacy Terminal
1183
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: [80, 25] } });
1184
}
1185
that.httprequest._dispatcher.ws = that;
1165
- that.httprequest._dispatcher.on('connection', function (c) {
1186
+ that.httprequest._dispatcher.on('connection', function (c)
1187
+ {
1188
console.log('client connected');
1189
this.ws._term = c;
1190
c.pipe(this.ws, { dataTypeSkip: 1 });
1169
- this.ws.pipe(c, { dataTypeSkip: 1, end: false });
1170
- this.ws.prependListener('end', function () {
1171
- if (this.httprequest._term) { this.httprequest._term.end(function () { console.log("Terminal was closed"); }); }
1172
- });
1191
+ this.ws.pipe(c, { dataTypeSkip: 1 });
1192
});
1193
}
1175
- });
1194
+ });
1195
}
1196
} catch (e) {
1197
MeshServerLog('Failed to start remote terminal session, ' + e.toString() + ' (' + this.httprequest.remoteaddr + ')', this.httprequest);
@@ -1180,14 +1199,17 @@ function createMeshCore(agent) {
1199
this.end();
1200
return;
1201
}
1183
- if (!this.httprequest._dispatcher) {
1202
+ if (!this.httprequest._dispatcher)
1203
+ {
1204
this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
1205
this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
1206
this.prependListener('end', function () { this.httprequest._term.end(function () { console.log("Terminal was closed"); }); });
1207
}
1208
}
1189
- else {
1190
- try {
1209
+ else
1210
+ {
1211
+ try
1212
+ {
1213
var bash = fs.existsSync('/bin/bash') ? '/bin/bash' : false;
1214
var sh = fs.existsSync('/bin/sh') ? '/bin/sh' : false;
1215
var script = fs.existsSync('/usr/bin/script') ? '/usr/bin/script' : false;