|
|
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, Microsoft Corp. All rights reserved.
//
// FILE
//
// logresult.cpp
//
// SYNOPSIS
//
// Defines the function IASRadiusLogResult.
//
///////////////////////////////////////////////////////////////////////////////
#include <radcommon.h>
#include <iastlutl.h>
#include <iasutil.h>
#include <logresult.h>
// Dummy attribute ID for the stringized reason code.
const DWORD IAS_ATTRIBUTE_REASON_STRING = 0xBADF00D;
// An empty string.
WCHAR emptyString[1];
// Create a newly-allocated copy of a string.
PWSTR copyString(PCWSTR sz) throw () { if (sz) { // Calculate the number of bytes.
size_t nbyte = (wcslen(sz) + 1) * sizeof(WCHAR);
// Allocate the memory.
PVOID p = LocalAlloc(LMEM_FIXED, nbyte); if (p) { // Copy the string and return.
return (PWSTR)memcpy(p, sz, nbyte); } }
// If anything went wrong, return an empty string.
return emptyString; }
// Frees a string returned by copyString.
void freeString(PWSTR sz) throw () { if (sz != emptyString) { LocalFree(sz); } }
// Format an integer value.
PWSTR formatInteger(DWORD value) throw () { WCHAR buffer[11], *p = buffer + 10; *p = L'\0'; do { *--p = L'0' + (WCHAR)(value % 10); } while (value /= 10); return copyString(p); }
// Format a parameter value.
PWSTR formatParameter(DWORD value) throw () { WCHAR buffer[13], *p = buffer + 12; *p = L'\0'; do { *--p = L'0' + (WCHAR)(value % 10); } while (value /= 10); *--p = L'%'; *--p = L'%'; return copyString(p); }
// Format the IAS_ATTRIBUTE_PROVIDER_TYPE value.
PWSTR formatProviderType(DWORD type) throw () { switch (type) { case IAS_PROVIDER_WINDOWS: return formatParameter(IASP_PROVIDER_WINDOWS); case IAS_PROVIDER_RADIUS_PROXY: return formatParameter(IASP_PROVIDER_RADIUS_PROXY); case IAS_PROVIDER_EXTERNAL_AUTH: return formatParameter(IASP_PROVIDER_EXTERNAL_AUTH); default: return formatParameter(IASP_NONE); } }
// Format the IAS_ATTRIBUTE_AUTHENTICATION_TYPE value.
PWSTR formatAuthType(DWORD type) throw () { switch (type) { case IAS_AUTH_PAP: return copyString(L"PAP"); case IAS_AUTH_MD5CHAP: return copyString(L"MD5-CHAP"); case IAS_AUTH_MSCHAP: return copyString(L"MS-CHAPv1"); case IAS_AUTH_MSCHAP2: return copyString(L"MS-CHAPv2"); case IAS_AUTH_EAP: return copyString(L"EAP"); case IAS_AUTH_ARAP: return copyString(L"ARAP"); case IAS_AUTH_NONE: return copyString(L"Unauthenticated"); case IAS_AUTH_CUSTOM: return copyString(L"Extension"); case IAS_AUTH_MSCHAP_CPW: return copyString(L"MS-CHAPv1 CPW"); case IAS_AUTH_MSCHAP2_CPW: return copyString(L"MS-CHAPv2 CPW"); case IAS_AUTH_PEAP: return copyString(L"PEAP"); default: return formatInteger(type); } }
// Format the NAS-Port-Type value.
PWSTR formatPortType(DWORD type) throw () { switch (type) { case 0: return copyString(L"Async"); case 1: return copyString(L"Sync"); case 2: return copyString(L"ISDN Sync"); case 3: return copyString(L"ISDN Async V.120"); case 4: return copyString(L"ISDN Async V.110"); case 5: return copyString(L"Virtual"); case 6: return copyString(L"PIAFS"); case 7: return copyString(L"HDLC Clear Channel"); case 8: return copyString(L"X.25"); case 9: return copyString(L"X.75"); case 10: return copyString(L"G.3 Fax"); case 11: return copyString(L"SDSL"); case 12: return copyString(L"ADSL-CAP"); case 13: return copyString(L"ADSL-DMT"); case 14: return copyString(L"IDSL"); case 15: return copyString(L"Ethernet"); case 16: return copyString(L"xDSL"); case 17: return copyString(L"Cable"); case 18: return copyString(L"Wireless - Other"); case 19: return copyString(L"Wireless - IEEE 802.11"); default: return formatInteger(type); } }
PWSTR formatAttribute( IRequest* request, IAttributesRaw* raw, DWORD dwId, DWORD defaultValue ) throw () { // Is this one of the 'special' attributes ?
switch (dwId) { case IAS_ATTRIBUTE_REASON_CODE: { LONG reason = 0; request->get_Reason(&reason); if (reason >= IAS_MAX_REASON_CODE) { reason = IAS_INTERNAL_ERROR; } return formatInteger(reason); }
case IAS_ATTRIBUTE_REASON_STRING: { LONG reason; request->get_Reason(&reason); if (reason >= IAS_MAX_REASON_CODE) { reason = IAS_INTERNAL_ERROR; } return formatParameter(reason + 0x1000); } }
// Get a single attribute with the give ID.
DWORD posCount = 1; ATTRIBUTEPOSITION pos; raw->GetAttributes(&posCount, &pos, 1, &dwId);
// If it's not present, use the defaultValue parameter.
if (!posCount) { return formatParameter(defaultValue); }
// Otherwise, save and release.
const IASVALUE& val = pos.pAttribute->Value; IASAttributeRelease(pos.pAttribute);
// Format the value.
switch (val.itType) { case IASTYPE_ENUM: case IASTYPE_INTEGER: { switch (dwId) { case RADIUS_ATTRIBUTE_NAS_PORT_TYPE: return formatPortType(val.Enumerator);
case IAS_ATTRIBUTE_PROVIDER_TYPE: return formatProviderType(val.Enumerator);
case IAS_ATTRIBUTE_AUTHENTICATION_TYPE: return formatAuthType(val.Enumerator);
// Fall through.
}
return formatInteger(val.Integer); }
case IASTYPE_INET_ADDR: { WCHAR buffer[16]; return copyString(ias_inet_htow(val.InetAddr, buffer)); }
case IASTYPE_STRING: { if (val.String.pszWide) { return copyString(val.String.pszWide); } else { USES_CONVERSION; return copyString(A2W(val.String.pszAnsi)); } }
case IASTYPE_OCTET_STRING: { return copyString(IAS_OCT2WIDE(val.OctetString)); } }
return emptyString; }
///////
// An InsertionString definition consists of the attribute ID and a
// defaultValue to be used if the attribute isn't present.
///////
struct InsertionString { DWORD attrID; DWORD defaultValue; };
// Insertion strings for an Access-Accept.
const InsertionString ACCEPT_ATTRS[] = { { RADIUS_ATTRIBUTE_USER_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME, IASP_UNDETERMINED }, { RADIUS_ATTRIBUTE_NAS_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_IDENTIFIER, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_CALLING_STATION_ID, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT_TYPE, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_PROXY_POLICY_NAME, IASP_NONE }, { IAS_ATTRIBUTE_PROVIDER_TYPE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REMOTE_SERVER_ADDRESS, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_NP_NAME, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_AUTHENTICATION_TYPE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_EAP_FRIENDLY_NAME, IASP_UNDETERMINED }, { ATTRIBUTE_UNDEFINED, IASP_UNDETERMINED } };
// Insertion strings for an Access-Reject.
const InsertionString REJECT_ATTRS[] = { { RADIUS_ATTRIBUTE_USER_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME, IASP_UNDETERMINED }, { RADIUS_ATTRIBUTE_NAS_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_IDENTIFIER, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_CALLED_STATION_ID, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_CALLING_STATION_ID, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT_TYPE, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_PROXY_POLICY_NAME, IASP_NONE }, { IAS_ATTRIBUTE_PROVIDER_TYPE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REMOTE_SERVER_ADDRESS, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_NP_NAME, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_AUTHENTICATION_TYPE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_EAP_FRIENDLY_NAME, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REASON_CODE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REASON_STRING, IASP_UNDETERMINED }, { ATTRIBUTE_UNDEFINED, IASP_UNDETERMINED } };
// Insertion strings for a discarded request.
const InsertionString DISCARD_ATTRS[] = { { RADIUS_ATTRIBUTE_USER_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME, IASP_UNDETERMINED }, { RADIUS_ATTRIBUTE_NAS_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_IDENTIFIER, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_CALLED_STATION_ID, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_CALLING_STATION_ID, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT_TYPE, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_PROXY_POLICY_NAME, IASP_NONE }, { IAS_ATTRIBUTE_PROVIDER_TYPE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REMOTE_SERVER_ADDRESS, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REASON_CODE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REASON_STRING, IASP_UNDETERMINED }, { ATTRIBUTE_UNDEFINED, IASP_UNDETERMINED } };
// Insertion strings for a discarded accounting request.
const InsertionString ACCT_DISCARD_ATTRS[] = { { RADIUS_ATTRIBUTE_USER_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME, IASP_UNDETERMINED }, { RADIUS_ATTRIBUTE_NAS_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_IDENTIFIER, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_CALLED_STATION_ID, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_CALLING_STATION_ID, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_NAME, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_CLIENT_IP_ADDRESS, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT_TYPE, IASP_NOT_PRESENT }, { RADIUS_ATTRIBUTE_NAS_PORT, IASP_NOT_PRESENT }, { IAS_ATTRIBUTE_PROXY_POLICY_NAME, IASP_NONE }, { IAS_ATTRIBUTE_PROVIDER_TYPE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REMOTE_SERVER_ADDRESS, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REASON_CODE, IASP_UNDETERMINED }, { IAS_ATTRIBUTE_REASON_STRING, IASP_UNDETERMINED }, { ATTRIBUTE_UNDEFINED, IASP_UNDETERMINED } };
VOID WINAPI IASRadiusLogResult( IRequest* request, IAttributesRaw* raw ) { // Determine which response type this is.
LONG type; HRESULT hr = request->get_Response(&type); if (FAILED(hr)) { return; }
DWORD eventID; const InsertionString* attrs; switch (type) { case IAS_RESPONSE_ACCESS_ACCEPT: { eventID = IAS_RESPONSE_ACCEPT; attrs = ACCEPT_ATTRS; break; }
case IAS_RESPONSE_ACCESS_REJECT: { eventID = IAS_RESPONSE_REJECT; attrs = REJECT_ATTRS; break; }
case IAS_RESPONSE_DISCARD_PACKET: { hr = request->get_Request(&type); if (FAILED(hr)) { return; }
switch (type) { case IAS_REQUEST_ACCESS_REQUEST: { eventID = IAS_RESPONSE_DISCARD; attrs = DISCARD_ATTRS; break; }
case IAS_REQUEST_ACCOUNTING: { eventID = IAS_ACCT_RESPONSE_DISCARD; attrs = ACCT_DISCARD_ATTRS; break; }
default: { return; } } break; }
default: { return; } }
// Format the insertion strings.
PWSTR strings[24]; DWORD numStrings = 0; for ( ; attrs->attrID != ATTRIBUTE_UNDEFINED; ++attrs, ++numStrings) { strings[numStrings] = formatAttribute( request, raw, attrs->attrID, attrs->defaultValue ); }
// Report the event.
IASReportEvent( eventID, numStrings, 0, (PCWSTR*)strings, NULL );
// Free the insertion strings.
while (numStrings--) { freeString(strings[numStrings]); } }
|