Kea 3.1.3
client_attribute.h
Go to the documentation of this file.
1// Copyright (C) 2023-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#ifndef RADIUS_CLIENT_ATTRIBUTE_H
8#define RADIUS_CLIENT_ATTRIBUTE_H
9
11#include <cc/cfg_to_element.h>
12#include <cc/data.h>
13#include <cc/simple_parser.h>
14#include <asiolink/io_address.h>
15#include <client_dictionary.h>
16#include <boost/multi_index_container.hpp>
17#include <boost/multi_index/hashed_index.hpp>
18#include <boost/multi_index/member.hpp>
19#include <boost/multi_index/sequenced_index.hpp>
20#include <boost/noncopyable.hpp>
21#include <boost/shared_ptr.hpp>
22#include <string>
23#include <vector>
24
25namespace isc {
26namespace radius {
27
29static constexpr size_t MAX_STRING_LEN = 253;
30
32static constexpr size_t MAX_VSA_DATA_LEN = MAX_STRING_LEN - 4;
33
35using isc::data::TypeError;
36
38class Attribute;
39typedef boost::shared_ptr<Attribute> AttributePtr;
40typedef boost::shared_ptr<const Attribute> ConstAttributePtr;
41
44protected:
45
51 explicit Attribute(const uint8_t type) : type_(type) {
52 }
53
54public:
56 virtual ~Attribute() = default;
57
61 uint8_t getType() const {
62 return (type_);
63 }
64
68 virtual AttrValueType getValueType() const = 0;
69
71
77 static AttributePtr fromBytes(const std::vector<uint8_t>& bytes);
78
80
89 static AttributePtr fromText(const AttrDefPtr& def,
90 const std::string& value);
91
100 static AttributePtr fromBytes(const AttrDefPtr& def,
101 const std::vector<uint8_t>& value);
102
106
113 static AttributePtr fromString(const uint8_t type,
114 const std::string& value);
115
122 static AttributePtr fromBinary(const uint8_t type,
123 const std::vector<uint8_t>& value);
124
131 static AttributePtr fromInt(const uint8_t type, const uint32_t value);
132
139 static AttributePtr fromIpAddr(const uint8_t type,
140 const asiolink::IOAddress& value);
141
148 static AttributePtr fromIpv6Addr(const uint8_t type,
149 const asiolink::IOAddress& value);
150
158 static AttributePtr fromIpv6Prefix(const uint8_t type,
159 const uint8_t len,
160 const asiolink::IOAddress& value);
161
170 static AttributePtr fromVsa(const uint8_t type,
171 const uint32_t vendor,
172 const std::string& value);
173
181 static AttributePtr fromVsa(const uint8_t type,
182 const uint32_t vendor,
183 const std::vector<uint8_t>& value);
184
186
190 virtual size_t getValueLen() const = 0;
191
198 virtual std::string toText(size_t indent = 0) const = 0;
199
203 virtual std::vector<uint8_t> toBytes() const = 0;
204
208
213 virtual std::string toString() const;
214
219 virtual std::vector<uint8_t> toBinary() const;
220
225 virtual uint32_t toInt() const;
226
231 virtual asiolink::IOAddress toIpAddr() const;
232
237 virtual asiolink::IOAddress toIpv6Addr() const;
238
243 virtual asiolink::IOAddress toIpv6Prefix() const;
244
249 virtual uint8_t toIpv6PrefixLen() const;
250
255 virtual uint32_t toVendorId() const;
256
261 virtual std::vector<uint8_t> toVsaData() const;
262
264 const uint8_t type_;
265
268
269private:
270
279 static AttributePtr fromText0(const AttrDefPtr& def,
280 const std::string& value);
281
290 static AttributePtr fromBytes0(const AttrDefPtr& def,
291 const std::vector<uint8_t>& value);
292};
293
296
298class AttrString : public Attribute {
299protected:
300
305 AttrString(const uint8_t type, const std::string& value)
306 : Attribute(type), value_(value) {
307 if (value.empty()) {
308 isc_throw(BadValue, "value is empty");
309 }
310 if (value.size() > MAX_STRING_LEN) {
311 isc_throw(BadValue, "value is too large " << value.size()
312 << " > " << MAX_STRING_LEN);
313 }
314 }
315
320 AttrString(const uint8_t type, const std::vector<uint8_t>& value);
321
327 static AttributePtr fromText(const uint8_t type, const std::string& repr);
328
334 static AttributePtr fromBytes(const uint8_t type,
335 const std::vector<uint8_t>& bytes);
336
338 friend class Attribute;
339
340public:
344 virtual AttrValueType getValueType() const override {
345 return (PW_TYPE_STRING);
346 }
347
351 virtual size_t getValueLen() const override {
352 return (value_.size());
353 }
354
359 virtual std::string toText(size_t indent = 0) const override;
360
364 virtual std::vector<uint8_t> toBytes() const override;
365
369 virtual std::string toString() const override {
370 return (value_);
371 }
372
376 virtual std::vector<uint8_t> toBinary() const override;
377
381 virtual data::ElementPtr toElement() const override;
382
383private:
385 std::string value_;
386};
387
389class AttrInt : public Attribute {
390protected:
391
396 AttrInt(const uint8_t type, const int32_t value)
397 : Attribute(type), value_(static_cast<uint32_t>(value)) {
398 }
399
404 AttrInt(const uint8_t type, const uint32_t value)
405 : Attribute(type), value_(value) {
406 }
407
413 static AttributePtr fromText(const uint8_t type, const std::string& repr);
414
420 static AttributePtr fromBytes(const uint8_t type,
421 const std::vector<uint8_t>& bytes);
422
424 friend class Attribute;
425
426public:
427
431 virtual AttrValueType getValueType() const override {
432 return (PW_TYPE_INTEGER);
433 }
434
438 virtual size_t getValueLen() const override {
439 return (4);
440 }
441
446 virtual std::string toText(size_t indent = 0) const override;
447
451 virtual std::vector<uint8_t> toBytes() const override;
452
456 virtual uint32_t toInt() const override {
457 return (value_);
458 }
459
463 virtual data::ElementPtr toElement() const override;
464
465private:
467 const uint32_t value_;
468};
469
471class AttrIpAddr : public Attribute {
472protected:
473
478 AttrIpAddr(const uint8_t type, const asiolink::IOAddress& value)
479 : Attribute(type), value_(value) {
480 if (!value.isV4()) {
481 isc_throw(BadValue, "not v4 address " << value);
482 }
483 }
484
490 static AttributePtr fromText(const uint8_t type, const std::string& repr);
491
497 static AttributePtr fromBytes(const uint8_t type,
498 const std::vector<uint8_t>& bytes);
499
501 friend class Attribute;
502
503public:
507 virtual AttrValueType getValueType() const override {
508 return (PW_TYPE_IPADDR);
509 }
510
514 virtual size_t getValueLen() const override {
515 return (4);
516 }
517
522 virtual std::string toText(size_t indent = 0) const override;
523
527 virtual std::vector<uint8_t> toBytes() const override;
528
532 virtual asiolink::IOAddress toIpAddr() const override {
533 return (value_);
534 }
535
539 virtual data::ElementPtr toElement() const override;
540
541private:
543 asiolink::IOAddress value_;
544};
545
547class AttrIpv6Addr : public Attribute {
548protected:
549
554 AttrIpv6Addr(const uint8_t type, const asiolink::IOAddress& value)
555 : Attribute(type), value_(value) {
556 if (!value.isV6()) {
557 isc_throw(BadValue, "not v6 address " << value);
558 }
559 }
560
566 static AttributePtr fromText(const uint8_t type, const std::string& repr);
567
573 static AttributePtr fromBytes(const uint8_t type,
574 const std::vector<uint8_t>& bytes);
575
577 friend class Attribute;
578
579public:
580
584 virtual AttrValueType getValueType() const override {
585 return (PW_TYPE_IPV6ADDR);
586 }
587
591 virtual size_t getValueLen() const override {
592 return (16);
593 }
594
599 virtual std::string toText(size_t indent = 0) const override;
600
604 virtual std::vector<uint8_t> toBytes() const override;
605
609 virtual asiolink::IOAddress toIpv6Addr() const override {
610 return (value_);
611 }
612
616 virtual data::ElementPtr toElement() const override;
617
618private:
620 asiolink::IOAddress value_;
621};
622
624class AttrIpv6Prefix : public Attribute {
625protected:
626
632 AttrIpv6Prefix(const uint8_t type, const uint8_t len,
633 const asiolink::IOAddress& value)
634 : Attribute(type), len_(len), value_(value) {
635 if (!value.isV6()) {
636 isc_throw(BadValue, "not v6 address " << value);
637 }
638 if (len > 128) {
639 isc_throw(BadValue, "too long prefix "
640 << static_cast<unsigned>(len));
641 }
642 }
643
649 static AttributePtr fromText(const uint8_t type, const std::string& repr);
650
656 static AttributePtr fromBytes(const uint8_t type,
657 const std::vector<uint8_t>& bytes);
658
660 friend class Attribute;
661
662public:
663
667 virtual AttrValueType getValueType() const override {
668 return (PW_TYPE_IPV6PREFIX);
669 }
670
674 virtual size_t getValueLen() const override {
675 return (17);
676 }
677
682 virtual std::string toText(size_t indent = 0) const override;
683
687 virtual std::vector<uint8_t> toBytes() const override;
688
692 virtual asiolink::IOAddress toIpv6Prefix() const override {
693 return (value_);
694 }
695
699 virtual uint8_t toIpv6PrefixLen() const override {
700 return (len_);
701 }
702
706 virtual data::ElementPtr toElement() const override;
707
708private:
710 const uint8_t len_;
711
713 asiolink::IOAddress value_;
714};
715
717class AttrVsa : public Attribute {
718protected:
719
725 AttrVsa(const uint8_t type, const uint32_t vendor,
726 const std::string& value)
727 : Attribute(type), vendor_(vendor), value_(value) {
728 if (value.empty()) {
729 isc_throw(BadValue, "value is empty");
730 }
731 if (value.size() > MAX_VSA_DATA_LEN) {
732 isc_throw(BadValue, "value is too large " << value.size()
733 << " > " << MAX_VSA_DATA_LEN);
734 }
735 }
736
742 AttrVsa(const uint8_t type, const uint32_t vendor,
743 const std::vector<uint8_t>& value);
744
751 static AttributePtr fromText(const uint8_t type, const std::string& repr);
752
758 static AttributePtr fromBytes(const uint8_t type,
759 const std::vector<uint8_t>& bytes);
760
762 friend class Attribute;
763
764public:
765
769 virtual AttrValueType getValueType() const override {
770 return (PW_TYPE_VSA);
771 }
772
776 virtual size_t getValueLen() const override {
777 return (4 + value_.size());
778 }
779
784 virtual std::string toText(size_t indent = 0) const override;
785
789 virtual std::vector<uint8_t> toBytes() const override;
790
794 virtual uint32_t toVendorId() const override {
795 return (vendor_);
796 }
797
801 virtual std::vector<uint8_t> toVsaData() const override;
802
806 virtual data::ElementPtr toElement() const override;
807
808private:
810 uint32_t vendor_;
811
813 std::string value_;
814};
815
820public:
821
823 typedef boost::multi_index_container<
824 // This container stores pointers to attributes.
826 // Start specification of indexes here.
827 boost::multi_index::indexed_by<
828 // Sequenced index to keep insert order.
829 boost::multi_index::sequenced<>,
830 // Hash index for direct retrieval.
831 boost::multi_index::hashed_non_unique<
832 boost::multi_index::member<
833 Attribute, const uint8_t, &Attribute::type_
834 >
835 >
836 >
838
841 }
842
844 virtual ~Attributes() {
845 clear();
846 }
847
851 bool empty() const {
852 return (container_.empty());
853 }
854
858 size_t size() const {
859 return (container_.size());
860 }
861
865 void add(const ConstAttributePtr& attr);
866
873 bool del(const uint8_t type);
874
876 void clear() {
877 container_.clear();
878 }
879
883 void append(const Attributes& other);
884
889 size_t count(const uint8_t type) const;
890
895 ConstAttributePtr get(const uint8_t type) const;
896
903 std::string toText(size_t indent = 0) const;
904
908 data::ElementPtr toElement() const override;
909
914 static Attributes fromElement(const data::ConstElementPtr& attr_list);
915
919 AttributeContainer::iterator begin() {
920 return (container_.begin());
921 }
922
926 AttributeContainer::const_iterator begin() const {
927 return (container_.begin());
928 }
929
933 AttributeContainer::const_iterator cbegin() const {
934 return (container_.cbegin());
935 }
936
940 AttributeContainer::iterator end() {
941 return (container_.end());
942 }
943
947 AttributeContainer::const_iterator end() const {
948 return (container_.end());
949 }
950
952 AttributeContainer::const_iterator cend() const {
953 return (container_.cend());
954 }
955
956protected:
959};
960
962typedef boost::shared_ptr<Attributes> AttributesPtr;
963
964} // end of namespace isc::radius
965} // end of namespace isc
966
967#endif
if(!(yy_init))
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual uint32_t toInt() const override
To integer.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
virtual size_t getValueLen() const override
Value length.
virtual data::ElementPtr toElement() const override
Unparse attribute.
AttrInt(const uint8_t type, const uint32_t value)
Constructor (unsigned).
friend class Attribute
Make Attribute a friend class.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
AttrInt(const uint8_t type, const int32_t value)
Constructor (signed).
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual AttrValueType getValueType() const override
Get value type.
AttrIpAddr(const uint8_t type, const asiolink::IOAddress &value)
Constructor.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
virtual asiolink::IOAddress toIpAddr() const override
To IPv4 address.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual size_t getValueLen() const override
Value length.
friend class Attribute
Make Attribute a friend class.
virtual AttrValueType getValueType() const override
Get value type.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
virtual asiolink::IOAddress toIpv6Addr() const override
To IPv6 address.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
virtual AttrValueType getValueType() const override
Get value type.
virtual size_t getValueLen() const override
Value length.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
AttrIpv6Addr(const uint8_t type, const asiolink::IOAddress &value)
Constructor.
friend class Attribute
Make Attribute a friend class.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual asiolink::IOAddress toIpv6Prefix() const override
To IPv6 prefix.
AttrIpv6Prefix(const uint8_t type, const uint8_t len, const asiolink::IOAddress &value)
Constructor.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual size_t getValueLen() const override
Value length.
virtual uint8_t toIpv6PrefixLen() const override
To IPv6 prefix length.
friend class Attribute
Make Attribute a friend class.
virtual AttrValueType getValueType() const override
Get value type.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
AttrString(const uint8_t type, const std::string &value)
Constructor.
virtual std::vector< uint8_t > toBinary() const override
To binary.
virtual size_t getValueLen() const override
Value length.
friend class Attribute
Make Attribute a friend class.
virtual std::string toString() const override
To string.
virtual AttrValueType getValueType() const override
Get value type.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
virtual uint32_t toVendorId() const override
To vendor id.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual AttrValueType getValueType() const override
Get value type.
friend class Attribute
Make Attribute a friend class.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
virtual std::vector< uint8_t > toVsaData() const override
To vsa data.
AttrVsa(const uint8_t type, const uint32_t vendor, const std::string &value)
Constructor.
virtual size_t getValueLen() const override
Value length.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
RADIUS attribute base class.
static AttributePtr fromBytes(const std::vector< uint8_t > &bytes)
Generic factories.
virtual std::string toString() const
Specific get methods.
virtual size_t getValueLen() const =0
Generic get methods.
static AttributePtr fromInt(const uint8_t type, const uint32_t value)
From integer with type.
static AttributePtr fromIpAddr(const uint8_t type, const asiolink::IOAddress &value)
From IPv4 address with type.
virtual uint32_t toInt() const
To integer.
Attribute(const uint8_t type)
Constructor.
virtual uint32_t toVendorId() const
To vendor id.
static AttributePtr fromString(const uint8_t type, const std::string &value)
From type specific factories.
virtual std::vector< uint8_t > toBytes() const =0
To bytes (wire format).
uint8_t getType() const
Get type.
virtual ~Attribute()=default
Virtual destructor.
virtual asiolink::IOAddress toIpAddr() const
To IPv4 address.
virtual asiolink::IOAddress toIpv6Addr() const
To IPv6 address.
static AttributePtr fromBinary(const uint8_t type, const std::vector< uint8_t > &value)
From binary with type.
static AttributePtr fromText(const AttrDefPtr &def, const std::string &value)
From definition generic factories.
virtual uint8_t toIpv6PrefixLen() const
To IPv6 prefix length.
static AttributePtr fromIpv6Prefix(const uint8_t type, const uint8_t len, const asiolink::IOAddress &value)
From IPv6 prefix with type.
virtual std::string toText(size_t indent=0) const =0
Returns text representation of the attribute.
static AttributePtr fromIpv6Addr(const uint8_t type, const asiolink::IOAddress &value)
From IPv6 address with type.
virtual asiolink::IOAddress toIpv6Prefix() const
To IPv6 prefix.
virtual AttrValueType getValueType() const =0
Get value type.
const uint8_t type_
Type.
virtual std::vector< uint8_t > toBinary() const
To binary.
static AttributePtr fromVsa(const uint8_t type, const uint32_t vendor, const std::string &value)
From Vendor ID and string data with type.
virtual std::vector< uint8_t > toVsaData() const
To vsa data.
Collection of attributes.
boost::multi_index_container< ConstAttributePtr, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_non_unique< boost::multi_index::member< Attribute, const uint8_t, &Attribute::type_ > > > > AttributeContainer
Type of the container.
void add(const ConstAttributePtr &attr)
Adds instance of the attribute to the collection.
AttributeContainer container_
The container.
size_t size() const
Returns the number of elements.
AttributeContainer::const_iterator begin() const
Get the iterator to the beginning.
std::string toText(size_t indent=0) const
Returns text representation of the collection.
bool empty() const
Indicates the object is empty.
void append(const Attributes &other)
Append another collection.
size_t count(const uint8_t type) const
Counts instance of the attribute in the collection.
virtual ~Attributes()
Destructor.
AttributeContainer::const_iterator cend() const
Get the const iterator to the past-the-end.
ConstAttributePtr get(const uint8_t type) const
Get instance of the attribute in the collection.
data::ElementPtr toElement() const override
Unparse collection.
AttributeContainer::const_iterator cbegin() const
Get the const iterator to the beginning.
void clear()
Clear the collection.
AttributeContainer::iterator begin()
Get the iterator to the beginning.
bool del(const uint8_t type)
Deletes an attribute from the collection.
static Attributes fromElement(const data::ConstElementPtr &attr_list)
Parse collection.
AttributeContainer::iterator end()
Get the iterator to the past-the-end.
AttributeContainer::const_iterator end() const
Get the iterator to the past-the-end.
#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< Attributes > AttributesPtr
Shared pointers to attribute collection.
boost::shared_ptr< const Attribute > ConstAttributePtr
AttrValueType
Attribute value types.
boost::shared_ptr< AttrDef > AttrDefPtr
Shared pointers to Attribute definition.
boost::shared_ptr< Attribute > AttributePtr
Defines the logger used by the top-level component of kea-lfc.
Abstract class for configuration Cfg_* classes.