verify checksums

This commit is contained in:
2026-02-14 14:00:07 +01:00
parent 03d20665b4
commit b4564fa5bb
16 changed files with 206 additions and 21 deletions

View File

@@ -1,13 +1,15 @@
#include "parser.h"
#include "util.h"
#include <fstream>
#include <iostream>
#include <span>
#include <stdexcept>
#include <sys/stat.h>
#include <thread>
static bool flag_raw = false;
void install_package(const std::string &name) {
// TODO: get this by the name field not filename
// TODO: actually resolve dependency tree
// TODO: track installed packages
std::ifstream file("packages/" + name + ".shrap");
if (!file) {
std::cerr << "Package " << name << "not found.\n";
@@ -16,11 +18,13 @@ void install_package(const std::string &name) {
Expr pkg = Expr::parse(file);
try {
for (const auto &dep : pkg.get("dependencies").children) {
install_package(dep.value);
if (!flag_raw) {
try {
for (const auto &dep : pkg.get("dependencies").children) {
install_package(dep.value);
}
} catch (std::out_of_range &) {
}
} catch (std::out_of_range &) {
}
Expr src = pkg.get("src").children[0];
@@ -31,10 +35,18 @@ void install_package(const std::string &name) {
if (src_type == "tar") {
std::string archive_path = "/tmp/shrap/" + Util::basename(src_url);
// TODO: replace wget with a library for zero runtime dependencies
Util::shell_command("wget -O " + archive_path + " " + src_url);
// TODO: ship ca certificates
Util::shell_command("./curl -k -L -o " + archive_path + " " + src_url);
// TODO: check archive hash from src.get("blake3").children[0].value
std::string expected_hash = src.get("blake3").children[0].value;
std::string hash = Util::hash_file(archive_path);
if (expected_hash != hash) {
std::cerr << "Checksum check failed.\n";
std::cerr << "Expected: " << expected_hash << "\n";
std::cerr << "Got: " << hash << "\n";
std::exit(1);
}
Util::shell_command("tar xf " + archive_path + " -C /tmp/shrap/");
} else {
@@ -72,10 +84,27 @@ int main(int argc, char **argv) {
}
Util::shell_command("mkdir -p /tmp/shrap");
try {
install_package(args[1]);
} catch (std::exception &e) {
std::cerr << "ERROR: " << e.what() << std::endl;
std::vector<std::string> packages;
for (size_t i = 1; i < args.size(); ++i) {
std::string arg = args[i];
if (arg == "-r") {
flag_raw = true;
} else {
packages.push_back(arg);
}
}
if (packages.empty()) {
std::cerr << "Usage: " << args[0] << " [-r] package1 [package2 ...]\n";
return 1;
}
for (const auto &pkg : packages) {
try {
install_package(pkg);
} catch (std::exception &e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
}
}

View File

@@ -1,9 +1,15 @@
#pragma once
#include "blake3.h"
#include <array>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>
namespace Util {
@@ -47,4 +53,30 @@ static std::string basename(const std::string &path) {
return path.substr(pos + 1);
}
static std::string hash_file(const std::string &path) {
blake3_hasher hasher;
blake3_hasher_init(&hasher);
std::ifstream file(path, std::ios::binary);
if (!file) {
throw std::runtime_error("failed to open file");
}
std::vector<char> buffer(65536);
while (file.read(buffer.data(), static_cast<long>(buffer.size())) ||
file.gcount() > 0) {
blake3_hasher_update(&hasher, buffer.data(), file.gcount());
}
std::array<uint8_t, BLAKE3_OUT_LEN> output{};
blake3_hasher_finalize(&hasher, output.data(), BLAKE3_OUT_LEN);
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (const auto &byte : output) {
ss << std::setw(2) << static_cast<int>(byte);
}
return ss.str();
}
}; // namespace Util