Kea 3.0.0
hooks_parser.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2025 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <cc/data.h>
11#include <hooks/hooks_parser.h>
12#include <boost/algorithm/string.hpp>
13#include <util/filesystem.h>
14#include <util/str.h>
15
16#include <vector>
17
18using namespace std;
19using namespace isc::data;
20using namespace isc::hooks;
21using namespace isc::dhcp;
22using namespace isc::util::file;
23
24namespace isc {
25namespace hooks {
26
27namespace {
28 // Singleton PathChecker to set and hold valid hooks library path.
29 PathCheckerPtr hooks_path_checker_;
30
31 // Singleton PathChecker to set and hold valid scripts path (scripts loaded by hook libraries).
32 PathCheckerPtr hook_scripts_path_checker_;
33};
34
35std::string
36HookLibraryScriptsChecker::getHookScriptsPath(bool reset /* = false */, const std::string explicit_path /* = "" */) {
37 if (!hook_scripts_path_checker_ || reset) {
38 hook_scripts_path_checker_.reset(new PathChecker(DEFAULT_HOOK_SCRIPTS_PATH, "KEA_HOOK_SCRIPTS_PATH"));
39 if (!explicit_path.empty()) {
40 hook_scripts_path_checker_->getPath(true, explicit_path);
41 }
42 }
43
44 return (hook_scripts_path_checker_->getPath());
45}
46
47std::string
48HookLibraryScriptsChecker::validatePath(const std::string libpath) {
49 if (!hook_scripts_path_checker_) {
51 }
52
53 return (hook_scripts_path_checker_->validatePath(libpath));
54}
55
56std::string
57HooksLibrariesParser::getHooksPath(bool reset /* = false */, const std::string explicit_path /* = "" */) {
58 if (!hooks_path_checker_ || reset) {
59 hooks_path_checker_.reset(new PathChecker(DEFAULT_HOOKS_PATH, "KEA_HOOKS_PATH"));
60 if (!explicit_path.empty()) {
61 hooks_path_checker_->getPath(true, explicit_path);
62 }
63 }
64
65 return (hooks_path_checker_->getPath());
66}
67
68std::string
69HooksLibrariesParser::validatePath(const std::string libpath) {
70 if (!hooks_path_checker_) {
72 }
73
74 return (hooks_path_checker_->validatePath(libpath));
75}
76
77// @todo use the flat style, split into list and item
78
79void
81 // Initialize.
82 libraries.clear();
83
84 if (!value) {
85 isc_throw(DhcpConfigError, "Tried to parse null hooks libraries");
86 }
87
88 // This is the new syntax. Iterate through it and get each map.
89 for (auto const& library_entry : value->listValue()) {
90 ConstElementPtr parameters;
91
92 // Is it a map?
93 if (library_entry->getType() != Element::map) {
94 isc_throw(DhcpConfigError, "hooks library configuration error:"
95 " one or more entries in the hooks-libraries list is not"
96 " a map (" << library_entry->getPosition() << ")");
97 }
98
99 // Iterate through each element in the map. We check
100 // whether we have found a library element.
101 bool lib_found = false;
102
103 string cfgname = "";
104 string libname = "";
105
106 // Let's explicitly reset the parameters, so we won't cover old
107 // values from the previous loop round.
108 parameters.reset();
109
110 for (auto const& entry_item : library_entry->mapValue()) {
111 if (entry_item.first == "library") {
112 if (entry_item.second->getType() != Element::string) {
113 isc_throw(DhcpConfigError, "hooks library configuration"
114 " error: value of 'library' element is not a string"
115 " giving the path to a hooks library (" <<
116 entry_item.second->getPosition() << ")");
117 }
118
119 // Get the name of the library and add it to the list after
120 // removing quotes.
121 try {
122 cfgname = (entry_item.second)->stringValue();
123 libname = validatePath(cfgname);
124 } catch (const std::exception& ex) {
125 isc_throw(DhcpConfigError, "hooks library configuration"
126 " error: " << ex.what() << " ("
127 << entry_item.second->getPosition() << ")");
128 }
129
130 // Note we have found the library name.
131 lib_found = true;
132 continue;
133 }
134
135 // If there are parameters, let's remember them.
136 if (entry_item.first == "parameters") {
137 parameters = entry_item.second;
138 continue;
139 }
140
141 // For all other parameters we will throw.
142 isc_throw(DhcpConfigError, "unknown hooks library parameter: "
143 << entry_item.first << "("
144 << library_entry->getPosition() << ")");
145 }
146
147 if (! lib_found) {
148 isc_throw(DhcpConfigError, "hooks library configuration error:"
149 " one or more hooks-libraries elements are missing the"
150 " name of the library" <<
151 " (" << library_entry->getPosition() << ")");
152 }
153
154 libraries.add(libname, parameters, cfgname);
155 }
156}
157
158}
159}
@ map
Definition data.h:147
@ string
Definition data.h:144
To be removed. Please use ConfigError instead.
static std::string validatePath(const std::string libpath)
Validates a script path (script loaded by a hook) against the supported path.
static std::string getHookScriptsPath(bool reset=false, const std::string explicit_path="")
Fetches the supported script path.
Wrapper class that holds hooks libraries configuration.
void clear()
Removes all configured hooks libraries.
void add(const std::string &libname, isc::data::ConstElementPtr parameters, const std::string &cfgname="")
Adds additional hooks libraries.
static std::string validatePath(const std::string libpath)
Validates a library path against the supported path for hooks libraries.
void parse(HooksConfig &libraries, isc::data::ConstElementPtr value)
Parses parameters value.
static std::string getHooksPath(bool reset=false, const std::string explicit_path="")
Fetches the supported Hooks path.
Embodies a supported path against which file paths can be validated.
Definition filesystem.h:179
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< PathChecker > PathCheckerPtr
Defines a pointer to a PathChecker.
Definition filesystem.h:298
Defines the logger used by the top-level component of kea-lfc.