• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender / 1047260214

24 Oct 2023 08:50AM UTC coverage: 80.226% (-0.1%) from 80.34%
1047260214

push

gitlab-ci

oleorhagen
test(artifact): Add signature verification of the test artifact for RSA

Signed-off-by: Ole Petter <ole.orhagen@northern.tech>

6873 of 8567 relevant lines covered (80.23%)

9388.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.52
/common/config_parser/config_parser.cpp
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
#include <common/config_parser.hpp>
16

17
#include <string>
18
#include <vector>
19
#include <algorithm>
20

21
#include <common/json.hpp>
22
#include <common/log.hpp>
23

24
namespace mender {
25
namespace common {
26
namespace config_parser {
27

28
using namespace std;
29

30
namespace json = mender::common::json;
31
namespace log = mender::common::log;
32

33
const ConfigParserErrorCategoryClass ConfigParserErrorCategory;
34

35
const char *ConfigParserErrorCategoryClass::name() const noexcept {
×
36
        return "ConfigParserErrorCategory";
×
37
}
38

39
string ConfigParserErrorCategoryClass::message(int code) const {
×
40
        switch (code) {
×
41
        case NoError:
42
                return "Success";
×
43
        case ValidationError:
44
                return "Validation error";
×
45
        default:
46
                return "Unknown";
×
47
        }
48
}
49

50
error::Error MakeError(ConfigParserErrorCode code, const string &msg) {
1✔
51
        return error::Error(error_condition(code, ConfigParserErrorCategory), msg);
3✔
52
}
53

54
ExpectedBool MenderConfigFromFile::ValidateServerConfig() const {
6✔
55
        if (server_url.size() != 0 && servers.size() != 0) {
6✔
56
                auto err = MakeError(
57
                        ConfigParserErrorCode::ValidationError,
58
                        "Both 'Servers' AND 'ServerURL given in the configuration. Please set only one of these fields");
2✔
59
                return expected::unexpected(err);
2✔
60
        }
61

62
        if (servers.size() == 0) {
5✔
63
                if (server_url.size() == 0) {
4✔
64
                        log::Warning(
3✔
65
                                "No ServerURL found in the configuration. The client will not be able to download updates");
6✔
66
                }
67
        }
68
        return true;
69
}
70

71
ExpectedBool MenderConfigFromFile::LoadFile(const string &path) {
236✔
72
        const json::ExpectedJson e_cfg_json = json::LoadFromFile(path);
472✔
73
        if (!e_cfg_json) {
236✔
74
                auto err = e_cfg_json.error();
220✔
75
                return expected::unexpected(err);
440✔
76
        }
77

78
        bool applied = false;
79

80
        const json::Json cfg_json = e_cfg_json.value();
16✔
81

82
        json::ExpectedJson e_cfg_value = cfg_json.Get("DeviceTypeFile");
16✔
83
        if (e_cfg_value) {
16✔
84
                const json::Json value_json = e_cfg_value.value();
11✔
85
                const json::ExpectedString e_cfg_string = value_json.GetString();
11✔
86
                if (e_cfg_string) {
11✔
87
                        this->device_type_file = e_cfg_string.value();
11✔
88
                        applied = true;
89
                }
90
        }
91

92
        e_cfg_value = cfg_json.Get("ServerCertificate");
32✔
93
        if (e_cfg_value) {
16✔
94
                const json::Json value_json = e_cfg_value.value();
7✔
95
                const json::ExpectedString e_cfg_string = value_json.GetString();
7✔
96
                if (e_cfg_string) {
7✔
97
                        this->server_certificate = e_cfg_string.value();
7✔
98
                        applied = true;
99
                }
100
        }
101

102
        e_cfg_value = cfg_json.Get("ServerURL");
32✔
103
        if (e_cfg_value) {
16✔
104
                const json::Json value_json = e_cfg_value.value();
11✔
105
                const json::ExpectedString e_cfg_string = value_json.GetString();
11✔
106
                if (e_cfg_string) {
11✔
107
                        this->server_url = e_cfg_string.value();
11✔
108
                        applied = true;
109
                }
110
        }
111

112
        e_cfg_value = cfg_json.Get("UpdateLogPath");
32✔
113
        if (e_cfg_value) {
16✔
114
                const json::Json value_json = e_cfg_value.value();
8✔
115
                const json::ExpectedString e_cfg_string = value_json.GetString();
8✔
116
                if (e_cfg_string) {
8✔
117
                        this->update_log_path = e_cfg_string.value();
8✔
118
                        applied = true;
119
                }
120
        }
121

122
        e_cfg_value = cfg_json.Get("TenantToken");
32✔
123
        if (e_cfg_value) {
16✔
124
                const json::Json value_json = e_cfg_value.value();
7✔
125
                const json::ExpectedString e_cfg_string = value_json.GetString();
7✔
126
                if (e_cfg_string) {
7✔
127
                        this->tenant_token = e_cfg_string.value();
7✔
128
                        applied = true;
129
                }
130
        }
131

132
        e_cfg_value = cfg_json.Get("DaemonLogLevel");
32✔
133
        if (e_cfg_value) {
16✔
134
                const json::Json value_json = e_cfg_value.value();
9✔
135
                const json::ExpectedString e_cfg_string = value_json.GetString();
9✔
136
                if (e_cfg_string) {
9✔
137
                        this->daemon_log_level = e_cfg_string.value();
9✔
138
                        applied = true;
139
                }
140
        }
141

142
        /* Boolean values now */
143
        e_cfg_value = cfg_json.Get("SkipVerify");
32✔
144
        if (e_cfg_value) {
16✔
145
                const json::Json value_json = e_cfg_value.value();
9✔
146
                const json::ExpectedBool e_cfg_bool = value_json.GetBool();
9✔
147
                if (e_cfg_bool) {
9✔
148
                        this->skip_verify = e_cfg_bool.value();
9✔
149
                        applied = true;
150
                }
151
        }
152

153
        e_cfg_value = cfg_json.Get("UpdatePollIntervalSeconds");
32✔
154
        if (e_cfg_value) {
16✔
155
                const json::Json value_json = e_cfg_value.value();
7✔
156
                const auto e_cfg_int = value_json.GetInt();
7✔
157
                if (e_cfg_int) {
7✔
158
                        this->update_poll_interval_seconds = e_cfg_int.value();
7✔
159
                        applied = true;
160
                }
161
        }
162

163
        e_cfg_value = cfg_json.Get("InventoryPollIntervalSeconds");
32✔
164
        if (e_cfg_value) {
16✔
165
                const json::Json value_json = e_cfg_value.value();
7✔
166
                const auto e_cfg_int = value_json.GetInt();
7✔
167
                if (e_cfg_int) {
7✔
168
                        this->inventory_poll_interval_seconds = e_cfg_int.value();
7✔
169
                        applied = true;
170
                }
171
        }
172

173
        e_cfg_value = cfg_json.Get("RetryPollIntervalSeconds");
32✔
174
        if (e_cfg_value) {
16✔
175
                const json::Json value_json = e_cfg_value.value();
7✔
176
                const auto e_cfg_int = value_json.GetInt();
7✔
177
                if (e_cfg_int) {
7✔
178
                        this->retry_poll_interval_seconds = e_cfg_int.value();
7✔
179
                        applied = true;
180
                }
181
        }
182

183
        e_cfg_value = cfg_json.Get("RetryPollCount");
32✔
184
        if (e_cfg_value) {
16✔
185
                const json::Json value_json = e_cfg_value.value();
7✔
186
                const auto e_cfg_int = value_json.GetInt();
7✔
187
                if (e_cfg_int) {
7✔
188
                        this->retry_poll_count = e_cfg_int.value();
7✔
189
                        applied = true;
190
                }
191
        }
192

193
        e_cfg_value = cfg_json.Get("StateScriptTimeoutSeconds");
32✔
194
        if (e_cfg_value) {
16✔
195
                const json::Json value_json = e_cfg_value.value();
7✔
196
                const auto e_cfg_int = value_json.GetInt();
7✔
197
                if (e_cfg_int) {
7✔
198
                        this->state_script_timeout_seconds = e_cfg_int.value();
7✔
199
                        applied = true;
200
                }
201
        }
202

203
        e_cfg_value = cfg_json.Get("StateScriptRetryTimeoutSeconds");
32✔
204
        if (e_cfg_value) {
16✔
205
                const json::Json value_json = e_cfg_value.value();
7✔
206
                const auto e_cfg_int = value_json.GetInt();
7✔
207
                if (e_cfg_int) {
7✔
208
                        this->state_script_retry_timeout_seconds = e_cfg_int.value();
7✔
209
                        applied = true;
210
                }
211
        }
212

213
        e_cfg_value = cfg_json.Get("StateScriptRetryIntervalSeconds");
32✔
214
        if (e_cfg_value) {
16✔
215
                const json::Json value_json = e_cfg_value.value();
7✔
216
                const auto e_cfg_int = value_json.GetInt();
7✔
217
                if (e_cfg_int) {
7✔
218
                        this->state_script_retry_interval_seconds = e_cfg_int.value();
7✔
219
                        applied = true;
220
                }
221
        }
222

223
        e_cfg_value = cfg_json.Get("ModuleTimeoutSeconds");
32✔
224
        if (e_cfg_value) {
16✔
225
                const json::Json value_json = e_cfg_value.value();
7✔
226
                const auto e_cfg_int = value_json.GetInt();
7✔
227
                if (e_cfg_int) {
7✔
228
                        this->module_timeout_seconds = e_cfg_int.value();
7✔
229
                        applied = true;
230
                }
231
        }
232

233

234
        e_cfg_value = cfg_json.Get("ArtifactVerifyKeys");
32✔
235
        if (e_cfg_value) {
16✔
236
                const json::Json value_array = e_cfg_value.value();
9✔
237
                const json::ExpectedSize e_n_items = value_array.GetArraySize();
9✔
238
                if (e_n_items) {
9✔
239
                        for (size_t i = 0; i < e_n_items.value(); i++) {
33✔
240
                                const json::ExpectedJson e_array_item = value_array.Get(i);
24✔
241
                                if (e_array_item) {
24✔
242
                                        const json::ExpectedString e_item_string = e_array_item.value().GetString();
24✔
243
                                        if (e_item_string) {
24✔
244
                                                const string item_value = e_item_string.value();
24✔
245
                                                if (count(
24✔
246
                                                                this->artifact_verify_keys.begin(),
247
                                                                this->artifact_verify_keys.end(),
248
                                                                item_value)
249
                                                        == 0) {
250
                                                        this->artifact_verify_keys.push_back(item_value);
24✔
251
                                                        applied = true;
252
                                                }
253
                                        }
254
                                }
255
                        }
256
                }
257
        }
258

259
        e_cfg_value = cfg_json.Get("ArtifactVerifyKey");
32✔
260
        if (e_cfg_value) {
16✔
261
                const json::Json value_json = e_cfg_value.value();
2✔
262
                const json::ExpectedString e_cfg_string = value_json.GetString();
2✔
263
                if (e_cfg_string) {
2✔
264
                        if (artifact_verify_keys.size() != 0) {
2✔
265
                                auto err = MakeError(
266
                                        ConfigParserErrorCode::ValidationError,
267
                                        "Both 'ArtifactVerifyKey' and 'ArtifactVerifyKeys' are set");
2✔
268
                                return expected::unexpected(err);
2✔
269
                        }
270
                        this->artifact_verify_keys.push_back(e_cfg_string.value());
1✔
271
                        applied = true;
272
                }
273
        }
274

275
        e_cfg_value = cfg_json.Get("Servers");
30✔
276
        if (e_cfg_value) {
15✔
277
                const json::Json value_array = e_cfg_value.value();
8✔
278
                const json::ExpectedSize e_n_items = value_array.GetArraySize();
8✔
279
                if (e_n_items) {
8✔
280
                        for (size_t i = 0; i < e_n_items.value(); i++) {
23✔
281
                                const json::ExpectedJson e_array_item = value_array.Get(i);
15✔
282
                                if (e_array_item) {
15✔
283
                                        const json::ExpectedJson e_item_json = e_array_item.value().Get("ServerURL");
15✔
284
                                        if (e_item_json) {
15✔
285
                                                const json::ExpectedString e_item_string = e_item_json.value().GetString();
15✔
286
                                                if (e_item_string) {
15✔
287
                                                        const string item_value = e_item_string.value();
15✔
288
                                                        if (count(this->servers.begin(), this->servers.end(), item_value)
15✔
289
                                                                == 0) {
290
                                                                this->servers.push_back(std::move(item_value));
15✔
291
                                                                applied = true;
292
                                                        }
293
                                                }
294
                                        }
295
                                }
296
                        }
297
                }
298
        }
299

300
        /* Last but not least, complex values */
301
        e_cfg_value = cfg_json.Get("HttpsClient");
30✔
302
        if (e_cfg_value) {
15✔
303
                const json::Json value_json = e_cfg_value.value();
8✔
304
                json::ExpectedJson e_cfg_subval = value_json.Get("Certificate");
8✔
305
                if (e_cfg_subval) {
8✔
306
                        const json::Json subval_json = e_cfg_subval.value();
8✔
307
                        const json::ExpectedString e_cfg_string = subval_json.GetString();
8✔
308
                        if (e_cfg_string) {
8✔
309
                                this->https_client.certificate = e_cfg_string.value();
8✔
310
                                applied = true;
311
                        }
312
                }
313

314
                e_cfg_subval = value_json.Get("Key");
16✔
315
                if (e_cfg_subval) {
8✔
316
                        const json::Json subval_json = e_cfg_subval.value();
7✔
317
                        const json::ExpectedString e_cfg_string = subval_json.GetString();
7✔
318
                        if (e_cfg_string) {
7✔
319
                                this->https_client.key = e_cfg_string.value();
7✔
320
                                applied = true;
321
                        }
322
                }
323

324
                e_cfg_subval = value_json.Get("SSLEngine");
16✔
325
                if (e_cfg_subval) {
8✔
326
                        const json::Json subval_json = e_cfg_subval.value();
7✔
327
                        const json::ExpectedString e_cfg_string = subval_json.GetString();
7✔
328
                        if (e_cfg_string) {
7✔
329
                                this->https_client.ssl_engine = e_cfg_string.value();
7✔
330
                                applied = true;
331
                        }
332
                }
333
        }
334

335
        e_cfg_value = cfg_json.Get("Security");
30✔
336
        if (e_cfg_value) {
15✔
337
                const json::Json value_json = e_cfg_value.value();
7✔
338
                json::ExpectedJson e_cfg_subval = value_json.Get("AuthPrivateKey");
7✔
339
                if (e_cfg_subval) {
7✔
340
                        const json::Json subval_json = e_cfg_subval.value();
7✔
341
                        const json::ExpectedString e_cfg_string = subval_json.GetString();
7✔
342
                        if (e_cfg_string) {
7✔
343
                                this->security.auth_private_key = e_cfg_string.value();
7✔
344
                                applied = true;
345
                        }
346
                }
347

348
                e_cfg_subval = value_json.Get("SSLEngine");
14✔
349
                if (e_cfg_subval) {
7✔
350
                        const json::Json subval_json = e_cfg_subval.value();
7✔
351
                        const json::ExpectedString e_cfg_string = subval_json.GetString();
7✔
352
                        if (e_cfg_string) {
7✔
353
                                this->security.ssl_engine = e_cfg_string.value();
7✔
354
                                applied = true;
355
                        }
356
                }
357
        }
358

359
        e_cfg_value = cfg_json.Get("Connectivity");
30✔
360
        if (e_cfg_value) {
15✔
361
                const json::Json value_json = e_cfg_value.value();
8✔
362
                json::ExpectedJson e_cfg_subval = value_json.Get("DisableKeepAlive");
8✔
363
                if (e_cfg_subval) {
8✔
364
                        const json::Json subval_json = e_cfg_subval.value();
8✔
365
                        const json::ExpectedBool e_cfg_bool = subval_json.GetBool();
8✔
366
                        if (e_cfg_bool) {
8✔
367
                                this->connectivity.disable_keep_alive = e_cfg_bool.value();
8✔
368
                                applied = true;
369
                        }
370
                }
371
        }
372

373
        return applied;
374
}
375

376
void MenderConfigFromFile::Reset() {
1✔
377
        *this = MenderConfigFromFile();
1✔
378
}
1✔
379

380
ExpectedBool MenderConfigFromFile::ValidateConfig() {
3✔
381
        auto server_conf = this->ValidateServerConfig();
3✔
382
        if (!server_conf) {
3✔
383
                return server_conf;
384
        }
385

386
        return true;
387
}
388

389

390

391
} // namespace config_parser
392
} // namespace common
393
} // namespace mender
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc