1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-15 07:43:50 +00:00

1. Updated fs.readSync

2. Added zip-reader.isZip()
3. Added support for zip compressed selfupdate
This commit is contained in:
Bryan Roe
2020-07-10 01:01:27 -07:00
parent c390676809
commit f9c9e4264d
4 changed files with 131 additions and 39 deletions

View File

@@ -2470,6 +2470,59 @@ void MeshServer_SendAgentInfo(MeshAgentHostContainer* agent, ILibWebClient_State
if (agent->serverAuthState == 3) { MeshServer_ServerAuthenticated(WebStateObject, agent); } if (agent->serverAuthState == 3) { MeshServer_ServerAuthenticated(WebStateObject, agent); }
} }
void MeshServer_selfupdate_continue(MeshAgentHostContainer *agent)
{
#ifdef WIN32
agent->performSelfUpdate = 1;
#else
// Set performSelfUpdate to the startupType, on Linux is this important: 1 = systemd, 2 = upstart, 3 = sysv-init
int len = ILibSimpleDataStore_Get(agent->masterDb, "StartupType", ILibScratchPad, sizeof(ILibScratchPad));
if (len > 0) { agent->performSelfUpdate = atoi(ILibScratchPad); }
if (agent->performSelfUpdate == 0) { agent->performSelfUpdate = 999; } // Never allow this value to be zero.
#endif
if (duk_peval_string_noresult(agent->meshCoreCtx, "require('service-manager').manager.getService('meshagentDiagnostic').start();") == 0)
{
if (agent->logUpdate != 0)
{
ILIBLOGMESSSAGE("SelfUpdate -> Starting Secondary Agent, to assist with self update");
}
}
else
{
if (agent->logUpdate != 0)
{
ILIBLOGMESSSAGE("SelfUpdate -> Secondary Agent unavailable to assist with self update");
}
}
// Everything looks good, lets perform the update
if (agent->logUpdate != 0)
{
char tmp[255];
sprintf_s(tmp, sizeof(tmp), "SelfUpdate -> Stopping Chain (%d)", agent->performSelfUpdate);
ILIBLOGMESSSAGE(tmp);
}
ILibStopChain(agent->chain);
}
duk_ret_t MeshServer_selfupdate_unzip_complete(duk_context *ctx)
{
duk_eval_string(ctx, "require('MeshAgent')"); // [MeshAgent]
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)Duktape_GetPointerProperty(ctx, -1, MESH_AGENT_PTR);
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Updated successfully unzipped..."); }
MeshServer_selfupdate_continue(agent);
return(0);
}
duk_ret_t MeshServer_selfupdate_unzip_error(duk_context *ctx)
{
duk_eval_string(ctx, "require('MeshAgent')"); // [MeshAgent]
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)Duktape_GetPointerProperty(ctx, -1, MESH_AGENT_PTR);
duk_push_sprintf(ctx, "SelfUpdate -> FAILED to unzip update: %s", (char*)duk_safe_to_string(ctx, 0));
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE(duk_safe_to_string(ctx, -1)); }
return(0);
}
// Process MeshCentral server commands. // Process MeshCentral server commands.
void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAgentHostContainer *agent, char *cmd, int cmdLen) void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAgentHostContainer *agent, char *cmd, int cmdLen)
{ {
@@ -2915,54 +2968,64 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
if ((GenerateSHA384FileHash(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0)) if ((GenerateSHA384FileHash(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0))
{ {
//printf("UPDATE: End OK\r\n"); //printf("UPDATE: End OK\r\n");
int updateTop = duk_get_top(agent->meshCoreCtx);
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Download Complete... Hash verified"); } if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Download Complete... Hash verified"); }
if (agent->fakeUpdate != 0) if (agent->fakeUpdate != 0)
{ {
int fsz; int fsz;
char *fsc; char *fsc;
fsz = ILibReadFileFromDiskEx(&fsc, agent->exePath); sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.zip", agent->exePath);
fsz = ILibReadFileFromDiskEx(&fsc, ILibScratchPad);
if (fsz == 0)
{
fsz = ILibReadFileFromDiskEx(&fsc, agent->exePath);
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Overriding update with same version..."); }
}
else
{
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Overriding update with provided zip..."); }
}
ILibWriteStringToDiskEx(updateFilePath, fsc, fsz); ILibWriteStringToDiskEx(updateFilePath, fsc, fsz);
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Overriding update with same version..."); }
} }
if (agent->fakeUpdate != 0 || agent->forceUpdate != 0) if (agent->fakeUpdate != 0 || agent->forceUpdate != 0)
{ {
ILibSimpleDataStore_Put(agent->masterDb, "disableUpdate", "1"); ILibSimpleDataStore_Put(agent->masterDb, "disableUpdate", "1");
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Disabling future updates..."); } if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Disabling future updates..."); }
} }
#ifdef WIN32
agent->performSelfUpdate = 1;
#else
// Set performSelfUpdate to the startupType, on Linux is this important: 1 = systemd, 2 = upstart, 3 = sysv-init
int len = ILibSimpleDataStore_Get(agent->masterDb, "StartupType", ILibScratchPad, sizeof(ILibScratchPad));
if (len > 0) { agent->performSelfUpdate = atoi(ILibScratchPad); }
if (agent->performSelfUpdate == 0) { agent->performSelfUpdate = 999; } // Never allow this value to be zero.
#endif
if (duk_peval_string_noresult(agent->meshCoreCtx, "require('service-manager').manager.getService('meshagentDiagnostic').start();") == 0) duk_eval_string(agent->meshCoreCtx, "require('zip-reader')"); // [reader]
duk_prepare_method_call(agent->meshCoreCtx, -1, "isZip"); // [reader][isZip][this]
duk_push_string(agent->meshCoreCtx, updateFilePath); // [reader][isZip][this][path]
duk_pcall_method(agent->meshCoreCtx, 1); // [reader][boolean]
if (duk_to_boolean(agent->meshCoreCtx, -1))
{ {
if (agent->logUpdate != 0) // Update File is zipped
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Unzipping update..."); }
duk_eval_string(agent->meshCoreCtx, "require('update-helper')"); // [helper]
duk_prepare_method_call(agent->meshCoreCtx, -1, "start"); // [helper][start][this]
duk_push_string(agent->meshCoreCtx, updateFilePath); // [helper][start][this][path]
if (duk_pcall_method(agent->meshCoreCtx, 1) == 0) // [helper][promise]
{ {
ILIBLOGMESSSAGE("SelfUpdate -> Starting Secondary Agent, to assist with self update"); duk_prepare_method_call(agent->meshCoreCtx, -1, "then"); // [helper][promise][then][this]
duk_push_c_function(agent->meshCoreCtx, MeshServer_selfupdate_unzip_complete, DUK_VARARGS);//..][res]
duk_push_c_function(agent->meshCoreCtx, MeshServer_selfupdate_unzip_error, DUK_VARARGS);//[this][res][rej]
duk_pcall_method(agent->meshCoreCtx, 2);
} }
} else
else
{
if (agent->logUpdate != 0)
{ {
ILIBLOGMESSSAGE("SelfUpdate -> Secondary Agent unavailable to assist with self update"); if (agent->logUpdate != 0)
{
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "SelfUpdate -> Error Unzipping: %s", duk_safe_to_string(agent->meshCoreCtx, -1));
ILIBLOGMESSSAGE(ILibScratchPad);
}
} }
duk_set_top(agent->meshCoreCtx, updateTop); // ...
break; // Break out here, and continue when finished unzipping (or in the case of error, abort)
} }
duk_set_top(agent->meshCoreCtx, updateTop); // ...
MeshServer_selfupdate_continue(agent);
// Everything looks good, lets perform the update }
if (agent->logUpdate != 0) else
{
char tmp[255];
sprintf_s(tmp, sizeof(tmp), "SelfUpdate -> Stopping Chain (%d)", agent->performSelfUpdate);
ILIBLOGMESSSAGE(tmp);
}
ILibStopChain(agent->chain);
} else
{ {
// Hash check failed, delete the file and do nothing. On next server reconnect, we will try again. // Hash check failed, delete the file and do nothing. On next server reconnect, we will try again.
if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Download Complete... Hash FAILED, aborting update..."); } if (agent->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Download Complete... Hash FAILED, aborting update..."); }

