blob: 6ef3ce8d4c52fe054f914b4980efe3f328c45dc1 [file] [log] [blame]
Junxiao Shid7631272016-08-17 04:16:31 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shia9079802017-08-26 14:12:30 +00002/*
Davide Pesaventoa599d2a2022-02-16 18:52:43 -05003 * Copyright (c) 2014-2022, Regents of the University of California,
Junxiao Shid7631272016-08-17 04:16:31 +00004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "mgmt/command-authenticator.hpp"
Junxiao Shid7631272016-08-17 04:16:31 +000027
Davide Pesavento78ddcab2019-02-28 22:00:03 -050028#include "manager-common-fixture.hpp"
Junxiao Shid7631272016-08-17 04:16:31 +000029
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040030namespace nfd::tests {
Junxiao Shid7631272016-08-17 04:16:31 +000031
Davide Pesavento20cafa82022-07-25 01:15:03 -040032class CommandAuthenticatorFixture : public InterestSignerFixture
Junxiao Shid7631272016-08-17 04:16:31 +000033{
34protected:
Junxiao Shid7631272016-08-17 04:16:31 +000035 void
36 makeModules(std::initializer_list<std::string> modules)
37 {
Davide Pesavento20cafa82022-07-25 01:15:03 -040038 for (const auto& module : modules) {
Junxiao Shid7631272016-08-17 04:16:31 +000039 authorizations.emplace(module, authenticator->makeAuthorization(module, "verb"));
40 }
41 }
42
43 void
44 loadConfig(const std::string& config)
45 {
Junxiao Shid7631272016-08-17 04:16:31 +000046 ConfigFile cf;
47 authenticator->setConfigFile(cf);
Davide Pesavento20cafa82022-07-25 01:15:03 -040048 cf.parse(config, false, "command-authenticator-test.conf");
Junxiao Shid7631272016-08-17 04:16:31 +000049 }
50
51 bool
52 authorize(const std::string& module, const Name& identity,
Davide Pesavento6d6f2072022-09-12 23:08:34 -040053 const std::function<void(Interest&)>& modifyInterest = nullptr,
Davide Pesaventob83d3df2022-09-13 14:04:34 -040054 ndn::security::SignedInterestFormat format = ndn::security::SignedInterestFormat::V03)
Junxiao Shid7631272016-08-17 04:16:31 +000055 {
Davide Pesavento6d6f2072022-09-12 23:08:34 -040056 Interest interest = makeControlCommandRequest(Name("/prefix/" + module + "/verb"),
57 {}, format, identity);
58 if (modifyInterest) {
Junxiao Shi8a1f1702017-07-03 00:05:08 +000059 modifyInterest(interest);
Junxiao Shid7631272016-08-17 04:16:31 +000060 }
61
Davide Pesavento20cafa82022-07-25 01:15:03 -040062 const auto& authorization = authorizations.at(module);
Junxiao Shid7631272016-08-17 04:16:31 +000063
64 bool isAccepted = false;
65 bool isRejected = false;
Junxiao Shi8a1f1702017-07-03 00:05:08 +000066 authorization(Name("/prefix"), interest, nullptr,
Junxiao Shid7631272016-08-17 04:16:31 +000067 [this, &isAccepted, &isRejected] (const std::string& requester) {
68 BOOST_REQUIRE_MESSAGE(!isAccepted && !isRejected,
69 "authorization function should invoke only one continuation");
70 isAccepted = true;
71 lastRequester = requester;
72 },
73 [this, &isAccepted, &isRejected] (ndn::mgmt::RejectReply act) {
74 BOOST_REQUIRE_MESSAGE(!isAccepted && !isRejected,
75 "authorization function should invoke only one continuation");
76 isRejected = true;
77 lastRejectReply = act;
78 });
79
Davide Pesaventod96744d2018-02-03 19:16:07 -050080 this->advanceClocks(1_ms, 10);
Junxiao Shid7631272016-08-17 04:16:31 +000081 BOOST_REQUIRE_MESSAGE(isAccepted || isRejected,
82 "authorization function should invoke one continuation");
83 return isAccepted;
84 }
85
86protected:
Davide Pesavento20cafa82022-07-25 01:15:03 -040087 shared_ptr<CommandAuthenticator> authenticator = CommandAuthenticator::create();
Junxiao Shid7631272016-08-17 04:16:31 +000088 std::unordered_map<std::string, ndn::mgmt::Authorization> authorizations;
89 std::string lastRequester;
90 ndn::mgmt::RejectReply lastRejectReply;
91};
92
93BOOST_AUTO_TEST_SUITE(Mgmt)
94BOOST_FIXTURE_TEST_SUITE(TestCommandAuthenticator, CommandAuthenticatorFixture)
95
96BOOST_AUTO_TEST_CASE(Certs)
97{
98 Name id0("/localhost/CommandAuthenticator/0");
99 Name id1("/localhost/CommandAuthenticator/1");
100 Name id2("/localhost/CommandAuthenticator/2");
Davide Pesavento21353752020-11-20 00:43:44 -0500101 BOOST_REQUIRE(m_keyChain.createIdentity(id0));
102 BOOST_REQUIRE(saveIdentityCert(id1, "1.ndncert", true));
103 BOOST_REQUIRE(saveIdentityCert(id2, "2.ndncert", true));
Junxiao Shid7631272016-08-17 04:16:31 +0000104
105 makeModules({"module0", "module1", "module2", "module3", "module4", "module5", "module6", "module7"});
Davide Pesavento20cafa82022-07-25 01:15:03 -0400106 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000107 authorizations
108 {
109 authorize
110 {
111 certfile any
112 privileges
113 {
114 module1
115 module3
116 module5
117 module7
118 }
119 }
120 authorize
121 {
122 certfile "1.ndncert"
123 privileges
124 {
125 module2
126 module3
127 module6
128 module7
129 }
130 }
131 authorize
132 {
133 certfile "2.ndncert"
134 privileges
135 {
136 module4
137 module5
138 module6
139 module7
140 }
141 }
142 }
143 )CONFIG";
144 loadConfig(config);
145
146 // module0: none
147 BOOST_CHECK_EQUAL(authorize("module0", id0), false);
148 BOOST_CHECK_EQUAL(authorize("module0", id1), false);
149 BOOST_CHECK_EQUAL(authorize("module0", id2), false);
150
151 // module1: any
152 BOOST_CHECK_EQUAL(authorize("module1", id0), true);
153 BOOST_CHECK_EQUAL(authorize("module1", id1), true);
154 BOOST_CHECK_EQUAL(authorize("module1", id2), true);
155
156 // module2: id1
157 BOOST_CHECK_EQUAL(authorize("module2", id0), false);
158 BOOST_CHECK_EQUAL(authorize("module2", id1), true);
159 BOOST_CHECK_EQUAL(authorize("module2", id2), false);
160
161 // module3: any,id1
162 BOOST_CHECK_EQUAL(authorize("module3", id0), true);
163 BOOST_CHECK_EQUAL(authorize("module3", id1), true);
164 BOOST_CHECK_EQUAL(authorize("module3", id2), true);
165
166 // module4: id2
167 BOOST_CHECK_EQUAL(authorize("module4", id0), false);
168 BOOST_CHECK_EQUAL(authorize("module4", id1), false);
169 BOOST_CHECK_EQUAL(authorize("module4", id2), true);
170
171 // module5: any,id2
172 BOOST_CHECK_EQUAL(authorize("module5", id0), true);
173 BOOST_CHECK_EQUAL(authorize("module5", id1), true);
174 BOOST_CHECK_EQUAL(authorize("module5", id2), true);
175
176 // module6: id1,id2
177 BOOST_CHECK_EQUAL(authorize("module6", id0), false);
178 BOOST_CHECK_EQUAL(authorize("module6", id1), true);
179 BOOST_CHECK_EQUAL(authorize("module6", id2), true);
180
181 // module7: any,id1,id2
182 BOOST_CHECK_EQUAL(authorize("module7", id0), true);
183 BOOST_CHECK_EQUAL(authorize("module7", id1), true);
184 BOOST_CHECK_EQUAL(authorize("module7", id2), true);
185}
186
187BOOST_AUTO_TEST_CASE(Requester)
188{
189 Name id0("/localhost/CommandAuthenticator/0");
190 Name id1("/localhost/CommandAuthenticator/1");
Davide Pesavento21353752020-11-20 00:43:44 -0500191 BOOST_REQUIRE(m_keyChain.createIdentity(id0));
192 BOOST_REQUIRE(saveIdentityCert(id1, "1.ndncert", true));
Junxiao Shid7631272016-08-17 04:16:31 +0000193
194 makeModules({"module0", "module1"});
Davide Pesavento20cafa82022-07-25 01:15:03 -0400195 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000196 authorizations
197 {
198 authorize
199 {
200 certfile any
201 privileges
202 {
203 module0
204 }
205 }
206 authorize
207 {
208 certfile "1.ndncert"
209 privileges
210 {
211 module1
212 }
213 }
214 }
215 )CONFIG";
216 loadConfig(config);
217
218 // module0: any
219 BOOST_CHECK_EQUAL(authorize("module0", id0), true);
220 BOOST_CHECK_EQUAL(lastRequester, "*");
221 BOOST_CHECK_EQUAL(authorize("module0", id1), true);
222 BOOST_CHECK_EQUAL(lastRequester, "*");
223
224 // module1: id1
225 BOOST_CHECK_EQUAL(authorize("module1", id0), false);
226 BOOST_CHECK_EQUAL(authorize("module1", id1), true);
227 BOOST_CHECK(id1.isPrefixOf(lastRequester));
228}
229
230class IdentityAuthorizedFixture : public CommandAuthenticatorFixture
231{
232protected:
233 IdentityAuthorizedFixture()
Junxiao Shid7631272016-08-17 04:16:31 +0000234 {
Davide Pesavento21353752020-11-20 00:43:44 -0500235 BOOST_REQUIRE(saveIdentityCert(id1, "1.ndncert", true));
Junxiao Shid7631272016-08-17 04:16:31 +0000236
237 makeModules({"module1"});
Davide Pesavento20cafa82022-07-25 01:15:03 -0400238 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000239 authorizations
240 {
241 authorize
242 {
243 certfile "1.ndncert"
244 privileges
245 {
246 module1
247 }
248 }
249 }
250 )CONFIG";
251 loadConfig(config);
252 }
253
254 bool
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400255 authorize1_V02(const std::function<void(Interest&)>& modifyInterest)
Junxiao Shid7631272016-08-17 04:16:31 +0000256 {
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400257 return authorize("module1", id1, modifyInterest, ndn::security::SignedInterestFormat::V02);
258 }
259
260 bool
261 authorize1_V03(const std::function<void(Interest&)>& modifyInterest)
262 {
263 return authorize("module1", id1, modifyInterest, ndn::security::SignedInterestFormat::V03);
Junxiao Shid7631272016-08-17 04:16:31 +0000264 }
265
266protected:
Davide Pesavento20cafa82022-07-25 01:15:03 -0400267 const Name id1{"/localhost/CommandAuthenticator/1"};
Junxiao Shid7631272016-08-17 04:16:31 +0000268};
269
Davide Pesavento20cafa82022-07-25 01:15:03 -0400270BOOST_FIXTURE_TEST_SUITE(Reject, IdentityAuthorizedFixture)
Junxiao Shid7631272016-08-17 04:16:31 +0000271
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400272BOOST_AUTO_TEST_CASE(NameTooShort)
Junxiao Shid7631272016-08-17 04:16:31 +0000273{
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400274 BOOST_CHECK_EQUAL(authorize1_V02(
Junxiao Shid7631272016-08-17 04:16:31 +0000275 [] (Interest& interest) {
276 interest.setName("/prefix");
277 }
278 ), false);
279 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::SILENT);
280}
281
Davide Pesavento20cafa82022-07-25 01:15:03 -0400282BOOST_AUTO_TEST_CASE(BadSigInfo)
Junxiao Shid7631272016-08-17 04:16:31 +0000283{
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400284 BOOST_CHECK_EQUAL(authorize1_V02(
Junxiao Shid7631272016-08-17 04:16:31 +0000285 [] (Interest& interest) {
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400286 setNameComponent(interest, ndn::command_interest::POS_SIG_INFO, "not-sig-info");
287 }
288 ), false);
289 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::SILENT);
290
291 BOOST_CHECK_EQUAL(authorize1_V03(
292 [] (Interest& interest) {
293 auto sigInfo = interest.getSignatureInfo().value();
294 sigInfo.addCustomTlv("7F00"_block);
295 interest.setSignatureInfo(sigInfo);
Junxiao Shid7631272016-08-17 04:16:31 +0000296 }
297 ), false);
298 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::SILENT);
299}
300
Davide Pesavento20cafa82022-07-25 01:15:03 -0400301BOOST_AUTO_TEST_CASE(MissingKeyLocator)
Junxiao Shid7631272016-08-17 04:16:31 +0000302{
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400303 BOOST_CHECK_EQUAL(authorize1_V02(
Junxiao Shid7631272016-08-17 04:16:31 +0000304 [] (Interest& interest) {
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400305 ndn::SignatureInfo sigInfo(interest.getName().at(ndn::command_interest::POS_SIG_INFO).blockFromValue());
306 sigInfo.setKeyLocator(ndn::nullopt);
307 setNameComponent(interest, ndn::command_interest::POS_SIG_INFO, span(sigInfo.wireEncode()));
308 }
309 ), false);
310 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::SILENT);
311
312 BOOST_CHECK_EQUAL(authorize1_V03(
313 [] (Interest& interest) {
314 auto sigInfo = interest.getSignatureInfo().value();
315 sigInfo.setKeyLocator(ndn::nullopt);
316 interest.setSignatureInfo(sigInfo);
Junxiao Shid7631272016-08-17 04:16:31 +0000317 }
318 ), false);
319 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::SILENT);
320}
321
Davide Pesavento20cafa82022-07-25 01:15:03 -0400322BOOST_AUTO_TEST_CASE(BadKeyLocatorType)
Junxiao Shid7631272016-08-17 04:16:31 +0000323{
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400324 ndn::KeyLocator kl;
325 kl.setKeyDigest(ndn::makeBinaryBlock(tlv::KeyDigest, {0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD}));
326
327 BOOST_CHECK_EQUAL(authorize1_V02(
328 [&kl] (Interest& interest) {
329 ndn::SignatureInfo sigInfo(tlv::SignatureSha256WithEcdsa, kl);
330 setNameComponent(interest, ndn::command_interest::POS_SIG_INFO, span(sigInfo.wireEncode()));
Junxiao Shid7631272016-08-17 04:16:31 +0000331 }
332 ), false);
333 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::SILENT);
Davide Pesaventob83d3df2022-09-13 14:04:34 -0400334
335 BOOST_CHECK_EQUAL(authorize1_V03(
336 [&kl] (Interest& interest) {
337 auto sigInfo = interest.getSignatureInfo().value();
338 sigInfo.setKeyLocator(kl);
339 interest.setSignatureInfo(sigInfo);
340 }
341 ), false);
342 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::SILENT);
343}
344
345BOOST_AUTO_TEST_CASE(BadSigValue)
346{
347 BOOST_CHECK_EQUAL(authorize1_V02(
348 [] (Interest& interest) {
349 setNameComponent(interest, ndn::command_interest::POS_SIG_VALUE, "bad-signature");
350 }
351 ), false);
352 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
353
354 BOOST_CHECK_EQUAL(authorize1_V03(
355 [] (Interest& interest) {
356 interest.setSignatureValue({0xBA, 0xAD});
357 }
358 ), false);
359 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
360}
361
362BOOST_AUTO_TEST_CASE(MissingTimestamp)
363{
364 BOOST_CHECK_EQUAL(authorize1_V02(
365 [] (Interest& interest) {
366 setNameComponent(interest, ndn::command_interest::POS_TIMESTAMP, "not-timestamp");
367 }
368 ), false);
369 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
370
371 BOOST_CHECK_EQUAL(authorize1_V03(
372 [] (Interest& interest) {
373 auto sigInfo = interest.getSignatureInfo().value();
374 sigInfo.setTime(ndn::nullopt);
375 interest.setSignatureInfo(sigInfo);
376 }
377 ), false);
378 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
379}
380
381BOOST_AUTO_TEST_CASE(ReplayedTimestamp)
382{
383 name::Component timestampComp;
384 BOOST_CHECK_EQUAL(authorize1_V02(
385 [&timestampComp] (const Interest& interest) {
386 timestampComp = interest.getName().at(ndn::command_interest::POS_TIMESTAMP);
387 }
388 ), true); // accept first command
389 BOOST_CHECK_EQUAL(authorize1_V02(
390 [&timestampComp] (Interest& interest) {
391 setNameComponent(interest, ndn::command_interest::POS_TIMESTAMP, timestampComp);
392 }
393 ), false); // reject second command because timestamp equals first command
394 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
395
396 time::system_clock::time_point tp;
397 BOOST_CHECK_EQUAL(authorize1_V03(
398 [&tp] (const Interest& interest) {
399 tp = interest.getSignatureInfo().value().getTime().value();
400 }
401 ), true); // accept first command
402 BOOST_CHECK_EQUAL(authorize1_V03(
403 [&tp] (Interest& interest) {
404 auto sigInfo = interest.getSignatureInfo().value();
405 sigInfo.setTime(tp);
406 interest.setSignatureInfo(sigInfo);
407 }
408 ), false); // reject second command because timestamp equals first command
409 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
Junxiao Shid7631272016-08-17 04:16:31 +0000410}
411
Junxiao Shid7631272016-08-17 04:16:31 +0000412BOOST_AUTO_TEST_CASE(NotAuthorized)
413{
414 Name id0("/localhost/CommandAuthenticator/0");
Davide Pesavento21353752020-11-20 00:43:44 -0500415 BOOST_REQUIRE(m_keyChain.createIdentity(id0));
Junxiao Shid7631272016-08-17 04:16:31 +0000416
417 BOOST_CHECK_EQUAL(authorize("module1", id0), false);
418 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
419}
420
Davide Pesaventod96744d2018-02-03 19:16:07 -0500421BOOST_FIXTURE_TEST_CASE(MissingAuthorizationsSection, CommandAuthenticatorFixture)
422{
423 Name id0("/localhost/CommandAuthenticator/0");
Davide Pesavento21353752020-11-20 00:43:44 -0500424 BOOST_REQUIRE(m_keyChain.createIdentity(id0));
Davide Pesaventod96744d2018-02-03 19:16:07 -0500425
426 makeModules({"module42"});
427 loadConfig("");
428
429 BOOST_CHECK_EQUAL(authorize("module42", id0), false);
430 BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
431}
432
Davide Pesavento20cafa82022-07-25 01:15:03 -0400433BOOST_AUTO_TEST_SUITE_END() // Reject
Junxiao Shid7631272016-08-17 04:16:31 +0000434
435BOOST_AUTO_TEST_SUITE(BadConfig)
436
437BOOST_AUTO_TEST_CASE(EmptyAuthorizationsSection)
438{
Davide Pesavento20cafa82022-07-25 01:15:03 -0400439 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000440 authorizations
441 {
442 }
443 )CONFIG";
444
445 BOOST_CHECK_THROW(loadConfig(config), ConfigFile::Error);
446}
447
448BOOST_AUTO_TEST_CASE(UnrecognizedKey)
449{
Davide Pesavento20cafa82022-07-25 01:15:03 -0400450 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000451 authorizations
452 {
453 unrecognized_key
454 {
455 }
456 }
457 )CONFIG";
458
459 BOOST_CHECK_THROW(loadConfig(config), ConfigFile::Error);
460}
461
462BOOST_AUTO_TEST_CASE(CertfileMissing)
463{
Davide Pesavento20cafa82022-07-25 01:15:03 -0400464 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000465 authorizations
466 {
467 authorize
468 {
469 privileges
470 {
471 }
472 }
473 }
474 )CONFIG";
475
476 BOOST_CHECK_THROW(loadConfig(config), ConfigFile::Error);
477}
478
479BOOST_AUTO_TEST_CASE(CertUnreadable)
480{
Davide Pesavento20cafa82022-07-25 01:15:03 -0400481 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000482 authorizations
483 {
484 authorize
485 {
486 certfile "1.ndncert"
487 privileges
488 {
489 }
490 }
491 }
492 )CONFIG";
493
494 BOOST_CHECK_THROW(loadConfig(config), ConfigFile::Error);
495}
496
497BOOST_AUTO_TEST_CASE(PrivilegesMissing)
498{
Davide Pesavento20cafa82022-07-25 01:15:03 -0400499 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000500 authorizations
501 {
502 authorize
503 {
504 certfile any
505 }
506 }
507 )CONFIG";
508
509 BOOST_CHECK_THROW(loadConfig(config), ConfigFile::Error);
510}
511
512BOOST_AUTO_TEST_CASE(UnregisteredModule)
513{
Davide Pesavento20cafa82022-07-25 01:15:03 -0400514 const std::string config = R"CONFIG(
Junxiao Shid7631272016-08-17 04:16:31 +0000515 authorizations
516 {
517 authorize
518 {
519 certfile any
520 privileges
521 {
522 nosuchmodule
523 }
524 }
525 }
526 )CONFIG";
527
528 BOOST_CHECK_THROW(loadConfig(config), ConfigFile::Error);
529}
530
531BOOST_AUTO_TEST_SUITE_END() // BadConfig
532
533BOOST_AUTO_TEST_SUITE_END() // TestCommandAuthenticator
534BOOST_AUTO_TEST_SUITE_END() // Mgmt
535
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400536} // namespace nfd::tests