Repository navigation
Expand file tree
/
Copy pathverify.cpp
More file actions
99 lines (75 loc) · 2.41 KB
/
Copy pathverify.cpp
File metadata and controls
99 lines (75 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "verify.h"
#include "scan.h"
#include "json.hpp"
#include <fstream>
#include <map>
#include <stdexcept>
namespace HashGuard
{
VerifyResult VerifyDirectory(
const std::filesystem::path& directory,
const std::filesystem::path& dataPath)
{
std::ifstream input(dataPath, std::ios::binary);
if (!input)
{
throw std::runtime_error("data.json not found");
}
nlohmann::json data;
input >> data;
if (!data.is_object() || !data.contains("version") || data.at("version") != 1 || !data.contains("files") || !data.at("files").is_array())
{
throw std::runtime_error("invalid baseline format");
}
std::map<std::string, std::string> oldFiles;
for (const auto& file : data.at("files"))
{
std::string path = file.at("path").get<std::string>();
std::string hash = file.at("sha256").get<std::string>();
if (path.empty() || hash.size() != 64)
{
throw std::runtime_error("invalid baseline entry");
}
if (!oldFiles.emplace(path, hash).second)
{
throw std::runtime_error("duplicate baseline path");
}
}
ScanResult scan = ScanDirectory(directory);
if (!scan.errors.empty())
{
throw std::runtime_error(
"scan failed, verification incomplete");
}
VerifyResult result;
std::map<std::string, std::string> newFiles;
for (const auto& file : scan.files)
{
newFiles[file.path.generic_string()] = file.sha256;
}
for (const auto& [path, hash] : newFiles)
{
auto it = oldFiles.find(path);
if (it == oldFiles.end())
{
result.added.push_back(path);
}
else if (it->second != hash)
{
result.modified.push_back(path);
}
else
{
result.unchanged.push_back(path);
}
}
for (const auto& [path, hash] : oldFiles)
{
if (newFiles.find(path) == newFiles.end())
{
result.deleted.push_back(path);
}
}
return result;
}
}