From b9af1630391f0ec4eb7726fdf6b3550c47ad3af9 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Thu, 14 Feb 2019 14:03:33 -0800 Subject: [PATCH] Added ability to log control channel messages --- meshcore/agentcore.c | 69 ++++++++++++++++++++++++++++++++++++---- meshcore/agentcore.h | 4 ++- microstack/ILibParsers.c | 12 +++++++ microstack/ILibParsers.h | 2 ++ 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index 67c6bf1..8b682e1 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -2249,6 +2249,12 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge unsigned short command = ntohs(((unsigned short*)cmd)[0]); unsigned short requestid; + if (agent->controlChannelDebug != 0) + { + printf("ProcessCommand(%u)...\n", command); + ILIBLOGMESSAGEX("ProcessCommand(%u)...\n", command); + } + #ifndef MICROSTACK_NOTLS // If we are not authenticated with the mesh server, we only support auth commands. if (agent->serverAuthState != 3) @@ -2260,6 +2266,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge case MeshCommand_AuthRequest: // This is basic authentication information from the server, we need to sign this and return the signature. if (cmdLen == sizeof(MeshCommand_BinaryPacket_AuthRequest)) { + if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Processing Authentication Request...\n"); } MeshCommand_BinaryPacket_AuthRequest *AuthRequest = (MeshCommand_BinaryPacket_AuthRequest*)cmd; int signLen; SHA512_CTX c; @@ -2268,10 +2275,16 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge // Hash the server's web certificate and check if it matches the one in the auth request util_certhash2(peer, ILibScratchPad2); // Hash the server certificate - if (memcmp(ILibScratchPad2, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)) != 0) { + if (memcmp(ILibScratchPad2, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)) != 0) + { util_keyhash2(peer, ILibScratchPad2); // Hash the server certificate public key (this is the old way) - if (memcmp(ILibScratchPad2, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)) != 0) { + if (memcmp(ILibScratchPad2, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)) != 0) + { printf("Bad server certificate hash\r\n"); // TODO: Disconnect + if (agent->controlChannelDebug != 0) + { + ILIBLOGMESSAGEX("Bad server certificate hash\n"); + } break; } } @@ -2327,6 +2340,8 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge case MeshCommand_AuthVerify: // This is the signature from the server. We need to check everything is ok. if (cmdLen > 8) { + if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Processing Authentication Verification...\n"); } + MeshCommand_BinaryPacket_AuthVerify_Header *avh = (MeshCommand_BinaryPacket_AuthVerify_Header*)cmd; #ifdef WIN32 MeshCommand_BinaryPacket_AuthVerify *AuthVerify = (MeshCommand_BinaryPacket_AuthVerify*)_alloca(sizeof(MeshCommand_BinaryPacket_AuthVerify)); @@ -2353,8 +2368,10 @@ 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, UTIL_SHA256_HASHSIZE) != 0) { + if (memcmp(ILibScratchPad, agent->serverHash, UTIL_SHA256_HASHSIZE) != 0) + { printf("Server certificate mismatch\r\n"); break; // TODO: Disconnect + if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Server certificate mismatch\n"); } } } @@ -2381,6 +2398,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge MeshServer_SendAgentInfo(agent, WebStateObject); } else { printf("Invalid server signature\r\n"); + if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Invalid Server Signature\n"); } // TODO: Disconnect } @@ -2391,6 +2409,8 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge break; case MeshCommand_AuthConfirm: // Server indicates that we are authenticated, we can now send data. { + if (agent->controlChannelDebug != 0) { printf("Authentication Complete...\n"); ILIBLOGMESSAGEX("Authentication Complete...\n"); } + // We have to wait for the server to indicate that it authenticated the agent (us) before sending any data to the server. // Node authentication requires the server make database calls, so we need to delay. agent->serverAuthState += 2; @@ -2453,6 +2473,13 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge if (cmdLen < 4) return; requestid = ntohs(((unsigned short*)cmd)[1]); + if (agent->controlChannelDebug != 0) + { + printf("BinaryCommand(%u, %u)...\n", command, requestid); + ILIBLOGMESSAGEX("BinaryCommand(%u, %u)...\n", command, requestid); + } + + // Process Core Module Commands here, but only if we aren't running a local script switch (command) { @@ -2761,6 +2788,11 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru break; case ILibWebClient_ReceiveStatus_Connection_Established: // New connection established. { + if (agent->controlChannelDebug != 0) + { + printf("Control Channel Connection Established...\n"); + ILIBLOGMESSAGEX("Control Channel Connection Established...\n"); + } #ifndef MICROSTACK_NOTLS int len; #endif @@ -2805,13 +2837,25 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru util_certhash2(peer, ar->serverHash); // Hash the server certificate public key and place it len = ILibSimpleDataStore_GetEx(agent->masterDb, "ServerTlsCertHash", 17, ILibScratchPad, sizeof(ILibScratchPad)); - if ((len == UTIL_SHA384_HASHSIZE) && (memcmp(ILibScratchPad, ar->serverHash, UTIL_SHA384_HASHSIZE) == 0)) { + if ((len == UTIL_SHA384_HASHSIZE) && (memcmp(ILibScratchPad, ar->serverHash, UTIL_SHA384_HASHSIZE) == 0)) + { + if (agent->controlChannelDebug != 0) + { + printf("TLS Server Cert matches Mesh Server Cert...\n"); + ILIBLOGMESSAGEX("TLS Server Cert matches Mesh Server Cert...\n"); + } // 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); } + if (agent->controlChannelDebug != 0) + { + printf("Sending Authentication Data...\n"); + ILIBLOGMESSAGEX("Sending Authentication Data...\n"); + } + // 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 @@ -2827,6 +2871,12 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru break; } case ILibWebClient_ReceiveStatus_Complete: // Disconnection + if (agent->controlChannelDebug != 0) + { + printf("Control Channel Disconnected...\n"); + ILIBLOGMESSAGEX("Control Channel Disconnected...\n"); + } + // If the channel had been authenticates, inform JavaScript core module that we are not disconnected #ifndef MICROSTACK_NOTLS if (agent->serverAuthState == 3) @@ -3002,8 +3052,8 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent) } } - printf("Connecting to: %s\n", serverUrl); - if (agent->logUpdate != 0) { ILIBLOGMESSSAGE(serverUrl); } + printf("Connecting to: %s\n", serverUrl); + if (agent->logUpdate != 0 || agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Connecting to: %s\n", serverUrl); } ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "AgentCore: Attempting connection to: %s", serverUrl); ILibDestructParserResults(rs); @@ -3125,8 +3175,15 @@ void MeshServer_Connect(MeshAgentHostContainer *agent) agent->forceUpdate = ILibSimpleDataStore_Get(agent->masterDb, "forceUpdate", NULL, 0); agent->logUpdate = ILibSimpleDataStore_Get(agent->masterDb, "logUpdate", NULL, 0); agent->fakeUpdate = ILibSimpleDataStore_Get(agent->masterDb, "fakeUpdate", NULL, 0); + agent->controlChannelDebug = ILibSimpleDataStore_Get(agent->masterDb, "controlChannelDebug", NULL, 0); if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("Attempting to connect to Server..."); } + if (agent->controlChannelDebug != 0) + { + ILIBLOGMESSSAGE("Attempting to connect to Server..."); + printf("Attempting to connect to Server...\n"); + } + else if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("Attempting to connect to Server..."); } if (agent->retryTime == 0) { diff --git a/meshcore/agentcore.h b/meshcore/agentcore.h index 26c1811..d63f28e 100644 --- a/meshcore/agentcore.h +++ b/meshcore/agentcore.h @@ -170,6 +170,7 @@ typedef struct MeshAgentHostContainer int forceUpdate; int logUpdate; int fakeUpdate; + int controlChannelDebug; void *coreTimeout; int webSocketMaskOverride; int jsDebugPort; @@ -213,7 +214,8 @@ char* MeshAgent_MakeAbsolutePath(char *basePath, char *localPath); /* List of DB Keys that can be set, to alter behavior of the Mesh Agent * * -AgentCapabilities: Integer Mask, specifying supported Agent Capabilities +AgentCapabilities: Integer Mask, specifying supported Agent Capabilities +controlChannelDebug: If set, will log/display controlChannel messages (Except for JSON messages) controlChannelIdleTimeout: Integer value specifying the idle timeout in seconds, to send Ping/Pong to server, to keep connection alive disableUpdate: If set, will prevent the agent from self-updating noUpdateCoreModule: If set, will prevent the agent from taking a new meshcore from the server diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 2a6e54e..70c8fc2 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -9355,6 +9355,18 @@ char* ILibCriticalLog (const char* msg, const char* file, int line, int user1, i } return(ILibCriticalLogBuffer); } +void ILIBLOGMESSAGEX(char *format, ...) +{ + char dest[4096]; + int len = 0; + va_list argptr; + + va_start(argptr, format); + len += vsnprintf(dest + len, sizeof(dest) - len, format, argptr); + va_end(argptr); + + ILIBLOGMESSSAGE(dest); +} //! Platform Agnostic method to Spawn a detached worker thread with normal priority/affinity /*! \param method Handler to dispatch on the new thread diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index bbc9a04..0fe9773 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -1370,6 +1370,8 @@ int ILibIsRunningOnChainThread(void* chain); #define ILIBCRITICALEXITMSG(code, msg) {printf("%s", ILibCriticalLog(msg, NULL, 0, 0, 0)); exit(code);} #define ILIBLOGMESSSAGE(msg) ILibCriticalLog(msg, NULL, 0, 0, 0) + void ILIBLOGMESSAGEX(char *format, ...); + #if defined(WIN32) #define ILIBCRITICALERREXIT(ex) { ILibCriticalLog(NULL, __FILE__, __LINE__, GetLastError(), 0); exit(ex); } #define ILIBCRITICALEXIT(ex) {ILibCriticalLog(NULL, __FILE__, __LINE__, ex, GetLastError());printf("CRITICALEXIT, FILE: %s, LINE: %d\r\n", __FILE__, __LINE__); exit(ex);}