mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-15 15:53:55 +00:00
Major agent update.
This commit is contained in:
@@ -132,21 +132,13 @@ typedef struct MeshCommand_BinaryPacket_AuthVerify
|
||||
}MeshCommand_BinaryPacket_AuthVerify;
|
||||
typedef enum MeshCommand_AuthInfo_PlatformType
|
||||
{
|
||||
MeshCommand_AuthInfo_PlatformType_DESKTOP = 1,
|
||||
MeshCommand_AuthInfo_PlatformType_LAPTOP = 2,
|
||||
MeshCommand_AuthInfo_PlatformType_MOBILE = 3,
|
||||
MeshCommand_AuthInfo_PlatformType_SERVER = 4,
|
||||
MeshCommand_AuthInfo_PlatformType_DISK = 5,
|
||||
MeshCommand_AuthInfo_PlatformType_ROUTER = 6
|
||||
MeshCommand_AuthInfo_PlatformType_DESKTOP = 1,
|
||||
MeshCommand_AuthInfo_PlatformType_LAPTOP = 2,
|
||||
MeshCommand_AuthInfo_PlatformType_MOBILE = 3,
|
||||
MeshCommand_AuthInfo_PlatformType_SERVER = 4,
|
||||
MeshCommand_AuthInfo_PlatformType_DISK = 5,
|
||||
MeshCommand_AuthInfo_PlatformType_ROUTER = 6
|
||||
}MeshCommand_BinaryPacket_AuthInfo_PlatformType;
|
||||
typedef enum MeshCommand_AuthInfo_CapabilitiesMask
|
||||
{
|
||||
MeshCommand_AuthInfo_CapabilitiesMask_DESKTOP = 0x01,
|
||||
MeshCommand_AuthInfo_CapabilitiesMask_TERMINAL = 0x02,
|
||||
MeshCommand_AuthInfo_CapabilitiesMask_FILES = 0x04,
|
||||
MeshCommand_AuthInfo_CapabilitiesMask_CONSOLE = 0x08,
|
||||
MeshCommand_AuthInfo_CapabilitiesMask_JAVASCRIPT= 0x10
|
||||
}MeshCommand_AuthInfo_CapabilitiesMask;
|
||||
typedef struct MeshCommand_BinaryPacket_AuthInfo
|
||||
{
|
||||
unsigned short command;
|
||||
@@ -870,11 +862,17 @@ duk_ret_t ILibDuktape_MeshAgent_ServerUrl(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_MeshAgent_isControlChannelConnected(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [agent]
|
||||
duk_get_prop_string(ctx, -1, MESH_AGENT_PTR); // [agent][ptr]
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)duk_get_pointer(ctx, -1);
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)Duktape_GetPointerProperty(ctx, -1, MESH_AGENT_PTR);
|
||||
|
||||
duk_push_boolean(ctx, agent->serverAuthState == 3 ? 1 : 0);
|
||||
return(1);
|
||||
if (agent != NULL)
|
||||
{
|
||||
duk_push_boolean(ctx, agent->serverAuthState == 3 ? 1 : 0);
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_MeshAgent_eval(duk_context *ctx)
|
||||
{
|
||||
@@ -902,7 +900,7 @@ void ILibDuktape_MeshAgent_dumpCoreModuleEx(void *chain, void *user)
|
||||
CoreModule = (char*)ILibMemory_Allocate(CoreModuleLen, 0, NULL, NULL);
|
||||
ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", CoreModule, CoreModuleLen);
|
||||
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScript(agentHost->meshCoreCtx, CoreModule + 4, CoreModuleLen - 4) != 0 ||
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScriptEx(agentHost->meshCoreCtx, CoreModule + 4, CoreModuleLen - 4, "CoreModule.js", 13) != 0 ||
|
||||
ILibDuktape_ScriptContainer_ExecuteByteCode(agentHost->meshCoreCtx) != 0)
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agentHost->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint,
|
||||
@@ -923,6 +921,7 @@ duk_ret_t ILibDuktape_MeshAgent_dumpCoreModule(duk_context *ctx)
|
||||
ILibChain_RunOnMicrostackThreadEx(agent->chain, ILibDuktape_MeshAgent_dumpCoreModuleEx, agent);
|
||||
return(0);
|
||||
}
|
||||
|
||||
void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
MeshAgentHostContainer *agent;
|
||||
@@ -967,6 +966,7 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Ready");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Connected");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Command");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "DesktopSessionChanged");
|
||||
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "isControlChannelConnected", ILibDuktape_MeshAgent_isControlChannelConnected);
|
||||
ILibDuktape_EventEmitter_AddHook(emitter, "Ready", ILibDuktape_MeshAgent_Ready);
|
||||
@@ -994,6 +994,8 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
||||
}
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "GenerateCertificate", ILibDuktape_MeshAgent_GenerateCertificate, 1);
|
||||
duk_push_pointer(ctx, agent->masterDb); duk_put_prop_string(ctx, -2, "\xFF_MasterDB");
|
||||
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_1, "Acquired MeshAgent");
|
||||
}
|
||||
void ILibDuktape_MeshAgent_Init(duk_context* ctx, void *chain, MeshAgentHostContainer *agent)
|
||||
@@ -1021,7 +1023,7 @@ char* MeshAgent_MakeAbsolutePath(char *basePath, char *localPath)
|
||||
{
|
||||
// Use Same executable Name, but different extension
|
||||
sz = (int)basePathLen;
|
||||
if (ntohl(((unsigned int*)(basePath + sz - 4))[0]) == EXE_IDENTIFIER)
|
||||
if (sz>=4 && ntohl(((unsigned int*)(basePath + sz - 4))[0]) == EXE_IDENTIFIER)
|
||||
{
|
||||
// BasePath ends with .exe
|
||||
memcpy_s(ILibScratchPad2, sizeof(ILibScratchPad2), basePath, sz - 4);
|
||||
@@ -1257,7 +1259,7 @@ char* ScriptEngine_Restart(MeshAgentHostContainer *agent, char *contextGUID, cha
|
||||
|
||||
if (ctx != NULL)
|
||||
{
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScript(ctx, buffer, bufferLen) != 0 || ILibDuktape_ScriptContainer_ExecuteByteCode(ctx) != 0)
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScriptEx(ctx, buffer, bufferLen, "CoreModule.js", 13) != 0 || ILibDuktape_ScriptContainer_ExecuteByteCode(ctx) != 0)
|
||||
{
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s", (char*)duk_safe_to_string(ctx, -1));
|
||||
duk_pop(ctx);
|
||||
@@ -1411,8 +1413,6 @@ int GenerateSHA384FileHash(char *filePath, char *fileHash)
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Called when the connection of the mesh server is fully authenticated
|
||||
void MeshServer_ServerAuthenticated(ILibWebClient_StateObject WebStateObject, MeshAgentHostContainer *agent) {
|
||||
int len = 0;
|
||||
@@ -1437,6 +1437,29 @@ void MeshServer_ServerAuthenticated(ILibWebClient_StateObject WebStateObject, Me
|
||||
}
|
||||
}
|
||||
|
||||
void MeshServer_SendAgentInfo(MeshAgentHostContainer* agent, ILibWebClient_StateObject WebStateObject) {
|
||||
int hostnamelen = (int)strnlen_s(agent->hostname, sizeof(agent->hostname));
|
||||
|
||||
// Send to the server information about this agent
|
||||
MeshCommand_BinaryPacket_AuthInfo *info = (MeshCommand_BinaryPacket_AuthInfo*)ILibScratchPad2;
|
||||
memset(info, 0, sizeof(MeshCommand_BinaryPacket_AuthInfo)); // Required because if hash are SHA384, they will not fully fill the struct.
|
||||
info->command = htons(MeshCommand_AuthInfo);
|
||||
info->infoVersion = htonl(1);
|
||||
info->agentId = htonl(MESH_AGENTID);
|
||||
info->agentVersion = htonl(agent->version);
|
||||
info->platformType = htonl(((agent->batteryState != MeshAgentHost_BatteryInfo_NONE) && (agent->batteryState != MeshAgentHost_BatteryInfo_UNKNOWN)) ? MeshCommand_AuthInfo_PlatformType_LAPTOP : MeshCommand_AuthInfo_PlatformType_DESKTOP);
|
||||
memcpy_s(info->MeshID, sizeof(info->MeshID), agent->meshId, sizeof(agent->meshId));
|
||||
info->capabilities = htonl(agent->capabilities);
|
||||
info->hostnameLen = htons(hostnamelen);
|
||||
memcpy_s(info->hostname, sizeof(ILibScratchPad2) - sizeof(MeshCommand_BinaryPacket_AuthInfo), agent->hostname, hostnamelen);
|
||||
|
||||
// Send mesh agent information to the server
|
||||
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)info, sizeof(MeshCommand_BinaryPacket_AuthInfo) + hostnamelen, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
agent->retryTime = 0;
|
||||
printf("Connected.\n");
|
||||
if (agent->serverAuthState == 3) { MeshServer_ServerAuthenticated(WebStateObject, agent); }
|
||||
}
|
||||
|
||||
// Process MeshCentral server commands.
|
||||
void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAgentHostContainer *agent, char *cmd, int cmdLen)
|
||||
{
|
||||
@@ -1521,7 +1544,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
||||
X509_pubkey_digest(serverCert, EVP_sha384(), (unsigned char*)ILibScratchPad, (unsigned int*)&hashlen); // OpenSSL 1.1, SHA384
|
||||
if (memcmp(ILibScratchPad, agent->serverHash, UTIL_SHA384_HASHSIZE) != 0) {
|
||||
X509_pubkey_digest(serverCert, EVP_sha256(), (unsigned char*)ILibScratchPad, (unsigned int*)&hashlen); // OpenSSL 1.1, SHA256 (For older .mshx policy file)
|
||||
if (memcmp(ILibScratchPad, agent->serverHash, 32) != 0) {
|
||||
if (memcmp(ILibScratchPad, agent->serverHash, UTIL_SHA256_HASHSIZE) != 0) {
|
||||
printf("Server certificate mismatch\r\n"); break; // TODO: Disconnect
|
||||
}
|
||||
}
|
||||
@@ -1539,28 +1562,15 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
||||
rsa_pubkey = EVP_PKEY_get1_RSA(evp_pubkey);
|
||||
if (RSA_verify(NID_sha384, (unsigned char*)ILibScratchPad, UTIL_SHA384_HASHSIZE, (unsigned char*)AuthVerify->signature, AuthVerify->signatureLen, rsa_pubkey) == 1)
|
||||
{
|
||||
int hostnamelen = (int)strnlen_s(agent->hostname, sizeof(agent->hostname));
|
||||
// Server signature verified, we are good to go.
|
||||
agent->serverAuthState += 1;
|
||||
|
||||
// Send to the server information about this agent (TODO: Replace this with a struct)
|
||||
MeshCommand_BinaryPacket_AuthInfo *info = (MeshCommand_BinaryPacket_AuthInfo*)ILibScratchPad2;
|
||||
memset(info, 0, sizeof(MeshCommand_BinaryPacket_AuthInfo)); // Required because if hash are SHA384, they will not fully fill the struct.
|
||||
info->command = htons(MeshCommand_AuthInfo);
|
||||
info->infoVersion = htonl(1);
|
||||
info->agentId = htonl(MESH_AGENTID);
|
||||
info->agentVersion = htonl(agent->version);
|
||||
info->platformType = htonl(((agent->batteryState != MeshAgentHost_BatteryInfo_NONE) && (agent->batteryState != MeshAgentHost_BatteryInfo_UNKNOWN)) ? MeshCommand_AuthInfo_PlatformType_LAPTOP : MeshCommand_AuthInfo_PlatformType_DESKTOP);
|
||||
memcpy_s(info->MeshID, sizeof(info->MeshID), agent->meshId, sizeof(agent->meshId));
|
||||
info->capabilities = htonl(MeshCommand_AuthInfo_CapabilitiesMask_CONSOLE | MeshCommand_AuthInfo_CapabilitiesMask_JAVASCRIPT);
|
||||
info->hostnameLen = htons(hostnamelen);
|
||||
memcpy_s(info->hostname, sizeof(ILibScratchPad2) - sizeof(MeshCommand_BinaryPacket_AuthInfo), agent->hostname, hostnamelen);
|
||||
|
||||
// Send mesh agent information to the server
|
||||
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)info, sizeof(MeshCommand_BinaryPacket_AuthInfo) + hostnamelen, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
agent->retryTime = 0;
|
||||
printf("Connected.\n");
|
||||
if (agent->serverAuthState == 3) { MeshServer_ServerAuthenticated(WebStateObject, agent); }
|
||||
// Store the server's TLS cert hash so in the future, we can skip server auth.
|
||||
util_keyhash2(peer, ILibScratchPad);
|
||||
ILibSimpleDataStore_PutEx(agent->masterDb, "ServerTlsCertHash", 17, ILibScratchPad, UTIL_SHA384_HASHSIZE);
|
||||
|
||||
// Send our agent information to the server
|
||||
MeshServer_SendAgentInfo(agent, WebStateObject);
|
||||
} else {
|
||||
printf("Invalid server signature\r\n");
|
||||
// TODO: Disconnect
|
||||
@@ -1823,7 +1833,7 @@ void MeshServer_ControlChannel_IdleTimeout(ILibWebClient_StateObject WebStateObj
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)user;
|
||||
ILibWebClient_WebSocket_Ping(WebStateObject);
|
||||
ILibWebClient_SetTimeout(WebStateObject, agent->controlChannel_idleTimeout_seconds, MeshServer_ControlChannel_IdleTimeout, user);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost | ILibRemoteLogging_Modules_ConsolePrint, ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore/MeshServer_ControlChannel_IdleTimeout(): Sending Ping");
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost , ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore/MeshServer_ControlChannel_IdleTimeout(): Sending Ping");
|
||||
}
|
||||
ILibWebClient_WebSocket_PingResponse MeshServer_ControlChannel_PingSink(ILibWebClient_StateObject WebStateObject, void *user)
|
||||
{
|
||||
@@ -1833,7 +1843,7 @@ void MeshServer_ControlChannel_PongSink(ILibWebClient_StateObject WebStateObject
|
||||
{
|
||||
#ifdef _REMOTELOGGING
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)user;
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost | ILibRemoteLogging_Modules_ConsolePrint, ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore/MeshServer_ControlChannel_IdleTimeout(): Received Pong");
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost , ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore/MeshServer_ControlChannel_IdleTimeout(): Received Pong");
|
||||
#endif
|
||||
}
|
||||
void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebClient_ReceiveStatus recvStatus, void *user1, void *user2, int *PAUSE)
|
||||
@@ -1849,6 +1859,7 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
||||
break;
|
||||
case ILibWebClient_ReceiveStatus_Connection_Established: // New connection established.
|
||||
{
|
||||
int len;
|
||||
int idleLen;
|
||||
if ((idleLen = ILibSimpleDataStore_Get(agent->masterDb, "controlChannelIdleTimeout", NULL, 0)) != 0)
|
||||
{
|
||||
@@ -1884,16 +1895,30 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
||||
memcpy_s(serveridcmd->serverId, sizeof(serveridcmd->serverId), agent->serverHash, sizeof(agent->serverHash)); // Place our mesh agent nonce
|
||||
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)serveridcmd, sizeof(MeshCommand_BinaryPacket_ServerId), ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
|
||||
// Start authentication by sending a auth nonce & server TLS cert hash.
|
||||
// Send 384 bits SHA384 hash of TLS cert public key + 384 bits nonce
|
||||
util_random(sizeof(agent->agentNonce), agent->agentNonce); // Generate a new mesh agent connection nonce
|
||||
MeshCommand_BinaryPacket_AuthRequest *ar = (MeshCommand_BinaryPacket_AuthRequest*)ILibScratchPad2;
|
||||
// Check to see if we already have a validated TLS cert hash
|
||||
{
|
||||
MeshCommand_BinaryPacket_AuthRequest *ar = (MeshCommand_BinaryPacket_AuthRequest*)ILibScratchPad2;
|
||||
util_keyhash2(peer, ar->serverHash); // Hash the server certificate public key and place it
|
||||
|
||||
ar->command = htons(MeshCommand_AuthRequest); // MeshCommand_AuthRequest (1), server hash + nonce
|
||||
util_keyhash2(peer, ar->serverHash); // Hash the server certificate public key and place it
|
||||
if (peer != NULL) { X509_free(peer); }
|
||||
memcpy_s(ar->serverNonce, sizeof(ar->serverNonce), agent->agentNonce, sizeof(agent->agentNonce)); // Place our mesh agent nonce
|
||||
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)ar, sizeof(MeshCommand_BinaryPacket_AuthRequest), ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
len = ILibSimpleDataStore_GetEx(agent->masterDb, "ServerTlsCertHash", 17, ILibScratchPad, sizeof(ILibScratchPad));
|
||||
if ((len == UTIL_SHA384_HASHSIZE) && (memcmp(ILibScratchPad, ar->serverHash, UTIL_SHA384_HASHSIZE) == 0)) {
|
||||
// The TLS certificate of this server is correct, no need to authenticate further.
|
||||
unsigned short response = htons(MeshCommand_AuthConfirm); // Send indication to the server that it's already authenticated
|
||||
agent->serverAuthState = 1;
|
||||
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)&response, 2, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
}
|
||||
|
||||
// Start authentication by sending a auth nonce & server TLS cert hash - If we indicated AuthConfirm already, the server will use this data but not respond to it.
|
||||
// Send 384 bits SHA384 hash of TLS cert public key + 384 bits nonce
|
||||
util_random(sizeof(agent->agentNonce), agent->agentNonce); // Generate a new mesh agent connection nonce
|
||||
ar->command = htons(MeshCommand_AuthRequest); // MeshCommand_AuthRequest (1), server hash + nonce
|
||||
if (peer != NULL) { X509_free(peer); }
|
||||
memcpy_s(ar->serverNonce, sizeof(ar->serverNonce), agent->agentNonce, sizeof(agent->agentNonce)); // Place our mesh agent nonce
|
||||
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)ar, sizeof(MeshCommand_BinaryPacket_AuthRequest), ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
|
||||
// If we know this is a good server, send our agent information right now.
|
||||
if (agent->serverAuthState == 1) { MeshServer_SendAgentInfo(agent, WebStateObject); }
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -1926,6 +1951,7 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
||||
// If there are no headers, this is a connection error. Log it and try again...
|
||||
if (header == NULL)
|
||||
{
|
||||
if (ILibIsChainBeingDestroyed(agent->chain)) { return; }
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(ILibWebClient_GetChainFromWebStateObject(WebStateObject)), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "Agent Host Container: Mesh Server Connection Error, trying again later.");
|
||||
printf("Mesh Server Connection Error\n");
|
||||
if (agent->multicastServerUrl != NULL) { free(agent->multicastServerUrl); agent->multicastServerUrl = NULL; }
|
||||
@@ -1981,13 +2007,13 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
||||
}
|
||||
else
|
||||
{
|
||||
agent->serverIndex = (agent->serverIndex % rs->NumResults) + 1;
|
||||
//if (agent->serverIndex == 1)
|
||||
//{
|
||||
// printf("Aborting...\r\n");
|
||||
// ILibDestructParserResults(rs);
|
||||
// return;
|
||||
//}
|
||||
#ifdef MICROSTACK_PROXY
|
||||
if (agent->triedNoProxy_Index == agent->serverIndex)
|
||||
#endif
|
||||
{
|
||||
agent->serverIndex = (agent->serverIndex % rs->NumResults) + 1;
|
||||
agent->triedNoProxy_Index = agent->serverIndex - 1;
|
||||
}
|
||||
}
|
||||
|
||||
f = ILibParseString_GetResultIndex(rs, agent->serverIndex);
|
||||
@@ -2002,7 +2028,7 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
||||
serverUrlLen = (int)strlen(serverUrl);
|
||||
} else {
|
||||
// Multicast discovery packet to try to find our server
|
||||
if ((agent->multicastDiscovery != NULL) && (ILibSimpleDataStore_Get(agent->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2)) == 97)) { ILibMulticastSocket_Broadcast(agent->multicastDiscovery, ILibScratchPad2, 96, 1); }
|
||||
if ((agent->multicastDiscovery2 != NULL) && (ILibSimpleDataStore_Get(agent->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2)) == 97)) { ILibMulticastSocket_Broadcast(agent->multicastDiscovery2, ILibScratchPad2, 96, 1); }
|
||||
ILibDestructParserResults(rs);
|
||||
MeshServer_Connect(agent);
|
||||
return;
|
||||
@@ -2061,7 +2087,7 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore: Attempting connection to: %s", serverUrl);
|
||||
ILibDestructParserResults(rs);
|
||||
|
||||
if ((len = ILibSimpleDataStore_Get(agent->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2))) == 0) { printf("ServerID entry not found in Db!\n"); return; }
|
||||
if ((len = ILibSimpleDataStore_Get(agent->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2))) == 0) { printf("ServerID entry not found in Db!\n"); free(host); free(path); return; }
|
||||
rs = ILibParseString(ILibScratchPad2, 0, len, ",", 1);
|
||||
f = ILibParseString_GetResultIndex(rs, agent->serverIndex);
|
||||
if (f == NULL)
|
||||
@@ -2070,6 +2096,7 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
||||
printf("ServerID Count Mismatch\r\n");
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore: ServerID Count Mismatch. Hash Count = %d, Server Index = %d", rs->NumResults, agent->serverIndex);
|
||||
ILibDestructParserResults(rs);
|
||||
free(host); free(path);
|
||||
return;
|
||||
}
|
||||
f->datalength = ILibTrimString(&(f->data), f->datalength);
|
||||
@@ -2078,6 +2105,7 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
||||
printf("ServerID too big\r\n");
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore: ServerID too big. Was %d bytes, but expected %d bytes", f->datalength / 2, sizeof(agent->serverHash) - 1);
|
||||
ILibDestructParserResults(rs);
|
||||
free(host); free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2114,21 +2142,45 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
||||
#ifdef MICROSTACK_PROXY
|
||||
unsigned short proxyPort = 80;
|
||||
int delimiter = ILibString_LastIndexOf(ILibScratchPad, len, ":", 1);
|
||||
if (delimiter > 0)
|
||||
|
||||
if (agent->triedNoProxy_Index < agent->serverIndex && agent->proxyServer != NULL)
|
||||
{
|
||||
ILibScratchPad[delimiter] = 0;
|
||||
ILibScratchPad[len] = 0;
|
||||
proxyPort = atoi(ILibScratchPad + delimiter + 1);
|
||||
printf("Disabling Proxy: %s\n", ILibScratchPad);
|
||||
agent->triedNoProxy_Index++;
|
||||
agent->proxyServer = NULL;
|
||||
|
||||
if (duk_peval_string(agent->meshCoreCtx, "require('global-tunnel');") == 0)
|
||||
{
|
||||
duk_get_prop_string(agent->meshCoreCtx, -1, "end"); // [tunnel][end]
|
||||
duk_swap_top(agent->meshCoreCtx, -2); // [end][this]
|
||||
duk_pcall_method(agent->meshCoreCtx, 0); // [undefined]
|
||||
}
|
||||
duk_pop(agent->meshCoreCtx); // ...
|
||||
}
|
||||
agent->proxyServer = ILibWebClient_SetProxy(reqToken, ILibScratchPad, proxyPort, NULL, NULL);
|
||||
if (agent->proxyServer != NULL)
|
||||
else
|
||||
{
|
||||
memcpy_s(&(ILibDuktape_GetNewGlobalTunnel(agent->meshCoreCtx)->proxyServer), sizeof(struct sockaddr_in6), agent->proxyServer, sizeof(struct sockaddr_in6));
|
||||
printf("Using proxy: %s\n", ILibScratchPad);
|
||||
if (delimiter > 0)
|
||||
{
|
||||
ILibScratchPad[delimiter] = 0;
|
||||
ILibScratchPad[len] = 0;
|
||||
proxyPort = atoi(ILibScratchPad + delimiter + 1);
|
||||
}
|
||||
agent->proxyServer = ILibWebClient_SetProxy(reqToken, ILibScratchPad, proxyPort, NULL, NULL);
|
||||
if (agent->proxyServer != NULL)
|
||||
{
|
||||
memcpy_s(&(ILibDuktape_GetNewGlobalTunnel(agent->meshCoreCtx)->proxyServer), sizeof(struct sockaddr_in6), agent->proxyServer, sizeof(struct sockaddr_in6));
|
||||
}
|
||||
}
|
||||
#else
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost | ILibRemoteLogging_Modules_ConsolePrint, ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore.MeshServer_ConnectEx(): Proxy Specified, but support was not enabled in this build");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Proxy was specified
|
||||
agent->triedNoProxy_Index++;
|
||||
}
|
||||
agent->serverConnectionState = 1; // We are trying to connect
|
||||
}
|
||||
else
|
||||
@@ -2293,7 +2345,7 @@ void agentDumpKeysSink(ILibSimpleDataStore sender, char* Key, int KeyLen, void *
|
||||
}
|
||||
}
|
||||
|
||||
MeshAgentHostContainer* MeshAgent_Create()
|
||||
MeshAgentHostContainer* MeshAgent_Create(MeshCommand_AuthInfo_CapabilitiesMask capabilities)
|
||||
{
|
||||
MeshAgentHostContainer* retVal = (MeshAgentHostContainer*)ILibMemory_Allocate(sizeof(MeshAgentHostContainer), 0, NULL, NULL);
|
||||
#ifdef WIN32
|
||||
@@ -2303,6 +2355,7 @@ MeshAgentHostContainer* MeshAgent_Create()
|
||||
retVal->agentID = (AgentIdentifiers)MESH_AGENTID;
|
||||
retVal->chain = ILibCreateChainEx(3 * sizeof(void*));
|
||||
retVal->pipeManager = ILibProcessPipe_Manager_Create(retVal->chain);
|
||||
retVal->capabilities = capabilities | MeshCommand_AuthInfo_CapabilitiesMask_CONSOLE | MeshCommand_AuthInfo_CapabilitiesMask_JAVASCRIPT;
|
||||
gethostname(retVal->hostname, (int)sizeof(retVal->hostname));
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -2347,6 +2400,8 @@ void MeshAgent_ChainEnd(void *chain, void *user)
|
||||
void MeshAgent_RunScriptOnly_Finalizer(duk_context *ctx, void *user)
|
||||
{
|
||||
MeshAgentHostContainer *agentHost = (MeshAgentHostContainer*)user;
|
||||
agentHost->exitCode = ILibDuktape_Process_GetExitCode(ctx);
|
||||
|
||||
agentHost->meshCoreCtx = NULL;
|
||||
if (ILibIsChainBeingDestroyed(agentHost->chain) == 0)
|
||||
{
|
||||
@@ -2396,10 +2451,57 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
#endif
|
||||
#ifdef _POSIX
|
||||
int options = 0;
|
||||
|
||||
if (paramLen >= 2)
|
||||
{
|
||||
if ((strcmp(param[1], "stop") == 0 || strcmp(param[1], "-s") == 0))
|
||||
{
|
||||
// Stop
|
||||
FILE *fd = NULL;
|
||||
char str[15];
|
||||
pid_t pid = 0;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
#if defined(__APPLE__) && defined(_DAEMON) && defined(_LINKVM)
|
||||
installOsx(0);
|
||||
#endif
|
||||
*/
|
||||
|
||||
#ifdef _ANDROID
|
||||
fd = fopen("/data/usr/tmp/meshagent.pid", "r");
|
||||
#else
|
||||
fd = fopen("/var/run/meshagent.pid", "r");
|
||||
#endif
|
||||
if (fd == NULL) fd = fopen(".meshagent.pid", "r");
|
||||
if (fd != NULL)
|
||||
{
|
||||
len = fread(str, sizeof(char), 15, fd);
|
||||
if (len > 0)
|
||||
{
|
||||
sscanf(str, "%d\r\n", &pid);
|
||||
if (pid > 0 && kill(pid, SIGKILL) == 0) printf("Mesh agent stopped.\r\n"); else printf("Mesh agent not running.\r\n");
|
||||
#ifdef _ANDROID
|
||||
remove("/data/usr/tmp/meshagent.pid");
|
||||
#else
|
||||
remove("/var/run/meshagent.pid");
|
||||
remove(".meshagent.pid");
|
||||
#endif
|
||||
}
|
||||
fclose(fd);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unable to find process id file.\r\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// We are a Mesh Agent
|
||||
printf("MeshCentral2 Agent\r\n"); // MESH_AGENT_VERSION
|
||||
if (agentHost->masterDb == NULL) { agentHost->masterDb = ILibSimpleDataStore_Create(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".db")); }
|
||||
#ifndef WIN32
|
||||
if (agentHost->masterDb == NULL)
|
||||
@@ -2413,17 +2515,17 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
switch (agentHost->dbRetryCount)
|
||||
{
|
||||
case 10:
|
||||
printf("Unable to open database... Giving up...\r\n");
|
||||
return(0);
|
||||
printf("Unable to open database.\r\n");
|
||||
return 0;
|
||||
default:
|
||||
printf("Unable to open database... Trying again later...\r\n");
|
||||
printf("Unable to open database (%d/10)...\r\n", agentHost->dbRetryCount + 1);
|
||||
agentHost->dbRetryCount++;
|
||||
ILibLifeTime_AddEx(ILibGetBaseTimer(agentHost->chain), data, 2000, MeshAgent_AgentMost_dbRetryCallback, NULL);
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (agentHost->masterDb == NULL) { printf("Unable to open database...\r\n"); return(0); }
|
||||
if (agentHost->masterDb == NULL) { printf("Unable to open database.\r\n"); return(0); }
|
||||
#endif
|
||||
agentHost->httpClientManager = ILibCreateWebClient(3, agentHost->chain);
|
||||
|
||||
@@ -2454,8 +2556,33 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
// Check the local MacAddresses, to see if we need to reset our NodeId
|
||||
duk_context *tmpCtx = ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(0, 0, agentHost->chain, NULL, NULL, agentHost->exePath, NULL, NULL, NULL);
|
||||
if (duk_peval_string(tmpCtx, "function _getMac() { var ret = ''; var ni = require('os').networkInterfaces(); for (var f in ni) { for (var i in ni[f]) { if(ni[f][i].type == 'ethernet' || ni[f][i].type == 'wireless') {ret += ('[' + ni[f][i].mac + ']');} } } return(ret); }; _getMac();") == 0)
|
||||
{
|
||||
int len;
|
||||
duk_size_t macLen;
|
||||
char *mac = (char*)duk_get_lstring(tmpCtx, -1, &macLen);
|
||||
if ((len = ILibSimpleDataStore_Get(agentHost->masterDb, "LocalMacAddresses", NULL, 0)) == 0)
|
||||
{
|
||||
ILibSimpleDataStore_PutEx(agentHost->masterDb, "LocalMacAddresses", 17, mac, (int)macLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *curr = ILibMemory_AllocateA(len);
|
||||
ILibSimpleDataStore_Get(agentHost->masterDb, "LocalMacAddresses", curr, len);
|
||||
int i = 0;
|
||||
while (i < len)
|
||||
{
|
||||
if (ILibString_IndexOf(mac, (int)macLen, curr + i, 19) >= 0) { break; }
|
||||
i += 19;
|
||||
}
|
||||
if (i >= len) { resetNodeId = 1; ILibSimpleDataStore_PutEx(agentHost->masterDb, "LocalMacAddresses", 17, mac, (int)macLen); }
|
||||
}
|
||||
}
|
||||
duk_destroy_heap(tmpCtx);
|
||||
|
||||
// Load the mesh agent certificates
|
||||
if ((resetNodeId == 1 || agent_LoadCertificates(agentHost) != 0) && agent_GenerateCertificates(agentHost, NULL) != 0) { printf("Certificate error\r\n"); }
|
||||
if (agent_VerifyMeshCertificates(agentHost) != 0) { printf("Certificate validation error\r\n"); }
|
||||
@@ -2506,16 +2633,40 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
if (RegCreateKey(HKEY_CURRENT_USER, TEXT("Software\\Open Source\\MeshAgent2"), &hKey) == ERROR_SUCCESS)
|
||||
#endif
|
||||
{
|
||||
int i, len;
|
||||
char* tmp = NULL;
|
||||
|
||||
// Save the NodeId
|
||||
util_tohex(agentHost->g_selfid, UTIL_SHA384_HASHSIZE, ILibScratchPad);
|
||||
RegSetValueExA(hKey, "NodeId", 0, REG_SZ, ILibScratchPad, (int)strlen(ILibScratchPad));
|
||||
len = ILibBase64Encode(agentHost->g_selfid, UTIL_SHA384_HASHSIZE, &tmp);
|
||||
if ((len > 0) && (tmp != NULL)) {
|
||||
for (i = 0; i < len; i++) { if (tmp[i] == '+') { tmp[i] = '@'; } else if (tmp[i] == '/') { tmp[i] = '$'; } } // Replace + --> @ and / --> $
|
||||
RegSetValueExA(hKey, "NodeId", 0, REG_SZ, tmp, len);
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
else { RegDeleteKeyA(hKey, "NodeId"); }
|
||||
|
||||
// Save the AgentHash
|
||||
util_tohex(agentHost->agentHash, UTIL_SHA384_HASHSIZE, ILibScratchPad);
|
||||
RegSetValueExA(hKey, "AgentHash", 0, REG_SZ, ILibScratchPad, (int)strlen(ILibScratchPad));
|
||||
|
||||
// Save the MeshId
|
||||
if (ILibSimpleDataStore_Get(agentHost->masterDb, "MeshID", NULL, 0) == 0) { RegDeleteKeyA(hKey, "MeshId"); } else {
|
||||
len = ILibSimpleDataStore_Get(agentHost->masterDb, "MeshID", ILibScratchPad2, (int)sizeof(ILibScratchPad2));
|
||||
if (len > 0) {
|
||||
len = ILibBase64Encode(ILibScratchPad2, len, &tmp);
|
||||
if ((len > 0) && (tmp != NULL)) {
|
||||
for (i = 0; i < len; i++) { if (tmp[i] == '+') { tmp[i] = '@'; } else if (tmp[i] == '/') { tmp[i] = '$'; } } // Replace + --> @ and / --> $
|
||||
RegSetValueExA(hKey, "MeshId", 0, REG_SZ, tmp, len);
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
else { RegDeleteKeyA(hKey, "MeshId"); }
|
||||
}
|
||||
else { RegDeleteKeyA(hKey, "MeshId"); }
|
||||
}
|
||||
|
||||
// Save a bunch of values in the registry
|
||||
if (ILibSimpleDataStore_Get(agentHost->masterDb, "MeshID", NULL, 0) == 0) { RegDeleteKeyA(hKey, "MeshId"); } else { util_tohex(ILibScratchPad2, ILibSimpleDataStore_Get(agentHost->masterDb, "MeshID", ILibScratchPad2, (int)sizeof(ILibScratchPad2)), ILibScratchPad); RegSetValueExA(hKey, "MeshId", 0, REG_SZ, ILibScratchPad, (int)strlen(ILibScratchPad)); } // Save the MeshId
|
||||
if ((pLen = ILibSimpleDataStore_Get(agentHost->masterDb, "MeshServer", ILibScratchPad2, (int)sizeof(ILibScratchPad2))) == 0) { RegDeleteKeyA(hKey, "MeshServerUrl"); } else { RegSetValueExA(hKey, "MeshServerUrl", 0, REG_SZ, (BYTE*)ILibScratchPad2, (int)strlen(ILibScratchPad2)); } // Save the mesh server URL
|
||||
if ((pLen = ILibSimpleDataStore_Get(agentHost->masterDb, "ServerID", ILibScratchPad2, (int)sizeof(ILibScratchPad2))) == 0) { RegDeleteKeyA(hKey, "MeshServerId"); } else { RegSetValueExA(hKey, "MeshServerId", 0, REG_SZ, (BYTE*)ILibScratchPad2, (int)strlen(ILibScratchPad2)); } // Save the mesh server id
|
||||
if ((pLen = ILibSimpleDataStore_Get(agentHost->masterDb, "WebProxy", ILibScratchPad2, (int)sizeof(ILibScratchPad2))) == 0) { RegDeleteKeyA(hKey, "Proxy"); } else { RegSetValueExA(hKey, "Proxy", 0, REG_SZ, (BYTE*)ILibScratchPad2, (int)strlen(ILibScratchPad2)); } // Save the proxy
|
||||
@@ -2539,48 +2690,6 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
else if ((strcmp(param[1], "restart") == 0 || strcmp(param[1], "-r") == 0)) options = 3;
|
||||
}
|
||||
|
||||
// Stop
|
||||
if (options & 2)
|
||||
{
|
||||
FILE *fd = NULL;
|
||||
char str[15];
|
||||
pid_t pid = 0;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
#if defined(__APPLE__) && defined(_DAEMON) && defined(_LINKVM)
|
||||
installOsx(0);
|
||||
#endif
|
||||
*/
|
||||
|
||||
#ifdef _ANDROID
|
||||
fd = fopen("/data/usr/tmp/meshagent.pid", "r");
|
||||
#else
|
||||
fd = fopen("/var/run/meshagent.pid", "r");
|
||||
#endif
|
||||
if (fd == NULL) fd = fopen(".meshagent.pid", "r");
|
||||
if (fd != NULL)
|
||||
{
|
||||
len = fread(str, sizeof(char), 15, fd);
|
||||
if (len > 0)
|
||||
{
|
||||
sscanf(str, "%d\r\n", &pid);
|
||||
if (pid > 0 && kill(pid, SIGKILL) == 0) printf("Mesh agent stopped.\r\n"); else printf("Mesh agent not running.\r\n");
|
||||
#ifdef _ANDROID
|
||||
remove("/data/usr/tmp/meshagent.pid");
|
||||
#else
|
||||
remove("/var/run/meshagent.pid");
|
||||
remove(".meshagent.pid");
|
||||
#endif
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unable to find process id file.\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Start
|
||||
if (options & 1)
|
||||
{
|
||||
@@ -2627,7 +2736,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
|
||||
#endif
|
||||
|
||||
if (parseCommands == 0 || paramLen == 1 || ((paramLen == 2) && (strcmp(param[1], "run") == 0)))
|
||||
if (parseCommands == 0 || paramLen == 1 || ((paramLen == 2) && (strcmp(param[1], "run") == 0 || strcmp(param[1], "connect") == 0)))
|
||||
{
|
||||
#ifdef WIN32
|
||||
char* updateFilePath = MeshAgent_MakeAbsolutePath(agentHost->exePath, ".update.exe");
|
||||
@@ -2666,7 +2775,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
CoreModule = (char*)ILibMemory_Allocate(CoreModuleLen, 0, NULL, NULL);
|
||||
ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", CoreModule, CoreModuleLen);
|
||||
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScript(agentHost->meshCoreCtx, CoreModule + 4, CoreModuleLen - 4) != 0 ||
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScriptEx(agentHost->meshCoreCtx, CoreModule + 4, CoreModuleLen - 4, "CoreModule.js", 13) != 0 ||
|
||||
ILibDuktape_ScriptContainer_ExecuteByteCode(agentHost->meshCoreCtx) != 0)
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agentHost->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint,
|
||||
@@ -2708,10 +2817,14 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
multicastAddr4.sin_port = htons(16989);
|
||||
ILibInet_pton(AF_INET, MESH_MCASTv4_GROUP, &(multicastAddr4.sin_addr));
|
||||
|
||||
// Multicast socket on fixed port, will receive multicast from the server.
|
||||
agentHost->multicastDiscovery = ILibMulticastSocket_Create(agentHost->chain, 1024, MESH_AGENT_PORT, &multicastAddr4, &multicastAddr6, UDPSocket_OnData, agentHost, 1);
|
||||
if (agentHost->multicastDiscovery == NULL) { ILIBMARKPOSITION(219); return 1; }
|
||||
}
|
||||
|
||||
// Multicast socket on a random port, used to multicast to the server and receive server unicast responses.
|
||||
agentHost->multicastDiscovery2 = ILibMulticastSocket_Create(agentHost->chain, 1024, 0, &multicastAddr4, &multicastAddr6, UDPSocket_OnData, agentHost, 1);
|
||||
if (agentHost->multicastDiscovery2 == NULL) { ILIBMARKPOSITION(219); return 1; }
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -2724,6 +2837,23 @@ void MeshAgent_ScriptMode_UncaughtExceptionSink(duk_context *ctx, char *msg, voi
|
||||
//ScriptEngine_Exit((MeshAgentHostContainer*)user, MeshAgent_JavaCore_ContextGuid, 254);
|
||||
}
|
||||
|
||||
void MeshAgent_ScriptMode_MeshDesktop_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)Duktape_GetPointerProperty(ctx, -1, "\xFF_MeshDesktop_AgentPtr");
|
||||
duk_pop(ctx);
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "MeshDesktop");
|
||||
if (agent != NULL)
|
||||
{
|
||||
duk_push_pointer(ctx, agent);
|
||||
duk_put_prop_string(ctx, -2, MESH_AGENT_PTR);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "getRemoteDesktopStream", ILibDuktape_MeshAgent_getRemoteDesktop, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **argv)
|
||||
{
|
||||
char *jsFile;
|
||||
@@ -2831,9 +2961,20 @@ void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **ar
|
||||
|
||||
agentHost->meshCoreCtx = ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(secFlags, execTimeout, agentHost->chain, scriptArgs, connectAgent != 0 ? agentHost->masterDb : NULL, agentHost->exePath, agentHost->pipeManager, connectAgent == 0 ? MeshAgent_RunScriptOnly_Finalizer : NULL, agentHost);
|
||||
ILibDuktape_SetNativeUncaughtExceptionHandler(agentHost->meshCoreCtx, MeshAgent_ScriptMode_UncaughtExceptionSink, agentHost);
|
||||
if (connectAgent != 0) { ILibDuktape_MeshAgent_Init(agentHost->meshCoreCtx, agentHost->chain, agentHost); }
|
||||
if (connectAgent != 0)
|
||||
{
|
||||
ILibDuktape_MeshAgent_Init(agentHost->meshCoreCtx, agentHost->chain, agentHost);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_heap_stash(agentHost->meshCoreCtx); // [stash]
|
||||
duk_push_pointer(agentHost->meshCoreCtx, agentHost); // [stash][ptr]
|
||||
duk_put_prop_string(agentHost->meshCoreCtx, -2, "\xFF_MeshDesktop_AgentPtr"); // [stash]
|
||||
duk_pop(agentHost->meshCoreCtx); // ...
|
||||
ILibDuktape_ModSearch_AddHandler(agentHost->meshCoreCtx, "meshDesktop", MeshAgent_ScriptMode_MeshDesktop_PUSH);
|
||||
}
|
||||
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScript(agentHost->meshCoreCtx, jsFile, jsFileLen) != 0 || ILibDuktape_ScriptContainer_ExecuteByteCode(agentHost->meshCoreCtx) != 0)
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScriptEx(agentHost->meshCoreCtx, jsFile, jsFileLen, agentHost->meshCoreCtx_embeddedScript == NULL ? scriptArgs[0] : "[embedded].js", 0) != 0 || ILibDuktape_ScriptContainer_ExecuteByteCode(agentHost->meshCoreCtx) != 0)
|
||||
{
|
||||
if (strcmp(duk_safe_to_string(agentHost->meshCoreCtx, -1), "Process.exit() forced script termination") != 0)
|
||||
{
|
||||
@@ -2850,6 +2991,7 @@ void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **ar
|
||||
// If in agent mode, setup the chain to be a mesh agent
|
||||
if (connectAgent != 0)
|
||||
{
|
||||
printf("MeshCentral2 Agent\r\n"); // MESH_AGENT_VERSION
|
||||
if (MeshAgent_AgentMode(agentHost, argc, argv, 0) == 0)
|
||||
{
|
||||
ILibStopChain(agentHost->chain); // Agent Error, stop the chain
|
||||
@@ -2863,6 +3005,7 @@ void MeshAgent_ScriptMode_Dispatched(void *chain, void *user)
|
||||
}
|
||||
void MeshAgent_AgentMode_Dispatched(void *chain, void *user)
|
||||
{
|
||||
printf("MeshCentral2 Agent\r\n"); // MESH_AGENT_VERSION
|
||||
if (MeshAgent_AgentMode((MeshAgentHostContainer*)((void**)user)[0], ((int*)((void**)user)[1])[0], (char**)((void**)user)[2], 1) == 0)
|
||||
{
|
||||
ILibStopChain(((MeshAgentHostContainer*)((void**)user)[0])->chain);
|
||||
@@ -2882,23 +3025,31 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
int x;
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && defined(_LINKVM) && !defined(WINSERVICE)
|
||||
SetProcessDPIAware();
|
||||
#endif
|
||||
|
||||
if ((paramLen == 1 && strcmp(param[0], "--slave") == 0) || (paramLen == 2 && strcmp(param[1], "--slave") == 0)) { MeshAgent_Slave(agentHost); return 0; }
|
||||
if (paramLen == 2 && strcmp(param[1], "--netinfo") == 0) { char* data; int len = MeshInfo_GetSystemInformation(&data); if (len > 0) { printf("%s\r\n", data); } return 0; }
|
||||
agentHost->exePath = exePath;
|
||||
exePath[0] = 0;
|
||||
if (paramLen == 2 && strcmp(param[1], "--netinfo") == 0) { char* data; int len = MeshInfo_GetSystemInformation(&data); if (len > 0) { printf("%s\r\n", data); free(data); } return 0; }
|
||||
|
||||
if (agentHost->exePath == NULL)
|
||||
{
|
||||
agentHost->exePath = exePath;
|
||||
exePath[0] = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
GetModuleFileName(NULL, exePath, sizeof(exePath));
|
||||
GetModuleFileName(NULL, exePath, sizeof(exePath));
|
||||
#elif defined(__APPLE__)
|
||||
if (_NSGetExecutablePath(exePath, &len) != 0) ILIBCRITICALEXIT(247);
|
||||
exePath[len] = 0;
|
||||
agentHost->exePath = exePath;
|
||||
if (_NSGetExecutablePath(exePath, &len) != 0) ILIBCRITICALEXIT(247);
|
||||
exePath[len] = 0;
|
||||
agentHost->exePath = exePath;
|
||||
#elif defined(NACL)
|
||||
#else
|
||||
x = readlink("/proc/self/exe", exePath, 1024);
|
||||
if (x < 0 || x >= 1024) ILIBCRITICALEXIT(246);
|
||||
exePath[x] = 0;
|
||||
x = readlink("/proc/self/exe", exePath, 1024);
|
||||
if (x < 0 || x >= 1024) ILIBCRITICALEXIT(246);
|
||||
exePath[x] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Perform a self SHA384 Hash
|
||||
GenerateSHA384FileHash(agentHost->exePath, agentHost->agentHash);
|
||||
@@ -2956,6 +3107,12 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
ILibStartChain(agentHost->chain);
|
||||
agentHost->chain = NULL; // Mesh agent has exited, set the chain to NULL
|
||||
|
||||
// Close the database
|
||||
if (agentHost->masterDb != NULL) {
|
||||
ILibSimpleDataStore_Close(agentHost->masterDb);
|
||||
agentHost->masterDb = NULL;
|
||||
}
|
||||
|
||||
// Check if we need to perform self-update (performSelfUpdate should indicate startup type on Liunx: 1 = systemd, 2 = upstart, 3 = sysv-init)
|
||||
if (agentHost->performSelfUpdate != 0)
|
||||
{
|
||||
@@ -2979,7 +3136,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
|
||||
// Build the argument list
|
||||
str[0] = 0;
|
||||
for (i = 1; i < paramLen; i++) ptr += sprintf_s(str + ptr, 4096 - ptr, " %s", param[i]);
|
||||
for (i = 1; i < paramLen && ptr >= 0; i++) ptr += sprintf_s(str + ptr, 4096 - ptr, " %s", param[i]);
|
||||
|
||||
#ifdef WIN32
|
||||
// Windows version
|
||||
@@ -3134,7 +3291,7 @@ void MeshAgent_PerformSelfUpdate(char* selfpath, char* exepath, int argc, char *
|
||||
|
||||
// Built the argument list
|
||||
ILibScratchPad[0] = 0;
|
||||
for (i = 2; i < argc; i++) ptr += sprintf_s(ILibScratchPad + ptr, 4096 - ptr, " %s", argv[i]);
|
||||
for (i = 2; i < argc && ptr >= 0; i++) ptr += sprintf_s(ILibScratchPad + ptr, 4096 - ptr, " %s", argv[i]);
|
||||
sprintf_s(ILibScratchPad2, 60000, "%s%s &", exepath, ILibScratchPad);
|
||||
|
||||
// Now run the updated process
|
||||
@@ -3235,4 +3392,4 @@ public:
|
||||
*/
|
||||
Buffer GenerateCertificate(passphrase);
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user