Source code of Windows XP (NT5)
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.

1016 lines
25 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1995 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: attrib.c
  7. //
  8. // Description: Contains code to manipulate RAS_AUTH_ATTRIBUTE structures
  9. //
  10. // History: Feb 11,1997 NarenG Created original version.
  11. //
  12. #define UNICODE
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <rtutils.h>
  18. #include <lmcons.h>
  19. #include <rasauth.h>
  20. #include <string.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #define INCL_RASAUTHATTRIBUTES
  24. #define INCL_HOSTWIRE
  25. #include "ppputil.h"
  26. //**
  27. //
  28. // Call: RasAuthAttributeCreate
  29. //
  30. // Returns: NO_ERROR - Success
  31. // Non-zero returns - Failure
  32. //
  33. // Description: Will create an array of attributes plus one for the terminator
  34. //
  35. RAS_AUTH_ATTRIBUTE *
  36. RasAuthAttributeCreate(
  37. IN DWORD dwNumAttributes
  38. )
  39. {
  40. RAS_AUTH_ATTRIBUTE * pAttributes;
  41. DWORD dwIndex;
  42. pAttributes = (RAS_AUTH_ATTRIBUTE * )
  43. LocalAlloc(LPTR,
  44. sizeof( RAS_AUTH_ATTRIBUTE )*(1+dwNumAttributes));
  45. if ( pAttributes == NULL )
  46. {
  47. return( NULL );
  48. }
  49. //
  50. // Initialize
  51. //
  52. for( dwIndex = 0; dwIndex < dwNumAttributes; dwIndex++ )
  53. {
  54. pAttributes[dwIndex].raaType = raatReserved;
  55. pAttributes[dwIndex].dwLength = 0;
  56. pAttributes[dwIndex].Value = NULL;
  57. }
  58. //
  59. // Terminate
  60. //
  61. pAttributes[dwNumAttributes].raaType = raatMinimum;
  62. pAttributes[dwNumAttributes].dwLength = 0;
  63. pAttributes[dwNumAttributes].Value = NULL;
  64. return( pAttributes );
  65. }
  66. //**
  67. //
  68. // Call: RasAuthAttributeDestroy
  69. //
  70. // Returns: NO_ERROR - Success
  71. // Non-zero returns - Failure
  72. //
  73. // Description: Will free up all allocated memory occupied by the attributes
  74. // structure
  75. //
  76. VOID
  77. RasAuthAttributeDestroy(
  78. IN RAS_AUTH_ATTRIBUTE * pAttributes
  79. )
  80. {
  81. DWORD dwIndex;
  82. if ( NULL == pAttributes )
  83. {
  84. return;
  85. }
  86. for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ )
  87. {
  88. switch( pAttributes[dwIndex].raaType )
  89. {
  90. case raatUserName:
  91. case raatUserPassword:
  92. case raatMD5CHAPPassword:
  93. case raatFilterId:
  94. case raatReplyMessage:
  95. case raatCallbackNumber:
  96. case raatCallbackId:
  97. case raatFramedRoute:
  98. case raatState:
  99. case raatClass:
  100. case raatVendorSpecific:
  101. case raatCalledStationId:
  102. case raatCallingStationId:
  103. case raatNASIdentifier:
  104. case raatProxyState:
  105. case raatLoginLATService:
  106. case raatLoginLATNode:
  107. case raatLoginLATGroup:
  108. case raatFramedAppleTalkZone:
  109. case raatAcctSessionId:
  110. case raatAcctMultiSessionId:
  111. case raatMD5CHAPChallenge:
  112. case raatLoginLATPort:
  113. case raatTunnelClientEndpoint:
  114. case raatTunnelServerEndpoint:
  115. case raatARAPPassword:
  116. case raatARAPFeatures:
  117. case raatARAPSecurityData:
  118. case raatConnectInfo:
  119. case raatConfigurationToken:
  120. case raatEAPMessage:
  121. case raatSignature:
  122. case raatARAPChallengeResponse:
  123. case raatCertificateOID:
  124. //
  125. // Allocated memory here so free it
  126. //
  127. if ( pAttributes[dwIndex].Value != NULL )
  128. {
  129. ZeroMemory( pAttributes[dwIndex].Value,
  130. pAttributes[dwIndex].dwLength);
  131. LocalFree( pAttributes[dwIndex].Value );
  132. }
  133. break;
  134. case raatReserved:
  135. //
  136. // Do nothing to uninitialized values
  137. //
  138. default:
  139. //
  140. // DWORDs, USHORTs or BYTEs so do nothing
  141. //
  142. break;
  143. }
  144. }
  145. LocalFree( pAttributes );
  146. }
  147. //**
  148. //
  149. // Call: RasAuthAttributeGet
  150. //
  151. // Returns: NO_ERROR - Success
  152. // Non-zero returns - Failure
  153. //
  154. // Description:
  155. //
  156. RAS_AUTH_ATTRIBUTE *
  157. RasAuthAttributeGet(
  158. IN RAS_AUTH_ATTRIBUTE_TYPE raaType,
  159. IN RAS_AUTH_ATTRIBUTE * pAttributes
  160. )
  161. {
  162. DWORD dwIndex;
  163. if ( pAttributes == NULL )
  164. {
  165. return( NULL );
  166. }
  167. for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ )
  168. {
  169. if ( pAttributes[dwIndex].raaType == raaType )
  170. {
  171. return( &(pAttributes[dwIndex]) );
  172. }
  173. }
  174. return( NULL );
  175. }
  176. //**
  177. //
  178. // Call: RasAuthAttributeGetFirst
  179. //
  180. // Returns: NO_ERROR - Success
  181. // Non-zero returns - Failure
  182. //
  183. // Description:
  184. //
  185. RAS_AUTH_ATTRIBUTE *
  186. RasAuthAttributeGetFirst(
  187. IN RAS_AUTH_ATTRIBUTE_TYPE raaType,
  188. IN RAS_AUTH_ATTRIBUTE * pAttributes,
  189. OUT HANDLE * phAttribute
  190. )
  191. {
  192. DWORD dwIndex;
  193. RAS_AUTH_ATTRIBUTE * pRequiredAttribute;
  194. pRequiredAttribute = RasAuthAttributeGet( raaType, pAttributes );
  195. if ( pRequiredAttribute == NULL )
  196. {
  197. *phAttribute = NULL;
  198. return( NULL );
  199. }
  200. *phAttribute = pRequiredAttribute;
  201. return( pRequiredAttribute );
  202. }
  203. //**
  204. //
  205. // Call: RasAuthAttributeGetNext
  206. //
  207. // Returns: NO_ERROR - Success
  208. // Non-zero returns - Failure
  209. //
  210. // Description:
  211. //
  212. RAS_AUTH_ATTRIBUTE *
  213. RasAuthAttributeGetNext(
  214. IN OUT HANDLE * phAttribute,
  215. IN RAS_AUTH_ATTRIBUTE_TYPE raaType
  216. )
  217. {
  218. DWORD dwIndex;
  219. RAS_AUTH_ATTRIBUTE * pAttributes = (RAS_AUTH_ATTRIBUTE *)*phAttribute;
  220. if ( pAttributes == NULL )
  221. {
  222. return( NULL );
  223. }
  224. pAttributes++;
  225. while( pAttributes->raaType != raatMinimum )
  226. {
  227. if ( pAttributes->raaType == raaType )
  228. {
  229. *phAttribute = pAttributes;
  230. return( pAttributes );
  231. }
  232. pAttributes++;
  233. }
  234. *phAttribute = NULL;
  235. return( NULL );
  236. }
  237. //**
  238. //
  239. // Call: RasAuthAttributesPrint
  240. //
  241. // Returns: VOID
  242. //
  243. // Description: Will print all the attributes in pAttributes
  244. //
  245. VOID
  246. RasAuthAttributesPrint(
  247. IN DWORD dwTraceID,
  248. IN DWORD dwFlags,
  249. IN RAS_AUTH_ATTRIBUTE * pAttributes
  250. )
  251. {
  252. DWORD dwIndex;
  253. if ( NULL == pAttributes )
  254. {
  255. return;
  256. }
  257. for ( dwIndex = 0;
  258. pAttributes[dwIndex].raaType != raatMinimum;
  259. dwIndex++)
  260. {
  261. switch( pAttributes[dwIndex].raaType )
  262. {
  263. case raatUserName:
  264. case raatUserPassword:
  265. case raatMD5CHAPPassword:
  266. case raatFilterId:
  267. case raatReplyMessage:
  268. case raatCallbackNumber:
  269. case raatCallbackId:
  270. case raatFramedRoute:
  271. case raatState:
  272. case raatClass:
  273. case raatVendorSpecific:
  274. case raatCalledStationId:
  275. case raatCallingStationId:
  276. case raatNASIdentifier:
  277. case raatProxyState:
  278. case raatLoginLATService:
  279. case raatLoginLATNode:
  280. case raatLoginLATGroup:
  281. case raatFramedAppleTalkZone:
  282. case raatAcctSessionId:
  283. case raatAcctMultiSessionId:
  284. case raatMD5CHAPChallenge:
  285. case raatLoginLATPort:
  286. case raatTunnelClientEndpoint:
  287. case raatTunnelServerEndpoint:
  288. case raatARAPPassword:
  289. case raatARAPFeatures:
  290. case raatARAPSecurityData:
  291. case raatConnectInfo:
  292. case raatConfigurationToken:
  293. case raatEAPMessage:
  294. case raatSignature:
  295. case raatARAPChallengeResponse:
  296. case raatCertificateOID:
  297. TracePrintfExA(
  298. dwTraceID, dwFlags,
  299. "Type=%d, Length=%d, Value=",
  300. pAttributes[dwIndex].raaType,
  301. pAttributes[dwIndex].dwLength );
  302. if ( ( pAttributes[dwIndex].raaType == raatVendorSpecific )
  303. && ( pAttributes[dwIndex].dwLength >= 5 )
  304. && ( WireToHostFormat32( pAttributes[dwIndex].Value ) == 311 ) )
  305. {
  306. DWORD dwVendorType;
  307. dwVendorType = ((BYTE*)(pAttributes[dwIndex].Value))[4];
  308. //
  309. // Do not print MS-CHAP-MPPE-Keys, MS-MPPE-Send-Key and
  310. // MS-MPPE-Recv-Key
  311. //
  312. if ( ( dwVendorType == 12 )
  313. || ( dwVendorType == 16 )
  314. || ( dwVendorType == 17 ) )
  315. {
  316. TracePrintfExA(
  317. dwTraceID, dwFlags,
  318. "MS vendor specific %d", dwVendorType );
  319. break;
  320. }
  321. }
  322. //
  323. // Do not print the password
  324. //
  325. if(pAttributes[dwIndex].raaType == raatUserPassword)
  326. {
  327. TracePrintfExA(
  328. dwTraceID, dwFlags,
  329. "raatUserPassword");
  330. break;
  331. }
  332. TraceDumpExA(
  333. dwTraceID, dwFlags,
  334. pAttributes[dwIndex].Value,
  335. pAttributes[dwIndex].dwLength,
  336. 1, FALSE, "" );
  337. break;
  338. default:
  339. TracePrintfExA(
  340. dwTraceID, dwFlags,
  341. "Type=%d, Length=%d, Value=0x%x",
  342. pAttributes[dwIndex].raaType,
  343. pAttributes[dwIndex].dwLength,
  344. pAttributes[dwIndex].Value );
  345. break;
  346. }
  347. }
  348. }
  349. //**
  350. //
  351. // Call: RasAuthAttributeInsert
  352. //
  353. // Returns: NO_ERROR - Success
  354. // Non-zero returns - Failure
  355. //
  356. // Description:
  357. //
  358. DWORD
  359. RasAuthAttributeInsert(
  360. IN DWORD dwIndex,
  361. IN RAS_AUTH_ATTRIBUTE * pAttributes,
  362. IN RAS_AUTH_ATTRIBUTE_TYPE raaType,
  363. IN BOOL fConvertToMultiByte,
  364. IN DWORD dwLength,
  365. IN PVOID pValue
  366. )
  367. {
  368. DWORD dwErr;
  369. if ( raatMinimum == pAttributes[dwIndex].raaType )
  370. {
  371. return( ERROR_NOT_ENOUGH_MEMORY );
  372. }
  373. switch( raaType )
  374. {
  375. case raatUserName:
  376. case raatUserPassword:
  377. case raatMD5CHAPPassword:
  378. case raatFilterId:
  379. case raatReplyMessage:
  380. case raatCallbackNumber:
  381. case raatCallbackId:
  382. case raatFramedRoute:
  383. case raatState:
  384. case raatClass:
  385. case raatVendorSpecific:
  386. case raatCalledStationId:
  387. case raatCallingStationId:
  388. case raatNASIdentifier:
  389. case raatProxyState:
  390. case raatLoginLATService:
  391. case raatLoginLATNode:
  392. case raatLoginLATGroup:
  393. case raatFramedAppleTalkZone:
  394. case raatAcctSessionId:
  395. case raatAcctMultiSessionId:
  396. case raatMD5CHAPChallenge:
  397. case raatLoginLATPort:
  398. case raatTunnelClientEndpoint:
  399. case raatTunnelServerEndpoint:
  400. case raatARAPPassword:
  401. case raatARAPFeatures:
  402. case raatARAPSecurityData:
  403. case raatConnectInfo:
  404. case raatConfigurationToken:
  405. case raatEAPMessage:
  406. case raatSignature:
  407. case raatARAPChallengeResponse:
  408. case raatCertificateOID:
  409. // If you add a new attribute here, update RasAuthAttributesPrint also.
  410. if ( pValue != NULL )
  411. {
  412. pAttributes[dwIndex].Value = LocalAlloc( LPTR, dwLength+1 );
  413. if ( pAttributes[dwIndex].Value == NULL )
  414. {
  415. return( GetLastError() );
  416. }
  417. if ( fConvertToMultiByte )
  418. {
  419. if (0 == WideCharToMultiByte(
  420. CP_ACP,
  421. 0,
  422. (WCHAR*)pValue,
  423. dwLength + 1,
  424. pAttributes[dwIndex].Value,
  425. dwLength + 1,
  426. NULL,
  427. NULL ) )
  428. {
  429. dwErr = GetLastError();
  430. LocalFree( pAttributes[dwIndex].Value );
  431. return( dwErr );
  432. }
  433. }
  434. else
  435. {
  436. CopyMemory( pAttributes[dwIndex].Value, pValue, dwLength );
  437. }
  438. }
  439. else
  440. {
  441. pAttributes[dwIndex].Value = NULL;
  442. }
  443. break;
  444. default:
  445. pAttributes[dwIndex].Value = pValue;
  446. break;
  447. }
  448. pAttributes[dwIndex].dwLength = dwLength;
  449. pAttributes[dwIndex].raaType = raaType;
  450. return( NO_ERROR );
  451. }
  452. //**
  453. //
  454. // Call: RasAuthAttributeInsertVSA
  455. //
  456. // Returns: NO_ERROR - Success
  457. // Non-zero returns - Failure
  458. //
  459. // Description:
  460. //
  461. DWORD
  462. RasAuthAttributeInsertVSA(
  463. IN DWORD dwIndex,
  464. IN RAS_AUTH_ATTRIBUTE * pAttributes,
  465. IN DWORD dwVendorId,
  466. IN DWORD dwLength,
  467. IN PVOID pValue
  468. )
  469. {
  470. if ( pValue != NULL )
  471. {
  472. pAttributes[dwIndex].Value = LocalAlloc( LPTR, dwLength+1+4 );
  473. if ( pAttributes[dwIndex].Value == NULL )
  474. {
  475. return( GetLastError() );
  476. }
  477. HostToWireFormat32( dwVendorId, (PBYTE)(pAttributes[dwIndex].Value) );
  478. CopyMemory( ((PBYTE)pAttributes[dwIndex].Value)+4,
  479. (PBYTE)pValue,
  480. dwLength );
  481. pAttributes[dwIndex].dwLength = dwLength+4;
  482. }
  483. else
  484. {
  485. pAttributes[dwIndex].Value = NULL;
  486. pAttributes[dwIndex].dwLength = 0;
  487. }
  488. pAttributes[dwIndex].raaType = raatVendorSpecific;
  489. return( NO_ERROR );
  490. }
  491. //**
  492. //
  493. // Call: RasAuthAttributeCopy
  494. //
  495. // Returns: Pointer to copy of attributes - Success
  496. // NULL - Failure
  497. //
  498. // Description:
  499. //
  500. RAS_AUTH_ATTRIBUTE *
  501. RasAuthAttributeCopy(
  502. IN RAS_AUTH_ATTRIBUTE * pAttributes
  503. )
  504. {
  505. RAS_AUTH_ATTRIBUTE * pAttributesCopy;
  506. DWORD dwAttributesCount = 0;
  507. DWORD dwIndex;
  508. DWORD dwRetCode;
  509. //
  510. // Find out how many attributes there are
  511. //
  512. if ( pAttributes == NULL )
  513. {
  514. return( NULL );
  515. }
  516. for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ );
  517. if ( ( pAttributesCopy = RasAuthAttributeCreate( dwIndex ) ) == NULL )
  518. {
  519. return( NULL );
  520. }
  521. for( dwIndex = 0; pAttributes[dwIndex].raaType != raatMinimum; dwIndex++ )
  522. {
  523. dwRetCode = RasAuthAttributeInsert( dwIndex,
  524. pAttributesCopy,
  525. pAttributes[dwIndex].raaType,
  526. FALSE,
  527. pAttributes[dwIndex].dwLength,
  528. pAttributes[dwIndex].Value );
  529. if ( dwRetCode != NO_ERROR )
  530. {
  531. RasAuthAttributeDestroy( pAttributesCopy );
  532. SetLastError( dwRetCode );
  533. return( NULL );
  534. }
  535. }
  536. return( pAttributesCopy );
  537. }
  538. //**
  539. //
  540. // Call: RasAuthAttributeCopyWithAlloc
  541. //
  542. // Returns: Pointer to copy of attributes - Success
  543. // NULL - Failure
  544. //
  545. // Description: Copies the attribute list and allocs dwNumExtraAttributes
  546. // extra blank attributes in the beginning. pAttributes can
  547. // be NULL.
  548. //
  549. RAS_AUTH_ATTRIBUTE *
  550. RasAuthAttributeCopyWithAlloc(
  551. IN RAS_AUTH_ATTRIBUTE * pAttributes,
  552. IN DWORD dwNumExtraAttributes
  553. )
  554. {
  555. RAS_AUTH_ATTRIBUTE * pAttributesCopy;
  556. DWORD dwAttributesCount = 0;
  557. DWORD dwIndex;
  558. DWORD dwRetCode;
  559. if ( pAttributes == NULL )
  560. {
  561. pAttributesCopy = RasAuthAttributeCreate( dwNumExtraAttributes );
  562. if ( pAttributesCopy == NULL )
  563. {
  564. return( NULL );
  565. }
  566. }
  567. else
  568. {
  569. //
  570. // Find out how many attributes there are
  571. //
  572. for( dwIndex = 0;
  573. pAttributes[dwIndex].raaType != raatMinimum;
  574. dwIndex++ );
  575. dwIndex += dwNumExtraAttributes;
  576. if ( ( pAttributesCopy = RasAuthAttributeCreate( dwIndex ) ) == NULL )
  577. {
  578. return( NULL );
  579. }
  580. for( dwIndex = 0;
  581. pAttributes[dwIndex].raaType != raatMinimum;
  582. dwIndex++ )
  583. {
  584. dwRetCode = RasAuthAttributeInsert( dwIndex + dwNumExtraAttributes,
  585. pAttributesCopy,
  586. pAttributes[dwIndex].raaType,
  587. FALSE,
  588. pAttributes[dwIndex].dwLength,
  589. pAttributes[dwIndex].Value );
  590. if ( dwRetCode != NO_ERROR )
  591. {
  592. RasAuthAttributeDestroy( pAttributesCopy );
  593. SetLastError( dwRetCode );
  594. return( NULL );
  595. }
  596. }
  597. }
  598. return( pAttributesCopy );
  599. }
  600. //**
  601. //
  602. // Call: RasAuthAttributeGetVendorSpecific
  603. //
  604. // Returns: Pointer to attribute
  605. // NULL if it couldn't find it
  606. //
  607. // Description:
  608. //
  609. RAS_AUTH_ATTRIBUTE *
  610. RasAuthAttributeGetVendorSpecific(
  611. IN DWORD dwVendorId,
  612. IN DWORD dwVendorType,
  613. IN RAS_AUTH_ATTRIBUTE * pAttributes
  614. )
  615. {
  616. HANDLE hAttribute;
  617. RAS_AUTH_ATTRIBUTE * pAttribute;
  618. //
  619. // First search for the vendor specific attribute
  620. //
  621. pAttribute = RasAuthAttributeGetFirst( raatVendorSpecific,
  622. pAttributes,
  623. &hAttribute );
  624. while ( pAttribute != NULL )
  625. {
  626. //
  627. // If this attribute is of at least size to hold vendor Id/Type
  628. //
  629. if ( pAttribute->dwLength >= 8 )
  630. {
  631. //
  632. // Does this have the correct VendorId
  633. //
  634. if (WireToHostFormat32( (PBYTE)(pAttribute->Value) ) == dwVendorId)
  635. {
  636. //
  637. // Does this have the correct Vendor Type
  638. //
  639. if ( *(((PBYTE)(pAttribute->Value))+4) == dwVendorType )
  640. {
  641. return( pAttribute );
  642. }
  643. }
  644. }
  645. pAttribute = RasAuthAttributeGetNext( &hAttribute,
  646. raatVendorSpecific );
  647. }
  648. return( NULL );
  649. }
  650. //**
  651. //
  652. // Call: RasAuthAttributeReAlloc
  653. //
  654. // Returns: NO_ERROR - Success
  655. // Non-zero returns - Failure
  656. //
  657. // Description: Will create an array of attributes plus one for the terminator
  658. //
  659. RAS_AUTH_ATTRIBUTE *
  660. RasAuthAttributeReAlloc(
  661. IN RAS_AUTH_ATTRIBUTE * pAttributes,
  662. IN DWORD dwNumAttributes
  663. )
  664. {
  665. DWORD dwIndex;
  666. RAS_AUTH_ATTRIBUTE * pOutAttributes;
  667. pOutAttributes = (RAS_AUTH_ATTRIBUTE *)
  668. LocalReAlloc(
  669. pAttributes,
  670. sizeof( RAS_AUTH_ATTRIBUTE )*(1+dwNumAttributes),
  671. LMEM_ZEROINIT );
  672. if ( pOutAttributes == NULL )
  673. {
  674. return( NULL );
  675. }
  676. //
  677. // Initialize the rest of the array.
  678. //
  679. for( dwIndex = 0; dwIndex < dwNumAttributes; dwIndex++ )
  680. {
  681. if ( pOutAttributes[dwIndex].raaType == raatMinimum )
  682. {
  683. while( dwIndex < dwNumAttributes )
  684. {
  685. pOutAttributes[dwIndex].raaType = raatReserved;
  686. pOutAttributes[dwIndex].dwLength = 0;
  687. pOutAttributes[dwIndex].Value = NULL;
  688. dwIndex++;
  689. }
  690. break;
  691. }
  692. }
  693. //
  694. // Terminate the new array.
  695. //
  696. pOutAttributes[dwNumAttributes].raaType = raatMinimum;
  697. pOutAttributes[dwNumAttributes].dwLength = 0;
  698. pOutAttributes[dwNumAttributes].Value = NULL;
  699. return( pOutAttributes );
  700. }
  701. //**
  702. //
  703. // Call: RasAuthAttributeGetConcatString
  704. //
  705. // Returns: pointer to a LocalAlloc'ed string
  706. //
  707. // Description: Looks for attributes of type raaType in pAttributes. Combines
  708. // them all into one string and returns the string. The string
  709. // must be LocalFree'd. *pdwStringLength will contain the number
  710. // of characters in the string.
  711. //
  712. CHAR *
  713. RasAuthAttributeGetConcatString(
  714. IN RAS_AUTH_ATTRIBUTE_TYPE raaType,
  715. IN RAS_AUTH_ATTRIBUTE * pAttributes,
  716. IN OUT DWORD * pdwStringLength
  717. )
  718. {
  719. #define MAX_STR_LENGTH 1500
  720. HANDLE hAttribute;
  721. CHAR * pszReplyMessage = NULL;
  722. RAS_AUTH_ATTRIBUTE * pAttribute;
  723. DWORD dwBytesRemaining;
  724. DWORD dwBytesToCopy;
  725. do
  726. {
  727. *pdwStringLength = 0;
  728. pAttribute = RasAuthAttributeGetFirst( raaType, pAttributes,
  729. &hAttribute );
  730. if ( NULL == pAttribute )
  731. {
  732. break;
  733. }
  734. pszReplyMessage = LocalAlloc( LPTR, MAX_STR_LENGTH + 1 );
  735. if ( NULL == pszReplyMessage )
  736. {
  737. break;
  738. }
  739. //
  740. // Bytes remaining, excluding terminating NULL
  741. //
  742. dwBytesRemaining = MAX_STR_LENGTH;
  743. while ( ( dwBytesRemaining > 0 )
  744. && ( NULL != pAttribute ) )
  745. {
  746. //
  747. // This does not include the terminating NULL
  748. //
  749. dwBytesToCopy = pAttribute->dwLength;
  750. if ( dwBytesToCopy > dwBytesRemaining )
  751. {
  752. dwBytesToCopy = dwBytesRemaining;
  753. }
  754. CopyMemory( pszReplyMessage + MAX_STR_LENGTH - dwBytesRemaining,
  755. pAttribute->Value,
  756. dwBytesToCopy );
  757. dwBytesRemaining -= dwBytesToCopy;
  758. pAttribute = RasAuthAttributeGetNext( &hAttribute,
  759. raaType );
  760. }
  761. *pdwStringLength = MAX_STR_LENGTH - dwBytesRemaining;
  762. }
  763. while ( FALSE );
  764. return( pszReplyMessage );
  765. }
  766. //**
  767. //
  768. // Call: RasAuthAttributeGetConcatVendorSpecific
  769. //
  770. // Returns: Pointer to a chunk of bytes
  771. // NULL if it couldn't find it
  772. //
  773. // Description: Looks for attributes of type dwVendorType in pAttributes.
  774. // Combines them all into the return value. The Value must be
  775. // LocalFree'd.
  776. //
  777. BYTE *
  778. RasAuthAttributeGetConcatVendorSpecific(
  779. IN DWORD dwVendorId,
  780. IN DWORD dwVendorType,
  781. IN RAS_AUTH_ATTRIBUTE * pAttributes
  782. )
  783. {
  784. DWORD dwMAX_ATTR_LENGTH = 1024;
  785. HANDLE hAttribute;
  786. RAS_AUTH_ATTRIBUTE * pAttribute;
  787. BYTE* pbValue = NULL;
  788. DWORD dwIndex = 0;
  789. DWORD dwLength;
  790. BOOL fFound = FALSE;
  791. pbValue = LocalAlloc( LPTR, dwMAX_ATTR_LENGTH );
  792. if ( NULL == pbValue )
  793. {
  794. return( NULL );
  795. }
  796. //
  797. // First search for the vendor specific attribute
  798. //
  799. pAttribute = RasAuthAttributeGetFirst( raatVendorSpecific,
  800. pAttributes,
  801. &hAttribute );
  802. while ( pAttribute != NULL )
  803. {
  804. //
  805. // If this attribute is of at least size to hold vendor Id/Type
  806. //
  807. if ( pAttribute->dwLength >= 8 )
  808. {
  809. //
  810. // Does this have the correct VendorId
  811. //
  812. if (WireToHostFormat32( (PBYTE)(pAttribute->Value) ) == dwVendorId)
  813. {
  814. //
  815. // Does this have the correct Vendor Type
  816. //
  817. if ( *(((PBYTE)(pAttribute->Value))+4) == dwVendorType )
  818. {
  819. //
  820. // Exclude Vendor-Type and Vendor-Length from the length
  821. //
  822. dwLength = *(((PBYTE)(pAttribute->Value))+5) - 2;
  823. // If we overrun the buffer, we should increase it
  824. if ( dwMAX_ATTR_LENGTH - dwIndex < dwLength )
  825. {
  826. BYTE *pbNewValue;
  827. dwMAX_ATTR_LENGTH += 1024;
  828. pbNewValue = LocalReAlloc(pbValue, dwMAX_ATTR_LENGTH, LMEM_ZEROINIT|LMEM_MOVEABLE);
  829. // Bail if we can't get more memory
  830. if( pbNewValue == NULL )
  831. {
  832. LocalFree( pbValue );
  833. return( NULL );
  834. }
  835. pbValue = pbNewValue;
  836. }
  837. CopyMemory(
  838. pbValue + dwIndex,
  839. ((PBYTE)(pAttribute->Value))+6,
  840. dwLength );
  841. dwIndex += dwLength;
  842. fFound = TRUE;
  843. }
  844. }
  845. }
  846. pAttribute = RasAuthAttributeGetNext( &hAttribute,
  847. raatVendorSpecific );
  848. }
  849. if ( fFound )
  850. {
  851. return( pbValue );
  852. }
  853. else
  854. {
  855. LocalFree( pbValue );
  856. return( NULL );
  857. }
  858. }