Kea 3.1.1
radius_parsers.cc
Go to the documentation of this file.
1// Copyright (C) 2018-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 <radius_parsers.h>
10#include <radius_log.h>
11
12#include <cc/data.h>
14#include <dhcpsrv/cfgmgr.h>
15#include <eval/eval_context.h>
16#include <util/encode/encode.h>
17
18#include <limits>
19#include <string>
20#include <cstdlib>
21#include <cstring>
22#include <sstream>
23
24using namespace std;
25using namespace isc;
26using namespace isc::asiolink;
27using namespace isc::data;
28using namespace isc::dhcp;
29using namespace isc::util;
30
31namespace isc {
32namespace radius {
33
35const set<string>
37 "access", "accounting", // services
38 "bindaddr", "canonical-mac-address", "client-id-pop0",
39 "client-id-printable", "deadtime", "dictionary",
40 "extract-duid", "identifier-type4", "identifier-type6",
41 "nas-ports", "realm",
42 "reselect-subnet-address", "reselect-subnet-pool",
43 "retries", "session-history", "thread-pool-size", "timeout",
44 "comment" // not saved for toElement
45};
46
49 { "bindaddr", Element::string, "*" },
50 { "canonical-mac-address", Element::boolean, "false" },
51 { "client-id-pop0", Element::boolean, "false" },
52 { "client-id-printable", Element::boolean, "false" },
53 { "deadtime", Element::integer, "0" },
54 { "dictionary", Element::string, DICTIONARY },
55 { "extract-duid", Element::boolean, "true" },
56 { "identifier-type4", Element::string, "client-id" },
57 { "identifier-type6", Element::string, "duid" },
58 { "realm", Element::string, "" },
59 { "reselect-subnet-address", Element::boolean, "false" },
60 { "reselect-subnet-pool", Element::boolean, "false" },
61 { "retries", Element::integer, "3" },
62 { "session-history", Element::string, "" },
63 { "thread-pool-size", Element::integer, "0" },
64 { "timeout", Element::integer, "10" }
65};
66
69 { PW_USER_NAME, "User-Name", PW_TYPE_STRING },
70 { PW_USER_PASSWORD, "User-Password", PW_TYPE_STRING },
71 { PW_NAS_IP_ADDRESS, "NAS-IP-Address", PW_TYPE_IPADDR },
72 { PW_NAS_PORT, "NAS-Port", PW_TYPE_INTEGER },
73 { PW_SERVICE_TYPE, "Service-Type", PW_TYPE_INTEGER },
74 { PW_FRAMED_IP_ADDRESS, "Framed-IP-Address", PW_TYPE_IPADDR },
75 { PW_REPLY_MESSAGE, "Reply-Message", PW_TYPE_STRING },
76 { PW_CLASS, "Class", PW_TYPE_STRING },
77 { PW_CALLING_STATION_ID, "Calling-Station-Id", PW_TYPE_STRING },
78 { PW_ACCT_STATUS_TYPE, "Acct-Status-Type", PW_TYPE_INTEGER },
79 { PW_ACCT_DELAY_TIME, "Acct-Delay-Time", PW_TYPE_INTEGER },
80 { PW_ACCT_SESSION_ID, "Acct-Session-Id", PW_TYPE_STRING },
81 { PW_FRAMED_POOL, "Framed-Pool", PW_TYPE_STRING },
82 { PW_NAS_IPV6_ADDRESS, "NAS-IPv6-Address", PW_TYPE_IPV6ADDR },
83 { PW_DELEGATED_IPV6_PREFIX, "Delegated-IPv6-Prefix", PW_TYPE_IPV6PREFIX },
84 { PW_FRAMED_IPV6_ADDRESS, "Framed-IPv6-Address", PW_TYPE_IPV6ADDR }
85};
86
89 { "data", Element::string, "" },
90 { "expr", Element::string, "" },
91 { "raw", Element::string, "" }
92};
93
94void
96 try {
98
99 // Set defaults.
101
102 // dictionary (do it first).
103 const ConstElementPtr& dictionary = config->get("dictionary");
104 riref.dictionary_ = dictionary->stringValue();
105
106 // Read the dictionary
107 if (!AttrDefs::instance().getByType(1)) {
108 try {
110 } catch (const exception& ex) {
111 isc_throw(BadValue, "can't read radius dictionary: "
112 << ex.what());
113 }
114 }
115
116 // Check it.
118
119 // bindaddr.
120 const ConstElementPtr& bindaddr = config->get("bindaddr");
121 riref.bindaddr_ = bindaddr->stringValue();
122
123 // canonical-mac-address.
124 const ConstElementPtr& canonical = config->get("canonical-mac-address");
125 riref.canonical_mac_address_ = canonical->boolValue();
126
127 // client-id-pop0.
128 const ConstElementPtr& pop0 = config->get("client-id-pop0");
129 riref.clientid_pop0_ = pop0->boolValue();
130
131 // client-id-printable.
132 const ConstElementPtr& try_printable = config->get("client-id-printable");
133 riref.clientid_printable_ = try_printable->boolValue();
134
135 // deadtime.
136 const ConstElementPtr& deadtime = config->get("deadtime");
137 int64_t deadtime64 = deadtime->intValue();
138 if ((deadtime64 < 0) ||
139 (deadtime64 > numeric_limits<unsigned>::max())) {
140 isc_throw(OutOfRange, "bad deadtime " << deadtime64
141 << " not in [0.."
142 << numeric_limits<unsigned>::max() << "]");
143 }
144 riref.deadtime_ = static_cast<unsigned>(deadtime64);
145
146 // extract-duid.
147 const ConstElementPtr& rfc4361 = config->get("extract-duid");
148 riref.extract_duid_ = rfc4361->boolValue();
149
150 // identifier-type4.
151 const ConstElementPtr& id_type4 = config->get("identifier-type4");
152 riref.id_type4_ = Host::getIdentifierType(id_type4->stringValue());
153
154 // identifier-type6.
155 const ConstElementPtr& id_type6 = config->get("identifier-type6");
156 riref.id_type6_ = Host::getIdentifierType(id_type6->stringValue());
157
158 // realm. Ignored.
159
160 // reselect-subnet-address.
161 const ConstElementPtr& resel_addr =
162 config->get("reselect-subnet-address");
163 riref.reselect_subnet_address_ = resel_addr->boolValue();
164
165 // reselect-subnet-pool.
166 const ConstElementPtr& resel_pool =
167 config->get("reselect-subnet-pool");
168 riref.reselect_subnet_pool_ = resel_pool->boolValue();
169
170 // retries.
171 const ConstElementPtr& retries = config->get("retries");
172 int64_t retries64 = retries->intValue();
173 if ((retries64 < 0) ||
174 (retries64 > numeric_limits<unsigned>::max())) {
175 isc_throw(OutOfRange, "bad retries " << retries64
176 << " not in [0.."
177 << numeric_limits<unsigned>::max() << "]");
178 }
179 riref.retries_ = static_cast<unsigned>(retries64);
180
181 // session-history.
182 const ConstElementPtr& session_history = config->get("session-history");
183 riref.session_history_filename_ = session_history->stringValue();
184
185 // thread-pool-size.
186 const ConstElementPtr& thread_pool_size = config->get("thread-pool-size");
187 riref.thread_pool_size_ = thread_pool_size->intValue();
188
189 // timeout.
190 const ConstElementPtr& timeout = config->get("timeout");
191 int64_t timeout64 = timeout->intValue();
192 if ((timeout64 < 0) ||
193 (timeout64 > numeric_limits<long>::max() / 1000)) {
194 isc_throw(OutOfRange, "bad timeout " << timeout64
195 << " not in [0.."
196 << (numeric_limits<long>::max() / 1000) << "]");
197 }
198 riref.timeout_ = static_cast<unsigned>(timeout64);
199
200 // Access service.
201 const ConstElementPtr& access = config->get("access");
202 if (access) {
203 RadiusServiceParser parser;
204 parser.parse(riref.auth_, access);
205 parser.checkAttributes(riref.auth_);
206 }
207
208 // Accounting service.
209 const ConstElementPtr& accounting = config->get("accounting");
210 if (accounting) {
211 RadiusServiceParser parser;
212 parser.parse(riref.acct_, accounting);
213 parser.checkAttributes(riref.acct_);
214 }
215
216 // nas-ports (last so we can return when it is not present.
217 const ConstElementPtr& nas_ports = config->get("nas-ports");
218 if (!nas_ports) {
219 return;
220 }
221 for (auto const& entry : nas_ports->listValue()) {
222 // port is mandatory.
223 const ConstElementPtr& port = entry->get("port");
224 if (!port) {
225 isc_throw(BadValue, "missing port in nas-ports entry: "
226 << entry->str());
227 }
228
229 // By subnet-id.
230 const ConstElementPtr& id = entry->get("subnet-id");
231 if (id) {
232 riref.remap_[id->intValue()] = port->intValue();
233 continue;
234 }
235
236 // By subnet-prefix (to be resolved into an ID).
237 const ConstElementPtr& prefix = entry->get("subnet-prefix");
238 if (prefix) {
239 if (CfgMgr::instance().getFamily() == AF_INET) {
240 auto subnet = CfgMgr::instance().getStagingCfg()->
241 getCfgSubnets4()->getByPrefix(prefix->stringValue());
242 if (!subnet) {
243 isc_throw(BadValue, "can't find subnet for "
244 << entry->str());
245 }
246 riref.remap_[subnet->getID()] = port->intValue();
247 continue;
248 } else {
249 auto subnet = CfgMgr::instance().getStagingCfg()->
250 getCfgSubnets6()->getByPrefix(prefix->stringValue());
251 if (!subnet) {
252 isc_throw(BadValue, "can't find subnet for "
253 << entry->str());
254 }
255 riref.remap_[subnet->getID()] = port->intValue();
256 continue;
257 }
258 }
259
260 // By shared-network-name (to be resolved, add all subnets).
261 const ConstElementPtr& name = entry->get("shared-network-name");
262 if (name) {
263 if (CfgMgr::instance().getFamily() == AF_INET) {
264 auto network = CfgMgr::instance().getStagingCfg()->
265 getCfgSharedNetworks4()->getByName(name->stringValue());
266 if (!network) {
267 isc_throw(BadValue, "can't find shared network for "
268 << entry->str());
269 }
270 for (auto const& subnet : *network->getAllSubnets()) {
271 riref.remap_[subnet->getID()] = port->intValue();
272 }
273 continue;
274 } else {
275 auto network = CfgMgr::instance().getStagingCfg()->
276 getCfgSharedNetworks6()->getByName(name->stringValue());
277 if (!network) {
278 isc_throw(BadValue, "can't find shared network for "
279 << entry->str());
280 }
281 for (auto const& subnet : *network->getAllSubnets()) {
282 riref.remap_[subnet->getID()] = port->intValue();
283 }
284 continue;
285 }
286 }
287
288 // Unknown selector.
289 if (entry->size() > 1) {
290 isc_throw(BadValue, "unknown selector in " << entry->str());
291 }
292
293 // Default is in subnet 0 (SUBNET_ID_DEFAULT).
294 riref.remap_[SUBNET_ID_DEFAULT] = port->intValue();
295 }
296
297 } catch (const ConfigError&) {
298 throw;
299 } catch (const std::exception& ex) {
300 isc_throw(ConfigError, ex.what());
301 }
302}
303
305const set<string>
307 "servers", "attributes", "peer-updates", "max-pending-requests"
308};
309
310void
312 const ConstElementPtr& srv_cfg) {
313 try {
314 // map type.
315 if (srv_cfg->getType() != Element::map) {
316 isc_throw(BadValue, "expected service to be map, but got "
317 << Element::typeToName(srv_cfg->getType())
318 << " instead");
319 }
320
321 // keywords.
322 const set<string> keywords = RadiusServiceParser::SERVICE_KEYWORDS;
323 for (auto const& entry : srv_cfg->mapValue()) {
324 if (keywords.count(entry.first) == 0) {
325 isc_throw(BadValue, "unknown service parameter: "
326 << entry.first);
327 }
328 }
329
330 // servers.
331 const ConstElementPtr& servers = srv_cfg->get("servers");
332 if (servers) {
334 parser.parse(service, servers);
335 if (!service->servers_.empty()) {
336 service->enabled_ = true;
337 }
338 }
339
340 // attributes.
341 const ConstElementPtr& attributes = srv_cfg->get("attributes");
342 if (attributes) {
344 parser.parse(service, attributes);
345 }
346
347 // peer-updates.
348 const ConstElementPtr& peer_updates = srv_cfg->get("peer-updates");
349 if (peer_updates) {
350 if (service->name_ == "access") {
351 isc_throw(BadValue, "peer-updates configured for the access service, but it is "
352 "only supported for the accounting service");
353 }
354 if (peer_updates->getType() != Element::boolean) {
355 isc_throw(BadValue, "expected peer-updates to be boolean, but got "
356 << Element::typeToName(peer_updates->getType())
357 << " instead");
358 }
359 service->peer_updates_ = peer_updates->boolValue();
360 }
361
362 // max-pending-requests.
363 const ConstElementPtr& max_pending_requests =
364 srv_cfg->get("max-pending-requests");
365 if (max_pending_requests) {
366 if (service->name_ == "accounting") {
367 isc_throw(BadValue, "max-pending-requests configured for the "
368 << "accounting service, but it is only supported "
369 << "for the access service");
370 }
371 if (max_pending_requests->getType() != Element::integer) {
372 isc_throw(BadValue, "expected max-pending-requests to be "
373 << "integer, but got "
374 << Element::typeToName(max_pending_requests->getType())
375 << " instead");
376 }
377 if (max_pending_requests->intValue() < 0) {
378 isc_throw(BadValue, "expected max-pending-requests to be "
379 << "positive, but got "
380 << max_pending_requests->intValue()
381 << " instead");
382 }
383 service->max_pending_requests_ = max_pending_requests->intValue();
384 }
385 } catch (const std::exception& ex) {
386 isc_throw(ConfigError, ex.what() << " (parsing "
387 << service->name_ << ")");
388 }
389}
390
391void
393 if (!service->enabled_) {
394 return;
395 }
396
397 const CfgAttributes& cfg_attrs = service->attributes_;
398 const Attributes& attrs = cfg_attrs.getAll();
399 if (service->name_ == "access") {
400 // Nothing yet.
401 } else if (service->name_ == "accounting") {
402 // Expressions have no associated attributes.
403 if (cfg_attrs.size() > attrs.size()) {
405 "Expressions are not yet supported in accounting");
406 }
407 }
408}
409
410void
412 const ConstElementPtr& srv_list) {
413 for (auto const& srv : srv_list->listValue()) {
414 RadiusServerParser parser;
415 parser.parse(service, srv);
416 }
417}
418
419void
421 const ElementPtr& server) {
423
424 // Details will be logged.
425 ostringstream msg;
426
427 // Peer address (was name).
428 IOAddress peer_addr("::");
429 const string& name = getString(server, "name");
430 try {
431 peer_addr = IOAddress(name);
432 } catch (const Exception&) {
433 try {
434 peer_addr = Server::getAddress(name);
435 } catch (const Exception& ex) {
436 isc_throw(ConfigError, "can't resolve '" << name << "': "
437 << ex.what());
438 }
439 }
440 msg << "peer-addr=" << peer_addr.toText();
441
442 // port.
443 uint16_t port;
444 if (server->contains("port")) {
445 port = getUint16(server, "port");
446 } else if (service->name_ == "access") {
447 port = PW_AUTH_UDP_PORT;
448 } else {
449 port = PW_ACCT_UDP_PORT;
450 }
451 msg << " port=" << port;
452
453 // Local address.
454 IOAddress local_addr("::");
455 const string& local = riref.bindaddr_;
456 if (local != "*") {
457 try {
458 local_addr = IOAddress(local);
459 } catch (const Exception& ex) {
460 isc_throw(ConfigError, "bad local address '" << local << "': "
461 << ex.what());
462 }
463 } else {
464 try {
465 local_addr = Server::getSrcAddress(peer_addr);
466 } catch (const Exception& ex) {
467 isc_throw(ConfigError, "can't get local address: " << ex.what());
468 }
469 }
470 msg << " local_addr=" << local_addr;
471
472 // secret.
473 const string& secret = getString(server, "secret");
474 try {
476 } catch (const DefaultCredential& ex) {
477 isc_throw(ConfigError, "illegal use of a default secret");
478 }
479 msg << " secret=*****";
480
481 try {
482 ServerPtr srv(new Server(peer_addr, port, local_addr, secret,
483 riref.timeout_, riref.deadtime_));
484 service->servers_.push_back(srv);
485 } catch (const Exception& ex) {
486 isc_throw(ConfigError, "can't create " << service->name_
487 << " server '" << msg.str() << "': " << ex.what());
488 }
489
490 // Done.
492 .arg(service->name_)
493 .arg(msg.str());
494}
495
496void
498 const ConstElementPtr& attr_list) {
499 for (auto const& attr : attr_list->listValue()) {
501 parser.parse(service, attr);
502 }
503}
504
505void
507 const ElementPtr& attr) {
508 AttrDefPtr def;
509
510 // Set defaults.
512
513 // name.
514 const ConstElementPtr& name = attr->get("name");
515 if (name) {
516 if (name->stringValue().empty()) {
517 isc_throw(ConfigError, "attribute name is empty");
518 }
519 def = AttrDefs::instance().getByName(name->stringValue());
520 if (!def) {
521 isc_throw(ConfigError, "attribute '"
522 << name->stringValue() << "' is unknown");
523 }
524 }
525
526 // type.
527 const ConstElementPtr& type = attr->get("type");
528 if (type) {
529 if ((type->intValue() < 0) || (type->intValue() > 255)) {
530 isc_throw(ConfigError, "out of range attribute type "
531 << type->intValue());
532 }
533 uint8_t attrib = static_cast<uint8_t>(type->intValue());
534 if (def && (def->type_ != attrib)) {
535 isc_throw(ConfigError, name->stringValue() << " attribute has "
536 << "type " << static_cast<unsigned>(def->type_)
537 << ", not " << static_cast<unsigned>(attrib));
538 }
539 if (!def) {
540 def = AttrDefs::instance().getByType(attrib);
541 }
542 if (!def) {
543 isc_throw(ConfigError, "attribute type "
544 << static_cast<unsigned>(attrib) << " is unknown");
545 }
546 }
547
548 // name or type are required.
549 if (!def) {
550 isc_throw(ConfigError, "name or type are required");
551 }
552
553 // data.
554 const string& data_txt = getString(attr, "data");
555
556 // raw.
557 const string& raw_txt = getString(attr, "raw");
558
559 // expr.
560 const string& expr_txt = getString(attr, "expr");
561
563
564 ExpressionPtr expression;
565 if (!expr_txt.empty()) {
566 if (!data_txt.empty() || !raw_txt.empty()) {
567 isc_throw(ConfigError, "data, raw and expr are exclusive");
568 }
569 Option::Universe universe;
570 if (CfgMgr::instance().getFamily() == AF_INET) {
571 universe = Option::V4;
572 } else {
573 universe = Option::V6;
574 }
575 try {
576 EvalContext eval_ctx(universe);
577 eval_ctx.parseString(expr_txt, EvalContext::PARSER_STRING);
578 expression.reset(new Expression());
579 *expression = eval_ctx.expression_;
580 } catch (const std::exception& ex) {
581 isc_throw(ConfigError, "expression: [" << expr_txt
582 << "] error: " << ex.what() << " for "
583 << def->name_ << " attribute");
584 }
585
586 service->attributes_.add(def, AttributePtr(), expression, expr_txt);
587 } else if (!raw_txt.empty()) {
588 if (!data_txt.empty()) {
589 isc_throw(ConfigError, "data and raw are exclusive");
590 }
591 // The decodeHex function expects that the string contains an
592 // even number of digits. If we don't meet this requirement,
593 // we have to insert a leading 0.
594 string padded = raw_txt;
595 if ((padded.size() % 2) != 0) {
596 padded = padded.insert(0, "0");
597 }
598 vector<uint8_t> binary;
599 try {
600 encode::decodeHex(padded, binary);
601 } catch (...) {
602 isc_throw(ConfigError, "can't decode raw: [" << raw_txt
603 << "] for " << def->name_ << " attribute");
604 }
605 try {
606 AttributePtr attribute = Attribute::fromBytes(def, binary);
607 service->attributes_.add(def, attribute);
608 } catch (const Exception& ex) {
609 isc_throw(ConfigError, "can't create " << def->name_
610 << " attribute from raw: [" << raw_txt << "]: "
611 << ex.what());
612 }
613 } else {
614 try {
615 AttributePtr attribute = Attribute::fromText(def, data_txt);
616 service->attributes_.add(def, attribute);
617 } catch (const Exception& ex) {
618 isc_throw(ConfigError, "can't create " << def->name_
619 << " attribute from [" << data_txt << "]: "
620 << ex.what());
621 }
622 }
623}
624
625} // end of namespace isc::radius
626} // end of namespace isc
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
Definition data.cc:651
@ map
Definition data.h:147
@ integer
Definition data.h:140
@ boolean
Definition data.h:142
@ string
Definition data.h:144
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
An exception that is thrown if an error occurs while configuring any server.
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Exception thrown on attempt to use a default credential.
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
uint16_t getUint16(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint16_t.
static size_t setDefaults(isc::data::ElementPtr scope, const SimpleDefaults &default_values)
Sets the default values.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition cfgmgr.cc:121
IdentifierType getIdentifierType() const
Returns the identifier type.
Definition host.cc:273
Universe
defines option universe DHCPv4 or DHCPv6
Definition option.h:90
Evaluation context, an interface to the expression evaluation.
bool parseString(const std::string &str, ParserType type=PARSER_BOOL)
Run the parser on the string specified.
@ PARSER_STRING
expression is expected to evaluate to string
isc::dhcp::Expression expression_
Parsed expression (output tokens are stored here)
static AttrDefs & instance()
Returns a single instance.
void readDictionary(const std::string &path)
Read a dictionary from a file.
AttrDefPtr getByName(const std::string &name) const
Get attribute definition by name.
AttrDefPtr getByType(const uint8_t type) const
Get attribute definition by type.
void checkStandardDefs(const AttrDefList &defs) const
Check if a list of standard attribute definitions are available and correct.
static AttributePtr fromBytes(const std::vector< uint8_t > &bytes)
From bytes (wire format).
static AttributePtr fromText(const std::string &repr)
Generic factories.
Collection of attributes.
size_t size() const
Returns the number of elements.
Attribute data configuration.
Attributes getAll() const
Get all attributes in the configuration.
size_t size() const
Returns the number of elements.
Attribute list parser for Radius.
void parse(const RadiusServicePtr &service, const data::ConstElementPtr &attr_list)
Parses Radius list of attribute configurations.
Attribute configuration parser for Radius.
static const data::SimpleDefaults ATTRIBUTE_DEFAULTS
Defaults for Radius attribute configuration.
void parse(const RadiusServicePtr &service, const data::ElementPtr &attr)
Parses Radius attribute configuration.
static const std::set< std::string > RADIUS_KEYWORDS
Keywords (aka global configuration entry names).
void parse(data::ElementPtr &config)
Parses Radius configuration.
static const data::SimpleDefaults RADIUS_DEFAULTS
Defaults for Radius configuration.
static const AttrDefList USED_STANDARD_ATTR_DEFS
Needed standard attributes definitions.
Radius hooks library implementation.
Definition radius.h:50
unsigned thread_pool_size_
Thread pool size.
Definition radius.h:196
std::string dictionary_
Dictionary path.
Definition radius.h:148
std::string bindaddr_
bindaddr.
Definition radius.h:166
bool clientid_pop0_
Client Id pop leading zero(s).
Definition radius.h:172
dhcp::Host::IdentifierType id_type4_
Identifier type for IPv4.
Definition radius.h:202
bool reselect_subnet_address_
Reselect subnet using address.
Definition radius.h:187
boost::shared_ptr< RadiusAccess > auth_
Definition radius.h:154
bool extract_duid_
Extract Duid from Client Id.
Definition radius.h:181
unsigned timeout_
Timeout.
Definition radius.h:199
dhcp::Host::IdentifierType id_type6_
Identifier type for IPv6.
Definition radius.h:205
bool canonical_mac_address_
Canonical MAC address.
Definition radius.h:169
unsigned deadtime_
Deadtime.
Definition radius.h:178
boost::shared_ptr< RadiusAccounting > acct_
Pointer to accounting (never null).
Definition radius.h:157
unsigned retries_
Retries.
Definition radius.h:190
std::map< uint32_t, uint32_t > remap_
Subnet ID to NAS port map.
Definition radius.h:151
std::string session_history_filename_
Session history filename.
Definition radius.h:193
bool reselect_subnet_pool_
Reselect subnet using pool.
Definition radius.h:184
bool clientid_printable_
Client Id try printable.
Definition radius.h:175
static RadiusImpl & instance()
RadiusImpl is a singleton class.
Definition radius.cc:37
Server list parser for Radius.
void parse(const RadiusServicePtr &service, const data::ConstElementPtr &srv_list)
Parses Radius server list.
Server parser for Radius.
void parse(const RadiusServicePtr &service, const data::ElementPtr &server)
Parses Radius server.
Service parser for Radius.
static const std::set< std::string > SERVICE_KEYWORDS
Keywords (aka service configuration entry names).
void checkAttributes(const RadiusServicePtr &service)
Check Radius attributes.
void parse(const RadiusServicePtr &service, const data::ConstElementPtr &srv_cfg)
Parses Radius service.
RADIUS server class.
static asiolink::IOAddress getSrcAddress(const asiolink::IOAddress &dest)
Get the source address from a destination address.
static asiolink::IOAddress getAddress(const std::string &name)
Get an address from a name.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
std::vector< SimpleDefault > SimpleDefaults
This specifies all default values in a given scope (e.g. a subnet).
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
boost::shared_ptr< Expression > ExpressionPtr
Definition token.h:31
std::vector< TokenPtr > Expression
This is a structure that holds an expression converted to RPN.
Definition token.h:29
const isc::log::MessageID RADIUS_SERVER_CONFIGURED
@ PW_DELEGATED_IPV6_PREFIX
ipv6prefix.
@ PW_FRAMED_IPV6_ADDRESS
ipv6addr.
std::list< AttrDef > AttrDefList
List of Attribute definitions.
boost::shared_ptr< AttrDef > AttrDefPtr
Shared pointers to Attribute definition.
boost::shared_ptr< Server > ServerPtr
Type of shared pointers to a RADIUS server object.
boost::shared_ptr< RadiusService > RadiusServicePtr
Type of pointers to Radius service.
boost::shared_ptr< Attribute > AttributePtr
isc::log::Logger radius_logger("radius-hooks")
Radius Logger.
Definition radius_log.h:35
vector< uint8_t > pop0(const ClientIdPtr &client_id)
Pop leading zero in a DHCPv4 client-id.
void decodeHex(const string &encoded_str, vector< uint8_t > &output)
Decode a base16 encoded string into binary data.
Definition encode.cc:367
Defines the logger used by the top-level component of kea-lfc.
static void check(const std::string &value)
Check if the value is a default credential.