Kea 3.1.1
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 <hooks/hooks_log.h>
13#include <boost/algorithm/string.hpp>
14#include <util/filesystem.h>
15#include <util/str.h>
16
17#include <vector>
18
19using namespace std;
20using namespace isc::data;
21using namespace isc::hooks;
22using namespace isc::dhcp;
23using namespace isc::util::file;
24
25namespace isc {
26namespace hooks {
27
28namespace {
29 // Singleton PathChecker to set and hold valid hooks library path.
30 PathCheckerPtr hooks_path_checker_;
31
32 // Singleton PathChecker to set and hold valid scripts path (scripts loaded by hook libraries).
33 PathCheckerPtr hook_scripts_path_checker_;
34};
35
36std::string
37HookLibraryScriptsChecker::getHookScriptsPath(bool reset /* = false */, const std::string explicit_path /* = "" */) {
38 if (!hook_scripts_path_checker_ || reset) {
39 hook_scripts_path_checker_.reset(new PathChecker(DEFAULT_HOOK_SCRIPTS_PATH, "KEA_HOOK_SCRIPTS_PATH"));
40 if (!explicit_path.empty()) {
41 hook_scripts_path_checker_->getPath(true, explicit_path);
42 }
43 }
44
45 return (hook_scripts_path_checker_->getPath());
46}
47
48std::string
49HookLibraryScriptsChecker::validatePath(const std::string libpath) {
50 if (!hook_scripts_path_checker_) {
52 }
53
54 return (hook_scripts_path_checker_->validatePath(libpath));
55}
56
57std::string
58HooksLibrariesParser::getHooksPath(bool reset /* = false */, const std::string explicit_path /* = "" */) {
59 if (!hooks_path_checker_ || reset) {
60 hooks_path_checker_.reset(new PathChecker(DEFAULT_HOOKS_PATH, "KEA_HOOKS_PATH"));
61 if (!explicit_path.empty()) {
62 hooks_path_checker_->getPath(true, explicit_path);
63 }
64 }
65
66 return (hooks_path_checker_->getPath());
67}
68
69std::string
70HooksLibrariesParser::validatePath(const std::string libpath) {
71 if (!hooks_path_checker_) {
73 }
74
75 try {
76 return (hooks_path_checker_->validatePath(libpath));
77 } catch (const SecurityWarn& ex) {
79 .arg(ex.what());
80 return (libpath);
81 }
82}
83
84// @todo use the flat style, split into list and item
85
86void
88 // Initialize.
89 libraries.clear();
90
91 if (!value) {
92 isc_throw(DhcpConfigError, "Tried to parse null hooks libraries");
93 }
94
95 // This is the new syntax. Iterate through it and get each map.
96 for (auto const& library_entry : value->listValue()) {
97 ConstElementPtr parameters;
98
99 // Is it a map?
100 if (library_entry->getType() != Element::map) {
101 isc_throw(DhcpConfigError, "hooks library configuration error:"
102 " one or more entries in the hooks-libraries list is not"
103 " a map (" << library_entry->getPosition() << ")");
104 }
105
106 // Iterate through each element in the map. We check
107 // whether we have found a library element.
108 bool lib_found = false;
109
110 string cfgname = "";
111 string libname = "";
112
113 // Let's explicitly reset the parameters, so we won't cover old
114 // values from the previous loop round.
115 parameters.reset();
116
117 for (auto const& entry_item : library_entry->mapValue()) {
118 if (entry_item.first == "library") {
119 if (entry_item.second->getType() != Element::string) {
120 isc_throw(DhcpConfigError, "hooks library configuration"
121 " error: value of 'library' element is not a string"
122 " giving the path to a hooks library (" <<
123 entry_item.second->getPosition() << ")");
124 }
125
126 // Get the name of the library and add it to the list after
127 // removing quotes.
128 try {
129 cfgname = (entry_item.second)->stringValue();
130 libname = validatePath(cfgname);
131 } catch (const std::exception& ex) {
132 isc_throw(DhcpConfigError, "hooks library configuration"
133 " error: " << ex.what() << " ("
134 << entry_item.second->getPosition() << ")");
135 }
136
137 // Note we have found the library name.
138 lib_found = true;
139 continue;
140 }
141
142 // If there are parameters, let's remember them.
143 if (entry_item.first == "parameters") {
144 parameters = entry_item.second;
145 continue;
146 }
147
148 // For all other parameters we will throw.
149 isc_throw(DhcpConfigError, "unknown hooks library parameter: "
150 << entry_item.first << "("
151 << library_entry->getPosition() << ")");
152 }
153
154 if (! lib_found) {
155 isc_throw(DhcpConfigError, "hooks library configuration error:"
156 " one or more hooks-libraries elements are missing the"
157 " name of the library" <<
158 " (" << library_entry->getPosition() << ")");
159 }
160
161 libraries.add(libname, parameters, cfgname);
162 }
163}
164
165}
166}
@ map
Definition data.h:147
@ string
Definition data.h:144
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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:203
A generic exception that is thrown if a parameter given violates security check but enforcement is la...
Definition filesystem.h:21
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
const isc::log::MessageID HOOKS_LIBPATH_SECURITY_WARNING
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
Definition hooks_log.h:37
boost::shared_ptr< PathChecker > PathCheckerPtr
Defines a pointer to a PathChecker.
Definition filesystem.h:323
Defines the logger used by the top-level component of kea-lfc.