mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-21 18:53:32 +00:00
1. Updated macOS to wait for network ready
2. Implemented Restart/Shutdown Power Actions for macOS
This commit is contained in:
@@ -1514,23 +1514,38 @@ duk_ret_t ILibDuktape_MeshAgent_NetInfo(duk_context *ctx)
|
|||||||
// Javascript ExecPowerState(int), executes power state command on the computer (Sleep, Hibernate...)
|
// Javascript ExecPowerState(int), executes power state command on the computer (Sleep, Hibernate...)
|
||||||
duk_ret_t ILibDuktape_MeshAgent_ExecPowerState(duk_context *ctx)
|
duk_ret_t ILibDuktape_MeshAgent_ExecPowerState(duk_context *ctx)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
|
||||||
duk_push_null(ctx);
|
|
||||||
#else
|
|
||||||
int force = 0;
|
int force = 0;
|
||||||
int numArgs = (int)duk_get_top(ctx);
|
int numArgs = (int)duk_get_top(ctx);
|
||||||
duk_push_this(ctx); // [MeshAgent]
|
|
||||||
|
|
||||||
if (numArgs == 2 && duk_is_number(ctx, 1)) { force = duk_get_int(ctx, 1); }
|
if (numArgs == 2 && duk_is_number(ctx, 1)) { force = duk_get_int(ctx, 1); }
|
||||||
|
|
||||||
|
|
||||||
|
duk_push_this(ctx); // [MeshAgent]
|
||||||
if (duk_is_number(ctx, 0))
|
if (duk_is_number(ctx, 0))
|
||||||
{
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
switch (duk_require_int(ctx, 0))
|
||||||
|
{
|
||||||
|
case 2: // SHUTDOWN
|
||||||
|
duk_peval_string_noresult(ctx, "require('mac-powerutil').shutdown();");
|
||||||
|
duk_push_int(ctx, 1);
|
||||||
|
break;
|
||||||
|
case 3: // REBOOT
|
||||||
|
duk_peval_string_noresult(ctx, "require('mac-powerutil').restart();");
|
||||||
|
duk_push_int(ctx, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
duk_push_int(ctx, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
duk_push_int(ctx, MeshInfo_PowerState((AgentPowerStateActions)duk_get_int(ctx, 0), force));
|
duk_push_int(ctx, MeshInfo_PowerState((AgentPowerStateActions)duk_get_int(ctx, 0), force));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
duk_push_null(ctx);
|
duk_push_null(ctx);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2488,7 +2503,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
|||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
printf("ProcessCommand(%u)...\n", command);
|
printf("ProcessCommand(%u)...\n", command);
|
||||||
ILIBLOGMESSAGEX("ProcessCommand(%u)...\n", command);
|
ILIBLOGMESSAGEX("ProcessCommand(%u)...", command);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MICROSTACK_NOTLS
|
#ifndef MICROSTACK_NOTLS
|
||||||
@@ -2502,7 +2517,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.
|
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 (cmdLen == sizeof(MeshCommand_BinaryPacket_AuthRequest))
|
||||||
{
|
{
|
||||||
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Processing Authentication Request...\n"); }
|
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Processing Authentication Request..."); }
|
||||||
MeshCommand_BinaryPacket_AuthRequest *AuthRequest = (MeshCommand_BinaryPacket_AuthRequest*)cmd;
|
MeshCommand_BinaryPacket_AuthRequest *AuthRequest = (MeshCommand_BinaryPacket_AuthRequest*)cmd;
|
||||||
int signLen;
|
int signLen;
|
||||||
SHA512_CTX c;
|
SHA512_CTX c;
|
||||||
@@ -2519,7 +2534,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
|||||||
printf("Bad server certificate hash\r\n"); // TODO: Disconnect
|
printf("Bad server certificate hash\r\n"); // TODO: Disconnect
|
||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
ILIBLOGMESSAGEX("Bad server certificate hash\n");
|
ILIBLOGMESSAGEX("Bad server certificate hash");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2577,7 +2592,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
|||||||
case MeshCommand_AuthVerify: // This is the signature from the server. We need to check everything is ok.
|
case MeshCommand_AuthVerify: // This is the signature from the server. We need to check everything is ok.
|
||||||
if (cmdLen > 8)
|
if (cmdLen > 8)
|
||||||
{
|
{
|
||||||
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Processing Authentication Verification...\n"); }
|
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Processing Authentication Verification..."); }
|
||||||
|
|
||||||
MeshCommand_BinaryPacket_AuthVerify_Header *avh = (MeshCommand_BinaryPacket_AuthVerify_Header*)cmd;
|
MeshCommand_BinaryPacket_AuthVerify_Header *avh = (MeshCommand_BinaryPacket_AuthVerify_Header*)cmd;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -2608,7 +2623,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
|||||||
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
|
printf("Server certificate mismatch\r\n"); break; // TODO: Disconnect
|
||||||
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Server certificate mismatch\n"); }
|
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Server certificate mismatch"); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2635,7 +2650,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
|||||||
MeshServer_SendAgentInfo(agent, WebStateObject);
|
MeshServer_SendAgentInfo(agent, WebStateObject);
|
||||||
} else {
|
} else {
|
||||||
printf("Invalid server signature\r\n");
|
printf("Invalid server signature\r\n");
|
||||||
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Invalid Server Signature\n"); }
|
if (agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Invalid Server Signature"); }
|
||||||
// TODO: Disconnect
|
// TODO: Disconnect
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2646,7 +2661,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
|||||||
break;
|
break;
|
||||||
case MeshCommand_AuthConfirm: // Server indicates that we are authenticated, we can now send data.
|
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"); }
|
if (agent->controlChannelDebug != 0) { printf("Authentication Complete...\n"); ILIBLOGMESSAGEX("Authentication Complete..."); }
|
||||||
|
|
||||||
// We have to wait for the server to indicate that it authenticated the agent (us) before sending any data to the server.
|
// 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.
|
// Node authentication requires the server make database calls, so we need to delay.
|
||||||
@@ -2713,7 +2728,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
|||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
printf("BinaryCommand(%u, %u)...\n", command, requestid);
|
printf("BinaryCommand(%u, %u)...\n", command, requestid);
|
||||||
ILIBLOGMESSAGEX("BinaryCommand(%u, %u)...\n", command, requestid);
|
ILIBLOGMESSAGEX("BinaryCommand(%u, %u)...", command, requestid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3043,7 +3058,7 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
|||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
printf("Control Channel Connection Established...\n");
|
printf("Control Channel Connection Established...\n");
|
||||||
ILIBLOGMESSAGEX("Control Channel Connection Established...\n");
|
ILIBLOGMESSAGEX("Control Channel Connection Established...");
|
||||||
}
|
}
|
||||||
#ifndef MICROSTACK_NOTLS
|
#ifndef MICROSTACK_NOTLS
|
||||||
int len;
|
int len;
|
||||||
@@ -3094,7 +3109,7 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
|||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
printf("TLS Server Cert matches Mesh Server Cert...\n");
|
printf("TLS Server Cert matches Mesh Server Cert...\n");
|
||||||
ILIBLOGMESSAGEX("TLS Server Cert matches Mesh Server Cert...\n");
|
ILIBLOGMESSAGEX("TLS Server Cert matches Mesh Server Cert...");
|
||||||
}
|
}
|
||||||
// The TLS certificate of this server is correct, no need to authenticate further.
|
// 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
|
unsigned short response = htons(MeshCommand_AuthConfirm); // Send indication to the server that it's already authenticated
|
||||||
@@ -3105,7 +3120,7 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
|||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
printf("Sending Authentication Data...\n");
|
printf("Sending Authentication Data...\n");
|
||||||
ILIBLOGMESSAGEX("Sending Authentication Data...\n");
|
ILIBLOGMESSAGEX("Sending Authentication Data...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
// 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.
|
||||||
@@ -3126,7 +3141,7 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
|||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
printf("Control Channel Disconnected...\n");
|
printf("Control Channel Disconnected...\n");
|
||||||
ILIBLOGMESSAGEX("Control Channel Disconnected...\n");
|
ILIBLOGMESSAGEX("Control Channel Disconnected...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the channel had been authenticates, inform JavaScript core module that we are not disconnected
|
// If the channel had been authenticates, inform JavaScript core module that we are not disconnected
|
||||||
@@ -3271,7 +3286,7 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
|||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
{
|
{
|
||||||
printf("Swapping [%s] for [%s]\n", agent->serveruri, "wss://meshcentral.com:443/agent.ashx");
|
printf("Swapping [%s] for [%s]\n", agent->serveruri, "wss://meshcentral.com:443/agent.ashx");
|
||||||
ILIBLOGMESSAGEX("Swapping [%s] for [%s]\n", agent->serveruri, "wss://meshcentral.com:443/agent.ashx");
|
ILIBLOGMESSAGEX("Swapping [%s] for [%s]", agent->serveruri, "wss://meshcentral.com:443/agent.ashx");
|
||||||
}
|
}
|
||||||
strcpy_s(agent->serveruri, sizeof(agent->serveruri), "wss://meshcentral.com:443/agent.ashx");
|
strcpy_s(agent->serveruri, sizeof(agent->serveruri), "wss://meshcentral.com:443/agent.ashx");
|
||||||
strcpy_s(serverUrl, serverUrlLen, "wss://meshcentral.com:443/agent.ashx");
|
strcpy_s(serverUrl, serverUrlLen, "wss://meshcentral.com:443/agent.ashx");
|
||||||
@@ -3366,7 +3381,7 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
|
|||||||
{
|
{
|
||||||
strcpy_s(agent->serverip, sizeof(agent->serverip), ILibRemoteLogging_ConvertAddress((struct sockaddr*)&meshServer));
|
strcpy_s(agent->serverip, sizeof(agent->serverip), ILibRemoteLogging_ConvertAddress((struct sockaddr*)&meshServer));
|
||||||
printf("Connecting to: %s\n", agent->serveruri);
|
printf("Connecting to: %s\n", agent->serveruri);
|
||||||
if (agent->logUpdate != 0 || agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Connecting to: %s\n", agent->serveruri); }
|
if (agent->logUpdate != 0 || agent->controlChannelDebug != 0) { ILIBLOGMESSAGEX("Connecting to: %s", agent->serveruri); }
|
||||||
|
|
||||||
ILibWebClient_AddWebSocketRequestHeaders(req, 65535, MeshServer_OnSendOK);
|
ILibWebClient_AddWebSocketRequestHeaders(req, 65535, MeshServer_OnSendOK);
|
||||||
if (agent->webSocketMaskOverride != 0) { ILibHTTPPacket_Stash_Put(req, "_WebSocketMaskOverride", 22, (void*)(uintptr_t)0x01); }
|
if (agent->webSocketMaskOverride != 0) { ILibHTTPPacket_Stash_Put(req, "_WebSocketMaskOverride", 22, (void*)(uintptr_t)0x01); }
|
||||||
@@ -3454,8 +3469,8 @@ void MeshServer_Connect(MeshAgentHostContainer *agent)
|
|||||||
SLAVELOG = ILibSimpleDataStore_Get(agent->masterDb, "slaveKvmLog", NULL, 0);
|
SLAVELOG = ILibSimpleDataStore_Get(agent->masterDb, "slaveKvmLog", NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (agent->logUpdate != 0) { ILIBLOGMESSAGEX("PLATFORM_TYPE: %d\n", agent->platformType); }
|
if (agent->logUpdate != 0) { ILIBLOGMESSAGEX("PLATFORM_TYPE: %d", agent->platformType); }
|
||||||
if (agent->logUpdate != 0) { ILIBLOGMESSAGEX("Running as Service: %d\n", agent->JSRunningAsService); }
|
if (agent->logUpdate != 0) { ILIBLOGMESSAGEX("Running as Service: %d", agent->JSRunningAsService); }
|
||||||
|
|
||||||
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("Attempting to connect to Server..."); }
|
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("Attempting to connect to Server..."); }
|
||||||
if (agent->controlChannelDebug != 0)
|
if (agent->controlChannelDebug != 0)
|
||||||
@@ -4007,6 +4022,20 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if !defined(MICROSTACK_NOTLS)
|
#if !defined(MICROSTACK_NOTLS)
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
if (ILibSimpleDataStore_Get(agentHost->masterDb, "controlChannelDebug", NULL, 0) != 0)
|
||||||
|
{
|
||||||
|
ILIBLOGMESSAGEX("Waiting for network...");
|
||||||
|
}
|
||||||
|
duk_peval_string_noresult(tmpCtx, "process.stdout.write('waiting for network...');var child = require('child_process').execFile('/bin/sh', ['sh']);child.stdin.write('ipconfig waitall\\nexit\\n');child.waitExit();process.stdout.write('[OK]\\n');");
|
||||||
|
if (ILibSimpleDataStore_Get(agentHost->masterDb, "controlChannelDebug", NULL, 0) != 0)
|
||||||
|
{
|
||||||
|
ILIBLOGMESSAGEX("...[OK]\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Check the local MacAddresses, to see if we need to reset our NodeId
|
// Check the local MacAddresses, to see if we need to reset our NodeId
|
||||||
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); })();") == 0)
|
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); })();") == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
74
modules/mac-powerutil.js
Normal file
74
modules/mac-powerutil.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 Intel Corporation
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function powerutil()
|
||||||
|
{
|
||||||
|
this._ObjectID = 'mac-powerutil';
|
||||||
|
|
||||||
|
this.sleep = function sleep()
|
||||||
|
{
|
||||||
|
var child;
|
||||||
|
switch (process.platform)
|
||||||
|
{
|
||||||
|
case 'darwin':
|
||||||
|
child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||||
|
child.stdout.str = ''; child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
|
||||||
|
child.stderr.str = ''; child.stderr.on('data', function (chunk) { this.str += chunk.toString(); });
|
||||||
|
child.stdin.write('osascript -e \'tell application "System Events" to sleep\'\nexit\n');
|
||||||
|
child.waitExit();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw ('sleep() not implemented on this platform');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.restart = function restart()
|
||||||
|
{
|
||||||
|
var child;
|
||||||
|
switch(process.platform)
|
||||||
|
{
|
||||||
|
case 'darwin':
|
||||||
|
child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||||
|
child.stdout.str = ''; child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
|
||||||
|
child.stderr.str = ''; child.stderr.on('data', function (chunk) { this.str += chunk.toString(); });
|
||||||
|
child.stdin.write('shutdown -r now\n');
|
||||||
|
child.waitExit();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw ('restart() not implemented on this platform');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.shutdown = function shutdown()
|
||||||
|
{
|
||||||
|
var child;
|
||||||
|
switch (process.platform)
|
||||||
|
{
|
||||||
|
case 'darwin':
|
||||||
|
child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||||
|
child.stdout.str = ''; child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
|
||||||
|
child.stderr.str = ''; child.stderr.on('data', function (chunk) { this.str += chunk.toString(); });
|
||||||
|
child.stdin.write('shutdown -h now\n');
|
||||||
|
child.waitExit();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw ('shutdown() not implemented on this platform');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new powerutil();
|
||||||
Reference in New Issue
Block a user