diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index 68d13342..9a21d7e9 100644 Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index c898c60a..0a3bfd2c 100644 Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ diff --git a/agents/MeshService-signed.exe b/agents/MeshService-signed.exe index 7e7fbac6..37fcd943 100644 Binary files a/agents/MeshService-signed.exe and b/agents/MeshService-signed.exe differ diff --git a/agents/MeshService.exe b/agents/MeshService.exe index eb008ef0..2002d607 100644 Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ diff --git a/agents/MeshService64-signed.exe b/agents/MeshService64-signed.exe index 006094ff..90c9e18c 100644 Binary files a/agents/MeshService64-signed.exe and b/agents/MeshService64-signed.exe differ diff --git a/agents/MeshService64.exe b/agents/MeshService64.exe index ba312327..db87bc90 100644 Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ diff --git a/agents/meshcore.min.js b/agents/meshcore.min.js index dc06510d..378f6317 100644 --- a/agents/meshcore.min.js +++ b/agents/meshcore.min.js @@ -1109,28 +1109,58 @@ function createMeshCore(agent) { { try { - if (((this.httprequest.protocol == 6) || (this.httprequest.protocol == 8)) && (require('win-terminal').PowerShellCapable() == true)) { - if (require('win-virtual-terminal').supported) { - this.httprequest._term = require('win-virtual-terminal').StartPowerShell(80, 25); // TODO: Start as logged in used when protocol is 8 - } else { - this.httprequest._term = require('win-terminal').StartPowerShell(80, 25); // TODO: Start as logged in used when protocol is 8 + if (!require('win-terminal').PowerShellCapable() && (this.httprequest.protocol == 6 || this.httprequest.protocol == 9)) { throw ('PowerShell is not supported on this version of windows'); } + if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6)) + { + // Admin Terminal + if (require('win-virtual-terminal').supported) + { + // ConPTY PseudoTerminal + this.httprequest._term = require('win-virtual-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](80, 25); } - } else { - if (require('win-virtual-terminal').supported) { - this.httprequest._term = require('win-virtual-terminal').Start(80, 25); // TODO: Start as logged in used when protocol is 8 - } else { - this.httprequest._term = require('win-terminal').Start(80, 25); // TODO: Start as logged in used when protocol is 8 + else + { + // Legacy Terminal + this.httprequest._term = require('win-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](80, 25); } } - } catch (e) { + else + { + // Logged in user + var username = require('user-sessions').getUsername(require('user-sessions').consoleUid()); + if (require('win-virtual-terminal').supported) + { + // ConPTY PseudoTerminal + this.httprequest._dispatcher = require('win-dispatcher').dispatch({ user: username, 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] } }); + } + else + { + // Legacy Terminal + this.httprequest._dispatcher = require('win-dispatcher').dispatch({ user: username, modules: [{ name: 'win-terminal', script: getJSModule('win-terminal') }], launch: { module: 'win-terminal', method: (this.httprequest.protocol == 9 ? 'StartPowerShell' : 'Start'), args: [80, 25] } }); + } + this.httprequest._dispatcher.ws = this; + this.httprequest._dispatcher.on('connection', function (c) + { + console.log('client connected'); + this.ws._term = c; + c.pipe(this.ws, { dataTypeSkip: 1 }); + this.ws.pipe(c, { dataTypeSkip: 1, end: false }); + this.ws.prependListener('end', function () { this.httprequest._term.end(function () { console.log("Terminal was closed"); }); }); + }); + } + } catch (e) + { MeshServerLog('Failed to start remote terminal session, ' + e.toString() + ' (' + this.httprequest.remoteaddr + ')', this.httprequest); this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() })); this.end(); return; } - this.httprequest._term.pipe(this, { dataTypeSkip: 1 }); - this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false }); - this.prependListener('end', function () { this.httprequest._term.end(function () { console.log("Terminal was closed"); }); }); + if (!this.httprequest._dispatcher) + { + this.httprequest._term.pipe(this, { dataTypeSkip: 1 }); + this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false }); + this.prependListener('end', function () { this.httprequest._term.end(function () { console.log("Terminal was closed"); }); }); + } } else { @@ -1212,7 +1242,7 @@ function createMeshCore(agent) { } // Remote desktop using native pipes - this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this }; + this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(require('MeshAgent')._tsid == null ? undefined : require('MeshAgent')._tsid), tunnel: this }; this.httprequest.desktop.kvm.parent = this.httprequest.desktop; this.desktop = this.httprequest.desktop; @@ -1256,7 +1286,7 @@ function createMeshCore(agent) { this.httprequest.desktop.kvm.connectionBar.removeAllListeners('close'); this.httprequest.desktop.kvm.connectionBar.close(); - this.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')('Sharing desktop with: ' + this.httprequest.desktop.kvm.users.sort().join(', ')); + this.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')('Sharing desktop with: ' + this.httprequest.desktop.kvm.users.sort().join(', '), require('MeshAgent')._tsid); this.httprequest.desktop.kvm.connectionBar.httprequest = this.httprequest; this.httprequest.desktop.kvm.connectionBar.on('close', function () { @@ -1321,7 +1351,7 @@ function createMeshCore(agent) { } try { - this.ws.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')('Sharing desktop with: ' + this.ws.httprequest.desktop.kvm.users.sort().join(', ')); + this.ws.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')('Sharing desktop with: ' + this.ws.httprequest.desktop.kvm.users.sort().join(', '), require('MeshAgent')._tsid); MeshServerLog('Remote Desktop Connection Bar Activated/Updated (' + this.ws.httprequest.remoteaddr + ')', this.ws.httprequest); } catch(xx) @@ -1375,7 +1405,7 @@ function createMeshCore(agent) { } try { - this.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')('Sharing desktop with: ' + this.httprequest.desktop.kvm.users.sort().join(', ')); + this.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')('Sharing desktop with: ' + this.httprequest.desktop.kvm.users.sort().join(', '), require('MeshAgent')._tsid); MeshServerLog('Remote Desktop Connection Bar Activated/Updated (' + this.httprequest.remoteaddr + ')', this.httprequest); } catch(xx) @@ -1836,6 +1866,40 @@ function createMeshCore(agent) { response = 'Available commands: \r\n' + fin + '.'; break; } + case 'tsid': + if (process.platform == 'win32') + { + if (args['_'].length != 1) + { + response = 'TSID: ' + (require('MeshAgent')._tsid == null ? 'console' : require('MeshAgent')._tsid); + } + else + { + var i = parseInt(args['_'][0]); + require('MeshAgent')._tsid = (isNaN(i) ? null : i); + response = 'TSID set to: ' + (require('MeshAgent')._tsid == null ? 'console' : require('MeshAgent')._tsid); + } + } + break; + case 'activeusers': + if (process.platform == 'win32') + { + var p = require('user-sessions').enumerateUsers(); + p.sessionid = sessionid; + p.then(function (u) + { + var v = []; + for(var i in u) + { + if(u[i].State == 'Active' || u[i].State == 'Connected') + { + v.push({ tsid: i, type: u[i].StationName, user: u[i].Username }); + } + } + sendConsoleText(JSON.stringify(v, null, 1), this.sessionid); + }); + } + break; case 'wallpaper': if (process.platform != 'win32' && !(process.platform == 'linux' && require('linux-gnome-helpers').available)) { diff --git a/agents/modules_meshcore/win-virtual-terminal.js b/agents/modules_meshcore/win-virtual-terminal.js index 4907815b..883d2079 100644 --- a/agents/modules_meshcore/win-virtual-terminal.js +++ b/agents/modules_meshcore/win-virtual-terminal.js @@ -115,18 +115,18 @@ function vt() ds.terminal = ret; ds._rpbuf = GM.CreateVariable(4096); ds._rpbufRead = GM.CreateVariable(4); - ds._read = function _read() + ds.__read = function __read() { - this._rp = this.terminal.k32.ReadFile.async(this.terminal._output.Deref(), this._rpbuf, this._rpbuf._size, this._rpbufRead, 0); + this._rp = this.terminal.k32.ReadFile.async(this.terminal._output.Deref(), this._rpbuf, this._rpbuf._size, this._rpbufRead, 0); this._rp.then(function () { var len = this.parent._rpbufRead.toBuffer().readUInt32LE(); this.parent.push(this.parent._rpbuf.toBuffer().slice(0, len)); - this.parent._read(); + this.parent.__read(); }); this._rp.parent = this; }; - ds._read(); + ds.__read(); return (ds); } else diff --git a/agents/modules_meshcore_min/win-virtual-terminal.min.js b/agents/modules_meshcore_min/win-virtual-terminal.min.js index 6c3d5f5e..ccf58575 100644 --- a/agents/modules_meshcore_min/win-virtual-terminal.min.js +++ b/agents/modules_meshcore_min/win-virtual-terminal.min.js @@ -1 +1 @@ -var PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE=131094;var EXTENDED_STARTUPINFO_PRESENT=524288;var HEAP_ZERO_MEMORY=8;var duplex=require("stream").Duplex;function vt(){this._ObjectID="win-virtual-terminal";Object.defineProperty(this,"supported",{value:(function(){var f=require("_GenericMarshal");var g=f.CreateNativeProxy("kernel32.dll");try{g.CreateMethod("CreatePseudoConsole")}catch(d){return(false)}return(true)})()});this.Create=function a(k,o,i){if(!this.supported){throw ("This build of Windows does not have support for PseudoConsoles")}if(!o){o=80}if(!i){i=25}var h=require("_GenericMarshal");var j=h.CreateNativeProxy("kernel32.dll");j.CreateMethod("CreatePipe");j.CreateMethod("CreateProcessW");j.CreateMethod("CreatePseudoConsole");j.CreateMethod("GetProcessHeap");j.CreateMethod("HeapAlloc");j.CreateMethod("InitializeProcThreadAttributeList");j.CreateMethod("UpdateProcThreadAttribute");j.CreateMethod("WriteFile");j.CreateMethod("ReadFile");j.CreateMethod("TerminateProcess");var m={_h:h.CreatePointer(),_consoleInput:h.CreatePointer(),_consoleOutput:h.CreatePointer(),_input:h.CreatePointer(),_output:h.CreatePointer(),k32:j};var f=h.CreateVariable(8);var e;var l=h.CreateVariable(h.PointerSize==4?16:24);if(j.CreatePipe(m._consoleInput,m._input,0,0).Val==0){console.log("PIPE/FAIL")}if(j.CreatePipe(m._output,m._consoleOutput,0,0).Val==0){console.log("PIPE/FAIL")}if(j.CreatePseudoConsole((i<<16)|o,m._consoleInput.Deref(),m._consoleOutput.Deref(),0,m._h).Val!=0){throw ("Error calling CreatePseudoConsole()")}j.InitializeProcThreadAttributeList(0,1,0,f);e=h.CreateVariable(f.toBuffer().readUInt32LE());var n=h.CreateVariable(h.PointerSize==8?112:72);n.toBuffer().writeUInt32LE(h.PointerSize==8?112:72,0);e.pointerBuffer().copy(n.Deref(h.PointerSize==8?104:68,h.PointerSize).toBuffer());if(j.InitializeProcThreadAttributeList(e,1,0,f).Val!=0){if(j.UpdateProcThreadAttribute(e,0,PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,m._h.Deref(),h.PointerSize,0,0).Val!=0){if(j.CreateProcessW(0,h.CreateVariable(k,{wide:true}),0,0,1,EXTENDED_STARTUPINFO_PRESENT,0,0,n,l).Val!=0){m._startupinfoex=n;m._process=l.Deref(0);m._pid=l.Deref(h.PointerSize==4?8:16,4).toBuffer().readUInt32LE();var g=new duplex({write:function(p,q){var r=require("_GenericMarshal").CreateVariable(4);this.terminal.k32.WriteFile(this.terminal._input.Deref(),require("_GenericMarshal").CreateVariable(p),p.length,r,0);q();return(true)},"final":function(p){if(this.terminal._process){this.terminal.k32.TerminateProcess(this.terminal._process,0);this.terminal._process=null;this.terminal.k32.ReadFile.async.abort()}p()}});m._waiter=require("DescriptorEvents").addDescriptor(l.Deref(0));m._waiter.ds=g;m._waiter.on("signaled",function(){this.ds.push(null)});g.terminal=m;g._rpbuf=h.CreateVariable(4096);g._rpbufRead=h.CreateVariable(4);g._read=function d(){this._rp=this.terminal.k32.ReadFile.async(this.terminal._output.Deref(),this._rpbuf,this._rpbuf._size,this._rpbufRead,0);this._rp.then(function(){var p=this.parent._rpbufRead.toBuffer().readUInt32LE();this.parent.push(this.parent._rpbuf.toBuffer().slice(0,p));this.parent._read()});this._rp.parent=this};g._read();return(g)}else{console.log("FAILED!")}}}throw ("Internal Error")};this.PowerShellCapable=function(){if(require("os").arch()=="x64"){return(require("fs").existsSync(process.env.windir+"\\SysWow64\\WindowsPowerShell\\v1.0\\powershell.exe"))}else{return(require("fs").existsSync(process.env.windir+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"))}};this.Start=function b(e,d){return(this.Create(process.env.windir+"\\System32\\cmd.exe",e,d))};this.StartPowerShell=function c(e,d){if(require("os").arch()=="x64"){return(this.Create(process.env.windir+"\\SysWow64\\WindowsPowerShell\\v1.0\\powershell.exe",e,d))}else{return(this.Create(process.env.windir+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",e,d))}}}if(process.platform=="win32"){module.exports=new vt()}; \ No newline at end of file +var PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE=131094;var EXTENDED_STARTUPINFO_PRESENT=524288;var HEAP_ZERO_MEMORY=8;var duplex=require("stream").Duplex;function vt(){this._ObjectID="win-virtual-terminal";Object.defineProperty(this,"supported",{value:(function(){var f=require("_GenericMarshal");var g=f.CreateNativeProxy("kernel32.dll");try{g.CreateMethod("CreatePseudoConsole")}catch(d){return(false)}return(true)})()});this.Create=function a(k,o,i){if(!this.supported){throw ("This build of Windows does not have support for PseudoConsoles")}if(!o){o=80}if(!i){i=25}var h=require("_GenericMarshal");var j=h.CreateNativeProxy("kernel32.dll");j.CreateMethod("CreatePipe");j.CreateMethod("CreateProcessW");j.CreateMethod("CreatePseudoConsole");j.CreateMethod("GetProcessHeap");j.CreateMethod("HeapAlloc");j.CreateMethod("InitializeProcThreadAttributeList");j.CreateMethod("UpdateProcThreadAttribute");j.CreateMethod("WriteFile");j.CreateMethod("ReadFile");j.CreateMethod("TerminateProcess");var m={_h:h.CreatePointer(),_consoleInput:h.CreatePointer(),_consoleOutput:h.CreatePointer(),_input:h.CreatePointer(),_output:h.CreatePointer(),k32:j};var f=h.CreateVariable(8);var e;var l=h.CreateVariable(h.PointerSize==4?16:24);if(j.CreatePipe(m._consoleInput,m._input,0,0).Val==0){console.log("PIPE/FAIL")}if(j.CreatePipe(m._output,m._consoleOutput,0,0).Val==0){console.log("PIPE/FAIL")}if(j.CreatePseudoConsole((i<<16)|o,m._consoleInput.Deref(),m._consoleOutput.Deref(),0,m._h).Val!=0){throw ("Error calling CreatePseudoConsole()")}j.InitializeProcThreadAttributeList(0,1,0,f);e=h.CreateVariable(f.toBuffer().readUInt32LE());var n=h.CreateVariable(h.PointerSize==8?112:72);n.toBuffer().writeUInt32LE(h.PointerSize==8?112:72,0);e.pointerBuffer().copy(n.Deref(h.PointerSize==8?104:68,h.PointerSize).toBuffer());if(j.InitializeProcThreadAttributeList(e,1,0,f).Val!=0){if(j.UpdateProcThreadAttribute(e,0,PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,m._h.Deref(),h.PointerSize,0,0).Val!=0){if(j.CreateProcessW(0,h.CreateVariable(k,{wide:true}),0,0,1,EXTENDED_STARTUPINFO_PRESENT,0,0,n,l).Val!=0){m._startupinfoex=n;m._process=l.Deref(0);m._pid=l.Deref(h.PointerSize==4?8:16,4).toBuffer().readUInt32LE();var g=new duplex({write:function(p,q){var r=require("_GenericMarshal").CreateVariable(4);this.terminal.k32.WriteFile(this.terminal._input.Deref(),require("_GenericMarshal").CreateVariable(p),p.length,r,0);q();return(true)},"final":function(p){if(this.terminal._process){this.terminal.k32.TerminateProcess(this.terminal._process,0);this.terminal._process=null;this.terminal.k32.ReadFile.async.abort()}p()}});m._waiter=require("DescriptorEvents").addDescriptor(l.Deref(0));m._waiter.ds=g;m._waiter.on("signaled",function(){this.ds.push(null)});g.terminal=m;g._rpbuf=h.CreateVariable(4096);g._rpbufRead=h.CreateVariable(4);g.__read=function d(){this._rp=this.terminal.k32.ReadFile.async(this.terminal._output.Deref(),this._rpbuf,this._rpbuf._size,this._rpbufRead,0);this._rp.then(function(){var p=this.parent._rpbufRead.toBuffer().readUInt32LE();this.parent.push(this.parent._rpbuf.toBuffer().slice(0,p));this.parent.__read()});this._rp.parent=this};g.__read();return(g)}else{console.log("FAILED!")}}}throw ("Internal Error")};this.PowerShellCapable=function(){if(require("os").arch()=="x64"){return(require("fs").existsSync(process.env.windir+"\\SysWow64\\WindowsPowerShell\\v1.0\\powershell.exe"))}else{return(require("fs").existsSync(process.env.windir+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"))}};this.Start=function b(e,d){return(this.Create(process.env.windir+"\\System32\\cmd.exe",e,d))};this.StartPowerShell=function c(e,d){if(require("os").arch()=="x64"){return(this.Create(process.env.windir+"\\SysWow64\\WindowsPowerShell\\v1.0\\powershell.exe",e,d))}else{return(this.Create(process.env.windir+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",e,d))}}}if(process.platform=="win32"){module.exports=new vt()}; \ No newline at end of file diff --git a/meshcentral.js b/meshcentral.js index 4a639418..ca3a85c3 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1979,7 +1979,8 @@ function CreateMeshCentralServer(config, args) { function logInfoEvent(msg) { if (obj.servicelog != null) { obj.servicelog.info(msg); } console.log(msg); } function logWarnEvent(msg) { if (obj.servicelog != null) { obj.servicelog.warn(msg); } console.log(msg); } function logErrorEvent(msg) { if (obj.servicelog != null) { obj.servicelog.error(msg); } console.error(msg); } - obj.getServerWarnings = function() { return serverWarnings; } + obj.getServerWarnings = function () { return serverWarnings; } + obj.addServerWarning = function(msg, print) { serverWarnings.push(msg); if (print !== false) { console.log("WARNING: " + msg); } } // Return the path of a file into the meshcentral-data path obj.getConfigFilePath = function (filename) { diff --git a/package.json b/package.json index 74195ab3..91e9aa56 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.4.5-o", + "version": "0.4.5-p", "keywords": [ "Remote Management", "Intel AMT", diff --git a/translate/translate.js b/translate/translate.js index b657ffd6..0afe7693 100644 --- a/translate/translate.js +++ b/translate/translate.js @@ -285,7 +285,7 @@ function fromtext(source, target, lang) { var splitOutput = []; for (var i in sourceLangFileData.strings) { if ((sourceLangFileData.strings[i]['en'] != null) && (sourceLangFileData.strings[i]['en'].indexOf('\r') == -1) && (sourceLangFileData.strings[i]['en'].indexOf('\n') == -1)) { - sourceLangFileData.strings[i][lang] = rawTextArray[i]; + if (sourceLangFileData.strings[i][lang] == null) { sourceLangFileData.strings[i][lang] = rawTextArray[i]; } } } @@ -313,7 +313,7 @@ function merge(source, target, lang) { // Merge the translation for (var i in sourceLangFileData.strings) { if ((sourceLangFileData.strings[i].en != null) && (sourceLangFileData.strings[i][lang] != null) && (index[sourceLangFileData.strings[i].en] != null)) { - index[sourceLangFileData.strings[i].en][lang] = sourceLangFileData.strings[i][lang]; + if (sourceLangFileData.strings[i][lang] == null) { index[sourceLangFileData.strings[i].en][lang] = sourceLangFileData.strings[i][lang]; } } } diff --git a/views/default.handlebars b/views/default.handlebars index 350015a1..7d427bbc 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -58,8 +58,8 @@