File diff suppressed because one or more lines are too long

View File

@@ -407,21 +407,33 @@ duk_ret_t ILibDuktape_fs_openSync(duk_context *ctx)
} }
duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx) duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
{ {
int narg = (int)duk_get_top(ctx);
if (narg > 3)
{
// Convert to Options Format
duk_push_this(ctx); // [fs]
duk_prepare_method_call(ctx, -1, "readSync"); // [fs][readSync][this]
duk_dup(ctx, 0); duk_dup(ctx, 1); // [fs][readSync][this][fd][buffer]
duk_push_object(ctx); // [fs][readSync][this][fd][buffer][options]
duk_dup(ctx, 2); duk_put_prop_string(ctx, -2, "offset");
duk_dup(ctx, 3); duk_put_prop_string(ctx, -2, "length");
duk_dup(ctx, 4); duk_put_prop_string(ctx, -2, "position");
duk_call_method(ctx, 3);
return(1);
}
duk_size_t bufferSize; duk_size_t bufferSize;
char *buffer = Duktape_GetBuffer(ctx, 1, &bufferSize); char *buffer = Duktape_GetBuffer(ctx, 1, &bufferSize);
int offset = duk_require_int(ctx, 2); int offset = Duktape_GetIntPropertyValue(ctx, 2, "offset", 0);
int length = duk_require_int(ctx, 3); int length = Duktape_GetIntPropertyValue(ctx, 2, "length", (int)bufferSize);
int position = Duktape_GetIntPropertyValue(ctx, 2, "position", -1);
int bytesRead; int bytesRead;
FILE *f = ILibDuktape_fs_getFilePtr(ctx, duk_require_int(ctx, 0)); FILE *f = ILibDuktape_fs_getFilePtr(ctx, duk_require_int(ctx, 0));
if (length > (int)bufferSize) { return(ILibDuktape_Error(ctx, "fs.readSync(): Buffer of size: %llu bytes, but attempting to read %d bytes", (uint64_t)bufferSize, length)); } if (length > (int)bufferSize) { return(ILibDuktape_Error(ctx, "fs.readSync(): Buffer of size: %llu bytes, but attempting to read %d bytes", (uint64_t)bufferSize, length)); }
if (f != NULL) if (f != NULL)
{ {
if (duk_is_number(ctx, 4)) if (position >= 0) { fseek(f, position, SEEK_SET); }
{
fseek(f, duk_require_int(ctx, 4), SEEK_SET);
}
bytesRead = (int)fread(buffer + offset, 1, length, f); bytesRead = (int)fread(buffer + offset, 1, length, f);
duk_push_int(ctx, bytesRead); duk_push_int(ctx, bytesRead);
return 1; return 1;
@@ -2319,7 +2331,7 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "closeSync", ILibDuktape_fs_closeSync, 1); ILibDuktape_CreateInstanceMethod(ctx, "closeSync", ILibDuktape_fs_closeSync, 1);
ILibDuktape_CreateInstanceMethod(ctx, "openSync", ILibDuktape_fs_openSync, DUK_VARARGS); ILibDuktape_CreateInstanceMethod(ctx, "openSync", ILibDuktape_fs_openSync, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "readSync", ILibDuktape_fs_readSync, 5); ILibDuktape_CreateInstanceMethod(ctx, "readSync", ILibDuktape_fs_readSync, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "writeSync", ILibDuktape_fs_writeSync, DUK_VARARGS); ILibDuktape_CreateInstanceMethod(ctx, "writeSync", ILibDuktape_fs_writeSync, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "read", ILibDuktape_fs_read, DUK_VARARGS); ILibDuktape_CreateInstanceMethod(ctx, "read", ILibDuktape_fs_read, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "write", ILibDuktape_fs_write, DUK_VARARGS); ILibDuktape_CreateInstanceMethod(ctx, "write", ILibDuktape_fs_write, DUK_VARARGS);

View File

@@ -438,4 +438,19 @@ function read(path)
return(ret); return(ret);
} }
module.exports = { read: read }; function isZip(path)
{
if (require('fs').statSync(path).size < 30) { return (false); }
var fd = require('fs').openSync(path, 'rb');
var jsFile = Buffer.alloc(4);
var bytesRead = require('fs').readSync(fd, jsFile, { position: 0 });
require('fs').closeSync(fd);
if (bytesRead == 4 && jsFile[0] == 0x50 && jsFile[1] == 0x4B && jsFile[2] == 0x03 && jsFile[3] == 0x04)
{
return (true);
}
return (false);
}
module.exports = { read: read, isZip: isZip };