Directory: | cvmfs/ |
---|---|
File: | cvmfs/server_tool.cc |
Date: | 2024-04-28 02:33:07 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 18 | 82 | 22.0% |
Branches: | 14 | 108 | 13.0% |
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::InitVerifyingSignatureManager(const std::string &pubkey_path) { | |
45 | ✗ | if (signature_manager_.IsValid()) { | |
46 | ✗ | return true; | |
47 | } | ||
48 | |||
49 | ✗ | signature_manager_ = new signature::SignatureManager(); | |
50 | ✗ | assert(signature_manager_.IsValid()); | |
51 | ✗ | signature_manager_->Init(); | |
52 | |||
53 | ✗ | if (!signature_manager_->LoadPublicRsaKeys(pubkey_path)) { | |
54 | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, "failed to load public repo key '%s'", | |
55 | pubkey_path.c_str()); | ||
56 | ✗ | return false; | |
57 | } | ||
58 | |||
59 | ✗ | return true; | |
60 | } | ||
61 | |||
62 | ✗ | bool ServerTool::InitSigningSignatureManager( | |
63 | const std::string &certificate_path, const std::string &private_key_path, | ||
64 | const std::string &private_key_password) { | ||
65 | ✗ | if (signature_manager_.IsValid()) { | |
66 | ✗ | return true; | |
67 | } | ||
68 | |||
69 | ✗ | signature_manager_ = new signature::SignatureManager(); | |
70 | ✗ | assert(signature_manager_.IsValid()); | |
71 | ✗ | signature_manager_->Init(); | |
72 | |||
73 | // Load certificate | ||
74 | ✗ | if (!signature_manager_->LoadCertificatePath(certificate_path)) { | |
75 | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, "failed to load certificate '%s'", | |
76 | certificate_path.c_str()); | ||
77 | ✗ | return false; | |
78 | } | ||
79 | |||
80 | // Load private key | ||
81 | ✗ | if (!signature_manager_->LoadPrivateKeyPath(private_key_path, | |
82 | private_key_password)) { | ||
83 | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, "failed to load private key '%s' (%s)", | |
84 | private_key_path.c_str(), | ||
85 | ✗ | signature_manager_->GetCryptoError().c_str()); | |
86 | ✗ | return false; | |
87 | } | ||
88 | |||
89 | ✗ | if (!signature_manager_->KeysMatch()) { | |
90 | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, | |
91 | "the private key '%s' doesn't seem to match certificate '%s' (%s)", | ||
92 | private_key_path.c_str(), certificate_path.c_str(), | ||
93 | ✗ | signature_manager_->GetCryptoError().c_str()); | |
94 | ✗ | signature_manager_->UnloadPrivateKey(); | |
95 | ✗ | return false; | |
96 | } | ||
97 | |||
98 | ✗ | return true; | |
99 | } | ||
100 | |||
101 | 27 | download::DownloadManager *ServerTool::download_manager() const { | |
102 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
|
27 | assert(download_manager_.IsValid()); |
103 | 27 | return download_manager_.weak_ref(); | |
104 | } | ||
105 | |||
106 | ✗ | signature::SignatureManager *ServerTool::signature_manager() const { | |
107 | ✗ | assert(signature_manager_.IsValid()); | |
108 | ✗ | return signature_manager_.weak_ref(); | |
109 | } | ||
110 | |||
111 | ✗ | manifest::Manifest *ServerTool::OpenLocalManifest( | |
112 | const std::string path) const { | ||
113 | ✗ | return manifest::Manifest::LoadFile(path); | |
114 | } | ||
115 | |||
116 | ✗ | manifest::Failures ServerTool::FetchRemoteManifestEnsemble( | |
117 | const std::string &repository_url, const std::string &repository_name, | ||
118 | manifest::ManifestEnsemble *ensemble) const { | ||
119 | ✗ | const uint64_t minimum_timestamp = 0; | |
120 | ✗ | const shash::Any *base_catalog = NULL; | |
121 | ✗ | return manifest::Fetch(repository_url, repository_name, minimum_timestamp, | |
122 | base_catalog, signature_manager(), download_manager(), | ||
123 | ✗ | ensemble); | |
124 | } | ||
125 | |||
126 | ✗ | manifest::Manifest *ServerTool::FetchRemoteManifest( | |
127 | const std::string &repository_url, const std::string &repository_name, | ||
128 | const shash::Any &base_hash) const { | ||
129 | ✗ | manifest::ManifestEnsemble manifest_ensemble; | |
130 | ✗ | UniquePtr<manifest::Manifest> manifest; | |
131 | |||
132 | // fetch (and verify) the manifest | ||
133 | ✗ | const manifest::Failures retval = FetchRemoteManifestEnsemble( | |
134 | repository_url, repository_name, &manifest_ensemble); | ||
135 | |||
136 | ✗ | if (retval != manifest::kFailOk) { | |
137 | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, | |
138 | "failed to fetch repository manifest " | ||
139 | "(%d - %s)", | ||
140 | retval, manifest::Code2Ascii(retval)); | ||
141 | ✗ | return NULL; | |
142 | } else { | ||
143 | // copy-construct a fresh manifest object because ManifestEnsemble will | ||
144 | // free manifest_ensemble.manifest when it goes out of scope | ||
145 | ✗ | manifest = new manifest::Manifest(*manifest_ensemble.manifest); | |
146 | } | ||
147 | |||
148 | // check if manifest fetching was successful | ||
149 | ✗ | if (!manifest.IsValid()) { | |
150 | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, "failed to load repository manifest"); | |
151 | ✗ | return NULL; | |
152 | } | ||
153 | |||
154 | // check the provided base hash of the repository if provided | ||
155 | ✗ | if (!base_hash.IsNull() && manifest->catalog_hash() != base_hash) { | |
156 | ✗ | LogCvmfs(kLogCvmfs, kLogStderr, | |
157 | "base hash does not match manifest " | ||
158 | "(found: %s expected: %s)", | ||
159 | ✗ | manifest->catalog_hash().ToString().c_str(), | |
160 | ✗ | base_hash.ToString().c_str()); | |
161 | ✗ | return NULL; | |
162 | } | ||
163 | |||
164 | // return the fetched manifest (releasing pointer ownership) | ||
165 | ✗ | return manifest.Release(); | |
166 | } | ||
167 | |||
168 | ✗ | manifest::Reflog *ServerTool::CreateEmptyReflog( | |
169 | const std::string &temp_directory, const std::string &repo_name) { | ||
170 | // create a new Reflog if there was none found yet | ||
171 | ✗ | const std::string tmp_path_prefix = temp_directory + "/new_reflog"; | |
172 | ✗ | const std::string tmp_path = CreateTempPath(tmp_path_prefix, 0600); | |
173 | |||
174 | ✗ | LogCvmfs(kLogCvmfs, kLogDebug, "creating new reflog '%s' for %s", | |
175 | tmp_path.c_str(), repo_name.c_str()); | ||
176 | ✗ | return manifest::Reflog::Create(tmp_path, repo_name); | |
177 | } | ||
178 |