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.

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