GCC Code Coverage Report


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