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