GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/server_tool.cc
Date: 2025-06-29 02:35:41
Exec Total Coverage
Lines: 18 78 23.1%
Branches: 14 110 12.7%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "server_tool.h"
6
7 #include "util/posix.h"
8
9
2/4
✓ Branch 2 taken 474 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 474 times.
✗ Branch 6 not taken.
474 ServerTool::ServerTool() { }
10
11 954 ServerTool::~ServerTool() {
12
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 473 times.
946 if (signature_manager_.IsValid()) {
13 signature_manager_->Fini();
14 }
15 954 }
16
17 474 bool ServerTool::InitDownloadManager(const bool follow_redirects,
18 const std::string &proxy,
19 const unsigned max_pool_handles) {
20
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 474 times.
474 if (download_manager_.IsValid()) {
21 return true;
22 }
23
24 download_manager_ = new download::DownloadManager(
25
6/12
✓ Branch 3 taken 474 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 474 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 474 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 474 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 474 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 474 times.
✗ Branch 20 not taken.
474 max_pool_handles, perf::StatisticsTemplate("download", statistics()));
26
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 474 times.
474 assert(download_manager_.IsValid());
27
28 474 download_manager_->SetTimeout(kDownloadTimeout, kDownloadTimeout);
29 474 download_manager_->SetRetryParameters(kDownloadRetries, 2000, 5000);
30 474 download_manager_->UseSystemCertificatePath();
31
32
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 474 times.
474 if (proxy != "") {
33 download_manager_->SetProxyChain(proxy, "",
34 download::DownloadManager::kSetProxyBoth);
35 }
36
37
1/2
✓ Branch 0 taken 474 times.
✗ Branch 1 not taken.
474 if (follow_redirects) {
38 474 download_manager_->EnableRedirects();
39 }
40
41 474 return true;
42 }
43
44 bool ServerTool::InitSignatureManager(const std::string &pubkey_path,
45 const std::string &certificate_path,
46 const std::string &private_key_path) {
47 if (signature_manager_.IsValid()) {
48 return true;
49 }
50
51 signature_manager_ = new signature::SignatureManager();
52 assert(signature_manager_.IsValid());
53 signature_manager_->Init();
54
55 // We may not have a public key. In this case, the signature manager
56 // can only be used for signing, not for verification.
57 if (!pubkey_path.empty()) {
58 if (!signature_manager_->LoadPublicRsaKeys(pubkey_path)) {
59 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load public repo key '%s'",
60 pubkey_path.c_str());
61 return false;
62 }
63 }
64
65 // We may not have a certificate and key. In this case, the signature manager
66 // can only be used for verification, not for signing.
67 if (certificate_path.empty())
68 return true;
69
70 if (!signature_manager_->LoadCertificatePath(certificate_path)) {
71 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load certificate '%s'",
72 certificate_path.c_str());
73 return false;
74 }
75
76 // Load private key
77 if (!signature_manager_->LoadPrivateKeyPath(private_key_path, "")) {
78 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load private key '%s' (%s)",
79 private_key_path.c_str(),
80 signature_manager_->GetCryptoError().c_str());
81 return false;
82 }
83
84 if (!signature_manager_->KeysMatch()) {
85 LogCvmfs(kLogCvmfs, kLogStderr,
86 "the private key '%s' doesn't seem to match certificate '%s' (%s)",
87 private_key_path.c_str(), certificate_path.c_str(),
88 signature_manager_->GetCryptoError().c_str());
89 signature_manager_->UnloadPrivateKey();
90 return false;
91 }
92
93 return true;
94 }
95
96 560 download::DownloadManager *ServerTool::download_manager() const {
97
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 560 times.
560 assert(download_manager_.IsValid());
98 560 return download_manager_.weak_ref();
99 }
100
101 signature::SignatureManager *ServerTool::signature_manager() const {
102 assert(signature_manager_.IsValid());
103 return signature_manager_.weak_ref();
104 }
105
106 manifest::Manifest *ServerTool::OpenLocalManifest(
107 const std::string path) const {
108 return manifest::Manifest::LoadFile(path);
109 }
110
111 manifest::Failures ServerTool::FetchRemoteManifestEnsemble(
112 const std::string &repository_url, const std::string &repository_name,
113 manifest::ManifestEnsemble *ensemble) const {
114 const uint64_t minimum_timestamp = 0;
115 const shash::Any *base_catalog = NULL;
116 return manifest::Fetch(repository_url, repository_name, minimum_timestamp,
117 base_catalog, signature_manager(), download_manager(),
118 ensemble);
119 }
120
121 manifest::Manifest *ServerTool::FetchRemoteManifest(
122 const std::string &repository_url, const std::string &repository_name,
123 const shash::Any &base_hash) const {
124 manifest::ManifestEnsemble manifest_ensemble;
125 UniquePtr<manifest::Manifest> manifest;
126
127 // fetch (and verify) the manifest
128 const manifest::Failures retval = FetchRemoteManifestEnsemble(
129 repository_url, repository_name, &manifest_ensemble);
130
131 if (retval != manifest::kFailOk) {
132 LogCvmfs(kLogCvmfs, kLogStderr,
133 "failed to fetch repository manifest "
134 "(%d - %s)",
135 retval, manifest::Code2Ascii(retval));
136 return NULL;
137 } else {
138 // copy-construct a fresh manifest object because ManifestEnsemble will
139 // free manifest_ensemble.manifest when it goes out of scope
140 manifest = new manifest::Manifest(*manifest_ensemble.manifest);
141 }
142
143 // check if manifest fetching was successful
144 if (!manifest.IsValid()) {
145 LogCvmfs(kLogCvmfs, kLogStderr, "failed to load repository manifest");
146 return NULL;
147 }
148
149 // check the provided base hash of the repository if provided
150 if (!base_hash.IsNull() && manifest->catalog_hash() != base_hash) {
151 LogCvmfs(kLogCvmfs, kLogStderr,
152 "base hash does not match manifest "
153 "(found: %s expected: %s)",
154 manifest->catalog_hash().ToString().c_str(),
155 base_hash.ToString().c_str());
156 return NULL;
157 }
158
159 // return the fetched manifest (releasing pointer ownership)
160 return manifest.Release();
161 }
162
163 manifest::Reflog *ServerTool::CreateEmptyReflog(
164 const std::string &temp_directory, const std::string &repo_name) {
165 // create a new Reflog if there was none found yet
166 const std::string tmp_path_prefix = temp_directory + "/new_reflog";
167 const std::string tmp_path = CreateTempPath(tmp_path_prefix, 0600);
168
169 LogCvmfs(kLogCvmfs, kLogDebug, "creating new reflog '%s' for %s",
170 tmp_path.c_str(), repo_name.c_str());
171 return manifest::Reflog::Create(tmp_path, repo_name);
172 }
173