#ifndef RadiusMessage_hxx
#define RadiusMessage_hxx
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2001 Vovida Networks, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* <http://www.vovida.org/>.
*
*/
static const char* const RadiusMessage_hxx_Version =
"$Id: RadiusMessage.hxx,v 1.6.28.1 2003/02/20 01:17:43 bko Exp $";
#include <string>
#include <list>
#include "RadiusData.hxx"
#include "radius.h"
#include "RadiusAttribute.hxx"
#include "VRadiusException.hxx"
///
typedef list<RadiusAttribute>::const_iterator RadiusAttrIter;
/** RADIUS Packet as defined in RFC 2865 Section 3.
<pre>
Data Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Code | Identifier | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Authenticator |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attributes ...
+-+-+-+-+-+-+-+-+-+-+-+-+-
</pre>
*/
class RadiusMessage
{
public:
/** Create a RADIUS Message with type, no Attriubte yet
Useful for composing a request
*/
RadiusMessage( const RadiusPacketType code );
/** Create a RADIUS Message with type and an Authenticator
No Attriubte yet
Useful for composing a response
*/
RadiusMessage( const RadiusPacketType code,
const u_int8_t requestIdentifer,
const u_int8_t *requestAuth );
/** Create a RADIUS Message from data
Use when a message is received
Request Authenticator is verified automatically. However,
RadiusMessage::verifyResponseAuthenticator(auth,secret)
should be called later for Responses.
If an exception is thrown, the message should be handled
(discarded or rejected) according to the RFCs.
*/
RadiusMessage( const RadiusData data, const char* secret )
throw( VRadiusException& );
///
RadiusMessage( const RadiusMessage& rhs )
{
copyRhsToThis( rhs );
}
///
RadiusMessage& operator=( const RadiusMessage& rhs )
{
if( this != &rhs )
{
copyRhsToThis( rhs );
}
return *this;
}
///
void copyRhsToThis( const RadiusMessage& rhs )
{
memcpy( &myRequestAuthenticator,
rhs.myRequestAuthenticator,
RadiusAuthenticatorLength );
myAttributes = rhs.myAttributes;
myData = rhs.myData;
}
///
RadiusPacketType type()
{
return myData.msgHdr.code;
}
/// Encode all Attributes in this list
RadiusData encodeAttributes() const;
/// TODO: throw exception instead
bool add( const RadiusAttribute& attr );
/// Get the number of attributes
u_int32_t attributeCount() const
{
return myAttributes.size();
}
/**
Get the first instance of Attribute t from the list
Use getAll( RadiusAttributeType ) to retrieve multiple
attributes with the same type
*/
const RadiusAttribute& get( const RadiusAttributeType attrType ) const
throw( VRadiusException& );
/**
Get the list of all attributes of type attrType
*/
list< RadiusAttribute > getAll( const RadiusAttributeType attrType ) const;
/**
For RADIUS requests only
Must be called before Authenticator is calculated
*/
void setIdentifier( const u_int8_t& id )
{
myData.msgHdr.identifier = id;
}
///
u_int8_t getIdentifier() const
{
return myData.msgHdr.identifier;
}
/** Calculate and set the Authenticator
Must be called right before the packet is sent
*/
void calcAuthenticator( const char* secret );
/** Get the Authenticator
*/
const u_int8_t* getAuthenticator() const
{
return myRequestAuthenticator;
}
/** Verify a response with the original request's Authenticator
*/
bool verifyResponseAuthenticator( const u_int8_t *reqAuth,
const char* secret );
/** Get raw message data for sending
*/
const RawMessage& data() const
{
return myData;
}
/// Get a human readable representation of all attributes
string verbose() const;
/// Raw message in hex for debugging
string hexDump() const;
/// Get a human readable representation of the message header
string headerDump() const;
/// Get a human readable representation of the message
string attributesVerbose() const;
private:
/// Disable default constructor
RadiusMessage()
{
}
/** Decode Attributes
If an Attribute is received in an Access-Request but an
exception is thrown, an Access-Reject SHOULD be transmitted.
If an Attribute is received in an Access-Accept, Access-Reject
or Access-Challenge packet and an exception is thrown, the
packet must either be treated as an Access-Reject or else
silently discarded.
*/
void decodeAttributes( const char* secret )
throw( VRadiusException& );
///
bool verifyAccountingRequestAuthenticator( const char* secret );
/** Encode User-Password in Access-Request
oldPassword length must be a multiple of 16 octets
*/
void encodeUserPassword( u_int8_t* newPassword,
const char* secret,
const RadiusData& oldPassword );
/** Decode User-Password in Access-Request
oldPassword length must be a multiple of 16 octets
*/
void decodeUserPassword( u_int8_t* newPassword,
const char* secret,
const RadiusData& oldPassword );
/// Hide User-Password in Access-Request
void hideUserPassword( const char* secret );
/// Calculate and set myRequestAuthenticator for Access-Request packets
void calcAccessRequestAuthenticator();
/** Calculate and set the Authenticator for response (Access-Accept,
Access-Reject, Access-Challenge or Accounting Response) packets
*/
void calcResponseAuthenticator( const char* secret );
/// Calculate and set the Authenticator for Accounting request packets
void calcAccountingRequestAuthenticator( const char* secret );
void calcMD5( u_int8_t *digest,
const u_int8_t *buf,
const u_int32_t bufLen );
/// Request Authenticator
u_int8_t myRequestAuthenticator[ RadiusAuthenticatorLength ];
// TODO: may need a flag to keep myAttrList and myData in sync
/// Attribute list
list< RadiusAttribute > myAttributes;
/// RADIUS packet (in network byte order)
RawMessage myData;
};
// Local Variables:
// mode:c++
// c-file-style:"bsd"
// c-basic-offset:4
// c-file-offsets:((inclass . ++))
// indent-tabs-mode:nil
// End:
#endif
syntax highlighted by Code2HTML, v. 0.9.1