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 |