/* ====================================================================
* 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
* .
*
*/
static const char* const radiusTest_cxx_Version =
"$Id: radiusTest.cxx,v 1.13 2002/12/12 02:34:48 bko Exp $";
#ifdef __FreeBSD__
#include
#endif
#include
#include
#include "cpLog.h"
#include "Verify.hxx"
#include "RadiusMessage.hxx"
// RADIUS test (automatic test framework) program
int
main()
{
cpLogSetPriority( LOG_DEBUG_STACK );
// cpLogSetPriority( LOG_INFO );
const char * const secret = "shhhh";
u_int8_t identifier = 0;
// Attributes
RadiusAttribute attrUserName( RA_USER_NAME,
reinterpret_cast("vovida"),
6 ); // Test include \0 at the end
RadiusAttribute attrUserPassword( RA_USER_PASSWORD,
reinterpret_cast("01234567890123456"),
17 );
u_int32_t ip( htonl(0x80818283) ); // 128.129.130.131
RadiusAttribute attrNasIpAddress( RA_NAS_IP_ADDRESS,
reinterpret_cast(&ip),
sizeof(ip) );
u_int32_t port( htonl(18) );
RadiusData valNasPort( &port , sizeof(port) );
RadiusAttribute attrNasPort( RA_NAS_PORT, valNasPort );
u_int32_t serviceType( htonl(RAST_LOGIN) );
RadiusData valServiceType( &serviceType , sizeof(serviceType) );
RadiusAttribute attrServiceType( RA_SERVICE_TYPE, valServiceType );
char displayMessage[ RadiusMaxAttributeLength - 2 ];
u_int32_t timeout( htonl(36000) );
snprintf( displayMessage,
sizeof(displayMessage),
"Credit: %d",
ntohl(timeout) );
RadiusData valReplyMessage1( displayMessage, strlen(displayMessage) );
RadiusAttribute attrReplyMessage1( RA_REPLY_MESSAGE, valReplyMessage1 );
RadiusData valReplyMessage2( "Access Denied", 13 );
RadiusAttribute attrReplyMessage2( RA_REPLY_MESSAGE, valReplyMessage2 );
snprintf( displayMessage, sizeof(displayMessage), "Credit: %d", 0 );
RadiusData valReplyMessage3( displayMessage, strlen(displayMessage) );
RadiusAttribute attrReplyMessage3( RA_REPLY_MESSAGE, valReplyMessage3 );
RadiusData valSessinTimeout( &timeout, sizeof(timeout) );
RadiusAttribute attrSessionTimeout( RA_SESSION_TIMEOUT, valSessinTimeout );
RadiusData valCallee( "555-1212", 9 );
RadiusAttribute attrCallee( RA_CALLED_STATION_ID, valCallee );
RadiusData valCaller( "Anonymous", 10 );
RadiusAttribute attrCaller( RA_CALLING_STATION_ID, valCaller );
u_int32_t acctType( htonl(RAS_START) );
RadiusData valAcctStatus( &acctType, sizeof(acctType) );
RadiusAttribute attrAcctStatusStart( RA_ACCT_STATUS_TYPE, valAcctStatus );
acctType = htonl(RAS_INTERIM);
RadiusData valAcctStatus2( &acctType, sizeof(acctType) );
RadiusAttribute attrAcctStatusInterim( RA_ACCT_STATUS_TYPE, valAcctStatus2 );
acctType = htonl(RAS_STOP);
RadiusData valAcctStatus3( &acctType, sizeof(acctType) );
RadiusAttribute attrAcctStatusStop( RA_ACCT_STATUS_TYPE, valAcctStatus3 );
RadiusData valAcctSessionId( "f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com", 49 );
RadiusAttribute attrAcctSessionId( RA_ACCT_SESSION_ID, valAcctSessionId );
u_int32_t duration( htonl(180) );
RadiusData valAcctSessionTime( &duration, sizeof(duration) );
RadiusAttribute attrAcctSessionTime( RA_ACCT_SESSION_TIME, valAcctSessionTime );
u_int32_t cause( htonl(RATC_SESSION_TIMEOUT) );
RadiusData valAcctTerminateCause( &cause, sizeof(cause) );
RadiusAttribute attrAcctTerminateCause( RA_ACCT_TERMINATE_CAUSE, valAcctTerminateCause );
u_int32_t portType( htonl(RANPT_VIRTUAL) );
RadiusData valNasPortType( &portType , sizeof(portType) );
RadiusAttribute attrNasPortType( RA_NAS_PORT_TYPE, valNasPortType );
u_int8_t accessReqAuth[ RadiusAuthenticatorLength ];
string resultRecv;
string resultSend;
cpLog( LOG_INFO, "\n-------------------- Test 1 ----------------------\n Access-Request\n" );
// At the client side
RadiusMessage accessReqMsg( RP_ACCESS_REQUEST );
// Warning: assert is used for testing only
assert( accessReqMsg.add( attrUserName ) );
assert( accessReqMsg.add( attrUserPassword ) );
assert( accessReqMsg.add( attrNasIpAddress ) );
assert( accessReqMsg.add( attrServiceType ) );
assert( accessReqMsg.add( attrNasPortType ) );
accessReqMsg.setIdentifier( ++identifier );
accessReqMsg.calcAuthenticator( secret );
resultSend = accessReqMsg.hexDump();
// At the server side
RawMessage udpMsg1( accessReqMsg.data() );
RadiusData msgReceived1( udpMsg1.buffer, ntohs(udpMsg1.msgHdr.length) );
try
{
RadiusMessage accessReqMsg2( msgReceived1, secret );
resultRecv = accessReqMsg2.hexDump();
test_verify( resultSend == resultRecv );
cpLog( LOG_INFO, "Verbose\n[%s]", accessReqMsg2.verbose().c_str() );
}
catch( VRadiusException &e )
{
cpLog( LOG_ERR, "Test failed - %s", e.getDescription().c_str() );
}
cpLog( LOG_INFO, "\n-------------------- Test 2 ----------------------\n Access-Accept\n" );
memcpy( accessReqAuth,
udpMsg1.msgHdr.authenticator,
RadiusAuthenticatorLength );
// At the server side
RadiusMessage accessAcceptMsg( RP_ACCESS_ACCEPT,
udpMsg1.msgHdr.identifier,
accessReqAuth );
RadiusAttribute attrClass( RA_CLASS, RadiusData( "Nas Ip:1.4.61.70", 16 ) );
// Warning: assert is used for testing only
assert( accessAcceptMsg.add( attrReplyMessage1 ) );
assert( accessAcceptMsg.add( attrClass ) );
assert( accessAcceptMsg.add( attrSessionTimeout ) );
accessAcceptMsg.calcAuthenticator( secret );
resultSend = accessAcceptMsg.hexDump();
// At the client side
RawMessage udpMsg2( accessAcceptMsg.data() );
RadiusData msgReceived2( udpMsg2.buffer, ntohs(udpMsg2.msgHdr.length) );
try
{
RadiusMessage accessAcceptMsg2( msgReceived2, secret );
resultRecv = accessAcceptMsg2.hexDump();
test_verify( accessAcceptMsg2.verifyResponseAuthenticator(accessReqAuth,
secret) &&
resultSend == resultRecv );
cpLog( LOG_INFO, "Verbose\n[%s]", accessAcceptMsg2.verbose().c_str() );
}
catch( VRadiusException &e )
{
cpLog( LOG_ERR, "Test failed - %s", e.getDescription().c_str() );
}
cpLog( LOG_INFO, "\n-------------------- Test 3 ----------------------\n Access-Reject\n" );
// At the server side
RadiusMessage accessRejectMsg( RP_ACCESS_REJECT,
udpMsg1.msgHdr.identifier,
accessReqAuth );
// Warning: assert is used for testing only
assert( accessRejectMsg.add( attrReplyMessage2 ) );
assert( accessRejectMsg.add( attrReplyMessage3 ) );
accessRejectMsg.calcAuthenticator( secret );
resultSend = accessRejectMsg.hexDump();
// At the client side
RawMessage udpMsg3( accessRejectMsg.data() );
RadiusData msgReceived3( udpMsg3.buffer, ntohs(udpMsg3.msgHdr.length) );
try
{
RadiusMessage accessRejectMsg2( msgReceived3, secret );
resultRecv = accessRejectMsg2.hexDump();
test_verify( accessRejectMsg2.verifyResponseAuthenticator(accessReqAuth,
secret) &&
resultSend == resultRecv );
cpLog( LOG_INFO, "Verbose\n[%s]",
accessRejectMsg.verbose().c_str() );
}
catch( VRadiusException &e )
{
cpLog( LOG_ERR, "Test failed - %s", e.getDescription().c_str() );
}
cpLog( LOG_INFO, "\n-------------------- Test 4 ----------------------\n Accounting-Requesst Start\n" );
// At the client side
RadiusMessage acctReqMsg( RP_ACCOUNTING_REQUEST );
// Warning: assert is used for testing only
assert( acctReqMsg.add( attrUserName ) );
assert( acctReqMsg.add( attrNasIpAddress ) );
assert( acctReqMsg.add( attrNasPort ) );
assert( acctReqMsg.add( accessAcceptMsg.get( RA_CLASS ) ) );
assert( acctReqMsg.add( attrCallee ) );
assert( acctReqMsg.add( attrCaller ) );
assert( acctReqMsg.add( attrAcctStatusStart ) );
assert( acctReqMsg.add( attrAcctSessionId ) );
acctReqMsg.setIdentifier( ++identifier );
acctReqMsg.calcAuthenticator( secret );
resultSend = acctReqMsg.hexDump();
// At the server side
RawMessage udpMsg4( acctReqMsg.data() );
RadiusData msgReceived4( udpMsg4.buffer, ntohs(udpMsg4.msgHdr.length) );
try
{
RadiusMessage acctReqMsg2( msgReceived4, secret );
resultRecv = acctReqMsg2.hexDump();
test_verify( resultSend == resultRecv );
cpLog( LOG_INFO, "Verbose\n[%s]", acctReqMsg2.verbose().c_str() );
}
catch( VRadiusException &e )
{
cpLog( LOG_ERR, "Test failed - %s", e.getDescription().c_str() );
}
cpLog( LOG_INFO, "\n-------------------- Test 5 ----------------------\n Accounting-Response\n" );
// At the server side
const u_int8_t* reqAuth = acctReqMsg.getAuthenticator();
RadiusMessage acctRespMsg( RP_ACCOUNTING_RESPONSE,
udpMsg4.msgHdr.identifier,
reqAuth );
acctRespMsg.calcAuthenticator( secret );
resultSend = acctRespMsg.hexDump();
// At the client side
RawMessage udpMsg5( acctRespMsg.data() );
RadiusData msgReceived5( udpMsg5.buffer, ntohs(udpMsg5.msgHdr.length) );
try
{
RadiusMessage acctRespMsg2( msgReceived5, secret );
if( acctRespMsg2.type() == RP_ACCOUNTING_RESPONSE )
{
if( acctRespMsg2.verifyResponseAuthenticator( reqAuth, secret ) )
{
resultRecv = acctRespMsg2.hexDump();
test_verify( resultSend == resultRecv );
cpLog( LOG_INFO, "Verbose\n[%s]", acctRespMsg2.verbose().c_str() );
}
else
{
cpLog( LOG_ERR, "Cannot verify Response Authenticator" );
}
}
}
catch( VRadiusException &e )
{
cpLog( LOG_ERR, "Test failed - %s", e.getDescription().c_str() );
}
cpLog( LOG_INFO, "\n-------------------- Test 6 ----------------------\n Accounting-Requesst Interim\n" );
// At the client side
RadiusMessage acctInterimMsg( RP_ACCOUNTING_REQUEST );
// Warning: assert is used for testing only
assert( acctInterimMsg.add( acctReqMsg.get( RA_USER_NAME ) ) );
assert( acctInterimMsg.add( acctReqMsg.get( RA_NAS_IP_ADDRESS ) ) );
assert( acctInterimMsg.add( acctReqMsg.get( RA_NAS_PORT ) ) );
assert( acctInterimMsg.add( accessAcceptMsg.get( RA_CLASS ) ) );
assert( acctInterimMsg.add( acctReqMsg.get( RA_CALLED_STATION_ID ) ) );
assert( acctInterimMsg.add( acctReqMsg.get( RA_CALLING_STATION_ID ) ) );
assert( acctInterimMsg.add( attrAcctStatusInterim ) );
assert( acctInterimMsg.add( acctReqMsg.get( RA_ACCT_SESSION_ID ) ) );
acctInterimMsg.setIdentifier( ++identifier );
acctInterimMsg.calcAuthenticator( secret );
resultSend = acctInterimMsg.hexDump();
// At the server side
RawMessage udpMsg6( acctInterimMsg.data() );
RadiusData msgReceived6( udpMsg6.buffer, ntohs(udpMsg6.msgHdr.length) );
try
{
RadiusMessage acctReqMsg2( msgReceived6, secret );
resultRecv = acctReqMsg2.hexDump();
test_verify( resultSend == resultRecv );
cpLog( LOG_INFO, "Verbose\n[%s]", acctReqMsg2.verbose().c_str() );
}
catch( VRadiusException &e )
{
cpLog( LOG_ERR, "Test failed - %s", e.getDescription().c_str() );
}
cpLog( LOG_INFO, "\n-------------------- Test 7 ----------------------\n Accounting-Requesst Stop\n" );
// At the client side
RadiusMessage acctStopMsg( RP_ACCOUNTING_REQUEST );
// Warning: assert is used for testing only
assert( acctStopMsg.add( acctReqMsg.get( RA_USER_NAME ) ) );
assert( acctStopMsg.add( acctReqMsg.get( RA_NAS_IP_ADDRESS ) ) );
assert( acctStopMsg.add( acctReqMsg.get( RA_NAS_PORT ) ) );
assert( acctStopMsg.add( acctReqMsg.get( RA_CALLED_STATION_ID ) ) );
assert( acctStopMsg.add( acctReqMsg.get( RA_CALLING_STATION_ID ) ) );
assert( acctStopMsg.add( attrAcctStatusStop ) );
assert( acctStopMsg.add( acctReqMsg.get( RA_ACCT_SESSION_ID ) ) );
assert( acctStopMsg.add( attrAcctSessionTime ) );
assert( acctStopMsg.add( attrAcctTerminateCause ) );
acctStopMsg.setIdentifier( ++identifier );
acctStopMsg.calcAuthenticator( secret );
resultSend = acctStopMsg.hexDump();
// At the server side
RawMessage udpMsg7( acctStopMsg.data() );
RadiusData msgReceived7( udpMsg7.buffer, ntohs(udpMsg7.msgHdr.length) );
try
{
RadiusMessage acctReqMsg2( msgReceived7, secret );
resultRecv = acctReqMsg2.hexDump();
test_verify( resultSend == resultRecv );
cpLog( LOG_INFO, "Verbose\n[%s]", acctReqMsg2.verbose().c_str() );
}
catch( VRadiusException &e )
{
cpLog( LOG_ERR, "Test failed - %s", e.getDescription().c_str() );
}
cpLog( LOG_INFO, "\n-------------------- End ----------------------\n");
return test_return_code( 7 );
}