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 |