Kea 2.7.7
http_command_config.cc
Go to the documentation of this file.
1// Copyright (C) 2015-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
10#include <config/command_mgr.h>
13#include <limits>
14
15using namespace isc;
16using namespace isc::asiolink;
17using namespace isc::config;
18using namespace isc::data;
19using namespace isc::dhcp;
20using namespace isc::http;
21using namespace std;
22
23namespace isc {
24namespace config {
25
27
29
31
33 : socket_type_("http"), socket_address_(DEFAULT_SOCKET_ADDRESS),
34 socket_port_(DEFAULT_SOCKET_PORT), http_headers_(), auth_config_(),
35 trust_anchor_(""), cert_file_(""), key_file_(""), cert_required_(true),
36 emulate_agent_response_(true) {
37 if (config->getType() != Element::map) {
38 isc_throw(DhcpConfigError, "expected map type ("
39 << config->getPosition() << ")");
40 }
41 // Get socket type.
42 ConstElementPtr socket_type = config->get("socket-type");
43 if (socket_type) {
44 if (socket_type->getType() != Element::string) {
46 "invalid type specified for parameter 'socket-type' ("
47 << socket_type->getPosition() << ")");
48 }
49 socket_type_ = socket_type->stringValue();
50 if ((socket_type_ != "http") && (socket_type_ != "https")) {
51 isc_throw(DhcpConfigError, "unsupported 'socket-type' '"
52 << socket_type_ << "' not 'http' or 'https'");
53 }
54 }
55 // Reject UNIX only socket-name.
56 if (config->contains("socket-name")) {
57 isc_throw(DhcpConfigError,
58 "parameter 'socket-name' is not supported by "
59 << (socket_type_ == string("http") ? string("HTTP") : string("HTTPS"))
60 << " control sockets");
61 }
62 // Get socket address.
63 ConstElementPtr socket_address = config->get("socket-address");
64 if (socket_address) {
65 if (socket_address->getType() != Element::string) {
67 "invalid type specified for parameter 'socket-address' ("
68 << socket_address->getPosition() << ")");
69 }
70 try {
71 socket_address_ = IOAddress(socket_address->stringValue());
72 } catch (const std::exception& ex) {
73 isc_throw(DhcpConfigError, "failed to convert '"
74 << socket_address->stringValue()
75 << "' to address: " << ex.what()
76 << " (" << socket_address->getPosition() << ")");
77 }
78 }
79
80 // Get socket port.
81 ConstElementPtr socket_port = config->get("socket-port");
82 if (socket_port) {
83 if (socket_port->getType() != Element::integer) {
85 "invalid type specified for parameter 'socket-port' ("
86 << socket_port->getPosition() << ")");
87 }
88 int64_t value = socket_port->intValue();
89 if ((value < numeric_limits<uint16_t>::min()) ||
90 (value > numeric_limits<uint16_t>::max())) {
92 "out of range value " << value
93 << " specified for parameter 'socket-port' ("
94 << socket_port->getPosition() << ")");
95 }
96 socket_port_ = static_cast<uint16_t>(value);
97 }
98
99 // Get HTTP headers.
100 ConstElementPtr headers = config->get("http-headers");
101 if (headers) {
102 http_headers_ = parseCfgHttpHeaders(headers);
103 }
104
105 // Get HTTP authentication.
106 ConstElementPtr auth_config = config->get("authentication");
107 if (auth_config) {
108 ElementPtr mutable_auth_config =
109 boost::const_pointer_cast<Element>(auth_config);
110 if (auth_config->getType() != Element::map) {
112 "invalid type specified for parameter 'authentication' ("
113 << auth_config->getPosition() << ")");
114 }
115 // Default type is basic.
116 ConstElementPtr type = auth_config->get("type");
117 if (!type) {
118 mutable_auth_config->set("type", Element::create(string("basic")));
119 }
120 // Set default realm when not present.
121 ConstElementPtr realm = auth_config->get("realm");
122 if (!realm) {
123 mutable_auth_config->set("realm",
125 }
126
128 auth->parse(auth_config);
129 auth_config_ = auth;
130 }
131
132 // Get trust anchor.
133 ConstElementPtr trust_anchor = config->get("trust-anchor");
134 if (trust_anchor) {
135 if (trust_anchor->getType() != Element::string) {
137 "invalid type specified for parameter 'trust-anchor' ("
138 << trust_anchor->getPosition() << ")");
139 }
140 trust_anchor_ = trust_anchor->stringValue();
141 }
142
143 // Get cert file.
144 ConstElementPtr cert_file = config->get("cert-file");
145 if (cert_file) {
146 if (cert_file->getType() != Element::string) {
148 "invalid type specified for parameter 'cert-file' ("
149 << cert_file->getPosition() << ")");
150 }
151 cert_file_ = cert_file->stringValue();
152 }
153
154 // Get key file.
155 ConstElementPtr key_file = config->get("key-file");
156 if (key_file) {
157 if (key_file->getType() != Element::string) {
159 "invalid type specified for parameter 'key-file' ("
160 << key_file->getPosition() << ")");
161 }
162 key_file_ = key_file->stringValue();
163 }
164
165 // Get cert required.
166 ConstElementPtr cert_required = config->get("cert-required");
167 if (cert_required) {
168 if (cert_required->getType() != Element::boolean) {
170 "invalid type specified for parameter 'cert-required' ("
171 << cert_required->getPosition() << ")");
172 }
173 cert_required_ = cert_required->boolValue();
174 }
175
176 // Check the TLS setup.
177 checkTlsSetup(socket_type_ == "https");
178
179 // Get user context.
180 ConstElementPtr user_context = config->get("user-context");
181 if (user_context) {
182 setContext(user_context);
183 }
184}
185
186void
187HttpCommandConfig::checkTlsSetup(bool require_tls) const {
188 bool have_ca = !trust_anchor_.empty();
189 bool have_cert = !cert_file_.empty();
190 bool have_key = !key_file_.empty();
191 if (!have_ca && !have_cert && !have_key) {
192 if (require_tls) {
194 "no TLS setup for a HTTPS control socket");
195 }
196 return;
197 }
198 // TLS is used: all 3 parameters are required.
199 if (!have_ca) {
201 "trust-anchor parameter is missing or empty:"
202 " all or none of TLS parameters must be set");
203 }
204 if (!have_cert) {
205 isc_throw(DhcpConfigError, "cert-file parameter is missing or empty:"
206 " all or none of TLS parameters must be set");
207 }
208 if (!have_key) {
209 isc_throw(DhcpConfigError, "key-file parameter is missing or empty:"
210 " all or none of TLS parameters must be set");
211 }
212}
213
217 // Set user-context.
218 contextToElement(result);
219 // Set socket type.
220 result->set("socket-type", Element::create(socket_type_));
221 // Set socket address.
222 result->set("socket-address", Element::create(socket_address_.toText()));
223 // Set http-headers.
224 if (!http_headers_.empty()) {
225 result->set("http-headers", CfgHttpHeaderstoElement(http_headers_));
226 }
227 // Set socket port.
228 result->set("socket-port",
229 Element::create(static_cast<uint32_t>(socket_port_)));
231 if (auth_config_) {
232 result->set("authentication", auth_config_->toElement());
233 }
234 // Set TLS setup when enabled.
235 if (!trust_anchor_.empty()) {
236 result->set("trust-anchor", Element::create(trust_anchor_));
237 result->set("cert-file", Element::create(cert_file_));
238 result->set("key-file", Element::create(key_file_));
239 result->set("cert-required", Element::create(cert_required_));
240 }
241 return (result);
242}
243
244} // end of isc::config
245} // end of isc
if(!(yy_init))
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
static std::string DEFAULT_AUTHENTICATION_REALM
Default HTTP authentication realm.
static isc::asiolink::IOAddress DEFAULT_SOCKET_ADDRESS
Default socket address (127.0.0.1).
static uint16_t DEFAULT_SOCKET_PORT
Default socket port.
HttpCommandConfig(isc::data::ConstElementPtr config)
Constructor.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
To be removed. Please use ConfigError instead.
Basic HTTP authentication configuration.
#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< Element > ElementPtr
Definition data.h:28
boost::shared_ptr< BasicHttpAuthConfig > BasicHttpAuthConfigPtr
Type of shared pointers to basic HTTP authentication configuration.
ElementPtr CfgHttpHeaderstoElement(const CfgHttpHeaders &headers)
Unparse config HTTP headers.
CfgHttpHeaders parseCfgHttpHeaders(const ConstElementPtr &config)
Parse config HTTP headers.
Defines the logger used by the top-level component of kea-lfc.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
void setContext(const data::ConstElementPtr &ctx)
Sets user context.