This commit is contained in:
Ylian Saint-Hilaire 2022-10-20 14:44:47 -07:00
commit a40e40757c
23 changed files with 613 additions and 133 deletions

View File

@ -5,6 +5,7 @@
"accountcreate",
"accountid",
"accountremove",
"acebase",
"acmd",
"acmepath",
"actiontype",
@ -599,6 +600,7 @@
"postflight",
"poweraction",
"powerevents",
"Preconfigured",
"Proto",
"publicid",
"pushlogin",
@ -662,6 +664,7 @@
"rport",
"rtpass",
"rtuser",
"runas",
"runasuser",
"runasuseronly",
"runcommand",
@ -822,6 +825,7 @@
"usercount",
"userex",
"userfiles",
"userfirst",
"usergroupchange",
"usergroups",
"userid",

View File

@ -47,6 +47,32 @@ var MESHRIGHT_NODESKTOP = 65536;
var pendingSetClip = false; // This is a temporary hack to prevent multiple setclips at the same time to stop the agent from crashing.
//
// This is a helper function used by the 32 bit Windows Agent, when running on 64 bit windows. It will check if the agent is already patched for this
// and will use this helper if it is not. This helper will inject 'sysnative' into the results when calling readdirSync() on %windir%.
//
function __readdirSync_fix(path)
{
var sysnative = false;
pathstr = require('fs')._fixwinpath(path);
if (pathstr.split('\\*').join('').toLowerCase() == process.env['windir'].toLowerCase()) { sysnative = true; }
var ret = __readdirSync_old(path);
if (sysnative) { ret.push('sysnative'); }
return (ret);
}
if (process.platform == 'win32' && require('_GenericMarshal').PointerSize == 4 && require('os').arch() == 'x64')
{
if (require('fs').readdirSync.version == null)
{
//
// 32 Bit Windows Agent on 64 bit Windows has not been patched for sysnative issue, so lets use our own solution
//
require('fs').__readdirSync_old = require('fs').readdirSync;
require('fs').readdirSync = __readdirSync_fix;
}
}
function bcdOK() {
if (process.platform != 'win32') { return (false); }
if (require('os').arch() == 'x64') {

View File

@ -103,14 +103,13 @@ if (msh.agentName) { connectArgs.push('--agentName="' + msh.agentName + '"'); }
function _install(parms)
{
var i;
var mstr = require('fs').createWriteStream(process.execPath + '.msh', { flags: 'wb' });
mstr.write('MeshName=' + msh.MeshName + '\n');
mstr.write('MeshType=' + msh.MeshType + '\n');
mstr.write('MeshID=' + msh.MeshID + '\n');
mstr.write('ServerID=' + msh.ServerID + '\n');
mstr.write('MeshServer=' + msh.MeshServer + '\n');
if (msh.agentName) { mstr.write('agentName=' + msh.agentName + '\n'); }
if (msh.meshServiceName) { mstr.write('meshServiceName=' + msh.meshServiceName + '\n'); }
for (i in msh)
{
mstr.write(i + '=' + msh[i] + '\n');
}
mstr.end();
if (parms == null) { parms = []; }
@ -156,7 +155,7 @@ if (process.argv.includes('-translations'))
console.log(JSON.stringify(translation));
process.exit();
}
if (process.argv.includes('-help') || (process.platform == 'linux' && process.env['XAUTHORITY']==null && process.env['DISPLAY'] == null))
if (process.argv.includes('-help') || (process.platform == 'linux' && process.env['XAUTHORITY'] == null && process.env['DISPLAY'] == null && process.argv.length == 1))
{
console.log("\n" + translation[lang].commands + ": ");
if ((msh.InstallFlags & 1) == 1)

View File

@ -269,15 +269,18 @@ function SMBiosTables()
this.amtInfo = function amtInfo(data) {
if (!data) { throw ('no data'); }
var retVal = { AMT: false };
if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT') {
if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT')
{
var amt = data[130].peek();
retVal.AMT = amt[4] ? true : false;
if (retVal.AMT) {
if (retVal.AMT)
{
retVal.enabled = amt[5] ? true : false;
retVal.storageRedirection = amt[6] ? true : false;
retVal.serialOverLan = amt[7] ? true : false;
retVal.kvm = amt[14] ? true : false;
if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro') {
if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro')
{
var settings = data[131].peek();
if (settings[0] & 0x04) { retVal.TXT = (settings[0] & 0x08) ? true : false; }
if (settings[0] & 0x10) { retVal.VMX = (settings[0] & 0x20) ? true : false; }
@ -295,6 +298,14 @@ function SMBiosTables()
}
}
}
if (!retVal.AMT)
{
if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro')
{
var settings = data[131].peek();
if ((settings[20] & 0x08) == 0x08) { retVal.AMT = true; }
}
}
return (retVal);
};
this.smTableTypes = {

View File

@ -269,15 +269,18 @@ function SMBiosTables()
this.amtInfo = function amtInfo(data) {
if (!data) { throw ('no data'); }
var retVal = { AMT: false };
if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT') {
if (data[130] && data[130].peek().slice(0, 4).toString() == '$AMT')
{
var amt = data[130].peek();
retVal.AMT = amt[4] ? true : false;
if (retVal.AMT) {
if (retVal.AMT)
{
retVal.enabled = amt[5] ? true : false;
retVal.storageRedirection = amt[6] ? true : false;
retVal.serialOverLan = amt[7] ? true : false;
retVal.kvm = amt[14] ? true : false;
if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro') {
if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro')
{
var settings = data[131].peek();
if (settings[0] & 0x04) { retVal.TXT = (settings[0] & 0x08) ? true : false; }
if (settings[0] & 0x10) { retVal.VMX = (settings[0] & 0x20) ? true : false; }
@ -295,6 +298,14 @@ function SMBiosTables()
}
}
}
if (!retVal.AMT)
{
if (data[131].peek() && data[131].peek().slice(52, 56).toString() == 'vPro')
{
var settings = data[131].peek();
if ((settings[20] & 0x08) == 0x08) { retVal.AMT = true; }
}
}
return (retVal);
};
this.smTableTypes = {

View File

@ -1,5 +1,5 @@
/*
Copyright 2018 Intel Corporation
Copyright 2018-2022 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -89,21 +89,50 @@ function windows_terminal() {
var newCsbi = GM.CreateVariable(22);
if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, newCsbi).Val == 0) { return; }
if (newCsbi.Deref(4, 2).toBuffer().readUInt16LE() != this.currentX || newCsbi.Deref(6, 2).toBuffer().readUInt16LE() != this.currentY) {
//wchar_t mywbuf[512];
//swprintf(mywbuf, 512, TEXT("csbi.dwCursorPosition.X = %d, csbi.dwCursorPosition.Y = %d, newCsbi.dwCursorPosition.X = %d, newCsbi.dwCursorPosition.Y = %d\r\n"), csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y, newCsbi.dwCursorPosition.X, newCsbi.dwCursorPosition.Y);
//OutputDebugString(mywbuf);
//m_viewOffset = newCsbi.srWindow.Top;
//WriteMoveCursor((SerialAgent *)this->sa, (char)(newCsbi.dwCursorPosition.Y - m_viewOffset), (char)(newCsbi.dwCursorPosition.X - m_viewOffset));
//LowStackSendData((SerialAgent *)(this->sa), "", 0);
if (newCsbi.Deref(4, 2).toBuffer().readUInt16LE() != this.currentX || newCsbi.Deref(6, 2).toBuffer().readUInt16LE() != this.currentY)
{
//
// Reference for CONSOLE_SCREEN_BUFFER_INFO can be found at:
// https://learn.microsoft.com/en-us/windows/console/console-screen-buffer-info-str
//
this.currentX = newCsbi.Deref(4, 2).toBuffer().readUInt16LE();
this.currentY = newCsbi.Deref(6, 2).toBuffer().readUInt16LE();
}
}
this.ClearScreen = function () {
this.ClearScreen = function ()
{
//
// Reference for CONSOLE_SCREEN_BUFFER_INFO can be found at:
// https://learn.microsoft.com/en-us/windows/console/console-screen-buffer-info-str
//
//
// Reference for GetConsoleScreenBufferInfo can be found at:
// https://learn.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo
//
//
// Reference for FillConsoleOutputCharacter can be found at:
// https://learn.microsoft.com/en-us/windows/console/fillconsoleoutputcharacter
//
//
// Reference for FillConsoleOutputAttribute can be found at:
// https://learn.microsoft.com/en-us/windows/console/fillconsoleoutputattribute
//
//
// Reference for SetConsoleCursorPosition can be found at:
// https://learn.microsoft.com/en-us/windows/console/setconsolecursorposition
//
//
// Reference for SetConsoleWindowInfo can be fount at:
// https://learn.microsoft.com/en-us/windows/console/setconsolewindowinfo
//
var CONSOLE_SCREEN_BUFFER_INFO = GM.CreateVariable(22);
if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, CONSOLE_SCREEN_BUFFER_INFO).Val == 0) { return; }
@ -132,6 +161,7 @@ function windows_terminal() {
this._kernel32.SetConsoleWindowInfo(this._stdoutput, 1, rect);
}
// This does a rudimentary check if the platform is capable of PowerShell
this.PowerShellCapable = function()
{
if (require('os').arch() == 'x64')
@ -144,6 +174,7 @@ function windows_terminal() {
}
}
// Starts a Legacy Windows Terminal Session
this.StartEx = function Start(CONSOLE_SCREEN_WIDTH, CONSOLE_SCREEN_HEIGHT, terminalTarget)
{
// The older windows terminal does not support
@ -164,6 +195,8 @@ function windows_terminal() {
this._stdinput = this._kernel32.GetStdHandle(STD_INPUT_HANDLE);
this._stdoutput = this._kernel32.GetStdHandle(STD_OUTPUT_HANDLE);
this._connected = false;
// Coord structure can be found at: https://learn.microsoft.com/en-us/windows/console/coord-str
var coordScreen = GM.CreateVariable(4);
coordScreen.Deref(0, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_WIDTH);
coordScreen.Deref(2, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_HEIGHT);
@ -172,10 +205,21 @@ function windows_terminal() {
rect.Deref(4, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_WIDTH - 1);
rect.Deref(6, 2).toBuffer().writeUInt16LE(CONSOLE_SCREEN_HEIGHT - 1);
if (this._kernel32.SetConsoleWindowInfo(this._stdoutput, 1, rect).Val == 0) {
//
// Reference for SetConsoleWindowInfo can be found at:
// https://learn.microsoft.com/en-us/windows/console/setconsolewindowinfo
//
if (this._kernel32.SetConsoleWindowInfo(this._stdoutput, 1, rect).Val == 0)
{
throw ('Failed to set Console Screen Size');
}
if (this._kernel32.SetConsoleScreenBufferSize(this._stdoutput, coordScreen.Deref(0, 4).toBuffer().readUInt32LE()).Val == 0) {
//
// Reference for SetConsoleScreenBufferSize can be found at:
// https://learn.microsoft.com/en-us/windows/console/setconsolescreenbuffersize
//
if (this._kernel32.SetConsoleScreenBufferSize(this._stdoutput, coordScreen.Deref(0, 4).toBuffer().readUInt32LE()).Val == 0)
{
throw ('Failed to set Console Buffer Size');
}
@ -278,8 +322,16 @@ function windows_terminal() {
return (this.stopping);
}
//
// This function uses the SetWinEventHook() method, so we can hook
// All events between EVENT_CONSOLE_CARET and EVENT_CONSOLE_END_APPLICATION
//
this._hookThread = function ()
{
//
// Reference for SetWinEventHook() can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwineventhook
//
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
ret.userArgs = [];
for (var a in arguments)
@ -292,24 +344,43 @@ function windows_terminal() {
var p = this._user32.SetWinEventHook.async(EVENT_CONSOLE_CARET, EVENT_CONSOLE_END_APPLICATION, 0, this._ConsoleWinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
p.ready = ret;
p.terminal = this;
p.then(function (hwinEventHook) {
if (hwinEventHook.Val == 0) {
p.then(function (hwinEventHook)
{
if (hwinEventHook.Val == 0)
{
this.ready._rej('Error calling SetWinEventHook');
} else {
} else
{
this.terminal.hwinEventHook = hwinEventHook;
this.ready._res();
this.terminal._GetMessage();
}
});
this._ConsoleWinEventProc.on('GlobalCallback', function (hhook, dwEvent, hwnd, idObject, idChild, idEventThread, swmsEventTime) {
//
// This is the WINEVENTPROC callback for the WinEventHook we set
//
this._ConsoleWinEventProc.on('GlobalCallback', function (hhook, dwEvent, hwnd, idObject, idChild, idEventThread, swmsEventTime)
{
//
// Reference for WINEVENTPROC can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wineventproc
//
if (!this.terminal.hwinEventHook || this.terminal.hwinEventHook.Val != hhook.Val) { return; }
var buffer = null;
switch (dwEvent.Val) {
//
// Reference for Console WinEvents can be found at:
// https://learn.microsoft.com/en-us/windows/console/console-winevents
//
switch (dwEvent.Val)
{
case EVENT_CONSOLE_CARET:
// The console caret has moved
break;
case EVENT_CONSOLE_UPDATE_REGION:
// More than one character has changed
if (!this.terminal.connected) {
this.terminal.connected = true;
this.terminal._stream._promise._res();
@ -321,25 +392,30 @@ function windows_terminal() {
}
break;
case EVENT_CONSOLE_UPDATE_SIMPLE:
// A single character has changed
//console.log('UPDATE SIMPLE: [X: ' + LOWORD(idObject.Val) + ' Y: ' + HIWORD(idObject.Val) + ' Char: ' + LOWORD(idChild.Val) + ' Attr: ' + HIWORD(idChild.Val) + ']');
var simplebuffer = { data: [ Buffer.alloc(1, LOWORD(idChild.Val)) ], attributes: [ HIWORD(idChild.Val) ], width: 1, height: 1, x: LOWORD(idObject.Val), y: HIWORD(idObject.Val) };
this.terminal._SendDataBuffer(simplebuffer);
break;
case EVENT_CONSOLE_UPDATE_SCROLL:
// The console has scrolled
//console.log('UPDATE SCROLL: [dx: ' + idObject.Val + ' dy: ' + idChild.Val + ']');
this.terminal._SendScroll(idObject.Val, idChild.Val);
break;
case EVENT_CONSOLE_LAYOUT:
// The console layout has changed.
//console.log('CONSOLE_LAYOUT');
//snprintf( Buf, 512, "Event Console LAYOUT!\r\n");
//SendLayout();
break;
case EVENT_CONSOLE_START_APPLICATION:
// A new console process has started
//console.log('START APPLICATION: [PID: ' + idObject.Val + ' CID: ' + idChild.Val + ']');
//snprintf( Buf, 512, "Event Console START APPLICATION!\r\nProcess ID: %d - Child ID: %d\r\n\r\n", (int)idObject, (int)idChild);
//SendConsoleEvent(dwEvent, idObject, idChild);
break;
case EVENT_CONSOLE_END_APPLICATION:
// A console process has exited
if (idObject.Val == this.terminal._hProcessID)
{
//console.log('END APPLICATION: [PID: ' + idObject.Val + ' CID: ' + idChild.Val + ']');
@ -360,18 +436,44 @@ function windows_terminal() {
return (ret);
}
this._GetMessage = function () {
// Retrieves a message from the calling thread's message queue
this._GetMessage = function ()
{
//
// Reference for GetMessage() can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage
//
//
// Reference for TranslateMessage() can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-translatemessage
//
//
// Reference for DispatchMessage() can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-dispatchmessage
//
if (this._user32.abort) { console.log('aborting loop'); return; }
this._user32.GetMessageA.async(this._user32.SetWinEventHook.async, MSG, 0, 0, 0).then(function (ret) {
this._user32.GetMessageA.async(this._user32.SetWinEventHook.async, MSG, 0, 0, 0).then(function (ret)
{
//console.log('GetMessage Response');
if (ret.Val != 0) {
if (ret.Val == -1) {
if (ret.Val != 0)
{
if (ret.Val == -1)
{
// handle the error and possibly exit
} else {
}
else
{
// Translates virtual-key messages into character messages
//console.log('TranslateMessage');
this.nativeProxy._user32.TranslateMessage.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function () {
this.nativeProxy._user32.TranslateMessage.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function ()
{
// Dispatches a message to a window procedure
//console.log('DispatchMessage');
this.nativeProxy._user32.DispatchMessageA.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function () {
this.nativeProxy._user32.DispatchMessageA.async(this.nativeProxy.user32.SetWinEventHook.async, MSG).then(function ()
{
this.nativeProxy.terminal._GetMessage();
}, console.log);
}, console.log);
@ -384,7 +486,8 @@ function windows_terminal() {
if (this.nativeProxy.terminal._hProcess == null) { return; }
this.nativeProxy.terminal.stopping._res();
if (this.nativeProxy.terminal._kernel32.TerminateProcess(this.nativeProxy.terminal._hProcess, 1067).Val == 0) {
if (this.nativeProxy.terminal._kernel32.TerminateProcess(this.nativeProxy.terminal._hProcess, 1067).Val == 0)
{
var e = this.nativeProxy.terminal._kernel32.GetLastError().Val;
console.log('Unable to kill Terminal Process, error: ' + e);
}
@ -394,22 +497,38 @@ function windows_terminal() {
console.log('REJECTED_UnhookWinEvent: ' + err);
});
}
}, function (err) {
}, function (err)
{
// Get Message Failed
console.log('REJECTED_GETMessage: ' + err);
});
}
this._WriteBuffer = function (buf) {
for (var i = 0; i < buf.length; ++i) {
if (typeof (buf) == 'string') {
this._WriteBuffer = function (buf)
{
for (var i = 0; i < buf.length; ++i)
{
if (typeof (buf) == 'string')
{
this._WriteCharacter(buf.charCodeAt(i), false);
} else {
} else
{
this._WriteCharacter(buf[i], false);
}
}
}
this._WriteCharacter = function (key, bControlKey)
{
//
// Reference for WriteConsoleInput() can be found at:
// https://learn.microsoft.com/en-us/windows/console/writeconsoleinput
//
//
// Reference for INPUT_RECORD can be found at:
// https://learn.microsoft.com/en-us/windows/console/input-record-str
//
var rec = GM.CreateVariable(20);
rec.Deref(0, 2).toBuffer().writeUInt16LE(KEY_EVENT); // rec.EventType
rec.Deref(4, 4).toBuffer().writeUInt16LE(1); // rec.Event.KeyEvent.bKeyDown
@ -427,20 +546,33 @@ function windows_terminal() {
}
// Get the current visible screen buffer
this._GetScreenBuffer = function (sx, sy, ex, ey) {
this._GetScreenBuffer = function (sx, sy, ex, ey)
{
//
// Reference for GetConsoleScreenBufferInfo() can be found at:
// https://learn.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo
//
//
// Reference for ReadConsoleOutput() can be found at:
// https://learn.microsoft.com/en-us/windows/console/readconsoleoutput
//
var info = GM.CreateVariable(22);
if (this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput, info).Val == 0) { throw ('Error getting screen buffer info'); }
var nWidth = info.Deref(14, 2).toBuffer().readUInt16LE() - info.Deref(10, 2).toBuffer().readUInt16LE() + 1;
var nHeight = info.Deref(16, 2).toBuffer().readUInt16LE() - info.Deref(12, 2).toBuffer().readUInt16LE() + 1;
if (arguments[3] == null) {
if (arguments[3] == null)
{
// Use Default Parameters
sx = 0;
sy = 0;
ex = nWidth - 1;
ey = nHeight - 1;
} else {
} else
{
if (this._scrx != 0) { sx += this._scrx; ex += this._scrx; }
if (this._scry != 0) { sy += this._scry; ey += this._scry; }
this._scrx = this._scry = 0;
@ -462,7 +594,8 @@ function windows_terminal() {
region.buffer.writeUInt16LE(ex, 4);
region.buffer.writeUInt16LE(ey, 6);
if (this._kernel32.ReadConsoleOutputA(this._stdoutput, nBuffer, size.Deref(0, 4).toBuffer().readUInt32LE(), startCoord.Deref(0, 4).toBuffer().readUInt32LE(), region).Val == 0) {
if (this._kernel32.ReadConsoleOutputA(this._stdoutput, nBuffer, size.Deref(0, 4).toBuffer().readUInt32LE(), startCoord.Deref(0, 4).toBuffer().readUInt32LE(), region).Val == 0)
{
throw ('Unable to read Console Output');
}
@ -472,12 +605,14 @@ function windows_terminal() {
var retVal = { data: [], attributes: [], width: ex - sx + 1, height: ey - sy + 1, x: sx, y: sy };
var x, y, line, ifo, tmp, lineWidth = ex - sx + 1;
for (y = 0; y <= (ey - sy) ; ++y) {
for (y = 0; y <= (ey - sy) ; ++y)
{
retVal.data.push(Buffer.alloc(lineWidth));
retVal.attributes.push(Buffer.alloc(lineWidth));
line = nBuffer.Deref(y * lineWidth * 4, lineWidth * 4).toBuffer();
for (x = 0; x < lineWidth; ++x) {
for (x = 0; x < lineWidth; ++x)
{
retVal.data.peek()[x] = line[x * 4];
retVal.attributes.peek()[x] = line[2 + (x * 4)];
}
@ -507,6 +642,11 @@ function windows_terminal() {
this._SendScroll = function _SendScroll(dx, dy)
{
//
// Reference for GetConsoleScreenBufferInfo() can be found at:
// https://learn.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo
//
if (this._scrollTimer || this._stream == null) { return; }
var info = GM.CreateVariable(22);
@ -546,12 +686,15 @@ function LOWORD(val) { return (val & 0xFFFF); }
function HIWORD(val) { return ((val >> 16) & 0xFFFF); }
function GetEsc(op, args) { return (Buffer.from('\x1B[' + args.join(';') + op)); }
function MeshConsole(msg) { require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": JSON.stringify(msg) }); }
function TranslateLine(x, y, data, attributes) {
function TranslateLine(x, y, data, attributes)
{
var i, fcolor, bcolor, rcolor, fbright, bbright, lastAttr, fc, bc, rc, fb, bb, esc = [], output = [GetEsc('H', [y, x])];
if (typeof attributes == 'number') { attributes = [attributes]; } // If we get a single attribute, turn it into an array.
for (i = 0; i < data.length; i++) {
if (lastAttr != attributes[i]) { // To boost performance, if the attribute is the same as the last one, skip this entire part.
for (i = 0; i < data.length; i++)
{
if (lastAttr != attributes[i])
{ // To boost performance, if the attribute is the same as the last one, skip this entire part.
fc = (attributes[i] & 0x0007);
fc = ((fc & 0x0001) << 2) + (fc & 0x0002) + ((fc & 0x0004) >> 2); // Foreground color
bc = (attributes[i] & 0x0070) >> 4;

View File

@ -47,20 +47,20 @@ function vt()
var GM = require('_GenericMarshal');
var k32 = GM.CreateNativeProxy('kernel32.dll');
k32.CreateMethod('CancelIoEx');
k32.CreateMethod('CreatePipe');
k32.CreateMethod('CreateProcessW');
k32.CreateMethod('CreatePseudoConsole');
k32.CreateMethod('CloseHandle');
k32.CreateMethod('ClosePseudoConsole');
k32.CreateMethod('GetProcessHeap');
k32.CreateMethod('HeapAlloc');
k32.CreateMethod('InitializeProcThreadAttributeList');
k32.CreateMethod('ResizePseudoConsole');
k32.CreateMethod('UpdateProcThreadAttribute');
k32.CreateMethod('WriteFile');
k32.CreateMethod('ReadFile');
k32.CreateMethod('TerminateProcess');
k32.CreateMethod('CancelIoEx'); // https://learn.microsoft.com/en-us/windows/win32/fileio/cancelioex-func
k32.CreateMethod('CreatePipe'); // https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-createpipe
k32.CreateMethod('CreateProcessW'); // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
k32.CreateMethod('CreatePseudoConsole'); // https://learn.microsoft.com/en-us/windows/console/createpseudoconsole
k32.CreateMethod('CloseHandle'); // https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
k32.CreateMethod('ClosePseudoConsole'); // https://learn.microsoft.com/en-us/windows/console/closepseudoconsole
k32.CreateMethod('GetProcessHeap'); // https://learn.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-getprocessheap
k32.CreateMethod('HeapAlloc'); // https://learn.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc
k32.CreateMethod('InitializeProcThreadAttributeList'); // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-initializeprocthreadattributelist
k32.CreateMethod('ResizePseudoConsole'); // https://learn.microsoft.com/en-us/windows/console/resizepseudoconsole
k32.CreateMethod('UpdateProcThreadAttribute'); // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute
k32.CreateMethod('WriteFile'); // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile
k32.CreateMethod('ReadFile'); // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile
k32.CreateMethod('TerminateProcess'); // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess
var ret = { _h: GM.CreatePointer(), _consoleInput: GM.CreatePointer(), _consoleOutput: GM.CreatePointer(), _input: GM.CreatePointer(), _output: GM.CreatePointer(), k32: k32 };
var attrSize = GM.CreateVariable(8);
@ -77,18 +77,31 @@ function vt()
throw ('Error calling CreatePseudoConsole()');
}
//
// Reference for STARTUPINFOEXW
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-startupinfoexw
//
//
// Reference for STARTUPINFOW
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfow
//
k32.InitializeProcThreadAttributeList(0, 1, 0, attrSize);
attrList = GM.CreateVariable(attrSize.toBuffer().readUInt32LE());
var startupinfoex = GM.CreateVariable(GM.PointerSize == 8 ? 112 : 72);
startupinfoex.toBuffer().writeUInt32LE(GM.PointerSize == 8 ? 112 : 72, 0);
attrList.pointerBuffer().copy(startupinfoex.Deref(GM.PointerSize == 8 ? 104 : 68, GM.PointerSize).toBuffer());
var startupinfoex = GM.CreateVariable(GM.PointerSize == 8 ? 112 : 72); // Create Structure, 64 bits is 112 bytes, 32 bits is 72 bytes
startupinfoex.toBuffer().writeUInt32LE(GM.PointerSize == 8 ? 112 : 72, 0); // Write buffer size
attrList.pointerBuffer().copy(startupinfoex.Deref(GM.PointerSize == 8 ? 104 : 68, GM.PointerSize).toBuffer()); // Write the reference to STARTUPINFOEX
if (k32.InitializeProcThreadAttributeList(attrList, 1, 0, attrSize).Val != 0)
{
if (k32.UpdateProcThreadAttribute(attrList, 0, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, ret._h.Deref(), GM.PointerSize, 0, 0).Val != 0)
{
if (k32.CreateProcessW(0, GM.CreateVariable(path, { wide: true }), 0, 0, 1, EXTENDED_STARTUPINFO_PRESENT, 0, 0, startupinfoex, pi).Val != 0)
if (k32.CreateProcessW(0, GM.CreateVariable(path, { wide: true }), 0, 0, 1, EXTENDED_STARTUPINFO_PRESENT, 0, 0, startupinfoex, pi).Val != 0) // Create the process to run in the pseudoconsole
{
//
// Create a Stream Object, to be able to read/write data to the pseudoconsole
//
ret._startupinfoex = startupinfoex;
ret._process = pi.Deref(0);
ret._pid = pi.Deref(GM.PointerSize == 4 ? 8 : 16, 4).toBuffer().readUInt32LE();
@ -111,6 +124,10 @@ function vt()
flush();
}
});
//
// The ProcessInfo object is signaled when the process exits
//
ds._obj = ret;
ret._waiter = require('DescriptorEvents').addDescriptor(pi.Deref(0));
ret._waiter.ds = ds;
@ -151,6 +168,7 @@ function vt()
ds._rpbufRead = GM.CreateVariable(4);
ds.__read = function __read()
{
// Asyncronously read data from the pseudoconsole
this._rp = this.terminal.k32.ReadFile.async(this.terminal._output.Deref(), this._rpbuf, this._rpbuf._size, this._rpbufRead, 0);
this._rp.then(function ()
{
@ -173,6 +191,8 @@ function vt()
}
throw ('Internal Error');
}
// This evaluates whether or not the powershell binary exists
this.PowerShellCapable = function ()
{
if (require('os').arch() == 'x64')
@ -184,10 +204,14 @@ function vt()
return (require('fs').existsSync(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'));
}
}
// Start the PseudoConsole with the Command Prompt
this.Start = function Start(CONSOLE_SCREEN_WIDTH, CONSOLE_SCREEN_HEIGHT)
{
return (this.Create(process.env['windir'] + '\\System32\\cmd.exe', CONSOLE_SCREEN_WIDTH, CONSOLE_SCREEN_HEIGHT));
}
// Start the PseduoConsole with PowerShell
this.StartPowerShell = function StartPowerShell(CONSOLE_SCREEN_WIDTH, CONSOLE_SCREEN_HEIGHT)
{
if (require('os').arch() == 'x64')

View File

@ -282,7 +282,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
// Construct the HTTP request
var request = req.method + ' ' + req.url + ' HTTP/' + req.httpVersion + '\r\n';
const blockedHeaders = ['origin', 'cookie', 'upgrade-insecure-requests', 'sec-ch-ua', 'sec-ch-ua-mobile', 'dnt', 'sec-fetch-user', 'sec-ch-ua-platform', 'sec-fetch-site', 'sec-fetch-mode', 'sec-fetch-dest']; // These are headers we do not forward
const blockedHeaders = ['cookie', 'upgrade-insecure-requests', 'sec-ch-ua', 'sec-ch-ua-mobile', 'dnt', 'sec-fetch-user', 'sec-ch-ua-platform', 'sec-fetch-site', 'sec-fetch-mode', 'sec-fetch-dest']; // These are headers we do not forward
for (var i in req.headers) { if (blockedHeaders.indexOf(i) == -1) { request += i + ': ' + req.headers[i] + '\r\n'; } }
var cookieStr = '';
for (var i in parent.webCookies) { if (cookieStr != '') { cookieStr += '; ' } cookieStr += (i + '=' + parent.webCookies[i].value); }
@ -331,7 +331,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
// Construct the HTTP request
var request = req.method + ' ' + req.url + ' HTTP/' + req.httpVersion + '\r\n';
const blockedHeaders = ['origin', 'cookie', 'sec-websocket-extensions']; // These are headers we do not forward
const blockedHeaders = ['cookie', 'sec-websocket-extensions']; // These are headers we do not forward
for (var i in req.headers) { if (blockedHeaders.indexOf(i) == -1) { request += i + ': ' + req.headers[i] + '\r\n'; } }
var cookieStr = '';
for (var i in parent.webCookies) { if (cookieStr != '') { cookieStr += '; ' } cookieStr += (i + '=' + parent.webCookies[i].value); }

View File

@ -1,27 +0,0 @@
# FAQ
## Help! I've been hacked there are weird agents appearing in my Tactical RMM
No, you haven't.
1. Your agent installer was scanned by an antivirus.
2. It didn't recognize the exe.
3. You have the option enabled to submit unknown applications for analysis.
![AV Option1](images/faq_av_option1.png)
4. They ran it against their virtualization testing cluster.
5. You allow anyone to connect to your rmm server (you should look into techniques to hide your server from the internet).
6. Here are some examples of what that looks like.
# Can't login on server after first setup
You're sure you're typing in everything right, giving it 2FA code and can't login
[TOTP](https://en.wikipedia.org/wiki/Time-based_one-time_password) is time sensitive, check your time/NTP and make sure it's right (on server and TOTP app device)! :)
![](images/2022-08-04-18-19-19.png)

View File

@ -9,7 +9,7 @@ npm install meshcentral
node node_modules/meshcentral
```
That's it. MeshCentral will set itself up and start managing computers on your local network. By default it will be setup in LAN mode and agents you install will multicast on the local network to find the server. To setup the server so that agents use a well known DNS name and to start customizing your server, go in the "meshcentral-data" folder and edit the config.json file. The configuration file must be valid JSON, you can use this link to validate the file format.
That's it. MeshCentral will set itself up and start managing computers on your local network. By default it will be setup in LAN mode and agents you install will multicast on the local network to find the server. To setup the server so that agents use a well known DNS name and to start customizing your server, go in the "meshcentral-data" folder and edit the config.json file. The configuration file must be valid JSON, you can use this [link](https://duckduckgo.com/?va=j&t=hc&q=json+lint&ia=answer) to validate the file format.
For Windows users, you can download the MeshCentral Installer that will automate installation of NodeJS and provide basic configuration of the server. This option is not recommended for advanced users.

View File

@ -0,0 +1,37 @@
# SSL/Letsencrypt
## MeshCentral supports SSL using self generated certs, your own certs or Letsencrypt
### Enabling letsencrypt
Make sure you match and/or adjust all the following settings appropriately in your config.json file:
```json
{
"settings": {
"redirPort"
"cert": "yourdomain.com"
},
"domains": {
"letsencrypt": {
"__comment__": "Requires NodeJS 8.x or better, Go to https://letsdebug.net/ first before trying Let's Encrypt.",
"email": "myemail@myserver.com",
"names": "myserver.com,customer1.myserver.com",
"skipChallengeVerification": false,
"production": true
},
}
}
```
If you need further clarification to know what each of these settings are, check out [the config schema](https://github.com/Ylianst/MeshCentral/blob/master/meshcentral-config-schema.json).
Then restart meshcentral and it will get a cert for you, the process will need to restart to apply the cert.
### Useful resources/troubleshooting
To check letsencrypt is working properly please use https://letsdebug.net/. We are using the [HTTP-O1 challenge](https://letsencrypt.org/docs/challenge-types/#http-01-challenge) method with these instructions.
Also make sure you have port 80 open and pointing to your meshcentral server, **IT WILL NOT WORK** if port 80 isn't open and it **HAS** to be port 80.
You can read more about Letsencrypt and meshcentral [here](https://ylianst.github.io/MeshCentral/meshcentral/#lets-encrypt-support).

View File

@ -25,6 +25,8 @@ xxx Path: `c:\Program Files\Mesh Agent\meshagent.msh`
## Linux / BSD
Uninstall: `sudo /usr/local/mesh_services/meshagent/[agent-name]/meshagent -fulluninstall`
## Apple macOS Binary Installer
Default Install Path: `/usr/local/mesh_services/meshagent/meshagent`
@ -38,6 +40,10 @@ launchctl stop meshagent
launchctl start meshagent
```
Install:
Uninstall: `sudo /usr/local/mesh_services/meshagent/[agent-name]/meshagent -fulluninstall`
## Apple macOS Universal
For OSx 11+ including Big Sur, Monterey and later

View File

@ -356,7 +356,7 @@ See description for information about each item.
"loginKey": { "type": [ "string", "array" ], "items": { "type": "string" }, "default": null, "description": "Requires that users add the value ?key=xxx in the URL in order to see the web site." },
"agentKey": { "type": [ "string", "array" ], "items": { "type": "string" }, "default": null, "description": "Requires that agents add the value ?key=xxx in the URL in order to connect. This is not automatic and needs to be manually added in the meshagent.msh file." },
"ipkvm": { "type": "boolean", "default": false, "description": "Set to true to enable IP KVM device support in this domain." },
"minify": { "type": "boolean", "default": false, "description": "When enabled, the server will send reduced sided web pages." },
"minify": { "type": "boolean", "default": false, "description": "When enabled, the server will send reduced sized web pages." },
"newAccounts": { "type": "boolean", "default": false, "description": "When set to true, allow new user accounts to be created from the login page." },
"newAccountsPass": { "type": "string", "default": null, "description": "When set this password will be required in order to create a new account from the login screen." },
"newAccountsCaptcha": { "type": "boolean", "default": false, "description": "When set to true, users will get a CAPTCHA when creating a new account from the login screen." },
@ -410,12 +410,12 @@ See description for information about each item.
"enum": [ "bat", "ps1", "sh", "agent" ]
},
"runas": {
"description": "How to run this script, does not appy to agent scripts.",
"description": "How to run this script, does not apply to agent scripts.",
"type": "string",
"enum": ["agent", "userfirst", "user"]
},
"cmd": {
"description": "The command or \\r\\n seperated commands to run, if set do not use the file key.",
"description": "The command or \\r\\n separated commands to run, if set do not use the file key.",
"type": "string"
},
"file": {
@ -562,13 +562,13 @@ See description for information about each item.
"ldapSyncWithUserGroups": {
"type": [ "boolean", "object" ],
"default": false,
"description": "When set to true or set to an object, MeshCentral will syncronized LDAP user memberships to MeshCentral user groups.",
"description": "When set to true or set to an object, MeshCentral will synchronize LDAP user memberships to MeshCentral user groups.",
"additionalProperties": false,
"properties": {
"filter": {
"type": [ "string", "array" ],
"default": null,
"description": "When set to a string or array of strings, only LDAP membership groups that includes one of the strings will be syncronized with MeshCentral user groups."
"description": "When set to a string or array of strings, only LDAP membership groups that includes one of the strings will be synchronized with MeshCentral user groups."
}
}
},

View File

@ -0,0 +1,50 @@
# FAQ
## json config files
Any item in the config.json file starting with an underscore character are ignored.
Ignored
```json
"_title": "MyServer"
```
Valid setting
```json
"title": "MyServer"
```
json requires correct formatting, if in doubt copy/paste your json config into a web based format checker to make sure you have it right: <https://duckduckgo.com/?va=j&t=hc&q=json+lint&ia=answer>
## Help! I've been hacked there are weird agents appearing in my MeshCentral Console
No, you haven't.
1. Your agent installer was scanned by an antivirus.
2. It didn't recognize the exe.
3. You have the option enabled to submit unknown applications for analysis.
![AV Option1](images/faq_av_option1.png)
4. They ran it against their virtualization testing cluster.
5. You allow anyone to connect to your server (you should look into techniques to hide your server from the internet).
6. Here are some examples of what that looks like.
# Can't login on server after first setup
You're sure you're typing in everything right, giving it 2FA code and can't login
[TOTP](https://en.wikipedia.org/wiki/Time-based_one-time_password) is time sensitive, check your time/NTP and make sure it's right (on server and TOTP app device)! :)
![](images/2022-08-04-18-19-19.png)
# Branding and Customisation
You can brand and customise MeshCentral almost as much as you like without delving into the code, a few changes in the config.json file and uplaoding images can change the way your system looks. Read more [here](https://ylianst.github.io/MeshCentral/meshcentral/#branding-terms-of-use)

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -1201,7 +1201,11 @@ And taking authentication to the next step is removing the login page entirely.
## Branding & Terms of use
Once MeshCentral is setup, you may want to customize the web site with your own brand and terms of use. This is important to personalize the web site to your organization. We also want to customize the web site in such a way that updating to the latest version will keep the branding as-is.
Whitelabeling your MeshCentral installation to personalize it to your companies brand, as well as having your own terms of use is one of the first things many people do after installation.
<div class="video-wrapper">
<iframe width="320" height="180" src="https://www.youtube.com/embed/xUZ1w9RSKpQ" frameborder="0" allowfullscreen></iframe>
</div>
### Branding
@ -1209,7 +1213,7 @@ You can put you own logo on the top of the web page. To get started, get the fil
![](images/2022-05-19-00-38-51.png)
Once done, edit the config.json file and set the following values:
Once done, edit the config.json file and set one or all of the following values:
```json
"domains": {
@ -1217,6 +1221,16 @@ Once done, edit the config.json file and set the following values:
"Title": "",
"Title2": "",
"TitlePicture": "title-sample.png",
"loginPicture": "logintitle-sample.png",
"welcomeText": "This is sample text",
"welcomePicture": "mainwelcome-04.jpg",
"welcomePictureFullScreen": true,
"siteStyle": "1",
"nightMode": "1",
"meshMessengerTitle": "Mesh Chat",
"meshMessengerPicture": "chatimage.png",
"footer": "This is a HTML string displayed at the bottom of the web page when a user is logged in.",
"loginfooter": "This is a HTML string displayed at the bottom of the web page when a user is not logged in."
},
```
@ -1240,6 +1254,8 @@ This is great to personalize the look of the server within the web site.
### Agent Branding
You can also customize the Agent to add your own logo.
![](images/2022-08-24-06-42-40.png)
### Terms of use

View File

@ -1,3 +1,8 @@
/* Maximum space for text block */
.md-grid {
max-width: 95%; /* or 100%, if you want to stretch to full-width */
}
.md-header {
background-color: #0b3e81 !important;
color: white !important;

View File

@ -15,8 +15,11 @@ nav:
- 'Debugging': 'meshcentral/debugging.md'
- 'Device Tabs': 'meshcentral/devicetabs.md'
- 'Plugins': 'meshcentral/plugins.md'
- 'SSL': 'meshcentral/SSLnletsencrypt.md'
- 'Security': 'meshcentral/security.md'
- 'Tokens': 'meshcentral/tokens.md'
- 'FAQ': 'meshcentral/faq.md'
- 'Tips n Tricks': 'meshcentral/tipsntricks.md'
- Design and Architecture:
- design/index.md

View File

@ -349,7 +349,7 @@
"loginKey": { "type": [ "string", "array" ], "items": { "type": "string" }, "default": null, "description": "Requires that users add the value ?key=xxx in the URL in order to see the web site." },
"agentKey": { "type": [ "string", "array" ], "items": { "type": "string" }, "default": null, "description": "Requires that agents add the value ?key=xxx in the URL in order to connect. This is not automatic and needs to be manually added in the meshagent.msh file." },
"ipkvm": { "type": "boolean", "default": false, "description": "Set to true to enable IP KVM device support in this domain." },
"minify": { "type": "boolean", "default": false, "description": "When enabled, the server will send reduced sided web pages." },
"minify": { "type": "boolean", "default": false, "description": "When enabled, the server will send reduced sized web pages." },
"newAccounts": { "type": "boolean", "default": false, "description": "When set to true, allow new user accounts to be created from the login page." },
"newAccountsPass": { "type": "string", "default": null, "description": "When set this password will be required in order to create a new account from the login screen." },
"newAccountsCaptcha": { "type": "boolean", "default": false, "description": "When set to true, users will get a CAPTCHA when creating a new account from the login screen." },
@ -403,12 +403,12 @@
"enum": [ "bat", "ps1", "sh", "agent" ]
},
"runas": {
"description": "How to run this script, does not appy to agent scripts.",
"description": "How to run this script, does not apply to agent scripts.",
"type": "string",
"enum": ["agent", "userfirst", "user"]
},
"cmd": {
"description": "The command or \\r\\n seperated commands to run, if set do not use the file key.",
"description": "The command or \\r\\n separated commands to run, if set do not use the file key.",
"type": "string"
},
"file": {
@ -555,13 +555,13 @@
"ldapSyncWithUserGroups": {
"type": [ "boolean", "object" ],
"default": false,
"description": "When set to true or set to an object, MeshCentral will syncronized LDAP user memberships to MeshCentral user groups.",
"description": "When set to true or set to an object, MeshCentral will synchronize LDAP user memberships to MeshCentral user groups.",
"additionalProperties": false,
"properties": {
"filter": {
"type": [ "string", "array" ],
"default": null,
"description": "When set to a string or array of strings, only LDAP membership groups that includes one of the strings will be syncronized with MeshCentral user groups."
"description": "When set to a string or array of strings, only LDAP membership groups that includes one of the strings will be synchronized with MeshCentral user groups."
}
}
},

View File

@ -1420,7 +1420,7 @@ function CreateMeshCentralServer(config, args) {
if (obj.args.mpsaliasport != null && (typeof obj.args.mpsaliasport != 'number')) obj.args.mpsaliasport = null;
if (obj.args.rediraliasport != null && (typeof obj.args.rediraliasport != 'number')) obj.args.rediraliasport = null;
if (obj.args.redirport == null) obj.args.redirport = 80;
if (obj.args.minifycore === 0) obj.args.minifycore = false;
if (obj.args.minifycore == null) obj.args.minifycore = false;
if (typeof args.agentidletimeout != 'number') { args.agentidletimeout = 150000; } else { args.agentidletimeout *= 1000 } // Default agent idle timeout is 2m, 30sec.
if ((obj.args.lanonly != true) && (obj.args.webrtconfig == null)) { obj.args.webrtconfig = { iceservers: [{ urls: 'stun:stun.l.google.com:19302' }, { urls: 'stun:stun.services.mozilla.com' }] }; } // Setup default WebRTC STUN servers
if (typeof obj.args.ignoreagenthashcheck == 'string') { if (obj.args.ignoreagenthashcheck == '') { delete obj.args.ignoreagenthashcheck; } else { obj.args.ignoreagenthashcheck = obj.args.ignoreagenthashcheck.split(','); } }

View File

@ -579,6 +579,7 @@ if (args['_'].length == 0) {
console.log("\r\nOptional arguments:\r\n");
console.log(" --desc [description] - New group description.");
console.log(" --amtonly - New group is agent-less, Intel AMT only.");
console.log(" --agentless - New group is agent-less only.");
console.log(" --features [number] - Set device group features, sum of numbers below.");
console.log(" 1 = Auto-Remove 2 = Hostname Sync");
console.log(" 4 = Record Sessions");
@ -1356,6 +1357,7 @@ function serverConnect() {
var op = { action: 'createmesh', meshname: args.name, meshtype: 2, responseid: 'meshctrl' };
if (args.desc) { op.desc = args.desc; }
if (args.amtonly) { op.meshtype = 1; }
if (args.agentless) { op.meshtype = 3; }
if (args.features) { op.flags = parseInt(args.features); }
if (args.consent) { op.consent = parseInt(args.consent); }
ws.send(JSON.stringify(op));

View File

@ -494,6 +494,8 @@
{
"bs": "“ zatražio pomoć.",
"en": "\" requested help.",
"nl": "\" vraagt om hulp.",
"pl": "\" prosi o pomoc.",
"xloc": [
"device-help.html->2->3"
]
@ -5939,6 +5941,7 @@
"bs": "Zapisi tokena za prijavu na račun",
"en": "Account login token records",
"nl": "Token vermeldingen voor accountaanmelding",
"pl": "Zapisy logowania tokenami użytkownika",
"xloc": [
"default.handlebars->47->2918"
]
@ -9639,6 +9642,7 @@
"bs": "Došlo je do nepoznate greške.",
"en": "An unknown error occured.",
"nl": "Er is een onbekende fout opgetreden.",
"pl": "Wystąpił nieznany błąd.",
"xloc": [
"default.handlebars->47->2798"
]
@ -15761,6 +15765,7 @@
"bs": "Naredbe iz datoteke",
"en": "Commands from file",
"nl": "Opdrachten uit bestand",
"pl": "Komendy z pliku",
"xloc": [
"default.handlebars->47->730"
]
@ -15769,6 +15774,7 @@
"bs": "Komande iz datoteke na serveru",
"en": "Commands from file on server",
"nl": "Opdrachten uit een bestand op de server",
"pl": "Komendy z pliku na serwerze",
"xloc": [
"default.handlebars->47->731"
]
@ -15777,6 +15783,7 @@
"bs": "Naredbe iz okvira za tekst",
"en": "Commands from text box",
"nl": "Opdrachten uit tekstvak",
"pl": "Komendy z okienka tekstowego",
"xloc": [
"default.handlebars->47->729"
]
@ -15939,6 +15946,7 @@
"bs": "Zapisi konfiguracionih datoteka",
"en": "Configuration file records",
"nl": "Configuratiebestand vermeldingen",
"pl": "Zapisy pliku konfiguracyjnego",
"xloc": [
"default.handlebars->47->2911"
]
@ -19523,6 +19531,7 @@
"bs": "Zapisi baze podataka",
"en": "Database Records",
"nl": "Database vermeldingen",
"pl": "Zapisy Bazy Danych",
"xloc": [
"default.handlebars->47->2837"
]
@ -20402,6 +20411,8 @@
{
"bs": "Odbijena prijava korisnika sa {0}, {1}, {2}",
"en": "Denied user login from {0}, {1}, {2}",
"nl": "Geweigerde gebruikerslogin van {0}, {1}, {2}",
"pl": "Odmówiono zalogowania użytkownika z {0}, {1}, {2}",
"xloc": [
"default.handlebars->47->2406"
]
@ -21210,6 +21221,8 @@
{
"bs": "uređaj \"",
"en": "Device \"",
"nl": "Apparaat \"",
"pl": "Urządzenie \"",
"xloc": [
"device-help.html->2->3"
]
@ -21217,6 +21230,8 @@
{
"bs": "Uređaj \"[[[DEVICENAME]]]\" je zatražio pomoć.",
"en": "Device \"[[[DEVICENAME]]]\" requested assistance.",
"nl": "Apparaat \"[[[DEVICENAME]]]\" heeft assistentie gevraagd",
"pl": "Urządzenie \"[[[DEVICENAME]]]\" prosiło o pomoc.",
"xloc": [
"device-help.txt"
]
@ -21643,6 +21658,7 @@
"bs": "Zapis push obavijesti uređaja",
"en": "Device Push Notification Record",
"nl": "Apparaat Push Notificatie vermelding",
"pl": "Zapis Powiadomień Push Urządzenia",
"xloc": [
"default.handlebars->47->2920"
]
@ -21651,6 +21667,7 @@
"bs": "SMBIOS zapis uređaja",
"en": "Device SMBIOS record",
"nl": "Apparaat SMBIOS vermelding",
"pl": "Zapis SMBIOS urządzenia",
"xloc": [
"default.handlebars->47->2919"
]
@ -22029,6 +22046,7 @@
"bs": "Zapis grupe uređaja",
"en": "Device group record",
"nl": "Apparaatgroep vermelding",
"pl": "Zapis grupy urządzeń",
"xloc": [
"default.handlebars->47->2905"
]
@ -22115,6 +22133,7 @@
"bs": "Zapisi informacija o uređaju",
"en": "Device information records",
"nl": "Apparaatinformatie vermeldingen",
"pl": "Zapisy informacji urządzenia",
"xloc": [
"default.handlebars->47->2907"
]
@ -22657,6 +22676,7 @@
"bs": "Zapisi o prelasku napajanja uređaja",
"en": "Device power transition records",
"nl": "Apparaat aan/uit vermeldingen",
"pl": "Zapisy zmiany stanu zasilania",
"xloc": [
"default.handlebars->47->2913"
]
@ -22665,6 +22685,7 @@
"bs": "Zapis uređaja",
"en": "Device record",
"nl": "Apparaat vermelding",
"pl": "Zapis urządzenia",
"xloc": [
"default.handlebars->47->2904"
]
@ -22725,6 +22746,7 @@
"bs": "Zapisi o dijeljenju uređaja",
"en": "Device sharing records",
"nl": "Apparaten delings vermeldingen",
"pl": "Zapisy udostępniania urządzenia",
"xloc": [
"default.handlebars->47->2917"
]
@ -22733,6 +22755,7 @@
"bs": "Uređaj, korisnici, grupe i drugi zapisi",
"en": "Device, users, groups and other records",
"nl": "Apparaat, gebruikers, groepen en andere vermeldingen",
"pl": "Zapisy urządzenia, użytkowników, grup i inne",
"xloc": [
"default.handlebars->47->2921"
]
@ -25980,6 +26003,8 @@
{
"bs": "Pošaljite zahtjev za pomoć e-poštom",
"en": "Email Help Request",
"nl": "E-mail hulpverzoek",
"pl": "Prośba Pomocy Email",
"xloc": [
"default.handlebars->47->1939",
"default.handlebars->47->889"
@ -28036,6 +28061,7 @@
"bs": "Evidencija događaja",
"en": "Event records",
"nl": "Gebeurtenis vermeldingen",
"pl": "Zapisy zdarzeń",
"xloc": [
"default.handlebars->47->2914"
]
@ -31158,6 +31184,8 @@
{
"bs": "Idi na prvu stranicu",
"en": "Go to first page",
"nl": "Ga naar de eerste pagina",
"pl": "Idź do pierwszej strony",
"xloc": [
"default.handlebars->container->column_l->p1->p1title->devListToolbarViewIcons"
]
@ -31165,6 +31193,8 @@
{
"bs": "Idi na posljednju stranicu",
"en": "Go to last page",
"nl": "Ga naar de laatste pagina ",
"pl": "Idź do ostatniej strony",
"xloc": [
"default.handlebars->container->column_l->p1->p1title->devListToolbarViewIcons"
]
@ -31226,6 +31256,8 @@
{
"bs": "Idi na sljedeću stranicu",
"en": "Go to next page",
"nl": "Ga naar de volgende pagina",
"pl": "Idź do następnej strony",
"xloc": [
"default.handlebars->container->column_l->p1->p1title->devListToolbarViewIcons"
]
@ -31233,6 +31265,8 @@
{
"bs": "Idi na prethodnu stranicu",
"en": "Go to previous page",
"nl": "Ga naar de vorige pagina",
"pl": "Idź do poprzedniej strony",
"xloc": [
"default.handlebars->container->column_l->p1->p1title->devListToolbarViewIcons"
]
@ -31620,6 +31654,8 @@
{
"bs": "Tip grupe",
"en": "Group Type",
"nl": "Groepstype",
"pl": "Typ Grupy",
"xloc": [
"default.handlebars->47->2576"
]
@ -32022,6 +32058,23 @@
{
"bs": "HTTP/",
"en": "HTTP/",
"nl": "HTTP/",
"cs": "HTTP/",
"es": "HTTP/",
"de": "HTTP/",
"da": "HTTP/",
"fi": "HTTP/",
"fr": "HTTP/",
"hi": "HTTP/",
"it": "HTTP/",
"ja": "HTTP/",
"ko": "HTTP/",
"pt": "HTTP/",
"pt-br": "HTTP/",
"pl": "HTTP/",
"sv": "HTTP/",
"ru": "HTTP/",
"tr": "HTTP/",
"xloc": [
"default.handlebars->47->1004",
"default.handlebars->47->1981"
@ -32030,6 +32083,8 @@
{
"bs": "HTTP/{0} link",
"en": "HTTP/{0} link",
"nl": "HTTP/{0} link",
"pl": "HTTP/{0} link",
"xloc": [
"default.handlebars->47->298"
]
@ -32116,6 +32171,23 @@
{
"bs": "HTTPS/",
"en": "HTTPS/",
"nl": "HTTPS/",
"cs": "HTTPS/",
"es": "HTTPS/",
"de": "HTTPS/",
"da": "HTTPS/",
"fi": "HTTPS/",
"fr": "HTTPS/",
"hi": "HTTPS/",
"it": "HTTPS/",
"ja": "HTTPS/",
"ko": "HTTPS/",
"pt": "HTTPS/",
"pt-br": "HTTPS/",
"sv": "HTTPS/",
"ru": "HTTPS/",
"tr": "HTTPS/",
"pl": "HTTPS/",
"xloc": [
"default.handlebars->47->1005",
"default.handlebars->47->1982"
@ -32124,6 +32196,23 @@
{
"bs": "HTTPS/{0}",
"en": "HTTPS/{0}",
"nl": "HTTPS/{0}",
"pl": "HTTPS/{0}",
"cs": "HTTPS/{0}",
"es": "HTTPS/{0}",
"de": "HTTPS/{0}",
"da": "HTTPS/{0}",
"fi": "HTTPS/{0}",
"fr": "HTTPS/{0}",
"hi": "HTTPS/{0}",
"it": "HTTPS/{0}",
"ja": "HTTPS/{0}",
"ko": "HTTPS/{0}",
"pt": "HTTPS/{0}",
"pt-br": "HTTPS/{0}",
"sv": "HTTPS/{0}",
"ru": "HTTPS/{0}",
"tr": "HTTPS/{0}",
"xloc": [
"default.handlebars->47->299"
]
@ -32524,6 +32613,8 @@
{
"bs": "Zahtjevi za pomoć",
"en": "Help requests",
"nl": "Hulpverzoeken",
"pl": "Prośby pomocy",
"xloc": [
"default.handlebars->47->1027",
"default.handlebars->47->2179"
@ -33126,6 +33217,7 @@
"bs": "Zapisi informacija o IP lokaciji",
"en": "IP location information records",
"nl": "IP locatiegegevens vermeldingen",
"pl": "Zapisy o informacji lokalizacji IP",
"xloc": [
"default.handlebars->47->2908"
]
@ -35244,6 +35336,8 @@
{
"bs": "Intel&reg; AMT Uključite BIOS",
"en": "Intel&reg; AMT Power on to BIOS",
"nl": "Intel&reg; AMT opstarten naar de BIOS",
"pl": "Intel&reg; AMT Uruchom do BIOS",
"xloc": [
"default.handlebars->47->1145"
]
@ -35306,6 +35400,8 @@
{
"bs": "Intel&reg; AMT Resetujte BIOS",
"en": "Intel&reg; AMT Reset to BIOS",
"nl": "Intel&reg; AMT reset naar de BIOS",
"pl": "Intel&reg; AMT Resetuj do BIOS",
"xloc": [
"default.handlebars->47->1144"
]
@ -38838,6 +38934,7 @@
"bs": "Zabilježeno vrijeme posljednje veze",
"en": "Last connection time records",
"nl": "Laatste verbindingstijd vermeldingen",
"pl": "Zapisy czasu ostatnich połączeń",
"xloc": [
"default.handlebars->47->2912"
]
@ -45805,6 +45902,7 @@
"bs": "Zapisi informacija o mrežnom interfejsu",
"en": "Network interface information records",
"nl": "Netwerkinterface informatie vermeldingen",
"pl": "Zapisy informacji o interfejsach sieciowych",
"xloc": [
"default.handlebars->47->2910"
]
@ -51426,6 +51524,8 @@
{
"bs": "Uključite Intel&reg; AMT napajanje u BIOS?",
"en": "Perform Intel&reg; AMT power on to BIOS?",
"nl": "Perform Intel&reg; AMT opstarten naar de BIOS?",
"pl": "Czy wykonać Intel&reg; AMT uruchomienie do BIOS?",
"xloc": [
"default.handlebars->47->1168"
]
@ -51460,6 +51560,8 @@
{
"bs": "Izvršiti Intel&reg; AMT resetovanje na BIOS?",
"en": "Perform Intel&reg; AMT reset to BIOS?",
"nl": "Perform Intel&reg; AMT resetten naar de BIOS?",
"pl": "Czy wykonać Intel&reg; AMT resetowanie do BIOS?",
"xloc": [
"default.handlebars->47->1170"
]
@ -52321,6 +52423,8 @@
{
"bs": "Port",
"en": "Port",
"nl": "Poort",
"pl": "Port",
"xloc": [
"default.handlebars->47->1126",
"default.handlebars->47->1127"
@ -57733,6 +57837,8 @@
{
"bs": "Zahtjev:",
"en": "Request:",
"nl": "Verzoek:",
"pl": "Prośba:",
"xloc": [
"device-help.html->2->5"
]
@ -57740,6 +57846,8 @@
{
"bs": "Zahtjev: \"[[[UPIT ZA POMOĆ]]]\"",
"en": "Request: \"[[[HELPREQUEST]]]\"",
"nl": "Verzoek: \"[[[HELPREQUEST]]]\"",
"pl": "Prośba: \"[[[HELPREQUEST]]]\"",
"xloc": [
"device-help.txt"
]
@ -58650,6 +58758,7 @@
"bs": "Trči",
"en": "Run",
"nl": "Uitvoeren",
"pl": "Wykonaj",
"xloc": [
"default.handlebars->47->924"
]
@ -58712,6 +58821,7 @@
"bs": "Pokrenite skriptu na ovom računaru",
"en": "Run a script on this computer",
"nl": "Voer een script uit op deze computer",
"pl": "Wykonaj skrypt na tym komputerze",
"xloc": [
"default.handlebars->container->column_l->p11->deskarea0->deskarea4->1"
]
@ -62381,6 +62491,7 @@
"bs": "Server ne može preuzeti snimke iz baze podataka.",
"en": "Server is unable to get recordings from the database.",
"nl": "Server kan geen opnamen uit de database halen.",
"pl": "Serwer nie może pobrać zapisów z bazy danych.",
"xloc": [
"default.handlebars->47->2797"
]
@ -62389,6 +62500,7 @@
"bs": "Server ne može čitati iz foldera sa snimcima.",
"en": "Server is unable to read from the recordings folder.",
"nl": "Server kan niet lezen uit de opnamemap.",
"pl": "Serwer nie może odczytać zapisów z folderu.",
"xloc": [
"default.handlebars->47->2796"
]
@ -62397,6 +62509,7 @@
"bs": "Statistički zapisi servera",
"en": "Server statistics records",
"nl": "Server statistieken vermeldingen",
"pl": "Zapisy statystyk serwera",
"xloc": [
"default.handlebars->47->2915"
]
@ -68186,6 +68299,7 @@
"bs": "Zapisi tekstualnih bilješki",
"en": "Text notes records",
"nl": "Tekst notities vermeldingen",
"pl": "Zapisy notatek tekstowych",
"xloc": [
"default.handlebars->47->2909"
]
@ -68580,6 +68694,8 @@
{
"bs": "Ova verzija NodeJS-a ne podržava OpenID.",
"en": "This NodeJS version does not support OpenID.",
"nl": "Deze NodeJS-versie ondersteunt OpenID niet.",
"pl": "Obecna wersja NodeJS nie wspiera OpenID.",
"xloc": [
"default.handlebars->47->107"
]
@ -71483,6 +71599,7 @@
"bs": "Nije moguće učitati fajl ikone agenta: {0}.",
"en": "Unable to load agent icon file: {0}.",
"nl": "Kan agent pictogram bestand niet laden: {0}.",
"pl": "Nie moge załadować pliku ikony agenta: {0}.",
"xloc": [
"default.handlebars->47->105"
]
@ -71491,6 +71608,7 @@
"bs": "Nije moguće učitati fajl logotipa agenta: {0}.",
"en": "Unable to load agent logo file: {0}.",
"nl": "Kan agent logo bestand niet laden: {0}.",
"pl": "Nie moge załadować pliku logo agenta: {0}.",
"xloc": [
"default.handlebars->47->106"
]
@ -73211,6 +73329,8 @@
{
"bs": "Dnevnik provjere autentičnosti korisnika",
"en": "User Authentication Log",
"nl": "Gebruikersauthenticatielogboek",
"pl": "Dziennik Autentykacji Użytkownika",
"xloc": [
"default.handlebars->47->3053"
]
@ -73939,6 +74059,7 @@
"bs": "Zapisi grupe korisnika",
"en": "User group records",
"nl": "Gebruikersgroep vermeldingen",
"pl": "Zapisy grupy użytkownika",
"xloc": [
"default.handlebars->47->2916"
]
@ -74056,6 +74177,7 @@
"bs": "Korisnički zapisi",
"en": "User records",
"nl": "Gebruikers vermeldingen",
"pl": "Zapisy użytkownika",
"xloc": [
"default.handlebars->47->2906"
]
@ -74090,6 +74212,8 @@
{
"bs": "Korisnik:",
"en": "User:",
"nl": "Gebruiker:",
"pl": "Użytkownik:",
"xloc": [
"device-help.html->2->5"
]
@ -74097,6 +74221,8 @@
{
"bs": "Korisnik: \"[[[IME POMOĆI]]]\"",
"en": "User: \"[[[HELPUSERNAME]]]\"",
"nl": "Gebruiker: \"[[[HELPUSERNAME]]]\"",
"pl": "Użytkownik: \"[[[HELPUSERNAME]]]\"",
"xloc": [
"device-help.txt"
]
@ -77959,6 +78085,8 @@
{
"bs": "[[[NAZIV UREĐAJA]]]",
"en": "[[[DEVICENAME]]]",
"nl": "[[[DEVICENAME]]]",
"pl": "[[[DEVICENAME]]]",
"xloc": [
"device-help.html->2->3->1"
]
@ -77992,6 +78120,22 @@
{
"bs": "[[[UPIT ZA POMOĆ]]]",
"en": "[[[HELPREQUEST]]]",
"nl": "[[[HELPREQUEST]]]",
"pl": "[[[HELPREQUEST]]]",
"cs": "[[[HELPREQUEST]]]",
"de": "[[[HELPREQUEST]]]",
"es": "[[[HELPREQUEST]]]",
"fi": "[[[HELPREQUEST]]]",
"it": "[[[HELPREQUEST]]]",
"hi": "[[[HELPREQUEST]]]",
"fr": "[[[HELPREQUEST]]]",
"ja": "[[[HELPREQUEST]]]",
"ko": "[[[HELPREQUEST]]]",
"pt": "[[[HELPREQUEST]]]",
"pt-br": "[[[HELPREQUEST]]]",
"ru": "[[[HELPREQUEST]]]",
"sv": "[[[HELPREQUEST]]]",
"tr": "[[[HELPREQUEST]]]",
"xloc": [
"device-help.html->2->5->4"
]
@ -77999,6 +78143,22 @@
{
"bs": "[[[IME POMOĆI]]]",
"en": "[[[HELPUSERNAME]]]",
"nl": "[[[HELPUSERNAME]]]",
"pl": "[[[HELPUSERNAME]]]",
"cs": "[[[HELPUSERNAME]]]",
"de": "[[[HELPUSERNAME]]]",
"es": "[[[HELPUSERNAME]]]",
"fi": "[[[HELPUSERNAME]]]",
"it": "[[[HELPUSERNAME]]]",
"hi": "[[[HELPUSERNAME]]]",
"fr": "[[[HELPUSERNAME]]]",
"ja": "[[[HELPUSERNAME]]]",
"ko": "[[[HELPUSERNAME]]]",
"pt": "[[[HELPUSERNAME]]]",
"pt-br": "[[[HELPUSERNAME]]]",
"ru": "[[[HELPUSERNAME]]]",
"sv": "[[[HELPUSERNAME]]]",
"tr": "[[[HELPUSERNAME]]]",
"xloc": [
"device-help.html->2->5->1"
]
@ -78034,6 +78194,8 @@
{
"bs": "[[[SERVERNAME]]] - \"[[[DEVICENAME]]]\" Zahtjev za pomoć",
"en": "[[[SERVERNAME]]] - \"[[[DEVICENAME]]]\" Help Request",
"nl": "[[[SERVERNAME]]] - \"[[[DEVICENAME]]]\" Verzoek om hulp",
"pl": "[[[SERVERNAME]]] - \"[[[DEVICENAME]]]\" Prośba Pomocy",
"xloc": [
"device-help.html->0"
]
@ -78150,6 +78312,8 @@
{
"bs": "[[[SERVERNAME]]] - Zahtjev za pomoć uređaja",
"en": "[[[SERVERNAME]]] - Device Help Request",
"nl": "[[[SERVERNAME]]] - Een verzoek om het apparaat te helpen",
"pl": "[[[SERVERNAME]]] - Prośba Pomocy Urządzenia",
"xloc": [
"device-help.txt"
]
@ -78212,6 +78376,8 @@
{
"bs": "[[[SERVERNAME]]] - Zahtjev za pomoć",
"en": "[[[SERVERNAME]]] - Help Request",
"nl": "[[[SERVERNAME]]] - Verzoek om hulp",
"pl": "[[[SERVERNAME]]] - Prośba Pomocy",
"xloc": [
"device-help.html->2->1->1->0->1->1"
]
@ -78273,6 +78439,8 @@
{
"bs": "[[[SERVERURL]]]?viewmode=10&gotonode=[[[NODEID]]]",
"en": "[[[SERVERURL]]]?viewmode=10&gotonode=[[[NODEID]]]",
"nl": "[[[SERVERURL]]]?viewmode=10&gotonode=[[[NODEID]]]",
"pl": "[[[SERVERURL]]]?viewmode=10&gotonode=[[[NODEID]]]",
"xloc": [
"device-help.txt"
]
@ -80581,6 +80749,8 @@
{
"bs": "za navigaciju do ovog uređaja.",
"en": "to navigate to this device.",
"nl": "naar dit apparaat navigeren.",
"pl": "by nawigować do tego urządzenia.",
"xloc": [
"device-help.html->2->7"
]