You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1056 lines
32 KiB
1056 lines
32 KiB
/********************************************************************/
|
|
/** Copyright(c) 1985-1998 Microsoft Corporation. **/
|
|
/********************************************************************/
|
|
|
|
//***
|
|
//
|
|
// Filename: packconv.c
|
|
//
|
|
// Description:
|
|
//
|
|
// History: Feb 11,1998 NarenG Created original version.
|
|
//
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <lmcons.h>
|
|
#include <lmapibuf.h>
|
|
#include <lmaccess.h>
|
|
#include <raserror.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
#include <rasauth.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <rtutils.h>
|
|
#include <mprlog.h>
|
|
#include <mprerror.h>
|
|
#define INCL_RASAUTHATTRIBUTES
|
|
#define INCL_HOSTWIRE
|
|
#include <ppputil.h>
|
|
#include "radclnt.h"
|
|
#include "hmacmd5.h"
|
|
#include "md5.h"
|
|
#include "radclnt.h"
|
|
|
|
//**
|
|
//
|
|
// Call: Router2Radius
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Converts attribute array from RAS_AUTH_ATTRIBUTE to
|
|
// RADIUS_ATTRIBUTE
|
|
// INPUT:
|
|
// prgRouter - array of attributes passed in from
|
|
// the application
|
|
// pRadiusServer - RADIUS server
|
|
// descriptor(ip address, secret)
|
|
// pHeader - RADIUS packet header
|
|
// bSubCode - accounting sub codes.
|
|
// OUTPUT:
|
|
// prgRadius - array of attribtes that will be sent
|
|
// to the RADIUS server.
|
|
// pAttrLength - Length of the Radius packet.
|
|
//
|
|
DWORD
|
|
Router2Radius(
|
|
IN RAS_AUTH_ATTRIBUTE * prgRouter,
|
|
OUT RADIUS_ATTRIBUTE UNALIGNED * prgRadius,
|
|
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
|
IN RADIUS_PACKETHEADER UNALIGNED * pHeader,
|
|
IN BYTE bSubCode,
|
|
IN DWORD dwRetryCount,
|
|
OUT PBYTE * ppSignature,
|
|
OUT DWORD * pAttrLength
|
|
)
|
|
{
|
|
DWORD dwError = NO_ERROR;
|
|
BOOL fEAPMessage = FALSE;
|
|
|
|
*pAttrLength = 0;
|
|
*ppSignature = NULL;
|
|
|
|
do
|
|
{
|
|
//
|
|
// add the attribute for accounting records
|
|
//
|
|
|
|
switch( bSubCode )
|
|
{
|
|
case atStart:
|
|
case atStop:
|
|
case atAccountingOn:
|
|
case atAccountingOff:
|
|
case atInterimUpdate:
|
|
|
|
//
|
|
// Add the accounting status type attribute
|
|
//
|
|
|
|
prgRadius->bType = ptAcctStatusType;
|
|
prgRadius->bLength = sizeof(RADIUS_ATTRIBUTE) + sizeof(DWORD);
|
|
(*pAttrLength) += prgRadius->bLength;
|
|
|
|
prgRadius++;
|
|
|
|
*((DWORD UNALIGNED *) prgRadius) = htonl(bSubCode);
|
|
prgRadius = (RADIUS_ATTRIBUTE *)(((PBYTE) prgRadius)+sizeof(DWORD));
|
|
|
|
//
|
|
// Add the accounting delay time attribute
|
|
//
|
|
|
|
prgRadius->bType = raatAcctDelayTime;
|
|
prgRadius->bLength = sizeof(RADIUS_ATTRIBUTE) + sizeof(DWORD);
|
|
(*pAttrLength) += prgRadius->bLength;
|
|
|
|
prgRadius++;
|
|
|
|
HostToWireFormat32( dwRetryCount * pRadiusServer->Timeout.tv_sec,
|
|
(LPBYTE)(prgRadius) );
|
|
|
|
prgRadius = (RADIUS_ATTRIBUTE *)(((PBYTE) prgRadius)+sizeof(DWORD));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
|
|
while( prgRouter->raaType != raatMinimum )
|
|
{
|
|
//
|
|
// Copy attribute type & length
|
|
//
|
|
|
|
prgRadius->bType = (BYTE)(prgRouter->raaType);
|
|
prgRadius->bLength = (BYTE)(prgRouter->dwLength);
|
|
|
|
switch( prgRouter->raaType )
|
|
{
|
|
case raatUserPassword:
|
|
|
|
(*pAttrLength) += EncryptPassword( prgRouter,
|
|
prgRadius,
|
|
pRadiusServer,
|
|
pHeader,
|
|
bSubCode);
|
|
break;
|
|
|
|
case raatUserName:
|
|
case raatMD5CHAPPassword:
|
|
case raatFilterId:
|
|
case raatReplyMessage:
|
|
case raatCallbackNumber:
|
|
case raatCallbackId:
|
|
case raatFramedRoute:
|
|
case raatState:
|
|
case raatClass:
|
|
case raatVendorSpecific:
|
|
case raatCalledStationId:
|
|
case raatCallingStationId:
|
|
case raatNASIdentifier:
|
|
case raatProxyState:
|
|
case raatLoginLATService:
|
|
case raatLoginLATNode:
|
|
case raatLoginLATGroup:
|
|
case raatFramedAppleTalkZone:
|
|
case raatAcctSessionId:
|
|
case raatAcctMultiSessionId:
|
|
case raatMD5CHAPChallenge:
|
|
case raatLoginLATPort:
|
|
case raatTunnelClientEndpoint:
|
|
case raatTunnelServerEndpoint:
|
|
case raatARAPPassword:
|
|
case raatARAPFeatures:
|
|
case raatARAPSecurityData:
|
|
case raatConnectInfo:
|
|
case raatConfigurationToken:
|
|
case raatSignature:
|
|
case raatCertificateOID:
|
|
|
|
CopyMemory( prgRadius+1,
|
|
(PBYTE)prgRouter->Value,
|
|
prgRadius->bLength);
|
|
|
|
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
|
|
|
(*pAttrLength) += prgRadius->bLength;
|
|
|
|
break;
|
|
|
|
case raatEAPMessage:
|
|
|
|
{
|
|
DWORD dwLength = prgRouter->dwLength;
|
|
PBYTE pRouterEapMessage = (PBYTE)(prgRouter->Value);
|
|
|
|
while( dwLength > 0 )
|
|
{
|
|
if ( dwLength > 253 )
|
|
{
|
|
CopyMemory( (PBYTE)(prgRadius+1),
|
|
pRouterEapMessage,
|
|
253 );
|
|
|
|
prgRadius->bLength = 253;
|
|
pRouterEapMessage += 253;
|
|
|
|
dwLength -= 253;
|
|
}
|
|
else
|
|
{
|
|
CopyMemory( prgRadius+1,
|
|
(PBYTE)pRouterEapMessage,
|
|
dwLength );
|
|
|
|
prgRadius->bLength = (BYTE)dwLength;
|
|
dwLength = 0;
|
|
}
|
|
|
|
prgRadius->bType = (BYTE)raatEAPMessage;
|
|
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
|
|
|
(*pAttrLength) += prgRadius->bLength;
|
|
|
|
if ( dwLength > 0 )
|
|
{
|
|
prgRadius = (PRADIUS_ATTRIBUTE)
|
|
((PBYTE) prgRadius + prgRadius->bLength);
|
|
}
|
|
}
|
|
}
|
|
|
|
fEAPMessage = TRUE;
|
|
|
|
break;
|
|
|
|
case raatNASPort:
|
|
case raatServiceType:
|
|
case raatFramedProtocol:
|
|
case raatFramedRouting:
|
|
case raatFramedMTU:
|
|
case raatFramedCompression:
|
|
case raatLoginIPHost:
|
|
case raatLoginService:
|
|
case raatLoginTCPPort:
|
|
case raatFramedIPXNetwork:
|
|
case raatSessionTimeout:
|
|
case raatIdleTimeout:
|
|
case raatTerminationAction:
|
|
case raatFramedAppleTalkLink:
|
|
case raatFramedAppleTalkNetwork:
|
|
case raatNASPortType:
|
|
case raatPortLimit:
|
|
case raatTunnelType:
|
|
case raatTunnelMediumType:
|
|
case raatAcctStatusType:
|
|
case raatAcctDelayTime:
|
|
case raatAcctInputOctets:
|
|
case raatAcctOutputOctets:
|
|
case raatAcctAuthentic:
|
|
case raatAcctSessionTime:
|
|
case raatAcctInputPackets:
|
|
case raatAcctOutputPackets:
|
|
case raatAcctTerminateCause:
|
|
case raatAcctLinkCount:
|
|
case raatFramedIPAddress:
|
|
case raatFramedIPNetmask:
|
|
case raatPrompt:
|
|
case raatPasswordRetry:
|
|
case raatARAPZoneAccess:
|
|
case raatARAPSecurity:
|
|
case raatAcctInterimInterval:
|
|
case raatAcctEventTimeStamp:
|
|
case raatPEAPFastRoamedSession:
|
|
case raatPEAPEmbeddedEAPTypeId:
|
|
|
|
switch( prgRouter->dwLength )
|
|
{
|
|
case 1:
|
|
*((LPBYTE)(prgRadius+1)) = (BYTE)prgRouter->Value;
|
|
break;
|
|
|
|
case 2:
|
|
HostToWireFormat16U( (WORD)prgRouter->Value,
|
|
(LPBYTE)(prgRadius+1) );
|
|
break;
|
|
|
|
case 4:
|
|
HostToWireFormat32( PtrToUlong(prgRouter->Value),
|
|
(LPBYTE)(prgRadius+1) );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
|
|
|
(*pAttrLength) += prgRadius->bLength;
|
|
|
|
break;
|
|
|
|
case raatNASIPAddress:
|
|
|
|
RTASSERT( 4 == prgRouter->dwLength );
|
|
|
|
if ( pRadiusServer->nboNASIPAddress != INADDR_NONE )
|
|
{
|
|
CopyMemory( (LPBYTE)(prgRadius+1),
|
|
(LPBYTE)&(pRadiusServer->nboNASIPAddress),
|
|
4 );
|
|
}
|
|
else if( pRadiusServer->nboBestIf != INADDR_NONE)
|
|
{
|
|
CopyMemory( (LPBYTE)(prgRadius+1),
|
|
(LPBYTE)&(pRadiusServer->nboBestIf),
|
|
4 );
|
|
}
|
|
else
|
|
{
|
|
HostToWireFormat32( PtrToUlong(prgRouter->Value),
|
|
(LPBYTE)(prgRadius+1) );
|
|
}
|
|
|
|
prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
|
|
|
|
(*pAttrLength) += prgRadius->bLength;
|
|
|
|
break;
|
|
}
|
|
|
|
prgRadius = (PRADIUS_ATTRIBUTE)
|
|
((PBYTE) prgRadius + prgRadius->bLength);
|
|
prgRouter++;
|
|
}
|
|
|
|
}while( FALSE );
|
|
|
|
if ( dwError != NO_ERROR )
|
|
{
|
|
(*pAttrLength) = 0;
|
|
}
|
|
else
|
|
{
|
|
if ( ( ( bSubCode == atInvalid )
|
|
? pRadiusServer->fSendSignature
|
|
: FALSE ) || ( fEAPMessage ) )
|
|
{
|
|
//
|
|
// Add a signature attribute as well. Zero this out for now.
|
|
//
|
|
|
|
*ppSignature = (BYTE *)prgRadius;
|
|
|
|
prgRadius->bType = (BYTE)raatSignature;
|
|
prgRadius->bLength = (BYTE)18;
|
|
|
|
ZeroMemory( prgRadius+1, 16 );
|
|
|
|
(*pAttrLength) += prgRadius->bLength;
|
|
}
|
|
}
|
|
|
|
return( dwError );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: Radius2Router
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Converts RADIUS attribute array to RAS_AUTH_ATTRIBUTE array
|
|
//
|
|
DWORD
|
|
Radius2Router(
|
|
IN RADIUS_PACKETHEADER UNALIGNED * pRecvHeader,
|
|
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
|
IN PBYTE pRequestAuthenticator,
|
|
IN DWORD dwNumAttributes,
|
|
OUT DWORD * pdwExtError,
|
|
OUT PRAS_AUTH_ATTRIBUTE * pprgRouter,
|
|
OUT BOOL * fEapMessageReceived
|
|
)
|
|
{
|
|
LONG cbLength;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
BOOL fEAPMessage = FALSE;
|
|
BOOL fSignature = FALSE;
|
|
PBYTE pEAPMessage = NULL;
|
|
DWORD cbEAPMessage = 0;
|
|
RADIUS_ATTRIBUTE UNALIGNED * prgRadius
|
|
= (PRADIUS_ATTRIBUTE)(pRecvHeader + 1);
|
|
*pdwExtError = 0;
|
|
*pprgRouter = NULL;
|
|
*fEapMessageReceived = FALSE;
|
|
|
|
*pprgRouter = RasAuthAttributeCreate( dwNumAttributes );
|
|
|
|
if ( *pprgRouter == NULL )
|
|
{
|
|
return( GetLastError() );
|
|
}
|
|
|
|
dwNumAttributes = 0;
|
|
|
|
cbLength = ntohs( pRecvHeader->wLength ) - sizeof(RADIUS_PACKETHEADER);
|
|
|
|
while( cbLength > 0 )
|
|
{
|
|
switch( (RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType )
|
|
{
|
|
case raatNASPort:
|
|
case raatServiceType:
|
|
case raatFramedProtocol:
|
|
case raatFramedRouting:
|
|
case raatFramedMTU:
|
|
case raatFramedCompression:
|
|
case raatLoginIPHost:
|
|
case raatLoginService:
|
|
case raatLoginTCPPort:
|
|
case raatFramedIPXNetwork:
|
|
case raatSessionTimeout:
|
|
case raatIdleTimeout:
|
|
case raatTerminationAction:
|
|
case raatFramedAppleTalkLink:
|
|
case raatFramedAppleTalkNetwork:
|
|
case raatNASPortType:
|
|
case raatPortLimit:
|
|
case raatTunnelType:
|
|
case raatTunnelMediumType:
|
|
case raatAcctStatusType:
|
|
case raatAcctDelayTime:
|
|
case raatAcctInputOctets:
|
|
case raatAcctOutputOctets:
|
|
case raatAcctAuthentic:
|
|
case raatAcctSessionTime:
|
|
case raatAcctInputPackets:
|
|
case raatAcctOutputPackets:
|
|
case raatAcctTerminateCause:
|
|
case raatAcctLinkCount:
|
|
case raatFramedIPAddress:
|
|
case raatFramedIPNetmask:
|
|
case raatNASIPAddress:
|
|
case raatPrompt:
|
|
case raatPasswordRetry:
|
|
case raatARAPZoneAccess:
|
|
case raatARAPSecurity:
|
|
case raatAcctInterimInterval:
|
|
case raatAcctEventTimeStamp:
|
|
case raatPEAPFastRoamedSession:
|
|
case raatPEAPEmbeddedEAPTypeId:
|
|
|
|
{
|
|
DWORD dwIntegralValue;
|
|
DWORD dwLength = prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE);
|
|
|
|
if ( dwLength == 1 )
|
|
{
|
|
dwIntegralValue = (DWORD)(*(LPBYTE)(prgRadius+1));
|
|
}
|
|
else if ( dwLength == 2 )
|
|
{
|
|
dwIntegralValue=(DWORD)WireToHostFormat16U(
|
|
(PBYTE)(prgRadius+1));
|
|
}
|
|
else if ( dwLength == 4 )
|
|
{
|
|
dwIntegralValue=(DWORD)WireToHostFormat32(
|
|
(PBYTE)(prgRadius+1));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Drop bad attribute
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
dwRetCode = RasAuthAttributeInsert(
|
|
dwNumAttributes++,
|
|
*pprgRouter,
|
|
(RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType,
|
|
FALSE,
|
|
prgRadius->bLength-sizeof(RADIUS_ATTRIBUTE),
|
|
(LPVOID)ULongToPtr(dwIntegralValue) );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case raatSignature:
|
|
|
|
//
|
|
// Check the signature
|
|
//
|
|
|
|
{
|
|
BYTE MD5d[MD5_LEN];
|
|
HmacContext HmacMD5c;
|
|
BYTE Signature[16];
|
|
|
|
HmacMD5Init( &HmacMD5c,
|
|
(PBYTE)(pRadiusServer->szSecret),
|
|
pRadiusServer->cbSecret);
|
|
|
|
//
|
|
// Zero out the signature attribute before calculating it
|
|
//
|
|
|
|
if ( prgRadius->bLength != 18 )
|
|
{
|
|
RADIUS_TRACE("Received invalid signature length in packet");
|
|
|
|
*pdwExtError = ERROR_INVALID_SIGNATURE_LENGTH;
|
|
|
|
dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
|
|
|
|
break;
|
|
}
|
|
|
|
CopyMemory( Signature, (prgRadius+1), 16 );
|
|
|
|
ZeroMemory( (PBYTE)(prgRadius+1), 16 );
|
|
|
|
CopyMemory( (PBYTE)(pRecvHeader->rgAuthenticator),
|
|
pRequestAuthenticator,
|
|
16 );
|
|
|
|
HmacMD5Update( &HmacMD5c,
|
|
(PBYTE)pRecvHeader,
|
|
ntohs(pRecvHeader->wLength) );
|
|
|
|
HmacMD5Final( MD5d, &HmacMD5c );
|
|
|
|
if ( memcmp( Signature, MD5d, 16 ) != 0 )
|
|
{
|
|
RADIUS_TRACE("Received invalid signature in packet");
|
|
|
|
*pdwExtError = ERROR_INVALID_SIGNATURE;
|
|
|
|
dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
|
|
|
|
break;
|
|
}
|
|
|
|
fSignature = TRUE;
|
|
}
|
|
|
|
//
|
|
// Fall thru
|
|
//
|
|
|
|
case raatUserName:
|
|
case raatUserPassword:
|
|
case raatMD5CHAPPassword:
|
|
case raatFilterId:
|
|
case raatReplyMessage:
|
|
case raatCallbackNumber:
|
|
case raatCallbackId:
|
|
case raatFramedRoute:
|
|
case raatState:
|
|
case raatClass:
|
|
case raatCalledStationId:
|
|
case raatCallingStationId:
|
|
case raatNASIdentifier:
|
|
case raatProxyState:
|
|
case raatLoginLATService:
|
|
case raatLoginLATNode:
|
|
case raatLoginLATGroup:
|
|
case raatFramedAppleTalkZone:
|
|
case raatAcctSessionId:
|
|
case raatAcctMultiSessionId:
|
|
case raatMD5CHAPChallenge:
|
|
case raatLoginLATPort:
|
|
case raatTunnelClientEndpoint:
|
|
case raatTunnelServerEndpoint:
|
|
case raatARAPPassword:
|
|
case raatARAPFeatures:
|
|
case raatARAPSecurityData:
|
|
case raatConnectInfo:
|
|
case raatConfigurationToken:
|
|
case raatARAPChallengeResponse:
|
|
case raatCertificateOID:
|
|
|
|
dwRetCode = RasAuthAttributeInsert(
|
|
dwNumAttributes++,
|
|
*pprgRouter,
|
|
(RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType,
|
|
FALSE,
|
|
prgRadius->bLength-sizeof(RADIUS_ATTRIBUTE),
|
|
(LPVOID)(prgRadius+1) );
|
|
break;
|
|
|
|
case raatVendorSpecific:
|
|
|
|
if ( WireToHostFormat32( (PBYTE)(prgRadius+1) ) == 311 )
|
|
{
|
|
BYTE abTemp[34];
|
|
PBYTE pVSAWalker = (PBYTE)(prgRadius+1)+4;
|
|
DWORD cbVSALength = prgRadius->bLength -
|
|
sizeof( RADIUS_ATTRIBUTE ) - 4;
|
|
|
|
while( cbVSALength > 1 )
|
|
{
|
|
if ( *pVSAWalker == 12 )
|
|
{
|
|
if ( *(pVSAWalker+1) != 34 )
|
|
{
|
|
RADIUS_TRACE("Recvd invalid MPPE key packet");
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We don't want to modify whatever data we got
|
|
// from RADIUS (to keep the signature valid).
|
|
//
|
|
|
|
CopyMemory( abTemp, pVSAWalker, 34 );
|
|
|
|
//
|
|
// Decrypt the MPPE session keys.
|
|
//
|
|
|
|
dwRetCode = DecryptMPPEKeys( pRadiusServer,
|
|
pRequestAuthenticator,
|
|
abTemp+2 );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwRetCode = RasAuthAttributeInsertVSA(
|
|
dwNumAttributes++,
|
|
*pprgRouter,
|
|
311,
|
|
*(pVSAWalker+1),
|
|
abTemp );
|
|
}
|
|
}
|
|
else if ( ( *pVSAWalker == 16 )
|
|
|| ( *pVSAWalker == 17 ) )
|
|
{
|
|
DWORD dwLength;
|
|
BYTE* pbTemp;
|
|
|
|
dwLength = *(pVSAWalker+1);
|
|
|
|
if ( ( dwLength <= 4 )
|
|
|| ( ( dwLength - 4 ) % 16 != 0 ) )
|
|
{
|
|
RADIUS_TRACE("Recvd invalid MPPE key packet");
|
|
}
|
|
else
|
|
{
|
|
pbTemp = LocalAlloc( LPTR, dwLength );
|
|
|
|
if ( NULL == pbTemp )
|
|
{
|
|
dwRetCode = GetLastError();
|
|
RADIUS_TRACE("Out of memory");
|
|
break;
|
|
}
|
|
|
|
//
|
|
// We don't want to modify whatever data we got
|
|
// from RADIUS (to keep the signature valid).
|
|
//
|
|
|
|
CopyMemory( pbTemp, pVSAWalker, dwLength );
|
|
|
|
//
|
|
// Decrypt the MPPE Send/Recv keys.
|
|
//
|
|
|
|
dwRetCode = DecryptMPPESendRecvKeys(
|
|
pRadiusServer,
|
|
pRequestAuthenticator,
|
|
dwLength,
|
|
pbTemp+2 );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
LocalFree( pbTemp );
|
|
break;
|
|
}
|
|
|
|
dwRetCode = RasAuthAttributeInsertVSA(
|
|
dwNumAttributes++,
|
|
*pprgRouter,
|
|
311,
|
|
*(pVSAWalker+1),
|
|
pbTemp );
|
|
|
|
LocalFree( pbTemp );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwRetCode = RasAuthAttributeInsertVSA(
|
|
dwNumAttributes++,
|
|
*pprgRouter,
|
|
311,
|
|
*(pVSAWalker+1),
|
|
pVSAWalker );
|
|
}
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
cbVSALength -= *(pVSAWalker+1);
|
|
pVSAWalker += *(pVSAWalker+1);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case raatEAPMessage:
|
|
|
|
fEAPMessage = TRUE;
|
|
|
|
{
|
|
if ( pEAPMessage == NULL )
|
|
{
|
|
//
|
|
// Nothing has been allocated for EAP yet.
|
|
//
|
|
|
|
pEAPMessage = (PBYTE)LocalAlloc(
|
|
LPTR,
|
|
prgRadius->bLength
|
|
- sizeof( RADIUS_ATTRIBUTE ) );
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Need to increase the size of the buffer to hold this
|
|
// message
|
|
//
|
|
|
|
PBYTE pReallocEAPMessage =
|
|
(PBYTE)LocalReAlloc(
|
|
pEAPMessage,
|
|
cbEAPMessage
|
|
+ prgRadius->bLength
|
|
- sizeof( RADIUS_ATTRIBUTE ),
|
|
LMEM_MOVEABLE );
|
|
|
|
if ( pReallocEAPMessage == NULL )
|
|
{
|
|
LocalFree( pEAPMessage );
|
|
|
|
pEAPMessage = NULL;
|
|
}
|
|
else
|
|
{
|
|
pEAPMessage = pReallocEAPMessage;
|
|
}
|
|
}
|
|
|
|
if ( pEAPMessage == NULL )
|
|
{
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Copy existing buffer to new buffer
|
|
//
|
|
|
|
CopyMemory( pEAPMessage+cbEAPMessage,
|
|
(PBYTE)(prgRadius+1),
|
|
prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE) );
|
|
|
|
//
|
|
// Increment the cbEAPMessage so that the size is updated
|
|
// properly
|
|
//
|
|
|
|
cbEAPMessage += (prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE));
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// Drop attributes we do not know about.
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
RasAuthAttributeDestroy( *pprgRouter );
|
|
|
|
*pprgRouter = NULL;
|
|
|
|
if ( pEAPMessage != NULL )
|
|
{
|
|
LocalFree( pEAPMessage );
|
|
}
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
RADIUS_TRACE1( "Returning attribute type %d", prgRadius->bType );
|
|
|
|
cbLength -= prgRadius->bLength;
|
|
|
|
prgRadius = (PRADIUS_ATTRIBUTE)((PBYTE)prgRadius+prgRadius->bLength);
|
|
}
|
|
|
|
if ( dwRetCode == NO_ERROR )
|
|
{
|
|
if ( fEAPMessage )
|
|
{
|
|
//
|
|
// If we have received an EAP message, make sure we received a valid
|
|
// signature as well
|
|
//
|
|
|
|
if ( !fSignature )
|
|
{
|
|
RADIUS_TRACE("Did not receive signature along auth EAPMessage");
|
|
|
|
*pdwExtError = ERROR_NO_SIGNATURE;
|
|
|
|
dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
|
|
}
|
|
else
|
|
{
|
|
|
|
dwRetCode = RasAuthAttributeInsert(
|
|
dwNumAttributes++,
|
|
*pprgRouter,
|
|
(RAS_AUTH_ATTRIBUTE_TYPE)raatEAPMessage,
|
|
FALSE,
|
|
cbEAPMessage,
|
|
(LPVOID)pEAPMessage );
|
|
|
|
*fEapMessageReceived = TRUE;
|
|
}
|
|
|
|
LocalFree( pEAPMessage );
|
|
}
|
|
}
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
DWORD
|
|
EncryptPassword(
|
|
IN RAS_AUTH_ATTRIBUTE * prgRouter,
|
|
IN RADIUS_ATTRIBUTE UNALIGNED * prgRadius,
|
|
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
|
IN RADIUS_PACKETHEADER UNALIGNED * pHeader,
|
|
IN BYTE bSubCode
|
|
)
|
|
{
|
|
MD5_CTX MD5c;
|
|
DWORD iIndex, iBlock, cBlocks;
|
|
DWORD bLength, AttrLength;
|
|
BYTE UNALIGNED *pbValue;
|
|
|
|
//
|
|
// make the password into a 16 octet multiple
|
|
//
|
|
|
|
bLength = ((prgRadius->bLength + 15) / 16) * 16;
|
|
|
|
if ( bLength == 0 )
|
|
{
|
|
bLength = 16;
|
|
}
|
|
|
|
prgRadius->bLength = (BYTE)(sizeof(RADIUS_ATTRIBUTE) + bLength);
|
|
|
|
pbValue = (PBYTE) (prgRadius + 1);
|
|
|
|
AttrLength = sizeof(RADIUS_ATTRIBUTE);
|
|
|
|
//
|
|
// Zero pad the password
|
|
//
|
|
|
|
ZeroMemory( pbValue, bLength );
|
|
|
|
//
|
|
// Copy the original password
|
|
//
|
|
|
|
CopyMemory( pbValue, (PBYTE)prgRouter->Value, (BYTE)prgRouter->dwLength);
|
|
|
|
cBlocks = bLength / 16;
|
|
|
|
for ( iBlock = 0; iBlock < cBlocks; iBlock++ )
|
|
{
|
|
MD5Init( &MD5c );
|
|
|
|
MD5Update(&MD5c,(PBYTE)pRadiusServer->szSecret,pRadiusServer->cbSecret);
|
|
|
|
if (iBlock == 0)
|
|
{
|
|
MD5Update( &MD5c,
|
|
pHeader->rgAuthenticator,
|
|
sizeof(pHeader->rgAuthenticator));
|
|
}
|
|
else
|
|
{
|
|
MD5Update(&MD5c, (pbValue - 16), 16);
|
|
}
|
|
|
|
MD5Final( &MD5c );
|
|
|
|
for ( iIndex = 0; iIndex < 16; iIndex++ )
|
|
{
|
|
*pbValue ^= MD5c.digest[iIndex];
|
|
|
|
pbValue++;
|
|
}
|
|
}
|
|
|
|
return( AttrLength + bLength );
|
|
}
|
|
|
|
DWORD
|
|
DecryptMPPEKeys(
|
|
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
|
IN PBYTE pRequestAuthenticator,
|
|
IN OUT PBYTE pEncryptionKeys
|
|
)
|
|
{
|
|
BYTE * pbValue = (BYTE *)pEncryptionKeys;
|
|
MD5_CTX MD5c;
|
|
DWORD dwIndex;
|
|
DWORD dwBlock;
|
|
BYTE abCipherText[16];
|
|
|
|
//
|
|
// Save the cipherText from the first block.
|
|
//
|
|
|
|
CopyMemory(abCipherText, pbValue, sizeof(abCipherText));
|
|
|
|
//
|
|
// Walk thru the 2 blocks
|
|
//
|
|
|
|
for ( dwBlock = 0; dwBlock < 2; dwBlock++ )
|
|
{
|
|
MD5Init( &MD5c );
|
|
|
|
MD5Update( &MD5c,
|
|
(PBYTE)(pRadiusServer->szSecret),
|
|
pRadiusServer->cbSecret);
|
|
|
|
if ( dwBlock == 0 )
|
|
{
|
|
//
|
|
// Use the Request Authenticator for the first block
|
|
//
|
|
|
|
MD5Update( &MD5c, pRequestAuthenticator, 16 );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Use the first block of cipherText for the second block
|
|
//
|
|
|
|
MD5Update( &MD5c, abCipherText, 16 );
|
|
}
|
|
|
|
MD5Final( &MD5c );
|
|
|
|
for ( dwIndex = 0; dwIndex < 16; dwIndex ++ )
|
|
{
|
|
*pbValue ^= MD5c.digest[dwIndex];
|
|
|
|
pbValue++;
|
|
}
|
|
}
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
DWORD
|
|
DecryptMPPESendRecvKeys(
|
|
IN RADIUSSERVER UNALIGNED * pRadiusServer,
|
|
IN PBYTE pRequestAuthenticator,
|
|
IN DWORD dwLength,
|
|
IN OUT PBYTE pEncryptionKeys
|
|
)
|
|
{
|
|
BYTE * pbValue = (BYTE *)pEncryptionKeys + 2;
|
|
BYTE abCipherText[16];
|
|
MD5_CTX MD5c;
|
|
DWORD dwIndex;
|
|
DWORD dwBlock;
|
|
DWORD dwNumBlocks;
|
|
|
|
dwNumBlocks = ( dwLength - 2 ) / 16;
|
|
|
|
//
|
|
// Walk thru the blocks
|
|
//
|
|
|
|
for ( dwBlock = 0; dwBlock < dwNumBlocks; dwBlock++ )
|
|
{
|
|
MD5Init( &MD5c );
|
|
|
|
MD5Update( &MD5c,
|
|
(PBYTE)(pRadiusServer->szSecret),
|
|
pRadiusServer->cbSecret);
|
|
|
|
if ( dwBlock == 0 )
|
|
{
|
|
//
|
|
// Use the Request Authenticator and salt for the first block
|
|
//
|
|
|
|
MD5Update( &MD5c, pRequestAuthenticator, 16 );
|
|
MD5Update( &MD5c, pEncryptionKeys, 2 );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Use the previous block of cipherText
|
|
//
|
|
|
|
MD5Update( &MD5c, abCipherText, 16 );
|
|
}
|
|
|
|
MD5Final( &MD5c );
|
|
|
|
//
|
|
// Save the cipherText from this block.
|
|
//
|
|
|
|
CopyMemory(abCipherText, pbValue, sizeof(abCipherText));
|
|
|
|
for ( dwIndex = 0; dwIndex < 16; dwIndex++ )
|
|
{
|
|
*pbValue ^= MD5c.digest[dwIndex];
|
|
|
|
pbValue++;
|
|
}
|
|
}
|
|
|
|
return( NO_ERROR );
|
|
}
|