18#include <boost/scoped_ptr.hpp>
37 return (
"Access-Request");
39 return (
"Access-Accept");
41 return (
"Access-Reject");
43 return (
"Accounting-Request");
45 return (
"Accounting-Response");
47 return (
"Accounting-Status");
49 return (
"Password-Request");
51 return (
"Password-Ack");
53 return (
"Password-Reject");
55 return (
"Accounting-Message");
57 return (
"Access-Challenge");
59 return (
"Status-Server");
61 return (
"Status-Client");
63 result <<
"Message-Code-" <<
static_cast<unsigned>(code);
64 return (result.str());
69 const vector<uint8_t>& auth,
const string& secret,
86 for (auto const& attr : *other.attributes_) {
87 attributes_->add(attr);
93 const vector<uint8_t>& auth,
117 if (auth.size() != AUTH_VECTOR_LEN) {
126 auth_.resize(AUTH_VECTOR_LEN, 0);
132 if (
auth_.size() != AUTH_VECTOR_LEN) {
139 if (secret.empty()) {
150 if (
auth_.size() != AUTH_VECTOR_LEN) {
163 size_t msg_auth_ptr = 0;
174 if (msg_auth_ptr != 0) {
178 (attr->getValueLen() != AUTH_VECTOR_LEN)) {
183 vector<uint8_t> binary = attr->toBytes();
184 if (binary.empty()) {
187 if (
buffer_.size() + binary.size() > PW_MAX_MSG_SIZE) {
200 if (msg_auth_ptr != 0) {
209 md->final(&
auth_[0], AUTH_VECTOR_LEN);
214 .arg(
static_cast<unsigned>(
code_))
228 if (
buffer_.size() < AUTH_HDR_LEN) {
230 <<
" < " << AUTH_HDR_LEN);
237 auth_.resize(AUTH_VECTOR_LEN);
239 }
else if (
auth_.size() != AUTH_VECTOR_LEN) {
249 <<
" length " <<
length_ <<
" < " << AUTH_HDR_LEN);
251 if (
length_ > PW_MAX_MSG_SIZE) {
253 <<
" length " <<
length_ <<
" > " << PW_MAX_MSG_SIZE);
261 vector<uint8_t> work =
buffer_;
264 md->update(&work[0], work.size());
267 digest.resize(AUTH_VECTOR_LEN);
268 md->final(&
digest[0], AUTH_VECTOR_LEN);
275 auth_.resize(AUTH_VECTOR_LEN);
281 size_t ptr = AUTH_HDR_LEN;
282 size_t msg_auth_ptr = 0;
290 const uint8_t type =
buffer_[ptr];
291 const uint8_t len =
buffer_[ptr + 1];
295 <<
static_cast<unsigned>(type) <<
"): length "
296 <<
static_cast<unsigned>(len) <<
", space "
301 <<
static_cast<unsigned>(len) <<
" < 3");
303 vector<uint8_t> binary;
305 memmove(&binary[0], &
buffer_[ptr], binary.size());
312 if (msg_auth_ptr != 0) {
320 if (msg_auth_ptr != 0) {
329 .arg(
static_cast<unsigned>(
code_))
338 (attr->getValueLen() == 0) ||
339 (
auth_.size() != AUTH_VECTOR_LEN) ||
345 vector<uint8_t> password = attr->toBinary();
346 size_t len = password.size();
347 len = (len + AUTH_VECTOR_LEN - 1) & ~(AUTH_VECTOR_LEN - 1);
348 if (len > AUTH_PASS_LEN) {
351 password.resize(len);
354 for (
size_t i = 0; i < len; i += AUTH_VECTOR_LEN) {
362 to_hash = &password[i - AUTH_VECTOR_LEN];
364 md->update(to_hash, AUTH_VECTOR_LEN);
367 digest.resize(AUTH_VECTOR_LEN);
368 md->final(&
digest[0], AUTH_VECTOR_LEN);
369 for (
size_t j = 0; j < AUTH_VECTOR_LEN; j++) {
370 password[i + j] ^=
digest[j];
372 memset(&
digest[0], 0, AUTH_VECTOR_LEN);
382 (attr->getValueLen() == 0) ||
383 ((attr->getValueLen() % AUTH_VECTOR_LEN) != 0) ||
384 (
auth_.size() != AUTH_VECTOR_LEN) ||
390 vector<uint8_t> password = attr->toBinary();
391 size_t len = password.size();
392 if (len > AUTH_PASS_LEN) {
394 password.resize(len);
400 if (i < AUTH_VECTOR_LEN) {
403 i -= AUTH_VECTOR_LEN;
411 to_hash = &password[i - AUTH_VECTOR_LEN];
413 md->update(to_hash, AUTH_VECTOR_LEN);
416 digest.resize(AUTH_VECTOR_LEN);
417 md->final(&
digest[0], AUTH_VECTOR_LEN);
418 for (
size_t j = 0; j < AUTH_VECTOR_LEN; j++) {
419 password[i + j] ^=
digest[j];
421 memset(&
digest[0], 0, AUTH_VECTOR_LEN);
425 while (password.back() == 0) {
427 if (password.size() == 1) {
439 if ((ptr < AUTH_HDR_LEN) || (ptr >
buffer_.size() - 2 - AUTH_VECTOR_LEN) ||
440 (
buffer_[ptr + 1] != 2 + AUTH_VECTOR_LEN) ||
441 (
auth_.size() != AUTH_VECTOR_LEN) ||
446 boost::scoped_ptr<HMAC> hmac(
450 std::vector<uint8_t> to_sign =
buffer_;
451 memmove(&to_sign[4], &
auth_[0],
auth_.size());
452 memset(&to_sign[ptr + 2], 0, AUTH_VECTOR_LEN);
453 hmac->update(&to_sign[0], to_sign.size());
454 vector<uint8_t> sign = hmac->sign(AUTH_VECTOR_LEN);
455 memmove(&
buffer_[ptr + 2], &sign[0], sign.size());
460 if ((ptr < AUTH_HDR_LEN) || (ptr >
buffer_.size() - 2 - AUTH_VECTOR_LEN) ||
461 (
buffer_[ptr + 1] != 2 + AUTH_VECTOR_LEN) ||
462 (
auth_.size() != AUTH_VECTOR_LEN) ||
467 vector<uint8_t> sign;
468 sign.resize(AUTH_VECTOR_LEN);
469 memmove(&sign[0], &
buffer_[ptr + 2], sign.size());
471 boost::scoped_ptr<HMAC> hmac(
475 std::vector<uint8_t> to_verify =
buffer_;
476 memmove(&to_verify[4], &
auth_[0],
auth_.size());
477 memset(&to_verify[ptr + 2], 0, AUTH_VECTOR_LEN);
479 hmac->update(&to_verify[0], to_verify.size());
480 if (!hmac->verify(&sign[0], sign.size())) {
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
static CryptoLink & getCryptoLink()
Returns a reference to the singleton instance.
static AttrDefs & instance()
Returns a single instance.
static AttributePtr fromBytes(const std::vector< uint8_t > &bytes)
Generic factories.
static AttributePtr fromBinary(const uint8_t type, const std::vector< uint8_t > &value)
From binary with type.
Collection of attributes.
std::vector< uint8_t > auth_
Authenticator: header[4] (16 octets).
void setAuth(const std::vector< uint8_t > &auth)
Set authenticator.
ConstAttributePtr encodeUserPassword(const ConstAttributePtr &attr)
Encode User-Password in an Access-Request.
ConstAttributePtr decodeUserPassword(const ConstAttributePtr &attr)
Decode User-Password in an Access-Request.
void signMessageAuthenticator(size_t ptr)
Encode Message-Authenticator in an Status-Server.
Message(const uint8_t code, uint16_t length, const std::vector< uint8_t > &auth, const std::string &secret, const AttributesPtr &attributes)
Constructor.
uint8_t identifier_
Identifier (random): header[1].
void randomAuth()
Randomize authenticator.
std::vector< uint8_t > encode()
Encode a message.
std::vector< uint8_t > buffer_
Buffer (message content).
uint8_t code_
Code (useful values in MsgCode): header[0].
void decode()
Decode a message.
AttributesPtr attributes_
Attributes: header[20]...
uint16_t length_
Length: header[2] (16 bits, network order).
std::string secret_
Secret (not empty).
void zeroAuth()
Fill authenticator with 0.
virtual ~Message()
Destructor.
void verifyMessageAuthenticator(size_t ptr)
Decode Message-Authenticator in an Status-Server.
void setSecret(const std::string &secret)
Set secret.
void randomIdentifier()
Randomize identifier.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
std::vector< uint8_t > random(size_t len)
Generate random value.
void digest(const void *data, const size_t data_len, const HashAlgorithm hash_algorithm, isc::util::OutputBuffer &result, size_t len)
Create an Hash digest for the given data.
@ PW_USER_PASSWORD
string.
@ PW_MESSAGE_AUTHENTICATOR
string.
boost::shared_ptr< Attributes > AttributesPtr
Shared pointers to attribute collection.
boost::shared_ptr< const Attribute > ConstAttributePtr
const isc::log::MessageID RADIUS_DECODE_MESSAGE
string msgCodeToText(const uint8_t code)
MsgCode value -> name function.
const int RADIUS_DBG_TRACE
Radius logging levels.
const isc::log::MessageID RADIUS_ENCODE_MESSAGE
isc::log::Logger radius_logger("radius-hooks")
Radius Logger.
Defines the logger used by the top-level component of kea-lfc.