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.

1761 lines
50 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: auth.c
  7. //
  8. // Description: Contains FSM code to handle and authentication protocols.
  9. //
  10. // History:
  11. // Nov 11,1993. NarenG Created original version.
  12. // Jan 09,1995 RamC Save Lsa hToken in the PCB structure
  13. // This will be closed
  14. // in ProcessLineDownWorker() routine
  15. // to release the RAS license.
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h> // needed for winbase.h
  19. #include <windows.h> // Win32 base API's
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <wchar.h>
  23. #include <lmcons.h>
  24. #include <raserror.h>
  25. #include <rasman.h>
  26. #include <rtutils.h>
  27. #include <mprlog.h>
  28. #include <mprerror.h>
  29. #include <rasppp.h>
  30. #include <pppcp.h>
  31. #include <ppp.h>
  32. #include <auth.h>
  33. #include <smevents.h>
  34. #include <smaction.h>
  35. #include <lcp.h>
  36. #include <timer.h>
  37. #include <util.h>
  38. #include <worker.h>
  39. #define INCL_RASAUTHATTRIBUTES
  40. #define INCL_MISC
  41. #include <ppputil.h>
  42. DWORD
  43. EapGetCredentials(
  44. VOID *pWorkBuf,
  45. VOID *ppCredentials);
  46. //**
  47. //
  48. // Call: SetMsChapMppeKeys
  49. //
  50. // Returns: NO_ERROR - Success
  51. // Non-zero returns - Failure
  52. //
  53. // Description: Set the MS-CHAP-MPPE-Keys with NDISWAN
  54. //
  55. DWORD
  56. SetMsChapMppeKeys(
  57. IN HPORT hPort,
  58. IN RAS_AUTH_ATTRIBUTE * pAttribute,
  59. IN BYTE * pChallenge,
  60. IN BYTE * pResponse,
  61. IN DWORD AP,
  62. IN DWORD APData
  63. )
  64. {
  65. RAS_COMPRESSION_INFO rciSend;
  66. RAS_COMPRESSION_INFO rciReceive;
  67. DWORD dwRetCode = NO_ERROR;
  68. ASSERT( 8 == sizeof( rciSend.RCI_LMSessionKey ) );
  69. ASSERT( 16 == sizeof( rciSend.RCI_UserSessionKey ) );
  70. //
  71. // Length of key is 8 (LM key) + 16 (NT key)
  72. //
  73. if ( pAttribute->dwLength < ( 6 + 8 + 16 ) )
  74. {
  75. return( ERROR_INVALID_PARAMETER );
  76. }
  77. ZeroMemory( &rciSend, sizeof( rciSend ) );
  78. rciSend.RCI_MacCompressionType = 0xFF;
  79. CopyMemory( rciSend.RCI_LMSessionKey,
  80. ((PBYTE)(pAttribute->Value))+6,
  81. 8 );
  82. CopyMemory( rciSend.RCI_UserSessionKey,
  83. ((PBYTE)(pAttribute->Value))+6+8,
  84. 16 );
  85. CopyMemory( rciSend.RCI_Challenge, pChallenge, 8 );
  86. CopyMemory( rciSend.RCI_NTResponse, pResponse, 24 );
  87. rciSend.RCI_Flags = CCP_SET_KEYS;
  88. ZeroMemory( &rciReceive, sizeof( rciReceive ) );
  89. rciReceive.RCI_MacCompressionType = 0xFF;
  90. CopyMemory( rciReceive.RCI_LMSessionKey,
  91. ((PBYTE)(pAttribute->Value))+6,
  92. 8 );
  93. CopyMemory( rciReceive.RCI_UserSessionKey,
  94. ((PBYTE)(pAttribute->Value))+6+8,
  95. 16 );
  96. CopyMemory( rciReceive.RCI_Challenge, pChallenge, 8 );
  97. CopyMemory( rciReceive.RCI_NTResponse, pResponse, 24 );
  98. rciReceive.RCI_Flags = CCP_SET_KEYS;
  99. rciSend.RCI_AuthType = AUTH_USE_MSCHAPV2;
  100. rciReceive.RCI_AuthType = AUTH_USE_MSCHAPV2;
  101. if ( ( AP == PPP_CHAP_PROTOCOL ) &&
  102. ( APData == PPP_CHAP_DIGEST_MSEXT ))
  103. {
  104. rciSend.RCI_AuthType = AUTH_USE_MSCHAPV1;
  105. rciReceive.RCI_AuthType = AUTH_USE_MSCHAPV1;
  106. }
  107. dwRetCode = RasCompressionSetInfo(hPort,&rciSend,&rciReceive);
  108. if ( dwRetCode != NO_ERROR )
  109. {
  110. PppLog( 1,"RasCompressionSetInfo failed, Error=%d", dwRetCode );
  111. }
  112. return( dwRetCode );
  113. }
  114. //**
  115. //
  116. // Call: SetMsMppeSendRecvKeys
  117. //
  118. // Returns: NO_ERROR - Success
  119. // Non-zero returns - Failure
  120. //
  121. // Description: Set the MS-MPPE-Send-Key and MS-MPPE-Recv-Key with NDISWAN
  122. //
  123. DWORD
  124. SetMsMppeSendRecvKeys(
  125. IN HPORT hPort,
  126. IN RAS_AUTH_ATTRIBUTE * pAttributeSendKey,
  127. IN RAS_AUTH_ATTRIBUTE * pAttributeRecvKey
  128. )
  129. {
  130. RAS_COMPRESSION_INFO rciSend;
  131. RAS_COMPRESSION_INFO rciRecv;
  132. DWORD dwRetCode = NO_ERROR;
  133. //
  134. // 4: for Vendor-Id.
  135. //
  136. // The Microsoft Vendor-specific RADIUS Attributes draft says that
  137. // Vendor-Length should be > 4.
  138. //
  139. if ( pAttributeSendKey->dwLength <= ( 4 + 4 ) )
  140. {
  141. return( ERROR_INVALID_PARAMETER );
  142. }
  143. ZeroMemory( &rciSend, sizeof( rciSend ) );
  144. rciSend.RCI_MacCompressionType = 0xFF;
  145. rciSend.RCI_EapKeyLength = *(((BYTE*)(pAttributeSendKey->Value))+8);
  146. CopyMemory( rciSend.RCI_EapKey,
  147. ((BYTE*)(pAttributeSendKey->Value))+9,
  148. rciSend.RCI_EapKeyLength );
  149. rciSend.RCI_Flags = CCP_SET_KEYS;
  150. rciSend.RCI_AuthType = AUTH_USE_EAP;
  151. if ( pAttributeRecvKey->dwLength <= ( 4 + 4 ) )
  152. {
  153. return( ERROR_INVALID_PARAMETER );
  154. }
  155. ZeroMemory( &rciRecv, sizeof( rciRecv ) );
  156. rciRecv.RCI_MacCompressionType = 0xFF;
  157. rciRecv.RCI_EapKeyLength = *(((BYTE*)(pAttributeRecvKey->Value))+8);
  158. CopyMemory( rciRecv.RCI_EapKey,
  159. ((BYTE*)(pAttributeRecvKey->Value))+9,
  160. rciRecv.RCI_EapKeyLength );
  161. rciRecv.RCI_Flags = CCP_SET_KEYS;
  162. rciRecv.RCI_AuthType = AUTH_USE_EAP;
  163. dwRetCode = RasCompressionSetInfo(hPort,&rciSend,&rciRecv);
  164. if ( dwRetCode != NO_ERROR )
  165. {
  166. PppLog( 1,"RasCompressionSetInfo failed, Error=%d", dwRetCode );
  167. }
  168. return( dwRetCode );
  169. }
  170. //**
  171. //
  172. // Call: SetUserAuthorizedAttributes
  173. //
  174. // Returns: NO_ERROR - Success
  175. // Non-zero returns - Failure
  176. //
  177. // Description:
  178. //
  179. DWORD
  180. SetUserAuthorizedAttributes(
  181. IN PCB * pPcb,
  182. IN RAS_AUTH_ATTRIBUTE * pUserAttributes,
  183. IN BOOL fAuthenticator,
  184. IN BYTE * pChallenge,
  185. IN BYTE * pResponse
  186. )
  187. {
  188. RAS_AUTH_ATTRIBUTE * pAttribute;
  189. RAS_AUTH_ATTRIBUTE * pAttributeSendKey;
  190. RAS_AUTH_ATTRIBUTE * pAttributeRecvKey;
  191. DWORD dwRetCode;
  192. DWORD dwEncryptionPolicy = 0;
  193. DWORD dwEncryptionTypes = 0;
  194. BOOL fL2tp = FALSE;
  195. BOOL fPptp = FALSE;
  196. CreateAccountingAttributes( pPcb );
  197. if ( RAS_DEVICE_TYPE( pPcb->dwDeviceType ) == RDT_Tunnel_L2tp )
  198. {
  199. fL2tp = TRUE;
  200. }
  201. if ( RAS_DEVICE_TYPE( pPcb->dwDeviceType ) == RDT_Tunnel_Pptp )
  202. {
  203. fPptp = TRUE;
  204. }
  205. //
  206. // Find out if we are to require encrypted data using MPPE
  207. //
  208. pAttribute = RasAuthAttributeGetVendorSpecific( 311, 7, pUserAttributes );
  209. if ( pAttribute != NULL )
  210. {
  211. dwEncryptionPolicy
  212. = WireToHostFormat32(((BYTE*)(pAttribute->Value))+6);
  213. pAttribute = RasAuthAttributeGetVendorSpecific( 311,
  214. 8,
  215. pUserAttributes );
  216. if ( pAttribute != NULL )
  217. {
  218. dwEncryptionTypes
  219. = WireToHostFormat32(((BYTE*)(pAttribute->Value))+6);
  220. if ( dwEncryptionPolicy == 2 )
  221. {
  222. if (!fL2tp)
  223. {
  224. //
  225. // Find out what types of encryption are to be required
  226. //
  227. if ( ( dwEncryptionTypes & 0x00000002 )
  228. || ( dwEncryptionTypes & 0x00000008 ) )
  229. {
  230. pPcb->ConfigInfo.dwConfigMask
  231. |= PPPCFG_RequireEncryption;
  232. PppLog( 1,"Encryption" );
  233. }
  234. if ( dwEncryptionTypes & 0x00000004 )
  235. {
  236. pPcb->ConfigInfo.dwConfigMask
  237. |= PPPCFG_RequireStrongEncryption;
  238. PppLog( 1,"Strong encryption" );
  239. }
  240. if ( dwEncryptionTypes == 0 )
  241. {
  242. pPcb->ConfigInfo.dwConfigMask
  243. |= PPPCFG_DisableEncryption;
  244. PppLog( 1,"Encryption is not allowed" );
  245. }
  246. }
  247. }
  248. else if ( dwEncryptionPolicy == 1 )
  249. {
  250. //
  251. // Find out what types of encryption are to be allowed
  252. //
  253. if ( !fL2tp && !dwEncryptionTypes )
  254. {
  255. pPcb->ConfigInfo.dwConfigMask |= PPPCFG_DisableEncryption;
  256. PppLog( 1,"Encryption is not allowed" );
  257. }
  258. }
  259. }
  260. }
  261. //
  262. // Set encryption keys if we got them, provided we have not already done so
  263. //
  264. if ( !( pPcb->fFlags & PCBFLAG_MPPE_KEYS_SET ) )
  265. {
  266. pAttribute = RasAuthAttributeGetVendorSpecific(
  267. 311, 12, pUserAttributes);
  268. if ( pAttribute != NULL )
  269. {
  270. //
  271. // Set the MS-CHAP-MPPE-Keys with NDISWAN
  272. //
  273. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  274. DWORD AP;
  275. DWORD APData = 0;
  276. AP = ( fAuthenticator ? pLcpCb->Local.Work.AP :
  277. pLcpCb->Remote.Work.AP );
  278. if ( AP == PPP_CHAP_PROTOCOL )
  279. {
  280. APData = ( fAuthenticator ? *(pLcpCb->Local.Work.pAPData) :
  281. *(pLcpCb->Remote.Work.pAPData) );
  282. }
  283. dwRetCode = SetMsChapMppeKeys( pPcb->hPort,
  284. pAttribute,
  285. pChallenge,
  286. pResponse,
  287. AP,
  288. APData
  289. );
  290. if ( NO_ERROR != dwRetCode )
  291. {
  292. return( dwRetCode );
  293. }
  294. PppLog( 1,"MS-CHAP-MPPE-Keys set" );
  295. pPcb->fFlags |= PCBFLAG_MPPE_KEYS_SET;
  296. }
  297. pAttributeSendKey = RasAuthAttributeGetVendorSpecific( 311, 16,
  298. pUserAttributes );
  299. pAttributeRecvKey = RasAuthAttributeGetVendorSpecific( 311, 17,
  300. pUserAttributes );
  301. if ( ( pAttributeSendKey != NULL )
  302. && ( pAttributeRecvKey != NULL ) )
  303. {
  304. //
  305. // Set the MS-MPPE-Send-Key and MS-MPPE-Recv-Key with NDISWAN
  306. //
  307. dwRetCode = SetMsMppeSendRecvKeys( pPcb->hPort,
  308. pAttributeSendKey,
  309. pAttributeRecvKey
  310. );
  311. if ( NO_ERROR != dwRetCode )
  312. {
  313. return( dwRetCode );
  314. }
  315. PppLog( 1,"MPPE-Send/Recv-Keys set" );
  316. pPcb->fFlags |= PCBFLAG_MPPE_KEYS_SET;
  317. }
  318. }
  319. //
  320. // Check if L2tp is being used
  321. //
  322. if ( fL2tp )
  323. {
  324. DWORD dwMask = 0;
  325. DWORD dwSize = sizeof(DWORD);
  326. DWORD dwConfigMask;
  327. dwRetCode = RasGetPortUserData( pPcb->hPort, PORT_IPSEC_INFO_INDEX,
  328. (BYTE*) &dwMask, &dwSize );
  329. if ( NO_ERROR != dwRetCode )
  330. {
  331. PppLog( 1, "RasGetPortUserData failed: 0x%x", dwRetCode );
  332. dwRetCode = NO_ERROR;
  333. }
  334. PppLog( 1, "Checking encryption. Policy=0x%x,Types=0x%x,Mask=0x%x",
  335. dwEncryptionPolicy, dwEncryptionTypes, dwMask );
  336. if ( dwMask == RASMAN_IPSEC_ESP_DES )
  337. {
  338. pPcb->pBcb->fFlags |= BCBFLAG_BASIC_ENCRYPTION;
  339. }
  340. else if ( dwMask == RASMAN_IPSEC_ESP_3_DES )
  341. {
  342. pPcb->pBcb->fFlags |= BCBFLAG_STRONGEST_ENCRYPTION;
  343. }
  344. if ( !fAuthenticator )
  345. {
  346. //
  347. // If the user requires maximum encryption (3DES), but we
  348. // negotiated weaker encryption (56-bit DES), then return an error.
  349. //
  350. dwConfigMask = pPcb->ConfigInfo.dwConfigMask;
  351. if ( ( dwConfigMask & PPPCFG_RequireStrongEncryption )
  352. && !( dwConfigMask & PPPCFG_RequireEncryption )
  353. && !( dwConfigMask & PPPCFG_DisableEncryption )
  354. && ( dwMask != RASMAN_IPSEC_ESP_3_DES ) )
  355. {
  356. return( ERROR_NO_REMOTE_ENCRYPTION );
  357. }
  358. //
  359. // We are done with the PPPCFG_Require*Encryption flags. Let us now
  360. // turn them off because we don't care what kind of encryption CCP
  361. // negotiates.
  362. //
  363. pPcb->ConfigInfo.dwConfigMask &= ~PPPCFG_RequireStrongEncryption;
  364. pPcb->ConfigInfo.dwConfigMask &= ~PPPCFG_RequireEncryption;
  365. }
  366. else if ( dwEncryptionPolicy != 0 )
  367. {
  368. BOOL fPolicyError = FALSE;
  369. //
  370. // There is an encryption policy
  371. //
  372. switch ( dwMask )
  373. {
  374. case 0:
  375. if ( ( dwEncryptionPolicy == 2 )
  376. && ( dwEncryptionTypes != 0 ) )
  377. {
  378. fPolicyError = TRUE;
  379. break;
  380. }
  381. break;
  382. case RASMAN_IPSEC_ESP_DES:
  383. if ( !( dwEncryptionTypes & 0x00000002 )
  384. && !( dwEncryptionTypes & 0x00000008 ) )
  385. {
  386. fPolicyError = TRUE;
  387. break;
  388. }
  389. break;
  390. case RASMAN_IPSEC_ESP_3_DES:
  391. if (!( dwEncryptionTypes & 0x00000004 ) )
  392. {
  393. fPolicyError = TRUE;
  394. break;
  395. }
  396. break;
  397. }
  398. if ( fPolicyError )
  399. {
  400. //
  401. // We need to send an Accounting Stop if RADIUS sends an Access
  402. // Accept but we still drop the line.
  403. //
  404. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  405. return( ERROR_NO_REMOTE_ENCRYPTION );
  406. }
  407. }
  408. }
  409. //
  410. // If we require encryption make sure we have the keys and that CCP is
  411. // loaded.
  412. //
  413. if ( pPcb->ConfigInfo.dwConfigMask & ( PPPCFG_RequireEncryption |
  414. PPPCFG_RequireStrongEncryption ) )
  415. {
  416. if ( !( pPcb->fFlags & PCBFLAG_MPPE_KEYS_SET )
  417. || ( GetCpIndexFromProtocol( PPP_CCP_PROTOCOL ) == -1 ) )
  418. {
  419. //
  420. // We need to send an Accounting Stop if RADIUS sends an Access
  421. // Accept but we still drop the line.
  422. //
  423. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  424. return( ERROR_NO_LOCAL_ENCRYPTION );
  425. }
  426. }
  427. //
  428. // If we are not the authenticator then there is nothing more to set
  429. //
  430. if ( !fAuthenticator )
  431. {
  432. return( NO_ERROR );
  433. }
  434. //
  435. // Check framed protocol attribute. It must be PPP.
  436. //
  437. pAttribute = RasAuthAttributeGet( raatFramedProtocol, pUserAttributes );
  438. if ( pAttribute != NULL )
  439. {
  440. if ( PtrToUlong(pAttribute->Value) != 1 )
  441. {
  442. //
  443. // We need to send an Accounting Stop if RADIUS sends an Access
  444. // Accept but we still drop the line.
  445. //
  446. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  447. return( ERROR_UNKNOWN_FRAMED_PROTOCOL );
  448. }
  449. }
  450. //
  451. // Check tunnel type attribute. It must be correct.
  452. //
  453. pAttribute = RasAuthAttributeGet( raatTunnelType, pUserAttributes );
  454. if ( pAttribute != NULL )
  455. {
  456. DWORD dwTunnelType = PtrToUlong(pAttribute->Value);
  457. if ( ( fL2tp && ( dwTunnelType != 3 ) )
  458. || ( fPptp && ( dwTunnelType != 1 ) ) )
  459. {
  460. //
  461. // We need to send an Accounting Stop if RADIUS sends an Access
  462. // Accept but we still drop the line.
  463. //
  464. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  465. return( ERROR_WRONG_TUNNEL_TYPE );
  466. }
  467. }
  468. //
  469. // Get the logon domain attribute
  470. //
  471. pAttribute = RasAuthAttributeGetVendorSpecific( 311, 10, pUserAttributes );
  472. if ( pAttribute != NULL )
  473. {
  474. DWORD cbDomain = sizeof( pPcb->pBcb->szRemoteDomain ) - 1;
  475. if ( ( pAttribute->dwLength - 7 ) < cbDomain )
  476. {
  477. cbDomain = pAttribute->dwLength - 7;
  478. }
  479. ZeroMemory( pPcb->pBcb->szRemoteDomain,
  480. sizeof( pPcb->pBcb->szRemoteDomain ) );
  481. CopyMemory( pPcb->pBcb->szRemoteDomain,
  482. (LPSTR)((PBYTE)(pAttribute->Value)+7),
  483. cbDomain );
  484. PppLog( 2, "Auth Attribute Domain = %s", pPcb->pBcb->szRemoteDomain);
  485. }
  486. //
  487. // Setup callback information, default is no callback
  488. //
  489. pPcb->fCallbackPrivilege = RASPRIV_NoCallback;
  490. pPcb->szCallbackNumber[0] = (CHAR)NULL;
  491. pAttribute = RasAuthAttributeGet( raatServiceType, pUserAttributes );
  492. if ( pAttribute != NULL )
  493. {
  494. if ( PtrToUlong(pAttribute->Value) == 4 )
  495. {
  496. //
  497. // If service type is callback framed
  498. //
  499. pAttribute=RasAuthAttributeGet(raatCallbackNumber,pUserAttributes);
  500. if ( ( pAttribute == NULL ) || ( pAttribute->dwLength == 0 ) )
  501. {
  502. pPcb->fCallbackPrivilege = RASPRIV_NoCallback |
  503. RASPRIV_CallerSetCallback;
  504. pPcb->szCallbackNumber[0] = (CHAR)NULL;
  505. PppLog(2,"Auth Attribute Caller Specifiable callback");
  506. }
  507. else
  508. {
  509. pPcb->fCallbackPrivilege = RASPRIV_AdminSetCallback;
  510. ZeroMemory(pPcb->szCallbackNumber,
  511. sizeof(pPcb->szCallbackNumber));
  512. CopyMemory( pPcb->szCallbackNumber,
  513. pAttribute->Value,
  514. pAttribute->dwLength );
  515. PppLog( 2, "Auth Attribute Forced callback to %s",
  516. pPcb->szCallbackNumber );
  517. //
  518. // Don't accept BAP Call-Requests. Otherwise, when the client
  519. // calls us, we will drop the line and callback. The first call
  520. // would be a waste.
  521. //
  522. pPcb->pBcb->fFlags &= ~BCBFLAG_CAN_ACCEPT_CALLS;
  523. }
  524. }
  525. else if ( PtrToUlong(pAttribute->Value) != 2 )
  526. {
  527. PppLog( 2, "Service Type %d is not of type Framed",
  528. PtrToUlong(pAttribute->Value) );
  529. //
  530. // We need to send an Accounting Stop if RADIUS sends an Access
  531. // Accept but we still drop the line.
  532. //
  533. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  534. return( ERROR_UNKNOWN_SERVICE_TYPE );
  535. }
  536. }
  537. if ( ( pPcb->fCallbackPrivilege & RASPRIV_CallerSetCallback )
  538. || ( pPcb->fCallbackPrivilege & RASPRIV_AdminSetCallback ) )
  539. {
  540. pPcb->pBcb->fFlags |= BCBFLAG_CAN_CALL;
  541. }
  542. //
  543. // Use idle-timeout value if we got one.
  544. //
  545. pAttribute = RasAuthAttributeGet( raatIdleTimeout, pUserAttributes );
  546. if ( pAttribute != NULL )
  547. {
  548. pPcb->dwAutoDisconnectTime = PtrToUlong(pAttribute->Value);
  549. }
  550. else
  551. {
  552. pPcb->dwAutoDisconnectTime = PppConfigInfo.dwDefaulIdleTimeout;
  553. }
  554. PppLog( 2, "Auth Attribute Idle Timeout Seconds = %d",
  555. pPcb->dwAutoDisconnectTime );
  556. //
  557. // Use MaxChannels value if we got one.
  558. //
  559. pAttribute = RasAuthAttributeGet( raatPortLimit, pUserAttributes );
  560. if ( pAttribute != NULL )
  561. {
  562. if ( PtrToUlong(pAttribute->Value) > 0 )
  563. {
  564. pPcb->pBcb->dwMaxLinksAllowed = PtrToUlong(pAttribute->Value);
  565. }
  566. else
  567. {
  568. pPcb->pBcb->dwMaxLinksAllowed = PppConfigInfo.dwDefaultPortLimit;
  569. }
  570. }
  571. else
  572. {
  573. pPcb->pBcb->dwMaxLinksAllowed = PppConfigInfo.dwDefaultPortLimit;
  574. }
  575. PppLog( 2, "AuthAttribute MaxChannelsAllowed = %d",
  576. pPcb->pBcb->dwMaxLinksAllowed );
  577. //
  578. // See if BAP is required
  579. //
  580. pAttribute = RasAuthAttributeGetVendorSpecific( 311, 13, pUserAttributes );
  581. if ( pAttribute != NULL )
  582. {
  583. if ( WireToHostFormat32( (PBYTE)(pAttribute->Value)+6 ) == 2 )
  584. {
  585. PppLog( 2, "AuthAttribute BAPRequired" );
  586. pPcb->pBcb->fFlags |= BCBFLAG_BAP_REQUIRED;
  587. }
  588. }
  589. //
  590. // For the server never send a request bring up the line
  591. //
  592. pPcb->pBcb->BapParams.dwDialExtraPercent = 100;
  593. pPcb->pBcb->BapParams.dwDialExtraSampleSeconds = 100;
  594. pAttribute = RasAuthAttributeGetVendorSpecific( 311, 14, pUserAttributes );
  595. if ( ( pAttribute != NULL ) && ( pAttribute->dwLength == 10 ) )
  596. {
  597. pPcb->pBcb->BapParams.dwHangUpExtraPercent =
  598. WireToHostFormat32( ((BYTE *)(pAttribute->Value))+6 );
  599. PppLog( 2, "AuthAttribute BAPLineDownLimit = %d",
  600. pPcb->pBcb->BapParams.dwHangUpExtraPercent );
  601. }
  602. else
  603. {
  604. pPcb->pBcb->BapParams.dwHangUpExtraPercent =
  605. PppConfigInfo.dwHangupExtraPercent;
  606. }
  607. pAttribute = RasAuthAttributeGetVendorSpecific( 311, 15, pUserAttributes );
  608. if ( ( pAttribute != NULL ) && ( pAttribute->dwLength == 10 ) )
  609. {
  610. pPcb->pBcb->BapParams.dwHangUpExtraSampleSeconds =
  611. WireToHostFormat32( ((BYTE *)(pAttribute->Value))+6 );
  612. PppLog( 2, "AuthAttribute BAPLineDownTime = %d",
  613. pPcb->pBcb->BapParams.dwHangUpExtraSampleSeconds );
  614. }
  615. else
  616. {
  617. pPcb->pBcb->BapParams.dwHangUpExtraSampleSeconds =
  618. PppConfigInfo.dwHangUpExtraSampleSeconds;
  619. }
  620. return( NO_ERROR );
  621. }
  622. //**
  623. //
  624. // Call: RasAuthenticateUserWorker
  625. //
  626. // Returns: None.
  627. //
  628. // Description:
  629. //
  630. VOID
  631. RasAuthenticateUserWorker(
  632. PVOID pContext
  633. )
  634. {
  635. PCB_WORK_ITEM * pWorkItem = (PCB_WORK_ITEM *)pContext;
  636. pWorkItem->PppMsg.AuthInfo.dwError =
  637. (*PppConfigInfo.RasAuthProviderAuthenticateUser)(
  638. pWorkItem->PppMsg.AuthInfo.pInAttributes,
  639. &(pWorkItem->PppMsg.AuthInfo.pOutAttributes),
  640. &(pWorkItem->PppMsg.AuthInfo.dwResultCode) );
  641. RasAuthAttributeDestroy( pWorkItem->PppMsg.AuthInfo.pInAttributes );
  642. InsertWorkItemInQ( pWorkItem );
  643. }
  644. //**
  645. //
  646. // Call: RasAuthenticateClient
  647. //
  648. // Returns: NO_ERROR - Success
  649. // Non-zero returns - Failure
  650. //
  651. // Description:
  652. //
  653. DWORD
  654. RasAuthenticateClient(
  655. IN HPORT hPort,
  656. IN RAS_AUTH_ATTRIBUTE * pInAttributes
  657. )
  658. {
  659. PCB * pPcb = GetPCBPointerFromhPort( hPort );
  660. LCPCB * pLcpCb = NULL;
  661. PCB_WORK_ITEM * pWorkItem = NULL;
  662. DWORD dwRetCode = NO_ERROR;
  663. if ( pPcb == NULL )
  664. {
  665. RasAuthAttributeDestroy( pInAttributes );
  666. return( ERROR_INVALID_PORT_HANDLE );
  667. }
  668. pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  669. pWorkItem = (PCB_WORK_ITEM *)LOCAL_ALLOC( LPTR, sizeof(PCB_WORK_ITEM) );
  670. if ( pWorkItem == (PCB_WORK_ITEM *)NULL )
  671. {
  672. LogPPPEvent( ROUTERLOG_NOT_ENOUGH_MEMORY, GetLastError() );
  673. RasAuthAttributeDestroy( pInAttributes );
  674. return( GetLastError() );
  675. }
  676. pWorkItem->hPort = hPort;
  677. pWorkItem->dwPortId = pPcb->dwPortId;
  678. pWorkItem->Protocol = pLcpCb->Local.Work.AP;
  679. pWorkItem->PppMsg.AuthInfo.pInAttributes = pInAttributes;
  680. pWorkItem->PppMsg.AuthInfo.dwId = GetUId( pPcb, LCP_INDEX );
  681. pWorkItem->Process = ProcessAuthInfo;
  682. pPcb->dwOutstandingAuthRequestId = pWorkItem->PppMsg.AuthInfo.dwId;
  683. dwRetCode = RtlNtStatusToDosError( RtlQueueWorkItem( RasAuthenticateUserWorker,
  684. pWorkItem,
  685. WT_EXECUTEDEFAULT ) );
  686. if ( dwRetCode != NO_ERROR )
  687. {
  688. RasAuthAttributeDestroy( pInAttributes );
  689. LOCAL_FREE( pWorkItem );
  690. }
  691. return( dwRetCode );
  692. }
  693. //**
  694. //
  695. // Call: RemoteError
  696. //
  697. // Returns: DWORD - Remote version of this error
  698. //
  699. // Description: Called by a client authenticating the server.
  700. //
  701. DWORD
  702. RemoteError(
  703. IN DWORD dwError
  704. )
  705. {
  706. switch( dwError )
  707. {
  708. case ERROR_NO_DIALIN_PERMISSION:
  709. return( ERROR_REMOTE_NO_DIALIN_PERMISSION );
  710. case ERROR_PASSWD_EXPIRED:
  711. return( ERROR_REMOTE_PASSWD_EXPIRED );
  712. case ERROR_ACCT_DISABLED:
  713. return( ERROR_REMOTE_ACCT_DISABLED );
  714. case ERROR_RESTRICTED_LOGON_HOURS:
  715. return( ERROR_REMOTE_RESTRICTED_LOGON_HOURS );
  716. case ERROR_AUTHENTICATION_FAILURE:
  717. return( ERROR_REMOTE_AUTHENTICATION_FAILURE );
  718. case ERROR_REQ_NOT_ACCEP:
  719. return( ERROR_LICENSE_QUOTA_EXCEEDED );
  720. default:
  721. return( dwError );
  722. }
  723. }
  724. //**
  725. //
  726. // Call: ApIsAuthenticatorPacket
  727. //
  728. // Returns: TRUE - Packet belongs to authenticator
  729. // FALSE - Otherwise
  730. //
  731. // Description: Called to figure out whether to send the auth packet to the
  732. // authenticator or authenticatee.
  733. //
  734. BOOL
  735. ApIsAuthenticatorPacket(
  736. IN DWORD CpIndex,
  737. IN BYTE bConfigCode
  738. )
  739. {
  740. switch( CpTable[CpIndex].CpInfo.Protocol )
  741. {
  742. case PPP_PAP_PROTOCOL:
  743. switch( bConfigCode )
  744. {
  745. case 1:
  746. return( TRUE );
  747. default:
  748. return( FALSE );
  749. }
  750. break;
  751. case PPP_CHAP_PROTOCOL:
  752. switch( bConfigCode )
  753. {
  754. case 2:
  755. case 5:
  756. case 6:
  757. case 7:
  758. return( TRUE );
  759. default:
  760. return( FALSE );
  761. }
  762. break;
  763. case PPP_SPAP_NEW_PROTOCOL:
  764. switch( bConfigCode )
  765. {
  766. case 1:
  767. case 6:
  768. return( TRUE );
  769. default:
  770. return( FALSE );
  771. }
  772. break;
  773. case PPP_EAP_PROTOCOL:
  774. switch( bConfigCode )
  775. {
  776. case 2:
  777. return( TRUE );
  778. default:
  779. return( FALSE );
  780. }
  781. break;
  782. default:
  783. PPP_ASSERT( FALSE );
  784. }
  785. PPP_ASSERT( FALSE );
  786. return( FALSE );
  787. }
  788. //**
  789. //
  790. // Call: ApStart
  791. //
  792. // Returns: TRUE - Success
  793. // FALSE - Otherwise
  794. //
  795. // Description: Called to initiatialze the authetication protocol and to
  796. // initiate to authentication.
  797. //
  798. BOOL
  799. ApStart(
  800. IN PCB * pPcb,
  801. IN DWORD CpIndex,
  802. IN BOOL fAuthenticator
  803. )
  804. {
  805. DWORD dwRetCode;
  806. PPPAP_INPUT PppApInput;
  807. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  808. CPCB * pCpCb = ( fAuthenticator )
  809. ? &(pPcb->AuthenticatorCb)
  810. : &(pPcb->AuthenticateeCb);
  811. pCpCb->fConfigurable = TRUE;
  812. pCpCb->State = FSM_INITIAL;
  813. pCpCb->Protocol = CpTable[CpIndex].CpInfo.Protocol;
  814. pCpCb->LastId = (DWORD)-1;
  815. InitRestartCounters( pPcb, pCpCb );
  816. ZeroMemory( &PppApInput, sizeof( PppApInput ) );
  817. PppApInput.hPort = pPcb->hPort;
  818. PppApInput.fServer = fAuthenticator;
  819. PppApInput.fRouter = ( ROUTER_IF_TYPE_FULL_ROUTER ==
  820. pPcb->pBcb->InterfaceInfo.IfType );
  821. PppApInput.Luid = pPcb->Luid;
  822. PppApInput.dwEapTypeToBeUsed = pPcb->dwEapTypeToBeUsed;
  823. PppApInput.hTokenImpersonateUser = pPcb->pBcb->hTokenImpersonateUser;
  824. PppApInput.pCustomAuthConnData = pPcb->pBcb->pCustomAuthConnData;
  825. PppApInput.pCustomAuthUserData = pPcb->pBcb->pCustomAuthUserData;
  826. PppApInput.EapUIData = pPcb->pBcb->EapUIData;
  827. PppApInput.fLogon = ( pPcb->pBcb->fFlags &
  828. BCBFLAG_LOGON_USER_DATA );
  829. PppApInput.fNonInteractive = ( pPcb->fFlags &
  830. PCBFLAG_NON_INTERACTIVE );
  831. PppApInput.fConfigInfo = pPcb->ConfigInfo.dwConfigMask;
  832. if ( fAuthenticator )
  833. {
  834. PppApInput.dwRetries = pPcb->dwAuthRetries;
  835. PppApInput.pAPData = pLcpCb->Local.Work.pAPData;
  836. PppApInput.APDataSize = pLcpCb->Local.Work.APDataSize;
  837. PppApInput.pUserAttributes = pPcb->pUserAttributes;
  838. ZeroMemory( &pPcb->pBcb->szRemoteUserName,
  839. sizeof( pPcb->pBcb->szRemoteUserName ) );
  840. }
  841. else
  842. {
  843. //
  844. // If we are a server and we do not know who is dialing in and therefore
  845. // do not have credentials to use for being authenticated by the
  846. // remote peer, then we wait till we do.
  847. //
  848. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  849. {
  850. if ( strlen( pPcb->pBcb->szRemoteUserName ) == 0 )
  851. {
  852. PppLog(1,"Remote user not identifiable at this time, waiting");
  853. return( FALSE );
  854. }
  855. //
  856. // Ok we know who is dialed in so get credentials to used for this
  857. // connection.
  858. //
  859. dwRetCode = GetCredentialsFromInterface( pPcb );
  860. if ( dwRetCode != NO_ERROR )
  861. {
  862. //
  863. // We do not have credentials to use for this user so we
  864. // renegotiate LCP and do not accept the authentication option
  865. //
  866. PppLog( 1, "No credentials available to use for user=%s",
  867. pPcb->pBcb->szRemoteUserName );
  868. FsmDown( pPcb, LCP_INDEX );
  869. pLcpCb->Remote.WillNegotiate &= (~LCP_N_AUTHENT);
  870. FsmUp( pPcb, LCP_INDEX );
  871. return( FALSE );
  872. }
  873. }
  874. //
  875. // Decode the password
  876. //
  877. DecodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szPassword );
  878. DecodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szOldPassword );
  879. PppApInput.pszUserName = pPcb->pBcb->szLocalUserName;
  880. PppApInput.pszPassword = pPcb->pBcb->szPassword;
  881. PppApInput.pszDomain = pPcb->pBcb->szLocalDomain;
  882. PppApInput.pszOldPassword = pPcb->pBcb->szOldPassword;
  883. PppApInput.pAPData = pLcpCb->Remote.Work.pAPData;
  884. PppApInput.APDataSize = pLcpCb->Remote.Work.APDataSize;
  885. PppApInput.dwInitialPacketId = (DWORD)GetUId( pPcb, CpIndex );
  886. if ( CpTable[CpIndex].CpInfo.Protocol == PPP_EAP_PROTOCOL )
  887. {
  888. PppApInput.fPortWillBeBundled = WillPortBeBundled( pPcb );
  889. PppApInput.fThisIsACallback =
  890. ( pPcb->fFlags & PCBFLAG_THIS_IS_A_CALLBACK );
  891. }
  892. }
  893. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpBegin)(&(pCpCb->pWorkBuf),
  894. &PppApInput );
  895. if ( !fAuthenticator )
  896. {
  897. //
  898. // Encode the password back
  899. //
  900. EncodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szPassword );
  901. EncodePw( pPcb->pBcb->chSeed, pPcb->pBcb->szOldPassword );
  902. }
  903. if ( dwRetCode != NO_ERROR )
  904. {
  905. pPcb->LcpCb.dwError = dwRetCode;
  906. NotifyCallerOfFailure( pPcb, dwRetCode );
  907. return( FALSE );
  908. }
  909. PppLog(1,"Calling APWork in APStart");
  910. ApWork( pPcb, CpIndex, NULL, NULL, fAuthenticator );
  911. return( TRUE );
  912. }
  913. //**
  914. //
  915. // Call: ApStop
  916. //
  917. // Returns: none
  918. //
  919. // Description: Called to stop the authentication machine.
  920. //
  921. VOID
  922. ApStop(
  923. IN PCB * pPcb,
  924. IN DWORD CpIndex,
  925. IN BOOL fAuthenticator
  926. )
  927. {
  928. CPCB * pCpCb = ( fAuthenticator )
  929. ? &(pPcb->AuthenticatorCb)
  930. : &(pPcb->AuthenticateeCb);
  931. if ( pCpCb->pWorkBuf == NULL )
  932. {
  933. return;
  934. }
  935. pCpCb->Protocol = 0;
  936. pCpCb->fConfigurable = FALSE;
  937. if ( pCpCb->LastId != (DWORD)-1 )
  938. {
  939. RemoveFromTimerQ(
  940. pPcb->dwPortId,
  941. pCpCb->LastId,
  942. CpTable[CpIndex].CpInfo.Protocol,
  943. fAuthenticator,
  944. TIMER_EVENT_TIMEOUT );
  945. }
  946. (CpTable[CpIndex].CpInfo.RasCpEnd)( pCpCb->pWorkBuf );
  947. pCpCb->pWorkBuf = NULL;
  948. }
  949. //**
  950. //
  951. // Call: ApWork
  952. //
  953. // Returns: none
  954. //
  955. // Description: Called when and authentication packet was received or
  956. // a timeout occurred or to initiate authentication.
  957. //
  958. VOID
  959. ApWork(
  960. IN PCB * pPcb,
  961. IN DWORD CpIndex,
  962. IN PPP_CONFIG * pRecvConfig,
  963. IN PPPAP_INPUT * pApInput,
  964. IN BOOL fAuthenticator
  965. )
  966. {
  967. DWORD dwRetCode;
  968. DWORD dwLength;
  969. PPPAP_RESULT ApResult;
  970. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  971. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  972. CPCB * pCpCb = ( fAuthenticator )
  973. ? &(pPcb->AuthenticatorCb)
  974. : &(pPcb->AuthenticateeCb);
  975. //
  976. // If the protocol has not been started yet, call ApStart
  977. //
  978. if ( pCpCb->pWorkBuf == NULL )
  979. {
  980. if ( !ApStart( pPcb, CpIndex, fAuthenticator ) )
  981. {
  982. return;
  983. }
  984. }
  985. ZeroMemory( &ApResult, sizeof(ApResult) );
  986. dwRetCode = (CpTable[CpIndex].CpInfo.RasApMakeMessage)(
  987. pCpCb->pWorkBuf,
  988. pRecvConfig,
  989. pSendConfig,
  990. ((pLcpCb->Remote.Work.MRU > LCP_DEFAULT_MRU)
  991. ? LCP_DEFAULT_MRU : pLcpCb->Remote.Work.MRU)
  992. - PPP_PACKET_HDR_LEN,
  993. &ApResult,
  994. pApInput );
  995. if ( NULL != ApResult.szReplyMessage )
  996. {
  997. LocalFree( pPcb->pBcb->szReplyMessage );
  998. pPcb->pBcb->szReplyMessage = ApResult.szReplyMessage;
  999. }
  1000. if ( dwRetCode != NO_ERROR )
  1001. {
  1002. switch( dwRetCode )
  1003. {
  1004. case ERROR_PPP_INVALID_PACKET:
  1005. PppLog( 1, "Silently discarding invalid auth packet on port %d",
  1006. pPcb->hPort );
  1007. break;
  1008. default:
  1009. pPcb->LcpCb.dwError = dwRetCode;
  1010. PppLog( 1, "Auth Protocol %x returned error %d",
  1011. CpTable[CpIndex].CpInfo.Protocol, dwRetCode );
  1012. if ( fAuthenticator )
  1013. {
  1014. //
  1015. // Get the username from the CP if it supplies one.
  1016. //
  1017. if ( strlen( ApResult.szUserName ) > 0 )
  1018. {
  1019. strcpy( pPcb->pBcb->szRemoteUserName, ApResult.szUserName );
  1020. }
  1021. }
  1022. NotifyCallerOfFailure( pPcb, dwRetCode );
  1023. break;
  1024. }
  1025. return;
  1026. }
  1027. //
  1028. // Check to see if we have to save any user data
  1029. //
  1030. if ( ( !fAuthenticator ) && ( ApResult.fSaveUserData ) )
  1031. {
  1032. dwRetCode = RasSetEapUserDataA(
  1033. pPcb->pBcb->hTokenImpersonateUser,
  1034. pPcb->pBcb->szPhonebookPath,
  1035. pPcb->pBcb->szEntryName,
  1036. ApResult.pUserData,
  1037. ApResult.dwSizeOfUserData );
  1038. PppLog( 2, "Saved EAP data for user, dwRetCode = %d", dwRetCode );
  1039. }
  1040. //
  1041. // Check to see if we have to save any connection data
  1042. //
  1043. if ( ( !fAuthenticator ) && ( ApResult.fSaveConnectionData ) &&
  1044. ( 0 != ApResult.SetCustomAuthData.dwSizeOfConnectionData ) )
  1045. {
  1046. NotifyCaller( pPcb, PPPMSG_SetCustomAuthData,
  1047. &(ApResult.SetCustomAuthData) );
  1048. PppLog( 2, "Saved EAP data for connection" );
  1049. }
  1050. switch( ApResult.Action )
  1051. {
  1052. case APA_Send:
  1053. case APA_SendWithTimeout:
  1054. case APA_SendWithTimeout2:
  1055. case APA_SendAndDone:
  1056. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  1057. (PBYTE)(pPcb->pSendBuf->Protocol) );
  1058. dwLength = WireToHostFormat16( pSendConfig->Length );
  1059. LogPPPPacket(FALSE,pPcb,pPcb->pSendBuf,dwLength+PPP_PACKET_HDR_LEN);
  1060. if ( ( dwRetCode = PortSendOrDisconnect( pPcb,
  1061. (dwLength + PPP_PACKET_HDR_LEN)))
  1062. != NO_ERROR )
  1063. {
  1064. return;
  1065. }
  1066. pCpCb->LastId = (DWORD)-1;
  1067. if ( ( ApResult.Action == APA_SendWithTimeout ) ||
  1068. ( ApResult.Action == APA_SendWithTimeout2 ) )
  1069. {
  1070. pCpCb->LastId = ApResult.bIdExpected;
  1071. InsertInTimerQ( pPcb->dwPortId,
  1072. pPcb->hPort,
  1073. pCpCb->LastId,
  1074. CpTable[CpIndex].CpInfo.Protocol,
  1075. fAuthenticator,
  1076. TIMER_EVENT_TIMEOUT,
  1077. pPcb->RestartTimer );
  1078. //
  1079. // For SendWithTimeout2 we increment the ConfigRetryCount. This
  1080. // means send with infinite retry count
  1081. //
  1082. if ( ApResult.Action == APA_SendWithTimeout2 )
  1083. {
  1084. (pCpCb->ConfigRetryCount)++;
  1085. }
  1086. }
  1087. if ( ApResult.Action != APA_SendAndDone )
  1088. {
  1089. break;
  1090. }
  1091. case APA_Done:
  1092. switch( ApResult.dwError )
  1093. {
  1094. case NO_ERROR:
  1095. //
  1096. // If authentication was successful
  1097. //
  1098. if ( CpTable[CpIndex].CpInfo.Protocol == PPP_EAP_PROTOCOL )
  1099. {
  1100. if ( fAuthenticator )
  1101. {
  1102. pPcb->dwServerEapTypeId = ApResult.dwEapTypeId;
  1103. }
  1104. else
  1105. {
  1106. VOID *pCredentials = NULL;
  1107. pPcb->dwClientEapTypeId = ApResult.dwEapTypeId;
  1108. //
  1109. // Call the eap dll to collect credentials here
  1110. // so that they can be passed to rasman to be
  1111. // saved in the cred manager.
  1112. //
  1113. if( (NO_ERROR == EapGetCredentials(pCpCb->pWorkBuf,
  1114. &pCredentials))
  1115. && (NULL != pCredentials))
  1116. {
  1117. //
  1118. // Below call is not fatal.
  1119. //
  1120. (void) RasSetPortUserData(
  1121. pPcb->hPort,
  1122. PORT_CREDENTIALS_INDEX,
  1123. pCredentials,
  1124. sizeof(RASMAN_CREDENTIALS));
  1125. ZeroMemory(pCredentials,
  1126. sizeof(RASMAN_CREDENTIALS));
  1127. LocalFree(pCredentials);
  1128. }
  1129. }
  1130. }
  1131. if ( fAuthenticator )
  1132. {
  1133. RAS_AUTH_ATTRIBUTE * pAttribute;
  1134. RAS_AUTH_ATTRIBUTE * pUserAttributes = NULL;
  1135. if ( NULL != pPcb->pBcb->szRemoteIdentity )
  1136. {
  1137. LOCAL_FREE( pPcb->pBcb->szRemoteIdentity );
  1138. pPcb->pBcb->szRemoteIdentity = NULL;
  1139. }
  1140. pPcb->pBcb->szRemoteIdentity =
  1141. LOCAL_ALLOC( LPTR, strlen( ApResult.szUserName ) + 1 );
  1142. if ( NULL == pPcb->pBcb->szRemoteIdentity )
  1143. {
  1144. dwRetCode = GetLastError();
  1145. pPcb->LcpCb.dwError = dwRetCode;
  1146. NotifyCallerOfFailure( pPcb, dwRetCode );
  1147. return;
  1148. }
  1149. strcpy( pPcb->pBcb->szRemoteIdentity, ApResult.szUserName );
  1150. dwRetCode = ExtractUsernameAndDomain(
  1151. ApResult.szUserName,
  1152. pPcb->pBcb->szRemoteUserName,
  1153. NULL );
  1154. if ( dwRetCode != NO_ERROR )
  1155. {
  1156. pPcb->LcpCb.dwError = dwRetCode;
  1157. NotifyCallerOfFailure( pPcb, dwRetCode );
  1158. return;
  1159. }
  1160. if ( 0 == pPcb->pBcb->szLocalUserName[0] )
  1161. {
  1162. if ( NO_ERROR != GetCredentialsFromInterface( pPcb ) )
  1163. {
  1164. pPcb->pBcb->szLocalUserName[0] =
  1165. pPcb->pBcb->szPassword[0] =
  1166. pPcb->pBcb->szLocalDomain[0] = 0;
  1167. }
  1168. }
  1169. if ( ApResult.pUserAttributes != NULL )
  1170. {
  1171. pPcb->pAuthProtocolAttributes = ApResult.pUserAttributes;
  1172. pUserAttributes = ApResult.pUserAttributes;
  1173. }
  1174. else
  1175. {
  1176. pUserAttributes = pPcb->pAuthenticatorAttributes;
  1177. }
  1178. //
  1179. // Set all the user connection parameters authorized by the
  1180. // back-end authenticator
  1181. //
  1182. dwRetCode = SetUserAuthorizedAttributes(
  1183. pPcb,
  1184. pUserAttributes,
  1185. fAuthenticator,
  1186. (BYTE*)&(ApResult.abChallenge),
  1187. (BYTE*)&(ApResult.abResponse));
  1188. if ( dwRetCode != NO_ERROR )
  1189. {
  1190. pPcb->LcpCb.dwError = dwRetCode;
  1191. NotifyCallerOfFailure( pPcb, dwRetCode );
  1192. return;
  1193. }
  1194. //
  1195. // If we are a server and we negotiated to be authenticated
  1196. // by the remote peer we can do so now that we know who
  1197. // is dialed in.
  1198. //
  1199. if ( ( pLcpCb->Remote.Work.AP != 0 ) &&
  1200. ( pPcb->AuthenticateeCb.pWorkBuf == NULL ) &&
  1201. ( pPcb->AuthenticateeCb.fConfigurable ) &&
  1202. ( pPcb->fFlags & PCBFLAG_IS_SERVER ) )
  1203. {
  1204. CpIndex = GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP );
  1205. PPP_ASSERT(( CpIndex != (DWORD)-1 ));
  1206. if ( !ApStart( pPcb, CpIndex, FALSE ) )
  1207. {
  1208. return;
  1209. }
  1210. }
  1211. }
  1212. else
  1213. {
  1214. //
  1215. // Get the username from the CP if it supplies one.
  1216. //
  1217. if ( ( strlen( pPcb->pBcb->szLocalUserName ) == 0 )
  1218. && ( strlen( ApResult.szUserName ) > 0 ) )
  1219. {
  1220. strcpy( pPcb->pBcb->szLocalUserName, ApResult.szUserName );
  1221. }
  1222. dwRetCode = SetUserAuthorizedAttributes(
  1223. pPcb,
  1224. ApResult.pUserAttributes,
  1225. fAuthenticator,
  1226. (BYTE*)&(ApResult.abChallenge),
  1227. (BYTE*)&(ApResult.abResponse));
  1228. if ( dwRetCode != NO_ERROR )
  1229. {
  1230. pPcb->LcpCb.dwError = dwRetCode;
  1231. NotifyCallerOfFailure( pPcb, dwRetCode );
  1232. return;
  1233. }
  1234. pPcb->pAuthProtocolAttributes = ApResult.pUserAttributes;
  1235. }
  1236. pCpCb->State = FSM_OPENED;
  1237. FsmThisLayerUp( pPcb, CpIndex );
  1238. break;
  1239. case ERROR_PASSWD_EXPIRED:
  1240. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  1241. {
  1242. //
  1243. // We are a server and hence in non-interactive mode and
  1244. // hence we cannot do this.
  1245. //
  1246. pPcb->LcpCb.dwError = ApResult.dwError;
  1247. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1248. return;
  1249. }
  1250. else
  1251. {
  1252. //
  1253. // Password has expired so the user has to change his/her
  1254. // password.
  1255. //
  1256. NotifyCaller( pPcb, PPPMSG_ChangePwRequest, NULL );
  1257. }
  1258. break;
  1259. default:
  1260. //
  1261. // If we can retry with a new password then tell the client to
  1262. // get a new one from the user.
  1263. //
  1264. if ( (!fAuthenticator) && ( ApResult.fRetry ))
  1265. {
  1266. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  1267. {
  1268. //
  1269. // We are a server and hence in non-interactive mode and
  1270. // hence we cannot do this.
  1271. //
  1272. pPcb->LcpCb.dwError = ApResult.dwError;
  1273. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1274. return;
  1275. }
  1276. else
  1277. {
  1278. PppLog( 2, "Sending auth retry message to UI" );
  1279. NotifyCaller( pPcb, PPPMSG_AuthRetry, &(ApResult.dwError) );
  1280. }
  1281. }
  1282. else
  1283. {
  1284. PppLog( 1, "Auth Protocol %x terminated with error %d",
  1285. CpTable[CpIndex].CpInfo.Protocol, ApResult.dwError );
  1286. if ( ApResult.szUserName[0] != (CHAR)NULL )
  1287. {
  1288. strcpy( pPcb->pBcb->szRemoteUserName, ApResult.szUserName );
  1289. }
  1290. if ( !( pPcb->fFlags & PCBFLAG_IS_SERVER ) &&
  1291. ( fAuthenticator) )
  1292. {
  1293. pPcb->LcpCb.dwError = RemoteError( ApResult.dwError );
  1294. }
  1295. else
  1296. {
  1297. pPcb->LcpCb.dwError = ApResult.dwError;
  1298. }
  1299. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1300. return;
  1301. }
  1302. break;
  1303. }
  1304. break;
  1305. case APA_Authenticate:
  1306. if ( fAuthenticator )
  1307. {
  1308. DWORD dwIndex = 0;
  1309. DWORD dwExtraAttributes = 0;
  1310. DWORD dwNumUserAttributes = 0;
  1311. RAS_AUTH_ATTRIBUTE * pUserAttributes = NULL;
  1312. for ( dwNumUserAttributes = 0;
  1313. pPcb->pUserAttributes[dwNumUserAttributes].raaType
  1314. != raatMinimum;
  1315. dwNumUserAttributes++ );
  1316. if ( CpTable[CpIndex].CpInfo.Protocol == PPP_EAP_PROTOCOL )
  1317. {
  1318. //
  1319. // One more for Framed-MTU
  1320. //
  1321. dwExtraAttributes = 1;
  1322. }
  1323. pUserAttributes = RasAuthAttributeCopyWithAlloc(
  1324. ApResult.pUserAttributes,
  1325. dwNumUserAttributes + dwExtraAttributes );
  1326. if ( pUserAttributes == NULL )
  1327. {
  1328. dwRetCode = GetLastError();
  1329. pPcb->LcpCb.dwError = dwRetCode;
  1330. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1331. return;
  1332. }
  1333. if ( dwExtraAttributes )
  1334. {
  1335. ULONG mru = (pLcpCb->Remote.Work.MRU > LCP_DEFAULT_MRU) ?
  1336. LCP_DEFAULT_MRU : pLcpCb->Remote.Work.MRU;
  1337. //
  1338. // Insert the Framed-MTU attribute at the start.
  1339. //
  1340. dwRetCode = RasAuthAttributeInsert(
  1341. 0,
  1342. pUserAttributes,
  1343. raatFramedMTU,
  1344. FALSE,
  1345. 4,
  1346. (LPVOID)
  1347. ( UlongToPtr(mru)) );
  1348. if ( dwRetCode != NO_ERROR )
  1349. {
  1350. RasAuthAttributeDestroy( pUserAttributes );
  1351. pPcb->LcpCb.dwError = dwRetCode;
  1352. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1353. return;
  1354. }
  1355. }
  1356. //
  1357. // Insert the extra (user) attributes at the start. Attributes
  1358. // returned by the auth protocol follow.
  1359. //
  1360. for ( dwIndex = 0; dwIndex < dwNumUserAttributes; dwIndex++ )
  1361. {
  1362. dwRetCode = RasAuthAttributeInsert(
  1363. dwIndex + dwExtraAttributes,
  1364. pUserAttributes,
  1365. pPcb->pUserAttributes[dwIndex].raaType,
  1366. FALSE,
  1367. pPcb->pUserAttributes[dwIndex].dwLength,
  1368. pPcb->pUserAttributes[dwIndex].Value );
  1369. if ( dwRetCode != NO_ERROR )
  1370. {
  1371. RasAuthAttributeDestroy( pUserAttributes );
  1372. pPcb->LcpCb.dwError = dwRetCode;
  1373. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1374. return;
  1375. }
  1376. }
  1377. dwRetCode = RasAuthenticateClient( pPcb->hPort, pUserAttributes );
  1378. if ( dwRetCode != NO_ERROR )
  1379. {
  1380. pPcb->LcpCb.dwError = dwRetCode;
  1381. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1382. return;
  1383. }
  1384. }
  1385. break;
  1386. case APA_NoAction:
  1387. break;
  1388. default:
  1389. break;
  1390. }
  1391. //
  1392. // Check to see if we have to bring up the UI for EAP
  1393. //
  1394. if ( ( !fAuthenticator ) && ( ApResult.fInvokeEapUI ) )
  1395. {
  1396. NotifyCaller(pPcb, PPPMSG_InvokeEapUI, &(ApResult.InvokeEapUIData));
  1397. }
  1398. }