Kea 2.7.3
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), 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")) {
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 authentication.
98 ConstElementPtr auth_config = config->get("authentication");
99 if (auth_config) {
100 ElementPtr mutable_auth_config =
101 boost::const_pointer_cast<Element>(auth_config);
102 if (auth_config->getType() != Element::map) {
104 "invalid type specified for parameter 'authentication' ("
105 << auth_config->getPosition() << ")");
106 }
107 // Default type is basic.
108 ConstElementPtr type = auth_config->get("type");
109 if (!type) {
110 mutable_auth_config->set("type", Element::create(string("basic")));
111 }
112 // Set default realm when not present.
113 ConstElementPtr realm = auth_config->get("realm");
114 if (!realm) {
115 mutable_auth_config->set("realm",
117 }
118
120 auth->parse(auth_config);
121 auth_config_ = auth;
122 }
123
124 // Get trust anchor.
125 ConstElementPtr trust_anchor = config->get("trust-anchor");
126 if (trust_anchor) {
127 if (trust_anchor->getType() != Element::string) {
129 "invalid type specified for parameter 'trust-anchor' ("
130 << trust_anchor->getPosition() << ")");
131 }
132 trust_anchor_ = trust_anchor->stringValue();
133 }
134
135 // Get cert file.
136 ConstElementPtr cert_file = config->get("cert-file");
137 if (cert_file) {
138 if (cert_file->getType() != Element::string) {
140 "invalid type specified for parameter 'cert-file' ("
141 << cert_file->getPosition() << ")");
142 }
143 cert_file_ = cert_file->stringValue();
144 }
145
146 // Get key file.
147 ConstElementPtr key_file = config->get("key-file");
148 if (key_file) {
149 if (key_file->getType() != Element::string) {
151 "invalid type specified for parameter 'key-file' ("
152 << key_file->getPosition() << ")");
153 }
154 key_file_ = key_file->stringValue();
155 }
156
157 // Get cert required.
158 ConstElementPtr cert_required = config->get("cert-required");
159 if (cert_required) {
160 if (cert_required->getType() != Element::boolean) {
162 "invalid type specified for parameter 'cert-required' ("
163 << cert_required->getPosition() << ")");
164 }
165 cert_required_ = cert_required->boolValue();
166 }
167
168 // Check the TLS setup.
169 checkTlsSetup(socket_type_ == "https");
170
171 // Get user context.
172 ConstElementPtr user_context = config->get("user-context");
173 if (user_context) {
174 setContext(user_context);
175 }
176}
177
178void
179HttpCommandConfig::checkTlsSetup(bool require_tls) const {
180 bool have_ca = !trust_anchor_.empty();
181 bool have_cert = !cert_file_.empty();
182 bool have_key = !key_file_.empty();
183 if (!have_ca && !have_cert && !have_key) {
184 if (require_tls) {
186 "no TLS setup for a HTTPS control socket");
187 }
188 return;
189 }
190 // TLS is used: all 3 parameters are required.
191 if (!have_ca) {
193 "trust-anchor parameter is missing or empty:"
194 " all or none of TLS parameters must be set");
195 }
196 if (!have_cert) {
197 isc_throw(DhcpConfigError, "cert-file parameter is missing or empty:"
198 " all or none of TLS parameters must be set");
199 }
200 if (!have_key) {
201 isc_throw(DhcpConfigError, "key-file parameter is missing or empty:"
202 " all or none of TLS parameters must be set");
203 }
204}
205
209 // Set user-context.
210 contextToElement(result);
211 // Set socket type.
212 result->set("socket-type", Element::create(socket_type_));
213 // Set socket address.
214 result->set("socket-address", Element::create(socket_address_.toText()));
215 // Set socket port.
216 result->set("socket-port",
217 Element::create(static_cast<uint32_t>(socket_port_)));
219 if (auth_config_) {
220 result->set("authentication", auth_config_->toElement());
221 }
222 // Set TLS setup when enabled.
223 if (!trust_anchor_.empty()) {
224 result->set("trust-anchor", Element::create(trust_anchor_));
225 result->set("cert-file", Element::create(cert_file_));
226 result->set("key-file", Element::create(key_file_));
227 result->set("cert-required", Element::create(cert_required_));
228 }
229 return (result);
230}
231
232} // end of isc::config
233} // end of isc
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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.
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.