/********************************************************************/ /** Copyright(c) 1995 Microsoft Corporation. **/ /********************************************************************/ //*** // // Filename: attrib.c // // Description: Contains code to manipulate RAS_AUTH_ATTRIBUTE structures // // History: Feb 11,1997 NarenG Created original version. // #define UNICODE #include #include #include #include #include #include #include #include #include #include #define INCL_RASAUTHATTRIBUTES #define INCL_HOSTWIRE #include "ppputil.h" //** // // Call: RasAuthAttributeCreate // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: Will create an array of attributes plus one for the terminator // RAS_AUTH_ATTRIBUTE * RasAuthAttributeCreate( IN DWORD dwNumAttributes ) { RAS_AUTH_ATTRIBUTE * pAttributes; DWORD dwIndex; pAttributes = (RAS_AUTH_ATTRIBUTE * ) LocalAlloc(LPTR, sizeof( RAS_AUTH_ATTRIBUTE )*(1+dwNumAttributes)); if ( pAttributes == NULL ) { return( NULL ); } // // Initialize // for( dwIndex = 0; dwIndex < dwNumAttributes; dwIndex++ ) { pAttributes[dwIndex].raaType = raatReserved; pAttributes[dwIndex].dwLength = 0; pAttributes[dwIndex].Value = NULL; } // // Terminate // pAttributes[dwNumAttributes].raaType = raatMinimum; pAttributes[dwNumAttributes].dwLength = 0; pAttributes[dwNumAttributes].Value = NULL; return( pAttributes ); } //** // // Call: RasAuthAttributeDestroy // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: Will free up all allocated memory occupied by the attributes // structure // VOID RasAuthAttributeDestroy( IN RAS_AUTH_ATTRIBUTE * pAttributes ) { DWORD dwIndex; if ( NULL == pAttributes ) { return; } for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ ) { switch( pAttributes[dwIndex].raaType ) { case raatUserName: case raatUserPassword: 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 raatEAPMessage: case raatSignature: case raatARAPChallengeResponse: case raatCertificateOID: // // Allocated memory here so free it // if ( pAttributes[dwIndex].Value != NULL ) { ZeroMemory( pAttributes[dwIndex].Value, pAttributes[dwIndex].dwLength); LocalFree( pAttributes[dwIndex].Value ); } break; case raatReserved: // // Do nothing to uninitialized values // default: // // DWORDs, USHORTs or BYTEs so do nothing // break; } } LocalFree( pAttributes ); } //** // // Call: RasAuthAttributeGet // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: // RAS_AUTH_ATTRIBUTE * RasAuthAttributeGet( IN RAS_AUTH_ATTRIBUTE_TYPE raaType, IN RAS_AUTH_ATTRIBUTE * pAttributes ) { DWORD dwIndex; if ( pAttributes == NULL ) { return( NULL ); } for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ ) { if ( pAttributes[dwIndex].raaType == raaType ) { return( &(pAttributes[dwIndex]) ); } } return( NULL ); } //** // // Call: RasAuthAttributeGetFirst // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: // RAS_AUTH_ATTRIBUTE * RasAuthAttributeGetFirst( IN RAS_AUTH_ATTRIBUTE_TYPE raaType, IN RAS_AUTH_ATTRIBUTE * pAttributes, OUT HANDLE * phAttribute ) { DWORD dwIndex; RAS_AUTH_ATTRIBUTE * pRequiredAttribute; pRequiredAttribute = RasAuthAttributeGet( raaType, pAttributes ); if ( pRequiredAttribute == NULL ) { *phAttribute = NULL; return( NULL ); } *phAttribute = pRequiredAttribute; return( pRequiredAttribute ); } //** // // Call: RasAuthAttributeGetNext // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: // RAS_AUTH_ATTRIBUTE * RasAuthAttributeGetNext( IN OUT HANDLE * phAttribute, IN RAS_AUTH_ATTRIBUTE_TYPE raaType ) { DWORD dwIndex; RAS_AUTH_ATTRIBUTE * pAttributes = (RAS_AUTH_ATTRIBUTE *)*phAttribute; if ( pAttributes == NULL ) { return( NULL ); } pAttributes++; while( pAttributes->raaType != raatMinimum ) { if ( pAttributes->raaType == raaType ) { *phAttribute = pAttributes; return( pAttributes ); } pAttributes++; } *phAttribute = NULL; return( NULL ); } //** // // Call: RasAuthAttributesPrint // // Returns: VOID // // Description: Will print all the attributes in pAttributes // VOID RasAuthAttributesPrint( IN DWORD dwTraceID, IN DWORD dwFlags, IN RAS_AUTH_ATTRIBUTE * pAttributes ) { DWORD dwIndex; if ( NULL == pAttributes ) { return; } for ( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++) { switch( pAttributes[dwIndex].raaType ) { case raatUserName: case raatUserPassword: 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 raatEAPMessage: case raatSignature: case raatARAPChallengeResponse: case raatCertificateOID: TracePrintfExA( dwTraceID, dwFlags, "Type=%d, Length=%d, Value=", pAttributes[dwIndex].raaType, pAttributes[dwIndex].dwLength ); if ( ( pAttributes[dwIndex].raaType == raatVendorSpecific ) && ( pAttributes[dwIndex].dwLength >= 5 ) && ( WireToHostFormat32( pAttributes[dwIndex].Value ) == 311 ) ) { DWORD dwVendorType; dwVendorType = ((BYTE*)(pAttributes[dwIndex].Value))[4]; // // Do not print MS-CHAP-MPPE-Keys, MS-MPPE-Send-Key and // MS-MPPE-Recv-Key // if ( ( dwVendorType == 12 ) || ( dwVendorType == 16 ) || ( dwVendorType == 17 ) ) { TracePrintfExA( dwTraceID, dwFlags, "MS vendor specific %d", dwVendorType ); break; } } // // Do not print the password // if(pAttributes[dwIndex].raaType == raatUserPassword) { TracePrintfExA( dwTraceID, dwFlags, "raatUserPassword"); break; } TraceDumpExA( dwTraceID, dwFlags, pAttributes[dwIndex].Value, pAttributes[dwIndex].dwLength, 1, FALSE, "" ); break; default: TracePrintfExA( dwTraceID, dwFlags, "Type=%d, Length=%d, Value=0x%x", pAttributes[dwIndex].raaType, pAttributes[dwIndex].dwLength, pAttributes[dwIndex].Value ); break; } } } //** // // Call: RasAuthAttributeInsert // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: // DWORD RasAuthAttributeInsert( IN DWORD dwIndex, IN RAS_AUTH_ATTRIBUTE * pAttributes, IN RAS_AUTH_ATTRIBUTE_TYPE raaType, IN BOOL fConvertToMultiByte, IN DWORD dwLength, IN PVOID pValue ) { DWORD dwErr; if ( raatMinimum == pAttributes[dwIndex].raaType ) { return( ERROR_NOT_ENOUGH_MEMORY ); } switch( raaType ) { case raatUserName: case raatUserPassword: 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 raatEAPMessage: case raatSignature: case raatARAPChallengeResponse: case raatCertificateOID: // If you add a new attribute here, update RasAuthAttributesPrint also. if ( pValue != NULL ) { pAttributes[dwIndex].Value = LocalAlloc( LPTR, dwLength+1 ); if ( pAttributes[dwIndex].Value == NULL ) { return( GetLastError() ); } if ( fConvertToMultiByte ) { if (0 == WideCharToMultiByte( CP_ACP, 0, (WCHAR*)pValue, dwLength + 1, pAttributes[dwIndex].Value, dwLength + 1, NULL, NULL ) ) { dwErr = GetLastError(); LocalFree( pAttributes[dwIndex].Value ); return( dwErr ); } } else { CopyMemory( pAttributes[dwIndex].Value, pValue, dwLength ); } } else { pAttributes[dwIndex].Value = NULL; } break; default: pAttributes[dwIndex].Value = pValue; break; } pAttributes[dwIndex].dwLength = dwLength; pAttributes[dwIndex].raaType = raaType; return( NO_ERROR ); } //** // // Call: RasAuthAttributeInsertVSA // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: // DWORD RasAuthAttributeInsertVSA( IN DWORD dwIndex, IN RAS_AUTH_ATTRIBUTE * pAttributes, IN DWORD dwVendorId, IN DWORD dwLength, IN PVOID pValue ) { if ( pValue != NULL ) { pAttributes[dwIndex].Value = LocalAlloc( LPTR, dwLength+1+4 ); if ( pAttributes[dwIndex].Value == NULL ) { return( GetLastError() ); } HostToWireFormat32( dwVendorId, (PBYTE)(pAttributes[dwIndex].Value) ); CopyMemory( ((PBYTE)pAttributes[dwIndex].Value)+4, (PBYTE)pValue, dwLength ); pAttributes[dwIndex].dwLength = dwLength+4; } else { pAttributes[dwIndex].Value = NULL; pAttributes[dwIndex].dwLength = 0; } pAttributes[dwIndex].raaType = raatVendorSpecific; return( NO_ERROR ); } //** // // Call: RasAuthAttributeCopy // // Returns: Pointer to copy of attributes - Success // NULL - Failure // // Description: // RAS_AUTH_ATTRIBUTE * RasAuthAttributeCopy( IN RAS_AUTH_ATTRIBUTE * pAttributes ) { RAS_AUTH_ATTRIBUTE * pAttributesCopy; DWORD dwAttributesCount = 0; DWORD dwIndex; DWORD dwRetCode; // // Find out how many attributes there are // if ( pAttributes == NULL ) { return( NULL ); } for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ ); if ( ( pAttributesCopy = RasAuthAttributeCreate( dwIndex ) ) == NULL ) { return( NULL ); } for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ ) { dwRetCode = RasAuthAttributeInsert( dwIndex, pAttributesCopy, pAttributes[dwIndex].raaType, FALSE, pAttributes[dwIndex].dwLength, pAttributes[dwIndex].Value ); if ( dwRetCode != NO_ERROR ) { RasAuthAttributeDestroy( pAttributesCopy ); SetLastError( dwRetCode ); return( NULL ); } } return( pAttributesCopy ); } //** // // Call: RasAuthAttributeCopyWithAlloc // // Returns: Pointer to copy of attributes - Success // NULL - Failure // // Description: Copies the attribute list and allocs dwNumExtraAttributes // extra blank attributes in the beginning. pAttributes can // be NULL. // RAS_AUTH_ATTRIBUTE * RasAuthAttributeCopyWithAlloc( IN RAS_AUTH_ATTRIBUTE * pAttributes, IN DWORD dwNumExtraAttributes ) { RAS_AUTH_ATTRIBUTE * pAttributesCopy; DWORD dwAttributesCount = 0; DWORD dwIndex; DWORD dwRetCode; if ( pAttributes == NULL ) { pAttributesCopy = RasAuthAttributeCreate( dwNumExtraAttributes ); if ( pAttributesCopy == NULL ) { return( NULL ); } } else { // // Find out how many attributes there are // for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ ); dwIndex += dwNumExtraAttributes; if ( ( pAttributesCopy = RasAuthAttributeCreate( dwIndex ) ) == NULL ) { return( NULL ); } for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ ) { dwRetCode = RasAuthAttributeInsert( dwIndex + dwNumExtraAttributes, pAttributesCopy, pAttributes[dwIndex].raaType, FALSE, pAttributes[dwIndex].dwLength, pAttributes[dwIndex].Value ); if ( dwRetCode != NO_ERROR ) { RasAuthAttributeDestroy( pAttributesCopy ); SetLastError( dwRetCode ); return( NULL ); } } } return( pAttributesCopy ); } //** // // Call: RasAuthAttributeGetVendorSpecific // // Returns: Pointer to attribute // NULL if it couldn't find it // // Description: // RAS_AUTH_ATTRIBUTE * RasAuthAttributeGetVendorSpecific( IN DWORD dwVendorId, IN DWORD dwVendorType, IN RAS_AUTH_ATTRIBUTE * pAttributes ) { HANDLE hAttribute; RAS_AUTH_ATTRIBUTE * pAttribute; // // First search for the vendor specific attribute // pAttribute = RasAuthAttributeGetFirst( raatVendorSpecific, pAttributes, &hAttribute ); while ( pAttribute != NULL ) { // // If this attribute is of at least size to hold vendor Id/Type // if ( pAttribute->dwLength >= 8 ) { // // Does this have the correct VendorId // if (WireToHostFormat32( (PBYTE)(pAttribute->Value) ) == dwVendorId) { // // Does this have the correct Vendor Type // if ( *(((PBYTE)(pAttribute->Value))+4) == dwVendorType ) { return( pAttribute ); } } } pAttribute = RasAuthAttributeGetNext( &hAttribute, raatVendorSpecific ); } return( NULL ); } //** // // Call: RasAuthAttributeReAlloc // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: Will create an array of attributes plus one for the terminator // RAS_AUTH_ATTRIBUTE * RasAuthAttributeReAlloc( IN RAS_AUTH_ATTRIBUTE * pAttributes, IN DWORD dwNumAttributes ) { DWORD dwIndex; RAS_AUTH_ATTRIBUTE * pOutAttributes; pOutAttributes = (RAS_AUTH_ATTRIBUTE *) LocalReAlloc( pAttributes, sizeof( RAS_AUTH_ATTRIBUTE )*(1+dwNumAttributes), LMEM_ZEROINIT ); if ( pOutAttributes == NULL ) { return( NULL ); } // // Initialize the rest of the array. // for( dwIndex = 0; dwIndex < dwNumAttributes; dwIndex++ ) { if ( pOutAttributes[dwIndex].raaType == raatMinimum ) { while( dwIndex < dwNumAttributes ) { pOutAttributes[dwIndex].raaType = raatReserved; pOutAttributes[dwIndex].dwLength = 0; pOutAttributes[dwIndex].Value = NULL; dwIndex++; } break; } } // // Terminate the new array. // pOutAttributes[dwNumAttributes].raaType = raatMinimum; pOutAttributes[dwNumAttributes].dwLength = 0; pOutAttributes[dwNumAttributes].Value = NULL; return( pOutAttributes ); } //** // // Call: RasAuthAttributeGetConcatString // // Returns: pointer to a LocalAlloc'ed string // // Description: Looks for attributes of type raaType in pAttributes. Combines // them all into one string and returns the string. The string // must be LocalFree'd. *pdwStringLength will contain the number // of characters in the string. // CHAR * RasAuthAttributeGetConcatString( IN RAS_AUTH_ATTRIBUTE_TYPE raaType, IN RAS_AUTH_ATTRIBUTE * pAttributes, IN OUT DWORD * pdwStringLength ) { #define MAX_STR_LENGTH 1500 HANDLE hAttribute; CHAR * pszReplyMessage = NULL; RAS_AUTH_ATTRIBUTE * pAttribute; DWORD dwBytesRemaining; DWORD dwBytesToCopy; do { *pdwStringLength = 0; pAttribute = RasAuthAttributeGetFirst( raaType, pAttributes, &hAttribute ); if ( NULL == pAttribute ) { break; } pszReplyMessage = LocalAlloc( LPTR, MAX_STR_LENGTH + 1 ); if ( NULL == pszReplyMessage ) { break; } // // Bytes remaining, excluding terminating NULL // dwBytesRemaining = MAX_STR_LENGTH; while ( ( dwBytesRemaining > 0 ) && ( NULL != pAttribute ) ) { // // This does not include the terminating NULL // dwBytesToCopy = pAttribute->dwLength; if ( dwBytesToCopy > dwBytesRemaining ) { dwBytesToCopy = dwBytesRemaining; } CopyMemory( pszReplyMessage + MAX_STR_LENGTH - dwBytesRemaining, pAttribute->Value, dwBytesToCopy ); dwBytesRemaining -= dwBytesToCopy; pAttribute = RasAuthAttributeGetNext( &hAttribute, raaType ); } *pdwStringLength = MAX_STR_LENGTH - dwBytesRemaining; } while ( FALSE ); return( pszReplyMessage ); } //** // // Call: RasAuthAttributeGetConcatVendorSpecific // // Returns: Pointer to a chunk of bytes // NULL if it couldn't find it // // Description: Looks for attributes of type dwVendorType in pAttributes. // Combines them all into the return value. The Value must be // LocalFree'd. // BYTE * RasAuthAttributeGetConcatVendorSpecific( IN DWORD dwVendorId, IN DWORD dwVendorType, IN RAS_AUTH_ATTRIBUTE * pAttributes ) { DWORD dwMAX_ATTR_LENGTH = 1024; HANDLE hAttribute; RAS_AUTH_ATTRIBUTE * pAttribute; BYTE* pbValue = NULL; DWORD dwIndex = 0; DWORD dwLength; BOOL fFound = FALSE; pbValue = LocalAlloc( LPTR, dwMAX_ATTR_LENGTH ); if ( NULL == pbValue ) { return( NULL ); } // // First search for the vendor specific attribute // pAttribute = RasAuthAttributeGetFirst( raatVendorSpecific, pAttributes, &hAttribute ); while ( pAttribute != NULL ) { // // If this attribute is of at least size to hold vendor Id/Type // if ( pAttribute->dwLength >= 8 ) { // // Does this have the correct VendorId // if (WireToHostFormat32( (PBYTE)(pAttribute->Value) ) == dwVendorId) { // // Does this have the correct Vendor Type // if ( *(((PBYTE)(pAttribute->Value))+4) == dwVendorType ) { // // Exclude Vendor-Type and Vendor-Length from the length // dwLength = *(((PBYTE)(pAttribute->Value))+5) - 2; // If we overrun the buffer, we should increase it if ( dwMAX_ATTR_LENGTH - dwIndex < dwLength ) { BYTE *pbNewValue; dwMAX_ATTR_LENGTH += 1024; pbNewValue = LocalReAlloc(pbValue, dwMAX_ATTR_LENGTH, LMEM_ZEROINIT|LMEM_MOVEABLE); // Bail if we can't get more memory if( pbNewValue == NULL ) { LocalFree( pbValue ); return( NULL ); } pbValue = pbNewValue; } CopyMemory( pbValue + dwIndex, ((PBYTE)(pAttribute->Value))+6, dwLength ); dwIndex += dwLength; fFound = TRUE; } } } pAttribute = RasAuthAttributeGetNext( &hAttribute, raatVendorSpecific ); } if ( fFound ) { return( pbValue ); } else { LocalFree( pbValue ); return( NULL ); } }