154 lines
6.5 KiB
C++
154 lines
6.5 KiB
C++
#include <fstream>
|
|
#include <filesystem>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <cstring>
|
|
|
|
/*
|
|
|
|
THIS FILE IS AUTO-GENERATED BY DEHYDRATE.
|
|
DO NOT EDIT THIS FILE.
|
|
|
|
*/
|
|
|
|
|
|
#include "_agent-local.hpp"
|
|
namespace recreate_agent_local {
|
|
|
|
|
|
// Tiny dependency-free FNV-1a 64-bit hash
|
|
static uint64_t fnv1a_64(const void* data, size_t len) {
|
|
const uint8_t* p = static_cast<const uint8_t*>(data);
|
|
uint64_t h = 0xcbf29ce484222325ULL;
|
|
for (size_t i = 0; i < len; ++i)
|
|
h = (h ^ p[i]) * 0x100000001b3ULL;
|
|
return h;
|
|
}
|
|
|
|
|
|
// Base64 decoding function - no dependencies
|
|
static void base64_decode(const char* encoded_data, size_t encoded_len, unsigned char* output, size_t* output_len) {
|
|
const char* base64_chars =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
size_t out_pos = 0;
|
|
int val = 0, valb = -8;
|
|
|
|
for (size_t i = 0; i < encoded_len; i++) {
|
|
char c = encoded_data[i];
|
|
if (c == '=') break;
|
|
|
|
// Find position in base64_chars
|
|
const char* pos = strchr(base64_chars, c);
|
|
if (pos == nullptr) continue; // Skip invalid characters
|
|
|
|
val = (val << 6) + static_cast<int>(pos - base64_chars);
|
|
valb += 6;
|
|
if (valb >= 0) {
|
|
output[out_pos++] = static_cast<unsigned char>((val >> valb) & 0xFF);
|
|
valb -= 8;
|
|
}
|
|
}
|
|
|
|
*output_len = out_pos;
|
|
}
|
|
|
|
// Utility function to recreate a file with proper permissions
|
|
static bool _recreate_file_(const std::filesystem::path& outpath, uint64_t file_hash, std::filesystem::perms file_perms, const unsigned char* filedata, size_t filedata_len) {
|
|
namespace fs = std::filesystem;
|
|
bool needs_write = false;
|
|
|
|
// Check if file exists and has correct hash
|
|
if (fs::exists(outpath)) {
|
|
// Check content hash
|
|
std::ifstream in(outpath, std::ios::binary);
|
|
std::ostringstream oss;
|
|
oss << in.rdbuf();
|
|
std::string data = oss.str();
|
|
uint64_t existing_hash = fnv1a_64(data.data(), data.size());
|
|
needs_write = existing_hash != file_hash;
|
|
} else {
|
|
needs_write = true; // File doesn't exist, need to create it
|
|
}
|
|
|
|
bool needs_permission_update = true;
|
|
if (!needs_write) { // we always update permissions if the file is written or changed. Othewise we check.
|
|
fs::perms current_perms = fs::status(outpath).permissions();
|
|
needs_permission_update = current_perms != file_perms;
|
|
}
|
|
|
|
if (needs_write) {
|
|
bool existed = fs::exists(outpath);
|
|
|
|
fs::create_directories(outpath.parent_path());
|
|
std::ofstream out(outpath, std::ios::binary);
|
|
out.write(reinterpret_cast<const char*>(filedata), filedata_len);
|
|
out.close();
|
|
// Set the file permissions
|
|
fs::permissions(outpath, file_perms);
|
|
|
|
if (!existed) {
|
|
std::cout << "[dehydrate] " << outpath.filename() << ": created\n";
|
|
} else {
|
|
std::cout << "[dehydrate] " << outpath.filename() << ": updated (hash changed)\n";
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (needs_permission_update) {
|
|
// Update only permissions
|
|
fs::permissions(outpath, file_perms);
|
|
std::cout << "[dehydrate] " << outpath.filename() << ": updated (permissions changed)\n";
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool recreate_tree(std::string destination_folder) {
|
|
namespace fs = std::filesystem;
|
|
bool any_written = false;
|
|
{
|
|
// File: agent-install.sh
|
|
fs::path outpath = fs::path(destination_folder) / "agent-install.sh";
|
|
static const char filedata_base64[] = "IyEvYmluL2Jhc2gKCiMgaW5zdGFsbCB0aGUgZHJvcHNoZWxsIGhvc3QgYWdlbnQgb24gdGhpcyBj"\
|
|
"b21wdXRlci4KIyAobm90IGZvciByZW1vdGUgc2VydmVycykKClNDUklQVF9ESVI9JChkaXJuYW1l"\
|
|
"ICIkMCIpCgplY2hvICJJbnN0YWxsaW5nIGRyb3BzaGVsbCBob3N0IGFnZW50IG9uIHRoaXMgY29t"\
|
|
"cHV0ZXIuLi4iCgoKIyBQcmludHMgYW4gZXJyb3IgbWVzc2FnZSBpbiByZWQgYW5kIGV4aXRzIHdp"\
|
|
"dGggc3RhdHVzIGNvZGUgMS4KX2RpZSgpIHsKICAgIGVjaG8gLWUgIkVycm9yOiAkMSIKICAgIGV4"\
|
|
"aXQgMQp9CgoKIyBDaGVja3MgaWYgbGlzdGVkIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgc2V0"\
|
|
"OyBjYWxscyBfZGllKCkgaWYgYW55IGFyZSBtaXNzaW5nLgpfY2hlY2tfcmVxdWlyZWRfZW52X3Zh"\
|
|
"cnMoKSB7CiAgICBsb2NhbCByZXF1aXJlZF92YXJzPSgiJEAiKQogICAgZm9yIHZhciBpbiAiJHty"\
|
|
"ZXF1aXJlZF92YXJzW0BdfSI7IGRvCiAgICAgICAgaWYgWyAteiAiJHshdmFyfSIgXTsgdGhlbgog"\
|
|
"ICAgICAgICAgICBfZGllICJSZXF1aXJlZCBlbnZpcm9ubWVudCB2YXJpYWJsZSAkdmFyIGlzIG5v"\
|
|
"dCBzZXQiCiAgICAgICAgZmkKICAgIGRvbmUKfQoKCmZ1bmN0aW9uIGluc3RhbGxfYmI2NCgpIHsg"\
|
|
"ICAgCiAgICAjIGNoZWNrIGN1cmwgaW5zdGFsbGVkCiAgICBpZiAhIGNvbW1hbmQgLXYgY3VybCAm"\
|
|
"PiAvZGV2L251bGw7IHRoZW4KICAgICAgICBfZGllICJDdXJsIGlzIG5vdCBpbnN0YWxsZWQuIEN1"\
|
|
"cmwgaXMgcmVxdWlyZWQgZm9yIGFnZW50IGluc3RhbGxhdGlvbi4iCiAgICBmaQoKICAgIEJCNjRf"\
|
|
"cGF0aD0iJHtBR0VOVF9MT0NBTF9QQVRIfS9iYjY0IgogICAgQVJDSD0kKHVuYW1lIC1tKQogICAg"\
|
|
"aWYgISBjdXJsICJodHRwczovL2dldGJpbi54eXovYmI2NDpsYXRlc3QtJHtBUkNIfSIgPiAiJHtC"\
|
|
"QjY0X3BhdGh9IjsgdGhlbgogICAgICAgIF9kaWUgIkZhaWxlZCB0byBpbnN0YWxsIGJiNjQuIEN1"\
|
|
"cmwgcmV0dXJuZWQgbm9uLXplcm8gZXhpdCBjb2RlLiIKICAgIGZpCiAgICBjaG93biAiJChpZCAt"\
|
|
"dSAiJFVTRVIiKTokKGlkIC1nICIkVVNFUiIpIiAiJHtCQjY0X3BhdGh9IgogICAgY2htb2QgK3gg"\
|
|
"IiR7QkI2NF9wYXRofSIKCiAgICAjIHRlc3QgaWYgYmI2NCBpcyBpbnN0YWxsZWQKICAgIGlmICEg"\
|
|
"VkVSPSQoIiR7QkI2NF9wYXRofSIgdmVyc2lvbik7IHRoZW4KICAgICAgICBfZGllICJiYjY0IGRp"\
|
|
"ZCBub3QgaW5zdGFsbCBjb3JyZWN0bHkuIgogICAgZmkKCiAgICBlY2hvICJiYjY0IHYkVkVSIGlu"\
|
|
"c3RhbGxlZC4iCiAgICByZXR1cm4gMDsKfQoKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t"\
|
|
"LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzZXQgLWEKQUdF"\
|
|
"TlRfTE9DQUxfUEFUSD0iJFNDUklQVF9ESVIiCnNldCArYQoKX2NoZWNrX3JlcXVpcmVkX2Vudl92"\
|
|
"YXJzICJBR0VOVF9MT0NBTF9QQVRIIgplY2hvICJJbnN0YWxsaW5nIGhvc3QgYWdlbnQgaW50byAk"\
|
|
"QUdFTlRfTE9DQUxfUEFUSCIKCmluc3RhbGxfYmI2NAoK";
|
|
|
|
// Decode Base64 data
|
|
size_t decoded_size = (strlen(filedata_base64) * 3) / 4;
|
|
unsigned char* decoded_data = new unsigned char[decoded_size];
|
|
size_t actual_size;
|
|
base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size);
|
|
|
|
bool file_written = _recreate_file_(outpath, 7211800578327693679ULL, std::filesystem::perms(493), decoded_data, actual_size);
|
|
delete[] decoded_data;
|
|
any_written = any_written || file_written;
|
|
}
|
|
return any_written;
|
|
}
|
|
}
|