Leaked source code of windows server 2003
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

  1. /********************************************************************/
  2. /** Copyright(c) 1985-1998 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: packconv.c
  7. //
  8. // Description:
  9. //
  10. // History: Feb 11,1998 NarenG Created original version.
  11. //
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <lmcons.h>
  17. #include <lmapibuf.h>
  18. #include <lmaccess.h>
  19. #include <raserror.h>
  20. #include <time.h>
  21. #include <string.h>
  22. #include <rasauth.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <rtutils.h>
  26. #include <mprlog.h>
  27. #include <mprerror.h>
  28. #define INCL_RASAUTHATTRIBUTES
  29. #define INCL_HOSTWIRE
  30. #include <ppputil.h>
  31. #include "radclnt.h"
  32. #include "hmacmd5.h"
  33. #include "md5.h"
  34. #include "radclnt.h"
  35. //**
  36. //
  37. // Call: Router2Radius
  38. //
  39. // Returns: NO_ERROR - Success
  40. // Non-zero returns - Failure
  41. //
  42. // Description: Converts attribute array from RAS_AUTH_ATTRIBUTE to
  43. // RADIUS_ATTRIBUTE
  44. // INPUT:
  45. // prgRouter - array of attributes passed in from
  46. // the application
  47. // pRadiusServer - RADIUS server
  48. // descriptor(ip address, secret)
  49. // pHeader - RADIUS packet header
  50. // bSubCode - accounting sub codes.
  51. // OUTPUT:
  52. // prgRadius - array of attribtes that will be sent
  53. // to the RADIUS server.
  54. // pAttrLength - Length of the Radius packet.
  55. //
  56. DWORD
  57. Router2Radius(
  58. IN RAS_AUTH_ATTRIBUTE * prgRouter,
  59. OUT RADIUS_ATTRIBUTE UNALIGNED * prgRadius,
  60. IN RADIUSSERVER UNALIGNED * pRadiusServer,
  61. IN RADIUS_PACKETHEADER UNALIGNED * pHeader,
  62. IN BYTE bSubCode,
  63. IN DWORD dwRetryCount,
  64. OUT PBYTE * ppSignature,
  65. OUT DWORD * pAttrLength
  66. )
  67. {
  68. DWORD dwError = NO_ERROR;
  69. BOOL fEAPMessage = FALSE;
  70. *pAttrLength = 0;
  71. *ppSignature = NULL;
  72. do
  73. {
  74. //
  75. // add the attribute for accounting records
  76. //
  77. switch( bSubCode )
  78. {
  79. case atStart:
  80. case atStop:
  81. case atAccountingOn:
  82. case atAccountingOff:
  83. case atInterimUpdate:
  84. //
  85. // Add the accounting status type attribute
  86. //
  87. prgRadius->bType = ptAcctStatusType;
  88. prgRadius->bLength = sizeof(RADIUS_ATTRIBUTE) + sizeof(DWORD);
  89. (*pAttrLength) += prgRadius->bLength;
  90. prgRadius++;
  91. *((DWORD UNALIGNED *) prgRadius) = htonl(bSubCode);
  92. prgRadius = (RADIUS_ATTRIBUTE *)(((PBYTE) prgRadius)+sizeof(DWORD));
  93. //
  94. // Add the accounting delay time attribute
  95. //
  96. prgRadius->bType = raatAcctDelayTime;
  97. prgRadius->bLength = sizeof(RADIUS_ATTRIBUTE) + sizeof(DWORD);
  98. (*pAttrLength) += prgRadius->bLength;
  99. prgRadius++;
  100. HostToWireFormat32( dwRetryCount * pRadiusServer->Timeout.tv_sec,
  101. (LPBYTE)(prgRadius) );
  102. prgRadius = (RADIUS_ATTRIBUTE *)(((PBYTE) prgRadius)+sizeof(DWORD));
  103. break;
  104. default:
  105. break;
  106. }
  107. while( prgRouter->raaType != raatMinimum )
  108. {
  109. //
  110. // Copy attribute type & length
  111. //
  112. prgRadius->bType = (BYTE)(prgRouter->raaType);
  113. prgRadius->bLength = (BYTE)(prgRouter->dwLength);
  114. switch( prgRouter->raaType )
  115. {
  116. case raatUserPassword:
  117. (*pAttrLength) += EncryptPassword( prgRouter,
  118. prgRadius,
  119. pRadiusServer,
  120. pHeader,
  121. bSubCode);
  122. break;
  123. case raatUserName:
  124. case raatMD5CHAPPassword:
  125. case raatFilterId:
  126. case raatReplyMessage:
  127. case raatCallbackNumber:
  128. case raatCallbackId:
  129. case raatFramedRoute:
  130. case raatState:
  131. case raatClass:
  132. case raatVendorSpecific:
  133. case raatCalledStationId:
  134. case raatCallingStationId:
  135. case raatNASIdentifier:
  136. case raatProxyState:
  137. case raatLoginLATService:
  138. case raatLoginLATNode:
  139. case raatLoginLATGroup:
  140. case raatFramedAppleTalkZone:
  141. case raatAcctSessionId:
  142. case raatAcctMultiSessionId:
  143. case raatMD5CHAPChallenge:
  144. case raatLoginLATPort:
  145. case raatTunnelClientEndpoint:
  146. case raatTunnelServerEndpoint:
  147. case raatARAPPassword:
  148. case raatARAPFeatures:
  149. case raatARAPSecurityData:
  150. case raatConnectInfo:
  151. case raatConfigurationToken:
  152. case raatSignature:
  153. case raatCertificateOID:
  154. CopyMemory( prgRadius+1,
  155. (PBYTE)prgRouter->Value,
  156. prgRadius->bLength);
  157. prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
  158. (*pAttrLength) += prgRadius->bLength;
  159. break;
  160. case raatEAPMessage:
  161. {
  162. DWORD dwLength = prgRouter->dwLength;
  163. PBYTE pRouterEapMessage = (PBYTE)(prgRouter->Value);
  164. while( dwLength > 0 )
  165. {
  166. if ( dwLength > 253 )
  167. {
  168. CopyMemory( (PBYTE)(prgRadius+1),
  169. pRouterEapMessage,
  170. 253 );
  171. prgRadius->bLength = 253;
  172. pRouterEapMessage += 253;
  173. dwLength -= 253;
  174. }
  175. else
  176. {
  177. CopyMemory( prgRadius+1,
  178. (PBYTE)pRouterEapMessage,
  179. dwLength );
  180. prgRadius->bLength = (BYTE)dwLength;
  181. dwLength = 0;
  182. }
  183. prgRadius->bType = (BYTE)raatEAPMessage;
  184. prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
  185. (*pAttrLength) += prgRadius->bLength;
  186. if ( dwLength > 0 )
  187. {
  188. prgRadius = (PRADIUS_ATTRIBUTE)
  189. ((PBYTE) prgRadius + prgRadius->bLength);
  190. }
  191. }
  192. }
  193. fEAPMessage = TRUE;
  194. break;
  195. case raatNASPort:
  196. case raatServiceType:
  197. case raatFramedProtocol:
  198. case raatFramedRouting:
  199. case raatFramedMTU:
  200. case raatFramedCompression:
  201. case raatLoginIPHost:
  202. case raatLoginService:
  203. case raatLoginTCPPort:
  204. case raatFramedIPXNetwork:
  205. case raatSessionTimeout:
  206. case raatIdleTimeout:
  207. case raatTerminationAction:
  208. case raatFramedAppleTalkLink:
  209. case raatFramedAppleTalkNetwork:
  210. case raatNASPortType:
  211. case raatPortLimit:
  212. case raatTunnelType:
  213. case raatTunnelMediumType:
  214. case raatAcctStatusType:
  215. case raatAcctDelayTime:
  216. case raatAcctInputOctets:
  217. case raatAcctOutputOctets:
  218. case raatAcctAuthentic:
  219. case raatAcctSessionTime:
  220. case raatAcctInputPackets:
  221. case raatAcctOutputPackets:
  222. case raatAcctTerminateCause:
  223. case raatAcctLinkCount:
  224. case raatFramedIPAddress:
  225. case raatFramedIPNetmask:
  226. case raatPrompt:
  227. case raatPasswordRetry:
  228. case raatARAPZoneAccess:
  229. case raatARAPSecurity:
  230. case raatAcctInterimInterval:
  231. case raatAcctEventTimeStamp:
  232. case raatPEAPFastRoamedSession:
  233. case raatPEAPEmbeddedEAPTypeId:
  234. switch( prgRouter->dwLength )
  235. {
  236. case 1:
  237. *((LPBYTE)(prgRadius+1)) = (BYTE)prgRouter->Value;
  238. break;
  239. case 2:
  240. HostToWireFormat16U( (WORD)prgRouter->Value,
  241. (LPBYTE)(prgRadius+1) );
  242. break;
  243. case 4:
  244. HostToWireFormat32( PtrToUlong(prgRouter->Value),
  245. (LPBYTE)(prgRadius+1) );
  246. break;
  247. default:
  248. break;
  249. }
  250. prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
  251. (*pAttrLength) += prgRadius->bLength;
  252. break;
  253. case raatNASIPAddress:
  254. RTASSERT( 4 == prgRouter->dwLength );
  255. if ( pRadiusServer->nboNASIPAddress != INADDR_NONE )
  256. {
  257. CopyMemory( (LPBYTE)(prgRadius+1),
  258. (LPBYTE)&(pRadiusServer->nboNASIPAddress),
  259. 4 );
  260. }
  261. else if( pRadiusServer->nboBestIf != INADDR_NONE)
  262. {
  263. CopyMemory( (LPBYTE)(prgRadius+1),
  264. (LPBYTE)&(pRadiusServer->nboBestIf),
  265. 4 );
  266. }
  267. else
  268. {
  269. HostToWireFormat32( PtrToUlong(prgRouter->Value),
  270. (LPBYTE)(prgRadius+1) );
  271. }
  272. prgRadius->bLength += sizeof(RADIUS_ATTRIBUTE);
  273. (*pAttrLength) += prgRadius->bLength;
  274. break;
  275. }
  276. prgRadius = (PRADIUS_ATTRIBUTE)
  277. ((PBYTE) prgRadius + prgRadius->bLength);
  278. prgRouter++;
  279. }
  280. }while( FALSE );
  281. if ( dwError != NO_ERROR )
  282. {
  283. (*pAttrLength) = 0;
  284. }
  285. else
  286. {
  287. if ( ( ( bSubCode == atInvalid )
  288. ? pRadiusServer->fSendSignature
  289. : FALSE ) || ( fEAPMessage ) )
  290. {
  291. //
  292. // Add a signature attribute as well. Zero this out for now.
  293. //
  294. *ppSignature = (BYTE *)prgRadius;
  295. prgRadius->bType = (BYTE)raatSignature;
  296. prgRadius->bLength = (BYTE)18;
  297. ZeroMemory( prgRadius+1, 16 );
  298. (*pAttrLength) += prgRadius->bLength;
  299. }
  300. }
  301. return( dwError );
  302. }
  303. //**
  304. //
  305. // Call: Radius2Router
  306. //
  307. // Returns: NO_ERROR - Success
  308. // Non-zero returns - Failure
  309. //
  310. // Description: Converts RADIUS attribute array to RAS_AUTH_ATTRIBUTE array
  311. //
  312. DWORD
  313. Radius2Router(
  314. IN RADIUS_PACKETHEADER UNALIGNED * pRecvHeader,
  315. IN RADIUSSERVER UNALIGNED * pRadiusServer,
  316. IN PBYTE pRequestAuthenticator,
  317. IN DWORD dwNumAttributes,
  318. OUT DWORD * pdwExtError,
  319. OUT PRAS_AUTH_ATTRIBUTE * pprgRouter,
  320. OUT BOOL * fEapMessageReceived
  321. )
  322. {
  323. LONG cbLength;
  324. DWORD dwRetCode = NO_ERROR;
  325. BOOL fEAPMessage = FALSE;
  326. BOOL fSignature = FALSE;
  327. PBYTE pEAPMessage = NULL;
  328. DWORD cbEAPMessage = 0;
  329. RADIUS_ATTRIBUTE UNALIGNED * prgRadius
  330. = (PRADIUS_ATTRIBUTE)(pRecvHeader + 1);
  331. *pdwExtError = 0;
  332. *pprgRouter = NULL;
  333. *fEapMessageReceived = FALSE;
  334. *pprgRouter = RasAuthAttributeCreate( dwNumAttributes );
  335. if ( *pprgRouter == NULL )
  336. {
  337. return( GetLastError() );
  338. }
  339. dwNumAttributes = 0;
  340. cbLength = ntohs( pRecvHeader->wLength ) - sizeof(RADIUS_PACKETHEADER);
  341. while( cbLength > 0 )
  342. {
  343. switch( (RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType )
  344. {
  345. case raatNASPort:
  346. case raatServiceType:
  347. case raatFramedProtocol:
  348. case raatFramedRouting:
  349. case raatFramedMTU:
  350. case raatFramedCompression:
  351. case raatLoginIPHost:
  352. case raatLoginService:
  353. case raatLoginTCPPort:
  354. case raatFramedIPXNetwork:
  355. case raatSessionTimeout:
  356. case raatIdleTimeout:
  357. case raatTerminationAction:
  358. case raatFramedAppleTalkLink:
  359. case raatFramedAppleTalkNetwork:
  360. case raatNASPortType:
  361. case raatPortLimit:
  362. case raatTunnelType:
  363. case raatTunnelMediumType:
  364. case raatAcctStatusType:
  365. case raatAcctDelayTime:
  366. case raatAcctInputOctets:
  367. case raatAcctOutputOctets:
  368. case raatAcctAuthentic:
  369. case raatAcctSessionTime:
  370. case raatAcctInputPackets:
  371. case raatAcctOutputPackets:
  372. case raatAcctTerminateCause:
  373. case raatAcctLinkCount:
  374. case raatFramedIPAddress:
  375. case raatFramedIPNetmask:
  376. case raatNASIPAddress:
  377. case raatPrompt:
  378. case raatPasswordRetry:
  379. case raatARAPZoneAccess:
  380. case raatARAPSecurity:
  381. case raatAcctInterimInterval:
  382. case raatAcctEventTimeStamp:
  383. case raatPEAPFastRoamedSession:
  384. case raatPEAPEmbeddedEAPTypeId:
  385. {
  386. DWORD dwIntegralValue;
  387. DWORD dwLength = prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE);
  388. if ( dwLength == 1 )
  389. {
  390. dwIntegralValue = (DWORD)(*(LPBYTE)(prgRadius+1));
  391. }
  392. else if ( dwLength == 2 )
  393. {
  394. dwIntegralValue=(DWORD)WireToHostFormat16U(
  395. (PBYTE)(prgRadius+1));
  396. }
  397. else if ( dwLength == 4 )
  398. {
  399. dwIntegralValue=(DWORD)WireToHostFormat32(
  400. (PBYTE)(prgRadius+1));
  401. }
  402. else
  403. {
  404. //
  405. // Drop bad attribute
  406. //
  407. break;
  408. }
  409. dwRetCode = RasAuthAttributeInsert(
  410. dwNumAttributes++,
  411. *pprgRouter,
  412. (RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType,
  413. FALSE,
  414. prgRadius->bLength-sizeof(RADIUS_ATTRIBUTE),
  415. (LPVOID)ULongToPtr(dwIntegralValue) );
  416. }
  417. break;
  418. case raatSignature:
  419. //
  420. // Check the signature
  421. //
  422. {
  423. BYTE MD5d[MD5_LEN];
  424. HmacContext HmacMD5c;
  425. BYTE Signature[16];
  426. HmacMD5Init( &HmacMD5c,
  427. (PBYTE)(pRadiusServer->szSecret),
  428. pRadiusServer->cbSecret);
  429. //
  430. // Zero out the signature attribute before calculating it
  431. //
  432. if ( prgRadius->bLength != 18 )
  433. {
  434. RADIUS_TRACE("Received invalid signature length in packet");
  435. *pdwExtError = ERROR_INVALID_SIGNATURE_LENGTH;
  436. dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
  437. break;
  438. }
  439. CopyMemory( Signature, (prgRadius+1), 16 );
  440. ZeroMemory( (PBYTE)(prgRadius+1), 16 );
  441. CopyMemory( (PBYTE)(pRecvHeader->rgAuthenticator),
  442. pRequestAuthenticator,
  443. 16 );
  444. HmacMD5Update( &HmacMD5c,
  445. (PBYTE)pRecvHeader,
  446. ntohs(pRecvHeader->wLength) );
  447. HmacMD5Final( MD5d, &HmacMD5c );
  448. if ( memcmp( Signature, MD5d, 16 ) != 0 )
  449. {
  450. RADIUS_TRACE("Received invalid signature in packet");
  451. *pdwExtError = ERROR_INVALID_SIGNATURE;
  452. dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
  453. break;
  454. }
  455. fSignature = TRUE;
  456. }
  457. //
  458. // Fall thru
  459. //
  460. case raatUserName:
  461. case raatUserPassword:
  462. case raatMD5CHAPPassword:
  463. case raatFilterId:
  464. case raatReplyMessage:
  465. case raatCallbackNumber:
  466. case raatCallbackId:
  467. case raatFramedRoute:
  468. case raatState:
  469. case raatClass:
  470. case raatCalledStationId:
  471. case raatCallingStationId:
  472. case raatNASIdentifier:
  473. case raatProxyState:
  474. case raatLoginLATService:
  475. case raatLoginLATNode:
  476. case raatLoginLATGroup:
  477. case raatFramedAppleTalkZone:
  478. case raatAcctSessionId:
  479. case raatAcctMultiSessionId:
  480. case raatMD5CHAPChallenge:
  481. case raatLoginLATPort:
  482. case raatTunnelClientEndpoint:
  483. case raatTunnelServerEndpoint:
  484. case raatARAPPassword:
  485. case raatARAPFeatures:
  486. case raatARAPSecurityData:
  487. case raatConnectInfo:
  488. case raatConfigurationToken:
  489. case raatARAPChallengeResponse:
  490. case raatCertificateOID:
  491. dwRetCode = RasAuthAttributeInsert(
  492. dwNumAttributes++,
  493. *pprgRouter,
  494. (RAS_AUTH_ATTRIBUTE_TYPE)prgRadius->bType,
  495. FALSE,
  496. prgRadius->bLength-sizeof(RADIUS_ATTRIBUTE),
  497. (LPVOID)(prgRadius+1) );
  498. break;
  499. case raatVendorSpecific:
  500. if ( WireToHostFormat32( (PBYTE)(prgRadius+1) ) == 311 )
  501. {
  502. BYTE abTemp[34];
  503. PBYTE pVSAWalker = (PBYTE)(prgRadius+1)+4;
  504. DWORD cbVSALength = prgRadius->bLength -
  505. sizeof( RADIUS_ATTRIBUTE ) - 4;
  506. while( cbVSALength > 1 )
  507. {
  508. if ( *pVSAWalker == 12 )
  509. {
  510. if ( *(pVSAWalker+1) != 34 )
  511. {
  512. RADIUS_TRACE("Recvd invalid MPPE key packet");
  513. }
  514. else
  515. {
  516. //
  517. // We don't want to modify whatever data we got
  518. // from RADIUS (to keep the signature valid).
  519. //
  520. CopyMemory( abTemp, pVSAWalker, 34 );
  521. //
  522. // Decrypt the MPPE session keys.
  523. //
  524. dwRetCode = DecryptMPPEKeys( pRadiusServer,
  525. pRequestAuthenticator,
  526. abTemp+2 );
  527. if ( dwRetCode != NO_ERROR )
  528. {
  529. break;
  530. }
  531. dwRetCode = RasAuthAttributeInsertVSA(
  532. dwNumAttributes++,
  533. *pprgRouter,
  534. 311,
  535. *(pVSAWalker+1),
  536. abTemp );
  537. }
  538. }
  539. else if ( ( *pVSAWalker == 16 )
  540. || ( *pVSAWalker == 17 ) )
  541. {
  542. DWORD dwLength;
  543. BYTE* pbTemp;
  544. dwLength = *(pVSAWalker+1);
  545. if ( ( dwLength <= 4 )
  546. || ( ( dwLength - 4 ) % 16 != 0 ) )
  547. {
  548. RADIUS_TRACE("Recvd invalid MPPE key packet");
  549. }
  550. else
  551. {
  552. pbTemp = LocalAlloc( LPTR, dwLength );
  553. if ( NULL == pbTemp )
  554. {
  555. dwRetCode = GetLastError();
  556. RADIUS_TRACE("Out of memory");
  557. break;
  558. }
  559. //
  560. // We don't want to modify whatever data we got
  561. // from RADIUS (to keep the signature valid).
  562. //
  563. CopyMemory( pbTemp, pVSAWalker, dwLength );
  564. //
  565. // Decrypt the MPPE Send/Recv keys.
  566. //
  567. dwRetCode = DecryptMPPESendRecvKeys(
  568. pRadiusServer,
  569. pRequestAuthenticator,
  570. dwLength,
  571. pbTemp+2 );
  572. if ( dwRetCode != NO_ERROR )
  573. {
  574. LocalFree( pbTemp );
  575. break;
  576. }
  577. dwRetCode = RasAuthAttributeInsertVSA(
  578. dwNumAttributes++,
  579. *pprgRouter,
  580. 311,
  581. *(pVSAWalker+1),
  582. pbTemp );
  583. LocalFree( pbTemp );
  584. }
  585. }
  586. else
  587. {
  588. dwRetCode = RasAuthAttributeInsertVSA(
  589. dwNumAttributes++,
  590. *pprgRouter,
  591. 311,
  592. *(pVSAWalker+1),
  593. pVSAWalker );
  594. }
  595. if ( dwRetCode != NO_ERROR )
  596. {
  597. break;
  598. }
  599. cbVSALength -= *(pVSAWalker+1);
  600. pVSAWalker += *(pVSAWalker+1);
  601. }
  602. }
  603. break;
  604. case raatEAPMessage:
  605. fEAPMessage = TRUE;
  606. {
  607. if ( pEAPMessage == NULL )
  608. {
  609. //
  610. // Nothing has been allocated for EAP yet.
  611. //
  612. pEAPMessage = (PBYTE)LocalAlloc(
  613. LPTR,
  614. prgRadius->bLength
  615. - sizeof( RADIUS_ATTRIBUTE ) );
  616. }
  617. else
  618. {
  619. //
  620. // Need to increase the size of the buffer to hold this
  621. // message
  622. //
  623. PBYTE pReallocEAPMessage =
  624. (PBYTE)LocalReAlloc(
  625. pEAPMessage,
  626. cbEAPMessage
  627. + prgRadius->bLength
  628. - sizeof( RADIUS_ATTRIBUTE ),
  629. LMEM_MOVEABLE );
  630. if ( pReallocEAPMessage == NULL )
  631. {
  632. LocalFree( pEAPMessage );
  633. pEAPMessage = NULL;
  634. }
  635. else
  636. {
  637. pEAPMessage = pReallocEAPMessage;
  638. }
  639. }
  640. if ( pEAPMessage == NULL )
  641. {
  642. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  643. break;
  644. }
  645. //
  646. // Copy existing buffer to new buffer
  647. //
  648. CopyMemory( pEAPMessage+cbEAPMessage,
  649. (PBYTE)(prgRadius+1),
  650. prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE) );
  651. //
  652. // Increment the cbEAPMessage so that the size is updated
  653. // properly
  654. //
  655. cbEAPMessage += (prgRadius->bLength - sizeof(RADIUS_ATTRIBUTE));
  656. }
  657. break;
  658. default:
  659. //
  660. // Drop attributes we do not know about.
  661. //
  662. break;
  663. }
  664. if ( dwRetCode != NO_ERROR )
  665. {
  666. RasAuthAttributeDestroy( *pprgRouter );
  667. *pprgRouter = NULL;
  668. if ( pEAPMessage != NULL )
  669. {
  670. LocalFree( pEAPMessage );
  671. }
  672. return( dwRetCode );
  673. }
  674. RADIUS_TRACE1( "Returning attribute type %d", prgRadius->bType );
  675. cbLength -= prgRadius->bLength;
  676. prgRadius = (PRADIUS_ATTRIBUTE)((PBYTE)prgRadius+prgRadius->bLength);
  677. }
  678. if ( dwRetCode == NO_ERROR )
  679. {
  680. if ( fEAPMessage )
  681. {
  682. //
  683. // If we have received an EAP message, make sure we received a valid
  684. // signature as well
  685. //
  686. if ( !fSignature )
  687. {
  688. RADIUS_TRACE("Did not receive signature along auth EAPMessage");
  689. *pdwExtError = ERROR_NO_SIGNATURE;
  690. dwRetCode = ERROR_INVALID_RADIUS_RESPONSE;
  691. }
  692. else
  693. {
  694. dwRetCode = RasAuthAttributeInsert(
  695. dwNumAttributes++,
  696. *pprgRouter,
  697. (RAS_AUTH_ATTRIBUTE_TYPE)raatEAPMessage,
  698. FALSE,
  699. cbEAPMessage,
  700. (LPVOID)pEAPMessage );
  701. *fEapMessageReceived = TRUE;
  702. }
  703. LocalFree( pEAPMessage );
  704. }
  705. }
  706. return( dwRetCode );
  707. }
  708. DWORD
  709. EncryptPassword(
  710. IN RAS_AUTH_ATTRIBUTE * prgRouter,
  711. IN RADIUS_ATTRIBUTE UNALIGNED * prgRadius,
  712. IN RADIUSSERVER UNALIGNED * pRadiusServer,
  713. IN RADIUS_PACKETHEADER UNALIGNED * pHeader,
  714. IN BYTE bSubCode
  715. )
  716. {
  717. MD5_CTX MD5c;
  718. DWORD iIndex, iBlock, cBlocks;
  719. DWORD bLength, AttrLength;
  720. BYTE UNALIGNED *pbValue;
  721. //
  722. // make the password into a 16 octet multiple
  723. //
  724. bLength = ((prgRadius->bLength + 15) / 16) * 16;
  725. if ( bLength == 0 )
  726. {
  727. bLength = 16;
  728. }
  729. prgRadius->bLength = (BYTE)(sizeof(RADIUS_ATTRIBUTE) + bLength);
  730. pbValue = (PBYTE) (prgRadius + 1);
  731. AttrLength = sizeof(RADIUS_ATTRIBUTE);
  732. //
  733. // Zero pad the password
  734. //
  735. ZeroMemory( pbValue, bLength );
  736. //
  737. // Copy the original password
  738. //
  739. CopyMemory( pbValue, (PBYTE)prgRouter->Value, (BYTE)prgRouter->dwLength);
  740. cBlocks = bLength / 16;
  741. for ( iBlock = 0; iBlock < cBlocks; iBlock++ )
  742. {
  743. MD5Init( &MD5c );
  744. MD5Update(&MD5c,(PBYTE)pRadiusServer->szSecret,pRadiusServer->cbSecret);
  745. if (iBlock == 0)
  746. {
  747. MD5Update( &MD5c,
  748. pHeader->rgAuthenticator,
  749. sizeof(pHeader->rgAuthenticator));
  750. }
  751. else
  752. {
  753. MD5Update(&MD5c, (pbValue - 16), 16);
  754. }
  755. MD5Final( &MD5c );
  756. for ( iIndex = 0; iIndex < 16; iIndex++ )
  757. {
  758. *pbValue ^= MD5c.digest[iIndex];
  759. pbValue++;
  760. }
  761. }
  762. return( AttrLength + bLength );
  763. }
  764. DWORD
  765. DecryptMPPEKeys(
  766. IN RADIUSSERVER UNALIGNED * pRadiusServer,
  767. IN PBYTE pRequestAuthenticator,
  768. IN OUT PBYTE pEncryptionKeys
  769. )
  770. {
  771. BYTE * pbValue = (BYTE *)pEncryptionKeys;
  772. MD5_CTX MD5c;
  773. DWORD dwIndex;
  774. DWORD dwBlock;
  775. BYTE abCipherText[16];
  776. //
  777. // Save the cipherText from the first block.
  778. //
  779. CopyMemory(abCipherText, pbValue, sizeof(abCipherText));
  780. //
  781. // Walk thru the 2 blocks
  782. //
  783. for ( dwBlock = 0; dwBlock < 2; dwBlock++ )
  784. {
  785. MD5Init( &MD5c );
  786. MD5Update( &MD5c,
  787. (PBYTE)(pRadiusServer->szSecret),
  788. pRadiusServer->cbSecret);
  789. if ( dwBlock == 0 )
  790. {
  791. //
  792. // Use the Request Authenticator for the first block
  793. //
  794. MD5Update( &MD5c, pRequestAuthenticator, 16 );
  795. }
  796. else
  797. {
  798. //
  799. // Use the first block of cipherText for the second block
  800. //
  801. MD5Update( &MD5c, abCipherText, 16 );
  802. }
  803. MD5Final( &MD5c );
  804. for ( dwIndex = 0; dwIndex < 16; dwIndex ++ )
  805. {
  806. *pbValue ^= MD5c.digest[dwIndex];
  807. pbValue++;
  808. }
  809. }
  810. return( NO_ERROR );
  811. }
  812. DWORD
  813. DecryptMPPESendRecvKeys(
  814. IN RADIUSSERVER UNALIGNED * pRadiusServer,
  815. IN PBYTE pRequestAuthenticator,
  816. IN DWORD dwLength,
  817. IN OUT PBYTE pEncryptionKeys
  818. )
  819. {
  820. BYTE * pbValue = (BYTE *)pEncryptionKeys + 2;
  821. BYTE abCipherText[16];
  822. MD5_CTX MD5c;
  823. DWORD dwIndex;
  824. DWORD dwBlock;
  825. DWORD dwNumBlocks;
  826. dwNumBlocks = ( dwLength - 2 ) / 16;
  827. //
  828. // Walk thru the blocks
  829. //
  830. for ( dwBlock = 0; dwBlock < dwNumBlocks; dwBlock++ )
  831. {
  832. MD5Init( &MD5c );
  833. MD5Update( &MD5c,
  834. (PBYTE)(pRadiusServer->szSecret),
  835. pRadiusServer->cbSecret);
  836. if ( dwBlock == 0 )
  837. {
  838. //
  839. // Use the Request Authenticator and salt for the first block
  840. //
  841. MD5Update( &MD5c, pRequestAuthenticator, 16 );
  842. MD5Update( &MD5c, pEncryptionKeys, 2 );
  843. }
  844. else
  845. {
  846. //
  847. // Use the previous block of cipherText
  848. //
  849. MD5Update( &MD5c, abCipherText, 16 );
  850. }
  851. MD5Final( &MD5c );
  852. //
  853. // Save the cipherText from this block.
  854. //
  855. CopyMemory(abCipherText, pbValue, sizeof(abCipherText));
  856. for ( dwIndex = 0; dwIndex < 16; dwIndex++ )
  857. {
  858. *pbValue ^= MD5c.digest[dwIndex];
  859. pbValue++;
  860. }
  861. }
  862. return( NO_ERROR );
  863. }