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.

2093 lines
57 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: smaction.c
  7. //
  8. // Description: This module contains actions that occure during state
  9. // transitions withing the Finite State Machine for PPP.
  10. //
  11. // History:
  12. // Oct 25,1993. NarenG Created original version.
  13. //
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h> // needed for winbase.h
  17. #include <windows.h> // Win32 base API's
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <wchar.h>
  21. #include <ntlsapi.h>
  22. #include <lmcons.h>
  23. #include <raserror.h>
  24. #include <rasman.h>
  25. #include <rtutils.h>
  26. #include <mprlog.h>
  27. #include <mprerror.h>
  28. #include <rasppp.h>
  29. #include <pppcp.h>
  30. #include <ppp.h>
  31. #include <smaction.h>
  32. #include <smevents.h>
  33. #include <receive.h>
  34. #include <auth.h>
  35. #include <callback.h>
  36. #include <receive.h>
  37. #include <lcp.h>
  38. #include <timer.h>
  39. #include <util.h>
  40. #include <worker.h>
  41. #include <bap.h>
  42. #define INCL_RASAUTHATTRIBUTES
  43. #include <ppputil.h>
  44. extern WORD WLinkDiscriminator; // Next Link Discriminator to use
  45. //**
  46. //
  47. // Call: FsmSendConfigReq
  48. //
  49. // Returns: TRUE - Config Req. sent successfully.
  50. // FALSE - Otherwise
  51. //
  52. // Description: Called to send a configuration request
  53. //
  54. BOOL
  55. FsmSendConfigReq(
  56. IN PCB * pPcb,
  57. IN DWORD CpIndex,
  58. IN BOOL fTimeout
  59. )
  60. {
  61. DWORD dwRetCode;
  62. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  63. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  64. DWORD dwLength;
  65. if ( pCpCb == NULL )
  66. {
  67. return( FALSE );
  68. }
  69. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpMakeConfigRequest)(
  70. pCpCb->pWorkBuf,
  71. pSendConfig,
  72. LCP_DEFAULT_MRU
  73. - PPP_PACKET_HDR_LEN );
  74. if ( dwRetCode != NO_ERROR )
  75. {
  76. pCpCb->dwError = dwRetCode;
  77. PppLog( 1,"The control protocol for %x, returned error %d",
  78. CpTable[CpIndex].CpInfo.Protocol, dwRetCode );
  79. PppLog(1,"while making a configure request on port %d",pPcb->hPort);
  80. FsmClose( pPcb, CpIndex );
  81. return( FALSE );
  82. }
  83. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  84. (PBYTE)(pPcb->pSendBuf->Protocol) );
  85. pSendConfig->Code = CONFIG_REQ;
  86. //
  87. // If we are resending a configure request because of a timeout, we do not
  88. // use the id of the previous configure request, instead we get a new Id.
  89. // Id we do not, then the wrong Config-Req's and Config-Acks may be matched
  90. // up and we start getting crossed connections.
  91. //
  92. pSendConfig->Id = GetUId( pPcb, CpIndex );
  93. dwLength = WireToHostFormat16( pSendConfig->Length );
  94. LogPPPPacket(FALSE,pPcb,pPcb->pSendBuf,dwLength+PPP_PACKET_HDR_LEN);
  95. if ( (dwRetCode = PortSendOrDisconnect( pPcb,
  96. (dwLength + PPP_PACKET_HDR_LEN)))
  97. != NO_ERROR )
  98. {
  99. return( FALSE );
  100. }
  101. pCpCb->LastId = pSendConfig->Id;
  102. InsertInTimerQ( pPcb->dwPortId,
  103. pPcb->hPort,
  104. pCpCb->LastId,
  105. CpTable[CpIndex].CpInfo.Protocol,
  106. FALSE,
  107. TIMER_EVENT_TIMEOUT,
  108. pPcb->RestartTimer );
  109. return( TRUE );
  110. }
  111. //**
  112. //
  113. // Call: FsmSendTermReq
  114. //
  115. // Returns: TRUE - Termination Req. sent successfully.
  116. // FALSE - Otherwise
  117. //
  118. // Description: Called to send a termination request.
  119. //
  120. BOOL
  121. FsmSendTermReq(
  122. IN PCB * pPcb,
  123. IN DWORD CpIndex
  124. )
  125. {
  126. DWORD dwRetCode;
  127. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  128. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  129. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  130. if ( pCpCb == NULL )
  131. {
  132. return( FALSE );
  133. }
  134. HostToWireFormat16( (WORD)(CpTable[CpIndex].CpInfo.Protocol),
  135. (PBYTE)(pPcb->pSendBuf->Protocol) );
  136. pSendConfig->Code = TERM_REQ;
  137. pSendConfig->Id = GetUId( pPcb, CpIndex );
  138. HostToWireFormat16( (WORD)((PPP_CONFIG_HDR_LEN)+(sizeof(DWORD)*3)),
  139. (PBYTE)(pSendConfig->Length) );
  140. HostToWireFormat32( pLcpCb->Local.Work.MagicNumber,
  141. (PBYTE)(pSendConfig->Data) );
  142. //
  143. // Signature
  144. //
  145. HostToWireFormat32( 3984756, (PBYTE)(pSendConfig->Data+4) );
  146. HostToWireFormat32( pCpCb->dwError, (PBYTE)(pSendConfig->Data+8) );
  147. LogPPPPacket( FALSE,pPcb,pPcb->pSendBuf,
  148. PPP_PACKET_HDR_LEN+PPP_CONFIG_HDR_LEN+(sizeof(DWORD)*3) );
  149. if ( ( dwRetCode = PortSendOrDisconnect( pPcb,
  150. PPP_PACKET_HDR_LEN +
  151. PPP_CONFIG_HDR_LEN +
  152. (sizeof(DWORD)*3)))
  153. != NO_ERROR )
  154. {
  155. return( FALSE );
  156. }
  157. pCpCb->LastId = pSendConfig->Id;
  158. dwRetCode = InsertInTimerQ( pPcb->dwPortId,
  159. pPcb->hPort,
  160. pCpCb->LastId,
  161. CpTable[CpIndex].CpInfo.Protocol,
  162. FALSE,
  163. TIMER_EVENT_TIMEOUT,
  164. pPcb->RestartTimer );
  165. if ( dwRetCode == NO_ERROR)
  166. {
  167. return( TRUE );
  168. }
  169. else
  170. {
  171. PppLog( 1, "InsertInTimerQ on port %d failed: %d",
  172. pPcb->hPort, dwRetCode );
  173. pPcb->LcpCb.dwError = dwRetCode;
  174. pPcb->fFlags |= PCBFLAG_STOPPED_MSG_SENT;
  175. NotifyCaller( pPcb,
  176. ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  177. ? PPPDDMMSG_Stopped
  178. : PPPMSG_Stopped,
  179. &(pPcb->LcpCb.dwError) );
  180. return( FALSE );
  181. }
  182. }
  183. //**
  184. //
  185. // Call: FsmSendTermAck
  186. //
  187. // Returns: TRUE - Termination Ack. sent successfully.
  188. // FALSE - Otherwise
  189. //
  190. // Description: Caller to send a Termination Ack packet.
  191. //
  192. BOOL
  193. FsmSendTermAck(
  194. IN PCB * pPcb,
  195. IN DWORD CpIndex,
  196. IN PPP_CONFIG * pRecvConfig
  197. )
  198. {
  199. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  200. DWORD dwLength = PPP_PACKET_HDR_LEN +
  201. WireToHostFormat16( pRecvConfig->Length );
  202. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  203. DWORD dwRetCode;
  204. if ( dwLength > LCP_DEFAULT_MRU )
  205. {
  206. dwLength = LCP_DEFAULT_MRU;
  207. }
  208. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  209. (PBYTE)(pPcb->pSendBuf->Protocol) );
  210. pSendConfig->Code = TERM_ACK;
  211. pSendConfig->Id = pRecvConfig->Id;
  212. HostToWireFormat16( (WORD)(dwLength - PPP_PACKET_HDR_LEN),
  213. (PBYTE)(pSendConfig->Length) );
  214. CopyMemory( pSendConfig->Data,
  215. pRecvConfig->Data,
  216. dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN );
  217. LogPPPPacket( FALSE, pPcb, pPcb->pSendBuf, dwLength );
  218. if ( ( dwRetCode = PortSendOrDisconnect( pPcb, dwLength ) ) != NO_ERROR )
  219. {
  220. return( FALSE );
  221. }
  222. return( TRUE );
  223. }
  224. //**
  225. //
  226. // Call: FsmSendConfigResult
  227. //
  228. // Returns: TRUE - Config Result sent successfully.
  229. // FALSE - Otherwise
  230. //
  231. // Description: Called to send a Ack/Nak/Rej packet.
  232. //
  233. BOOL
  234. FsmSendConfigResult(
  235. IN PCB * pPcb,
  236. IN DWORD CpIndex,
  237. IN PPP_CONFIG * pRecvConfig,
  238. IN BOOL * pfAcked
  239. )
  240. {
  241. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  242. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  243. DWORD dwLength;
  244. DWORD dwRetCode;
  245. *pfAcked = FALSE;
  246. if ( pCpCb == NULL )
  247. {
  248. return( FALSE );
  249. }
  250. ZeroMemory( pSendConfig, 30 );
  251. pSendConfig->Id = pRecvConfig->Id;
  252. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpMakeConfigResult)(
  253. pCpCb->pWorkBuf,
  254. pRecvConfig,
  255. pSendConfig,
  256. LCP_DEFAULT_MRU - PPP_PACKET_HDR_LEN,
  257. ( pCpCb->NakRetryCount == 0 ));
  258. if ( dwRetCode == PENDING )
  259. {
  260. return( FALSE );
  261. }
  262. if ( dwRetCode == ERROR_PPP_INVALID_PACKET )
  263. {
  264. PppLog( 1, "Silently discarding invalid packet on port=%d",
  265. pPcb->hPort );
  266. return( FALSE );
  267. }
  268. if ( dwRetCode != NO_ERROR )
  269. {
  270. pCpCb->dwError = dwRetCode;
  271. PppLog( 1, "The control protocol for %x, returned error %d",
  272. CpTable[CpIndex].CpInfo.Protocol, dwRetCode );
  273. PppLog( 1, "while making a configure result on port %d", pPcb->hPort );
  274. FsmClose( pPcb, CpIndex );
  275. return( FALSE );
  276. }
  277. switch( pSendConfig->Code )
  278. {
  279. case CONFIG_ACK:
  280. *pfAcked = TRUE;
  281. break;
  282. case CONFIG_NAK:
  283. if ( pCpCb->NakRetryCount > 0 )
  284. {
  285. (pCpCb->NakRetryCount)--;
  286. }
  287. else
  288. {
  289. if ( CpTable[CpIndex].CpInfo.Protocol == PPP_CCP_PROTOCOL )
  290. {
  291. //
  292. // If we need to force encryption but encryption negotiation
  293. // failed then we drop the link
  294. //
  295. if ( pPcb->ConfigInfo.dwConfigMask &
  296. (PPPCFG_RequireEncryption |
  297. PPPCFG_RequireStrongEncryption ) )
  298. {
  299. PppLog( 1, "Encryption is required" );
  300. //
  301. // We need to send an Accounting Stop if RADIUS sends
  302. // an Access Accept but we still drop the line.
  303. //
  304. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  305. //
  306. // If we do FsmClose for CCP instead, the other side may
  307. // conclude that PPP was negotiated successfully before we
  308. // send an LCP Terminate Request.
  309. //
  310. pPcb->LcpCb.dwError = ERROR_NO_REMOTE_ENCRYPTION;
  311. FsmClose( pPcb, LCP_INDEX );
  312. return( FALSE );
  313. }
  314. }
  315. pCpCb->dwError = ERROR_PPP_NOT_CONVERGING;
  316. FsmClose( pPcb, CpIndex );
  317. return( FALSE );
  318. }
  319. break;
  320. case CONFIG_REJ:
  321. if ( pCpCb->RejRetryCount > 0 )
  322. {
  323. (pCpCb->RejRetryCount)--;
  324. }
  325. else
  326. {
  327. pCpCb->dwError = ERROR_PPP_NOT_CONVERGING;
  328. FsmClose( pPcb, CpIndex );
  329. return( FALSE );
  330. }
  331. break;
  332. default:
  333. break;
  334. }
  335. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  336. (PBYTE)(pPcb->pSendBuf->Protocol) );
  337. pSendConfig->Id = pRecvConfig->Id;
  338. dwLength = WireToHostFormat16( pSendConfig->Length );
  339. LogPPPPacket(FALSE,pPcb,pPcb->pSendBuf,dwLength+PPP_PACKET_HDR_LEN);
  340. if ( ( dwRetCode = PortSendOrDisconnect( pPcb,
  341. (dwLength + PPP_PACKET_HDR_LEN)))
  342. != NO_ERROR )
  343. {
  344. return( FALSE );
  345. }
  346. return( TRUE );
  347. }
  348. //**
  349. //
  350. // Call: FsmSendEchoRequest
  351. //
  352. // Returns: TRUE - Echo reply sent successfully.
  353. // FALSE - Otherwise
  354. //
  355. // Description: Called to send an Echo Rely packet
  356. //
  357. BOOL
  358. FsmSendEchoRequest(
  359. IN PCB * pPcb,
  360. IN DWORD CpIndex
  361. )
  362. {
  363. DWORD dwRetCode = NO_ERROR;
  364. char szEchoText[] = PPP_DEF_ECHO_TEXT;
  365. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  366. DWORD dwLength = (DWORD)(PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + strlen( szEchoText)+ sizeof(pLcpCb->Local.Work.MagicNumber));
  367. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  368. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  369. (PBYTE)(pPcb->pSendBuf->Protocol) );
  370. pSendConfig->Code = ECHO_REQ;
  371. //Get a unique Id for this request
  372. pSendConfig->Id = GetUId( pPcb, CpIndex );
  373. HostToWireFormat16( (WORD)(dwLength - PPP_PACKET_HDR_LEN),
  374. (PBYTE)(pSendConfig->Length) );
  375. HostToWireFormat32( pLcpCb->Local.Work.MagicNumber,
  376. (PBYTE)(pSendConfig->Data) );
  377. CopyMemory( pSendConfig->Data + 4,
  378. szEchoText,
  379. strlen(szEchoText));
  380. LogPPPPacket( FALSE, pPcb, pPcb->pSendBuf, dwLength );
  381. if ( ( dwRetCode = PortSendOrDisconnect( pPcb, dwLength ) ) != NO_ERROR )
  382. {
  383. return( FALSE );
  384. }
  385. return( TRUE );
  386. }
  387. //**
  388. //
  389. // Call: FsmSendEchoReply
  390. //
  391. // Returns: TRUE - Echo reply sent successfully.
  392. // FALSE - Otherwise
  393. //
  394. // Description: Called to send an Echo Rely packet
  395. //
  396. BOOL
  397. FsmSendEchoReply(
  398. IN PCB * pPcb,
  399. IN DWORD CpIndex,
  400. IN PPP_CONFIG * pRecvConfig
  401. )
  402. {
  403. DWORD dwRetCode;
  404. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  405. DWORD dwLength = PPP_PACKET_HDR_LEN +
  406. WireToHostFormat16( pRecvConfig->Length );
  407. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  408. if ( dwLength > LCP_DEFAULT_MRU )
  409. {
  410. dwLength = LCP_DEFAULT_MRU;
  411. }
  412. if ( dwLength < PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + 4 )
  413. {
  414. PppLog( 1, "Silently discarding invalid packet on port=%d",
  415. pPcb->hPort );
  416. return( FALSE );
  417. }
  418. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  419. (PBYTE)(pPcb->pSendBuf->Protocol) );
  420. pSendConfig->Code = ECHO_REPLY;
  421. pSendConfig->Id = pRecvConfig->Id;
  422. HostToWireFormat16( (WORD)(dwLength - PPP_PACKET_HDR_LEN),
  423. (PBYTE)(pSendConfig->Length) );
  424. HostToWireFormat32( pLcpCb->Local.Work.MagicNumber,
  425. (PBYTE)(pSendConfig->Data) );
  426. CopyMemory( pSendConfig->Data + 4,
  427. pRecvConfig->Data + 4,
  428. dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN - 4 );
  429. LogPPPPacket( FALSE, pPcb, pPcb->pSendBuf, dwLength );
  430. if ( ( dwRetCode = PortSendOrDisconnect( pPcb, dwLength ) ) != NO_ERROR )
  431. {
  432. return( FALSE );
  433. }
  434. return( TRUE );
  435. }
  436. //**
  437. //
  438. // Call: FsmSendCodeReject
  439. //
  440. // Returns: TRUE - Code Reject sent successfully.
  441. // FALSE - Otherwise
  442. //
  443. // Description: Called to send a Code Reject packet.
  444. //
  445. BOOL
  446. FsmSendCodeReject(
  447. IN PCB * pPcb,
  448. IN DWORD CpIndex,
  449. IN PPP_CONFIG * pRecvConfig
  450. )
  451. {
  452. DWORD dwRetCode;
  453. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  454. DWORD dwLength = PPP_PACKET_HDR_LEN +
  455. PPP_CONFIG_HDR_LEN +
  456. WireToHostFormat16( pRecvConfig->Length );
  457. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  458. if ( dwLength > LCP_DEFAULT_MRU )
  459. dwLength = LCP_DEFAULT_MRU;
  460. HostToWireFormat16( (WORD)CpTable[CpIndex].CpInfo.Protocol,
  461. (PBYTE)(pPcb->pSendBuf->Protocol) );
  462. pSendConfig->Code = CODE_REJ;
  463. pSendConfig->Id = GetUId( pPcb, CpIndex );
  464. HostToWireFormat16( (WORD)(dwLength - PPP_PACKET_HDR_LEN),
  465. (PBYTE)(pSendConfig->Length) );
  466. CopyMemory( pSendConfig->Data,
  467. pRecvConfig,
  468. dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN );
  469. LogPPPPacket( FALSE, pPcb, pPcb->pSendBuf, dwLength );
  470. if ( ( dwRetCode = PortSendOrDisconnect( pPcb, dwLength ) ) != NO_ERROR )
  471. {
  472. return( FALSE );
  473. }
  474. return( TRUE );
  475. }
  476. //**
  477. //
  478. // Call: FsmSendProtocolRej
  479. //
  480. // Returns: TRUE - Protocol Reject sent successfully.
  481. // FALSE - Otherwise
  482. //
  483. // Description: Called to send a protocol reject packet.
  484. //
  485. BOOL
  486. FsmSendProtocolRej(
  487. IN PCB * pPcb,
  488. IN PPP_PACKET * pPacket,
  489. IN DWORD dwPacketLength
  490. )
  491. {
  492. DWORD dwRetCode;
  493. PPP_CONFIG * pRecvConfig = (PPP_CONFIG*)(pPacket->Information);
  494. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  495. DWORD dwLength = PPP_PACKET_HDR_LEN +
  496. PPP_CONFIG_HDR_LEN +
  497. dwPacketLength;
  498. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  499. //
  500. // If LCP is not in the opened state we cannot send a protocol reject
  501. // packet
  502. //
  503. if ( !IsLcpOpened( pPcb ) )
  504. return( FALSE );
  505. if ( dwLength > LCP_DEFAULT_MRU )
  506. dwLength = LCP_DEFAULT_MRU;
  507. HostToWireFormat16( (WORD)CpTable[LCP_INDEX].CpInfo.Protocol,
  508. (PBYTE)(pPcb->pSendBuf->Protocol) );
  509. pSendConfig->Code = PROT_REJ;
  510. pSendConfig->Id = GetUId( pPcb, LCP_INDEX );
  511. HostToWireFormat16( (WORD)(dwLength - PPP_PACKET_HDR_LEN),
  512. (PBYTE)(pSendConfig->Length) );
  513. CopyMemory( pSendConfig->Data,
  514. pPacket,
  515. dwLength - PPP_CONFIG_HDR_LEN - PPP_PACKET_HDR_LEN );
  516. LogPPPPacket( FALSE, pPcb, pPcb->pSendBuf, dwLength );
  517. if ( ( dwRetCode = PortSendOrDisconnect( pPcb, dwLength ) ) != NO_ERROR )
  518. {
  519. return( FALSE );
  520. }
  521. return( TRUE );
  522. }
  523. //**
  524. //
  525. // Call: FsmSendIndentification
  526. //
  527. // Returns: TRUE - Identification sent successfully.
  528. // FALSE - Otherwise
  529. //
  530. // Description: Called to send an LCP Identification message to the peer
  531. //
  532. BOOL
  533. FsmSendIdentification(
  534. IN PCB * pPcb,
  535. IN BOOL fSendVersion
  536. )
  537. {
  538. DWORD dwRetCode;
  539. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  540. DWORD dwLength = PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + 4;
  541. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  542. if ( !(pPcb->ConfigInfo.dwConfigMask & PPPCFG_UseLcpExtensions) )
  543. {
  544. return( FALSE );
  545. }
  546. if ( fSendVersion )
  547. {
  548. CopyMemory( pSendConfig->Data + 4,
  549. MS_RAS_VERSION,
  550. strlen( MS_RAS_VERSION ) );
  551. dwLength += strlen( MS_RAS_VERSION );
  552. }
  553. else
  554. {
  555. //
  556. // If we couldn't get the computername for any reason
  557. //
  558. if ( *(pPcb->pBcb->szComputerName) == (CHAR)NULL )
  559. {
  560. return( FALSE );
  561. }
  562. CopyMemory( pSendConfig->Data + 4,
  563. pPcb->pBcb->szComputerName,
  564. strlen( pPcb->pBcb->szComputerName ) );
  565. dwLength += strlen( pPcb->pBcb->szComputerName );
  566. }
  567. HostToWireFormat16( (WORD)PPP_LCP_PROTOCOL,
  568. (PBYTE)(pPcb->pSendBuf->Protocol) );
  569. pSendConfig->Code = IDENTIFICATION;
  570. pSendConfig->Id = GetUId( pPcb, LCP_INDEX );
  571. HostToWireFormat16( (WORD)(dwLength - PPP_PACKET_HDR_LEN),
  572. (PBYTE)(pSendConfig->Length) );
  573. HostToWireFormat32( pLcpCb->Local.Work.MagicNumber,
  574. (PBYTE)(pSendConfig->Data) );
  575. LogPPPPacket( FALSE,pPcb,pPcb->pSendBuf,dwLength );
  576. if ( ( dwRetCode = PortSendOrDisconnect( pPcb, dwLength ) ) != NO_ERROR )
  577. {
  578. return( FALSE );
  579. }
  580. return( TRUE );
  581. }
  582. //**
  583. //
  584. // Call: FsmSendTimeRemaining
  585. //
  586. // Returns: TRUE - TimeRemaining sent successfully.
  587. // FALSE - Otherwise
  588. //
  589. // Description: Called to send an LCP Time Remaining packet from the server
  590. // to the client
  591. //
  592. BOOL
  593. FsmSendTimeRemaining(
  594. IN PCB * pPcb
  595. )
  596. {
  597. DWORD dwRetCode;
  598. PPP_CONFIG * pSendConfig = (PPP_CONFIG*)(pPcb->pSendBuf->Information);
  599. DWORD dwLength = PPP_PACKET_HDR_LEN + PPP_CONFIG_HDR_LEN + 8;
  600. LCPCB * pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  601. if ( !(pPcb->ConfigInfo.dwConfigMask & PPPCFG_UseLcpExtensions) )
  602. {
  603. return( FALSE );
  604. }
  605. dwLength += strlen( MS_RAS );
  606. HostToWireFormat16( (WORD)PPP_LCP_PROTOCOL,
  607. (PBYTE)(pPcb->pSendBuf->Protocol) );
  608. pSendConfig->Code = TIME_REMAINING;
  609. pSendConfig->Id = GetUId( pPcb, LCP_INDEX );
  610. HostToWireFormat16( (WORD)(dwLength - PPP_PACKET_HDR_LEN),
  611. (PBYTE)(pSendConfig->Length) );
  612. HostToWireFormat32( pLcpCb->Local.Work.MagicNumber,
  613. (PBYTE)(pSendConfig->Data) );
  614. HostToWireFormat32( 0, (PBYTE)(pSendConfig->Data+4) );
  615. CopyMemory( pSendConfig->Data + 8, MS_RAS, strlen( MS_RAS ) );
  616. LogPPPPacket( FALSE, pPcb, pPcb->pSendBuf, dwLength );
  617. if ( ( dwRetCode = PortSendOrDisconnect( pPcb, dwLength ) ) != NO_ERROR )
  618. {
  619. return( FALSE );
  620. }
  621. return( TRUE );
  622. }
  623. //**
  624. //
  625. // Call: FsmInit
  626. //
  627. // Returns: TRUE - Control Protocol was successfully initialized
  628. // FALSE - Otherwise.
  629. //
  630. // Description: Called to initialize the state machine
  631. //
  632. BOOL
  633. FsmInit(
  634. IN PCB * pPcb,
  635. IN DWORD CpIndex
  636. )
  637. {
  638. DWORD dwRetCode;
  639. PPPCP_INIT PppCpInit;
  640. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  641. if ( pCpCb == NULL )
  642. {
  643. return( FALSE );
  644. }
  645. PppLog( 1, "FsmInit called for protocol = %x, port = %d",
  646. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort );
  647. pCpCb->NcpPhase = NCP_CONFIGURING;
  648. pCpCb->dwError = NO_ERROR;
  649. pCpCb->State = FSM_INITIAL;
  650. PppCpInit.fServer = (pPcb->fFlags & PCBFLAG_IS_SERVER);
  651. PppCpInit.hPort = pPcb->hPort;
  652. PppCpInit.dwDeviceType = pPcb->dwDeviceType;
  653. PppCpInit.CompletionRoutine = CompletionRoutine;
  654. PppCpInit.pszzParameters = pPcb->pBcb->InterfaceInfo.szzParameters;
  655. PppCpInit.fThisIsACallback = pPcb->fFlags & PCBFLAG_THIS_IS_A_CALLBACK;
  656. PppCpInit.IfType = pPcb->pBcb->InterfaceInfo.IfType;
  657. PppCpInit.pszUserName = pPcb->pBcb->szRemoteUserName;
  658. PppCpInit.pszPortName = pPcb->szPortName;
  659. PppCpInit.hConnection = pPcb->pBcb->hConnection;
  660. PppCpInit.pAttributes = ( pPcb->pAuthProtocolAttributes )
  661. ? pPcb->pAuthProtocolAttributes
  662. : pPcb->pAuthenticatorAttributes;
  663. PppCpInit.fDisableNetbt = (pPcb->fFlags & PCBFLAG_DISABLE_NETBT);
  664. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  665. {
  666. PppCpInit.PppConfigInfo = PppConfigInfo.ServerConfigInfo;
  667. if ( PppConfigInfo.ServerConfigInfo.dwConfigMask
  668. & PPPCFG_AllowNoAuthOnDCPorts )
  669. {
  670. if ( RAS_DEVICE_CLASS( pPcb->dwDeviceType ) & RDT_Direct )
  671. {
  672. PppCpInit.PppConfigInfo.dwConfigMask |=
  673. PPPCFG_AllowNoAuthentication;
  674. }
  675. else
  676. {
  677. PppCpInit.PppConfigInfo.dwConfigMask &=
  678. ~PPPCFG_AllowNoAuthOnDCPorts;
  679. }
  680. }
  681. }
  682. else
  683. {
  684. PppCpInit.PppConfigInfo = pPcb->ConfigInfo;
  685. }
  686. switch( CpTable[CpIndex].CpInfo.Protocol )
  687. {
  688. case PPP_IPCP_PROTOCOL:
  689. PppCpInit.hInterface = pPcb->pBcb->InterfaceInfo.hIPInterface;
  690. break;
  691. case PPP_IPXCP_PROTOCOL:
  692. PppCpInit.hInterface = pPcb->pBcb->InterfaceInfo.hIPXInterface;
  693. break;
  694. default:
  695. PppCpInit.hInterface = INVALID_HANDLE_VALUE;
  696. break;
  697. }
  698. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpBegin)(
  699. &(pCpCb->pWorkBuf), &PppCpInit );
  700. if ( dwRetCode != NO_ERROR )
  701. {
  702. PppLog( 1, "FsmInit for protocol = %x failed with error %d",
  703. CpTable[CpIndex].CpInfo.Protocol, dwRetCode );
  704. pCpCb->dwError = dwRetCode;
  705. pCpCb->fConfigurable = FALSE;
  706. return( FALSE );
  707. }
  708. pCpCb->fBeginCalled = TRUE;
  709. if ( !FsmReset( pPcb, CpIndex ) )
  710. {
  711. pCpCb->fConfigurable = FALSE;
  712. return( FALSE );
  713. }
  714. return( TRUE );
  715. }
  716. //**
  717. //
  718. // Call: FsmReset
  719. //
  720. // Returns: TRUE - Control Protocol was successfully reset
  721. // FALSE - Otherwise.
  722. //
  723. // Description: Called to reset the state machine
  724. //
  725. BOOL
  726. FsmReset(
  727. IN PCB * pPcb,
  728. IN DWORD CpIndex
  729. )
  730. {
  731. DWORD dwRetCode;
  732. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  733. if ( pCpCb == NULL )
  734. {
  735. return( FALSE );
  736. }
  737. PppLog( 1, "FsmReset called for protocol = %x, port = %d",
  738. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort );
  739. pCpCb->LastId = 0;
  740. InitRestartCounters( pPcb, pCpCb );
  741. pCpCb->NakRetryCount = PppConfigInfo.MaxFailure;
  742. pCpCb->RejRetryCount = PppConfigInfo.MaxReject;
  743. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpReset)( pCpCb->pWorkBuf );
  744. if ( dwRetCode != NO_ERROR )
  745. {
  746. PppLog( 1, "Reset for protocol = %x failed with error %d",
  747. CpTable[CpIndex].CpInfo.Protocol, dwRetCode );
  748. pCpCb->dwError = dwRetCode;
  749. FsmClose( pPcb, CpIndex );
  750. return( FALSE );
  751. }
  752. return( TRUE );
  753. }
  754. //**
  755. //
  756. // Call: FsmThisLayerUp
  757. //
  758. // Returns: TRUE - Success
  759. // FALSE - Otherwise
  760. //
  761. // Description: Called when configuration negotiation is completed.
  762. //
  763. BOOL
  764. FsmThisLayerUp(
  765. IN PCB * pPcb,
  766. IN DWORD CpIndex
  767. )
  768. {
  769. DWORD dwIndex;
  770. DWORD dwRetCode;
  771. PPP_PROJECTION_RESULT ProjectionResult;
  772. RAS_AUTH_ATTRIBUTE * pUserAttributes = NULL;
  773. NCP_PHASE dwNcpState;
  774. BOOL fAreCPsDone = FALSE;
  775. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  776. LCPCB * pLcpCb;
  777. DWORD dwLinkDiscrim;
  778. BOOL fCanDoBAP = FALSE;
  779. if ( NULL != pCpCb )
  780. {
  781. PppLog( 1, "FsmThisLayerUp called for protocol = %x, port = %d",
  782. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort );
  783. if ( CpTable[CpIndex].CpInfo.RasCpThisLayerUp != NULL )
  784. {
  785. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpThisLayerUp)(
  786. pCpCb->pWorkBuf);
  787. if ( dwRetCode != NO_ERROR )
  788. {
  789. PppLog( 1, "FsmThisLayerUp for protocol=%x,port=%d,RetCode=%d",
  790. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort,
  791. dwRetCode);
  792. if ( dwRetCode != PENDING )
  793. {
  794. pCpCb->dwError = dwRetCode;
  795. FsmClose( pPcb, CpIndex );
  796. }
  797. return( FALSE );
  798. }
  799. }
  800. }
  801. else
  802. {
  803. PppLog( 1, "FsmThisLayerUp called in no auth case, port = %d",
  804. pPcb->hPort );
  805. }
  806. if ( CpIndex == GetCpIndexFromProtocol( PPP_BACP_PROTOCOL ) )
  807. {
  808. BapSetPolicy( pPcb->pBcb );
  809. }
  810. switch( pPcb->PppPhase )
  811. {
  812. case PPP_LCP:
  813. PppLog( 1, "LCP Configured successfully" );
  814. if (!( pPcb->fFlags & PCBFLAG_IS_SERVER ) )
  815. {
  816. AdjustHTokenImpersonateUser( pPcb );
  817. }
  818. //
  819. // Send Identification messages if we are a client.
  820. //
  821. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) )
  822. {
  823. FsmSendIdentification( pPcb, TRUE );
  824. FsmSendIdentification( pPcb, FALSE );
  825. }
  826. //
  827. // If an Authentication protocol was negotiated
  828. //
  829. pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  830. if ( ( pLcpCb->Local.Work.AP != 0 ) || ( pLcpCb->Remote.Work.AP != 0 ) )
  831. {
  832. //
  833. // Start authenticating
  834. //
  835. PppLog( 1, "Authenticating phase started" );
  836. pPcb->PppPhase = PPP_AP;
  837. //
  838. // Start server side authentication if one was negotiated
  839. //
  840. if ( pLcpCb->Local.Work.AP != 0 )
  841. {
  842. CpIndex = GetCpIndexFromProtocol( pLcpCb->Local.Work.AP );
  843. PPP_ASSERT(( CpIndex != (DWORD)-1 ));
  844. ApStart( pPcb, CpIndex, TRUE );
  845. }
  846. //
  847. // Start client side negotiation if one was negotiated
  848. //
  849. if ( pLcpCb->Remote.Work.AP != 0 )
  850. {
  851. CpIndex = GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP );
  852. PPP_ASSERT(( CpIndex != (DWORD)-1 ));
  853. ApStart( pPcb, CpIndex, FALSE );
  854. }
  855. break;
  856. }
  857. //
  858. // If we are a server and did not authenticate the user, then see if
  859. // Guests have dial-in privilege. In the case of DCC, we don't care if
  860. // Guests have the privilege. We allow the call to succeed.
  861. //
  862. if ( ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  863. && ( pLcpCb->Local.Work.AP == 0 )
  864. && (0 == (pLcpCb->PppConfigInfo.dwConfigMask & PPPCFG_AllowNoAuthOnDCPorts)))
  865. // && ( ( RAS_DEVICE_CLASS( pPcb->dwDeviceType ) & RDT_Direct ) == 0 ))
  866. {
  867. pPcb->PppPhase = PPP_AP;
  868. pUserAttributes = RasAuthAttributeCopy(
  869. pPcb->pUserAttributes );
  870. if ( pUserAttributes == NULL )
  871. {
  872. dwRetCode = GetLastError();
  873. pPcb->LcpCb.dwError = dwRetCode;
  874. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  875. return( FALSE );
  876. }
  877. dwRetCode = RasAuthenticateClient(pPcb->hPort, pUserAttributes);
  878. if ( dwRetCode != NO_ERROR )
  879. {
  880. pPcb->LcpCb.dwError = dwRetCode;
  881. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  882. return( FALSE );
  883. }
  884. break;
  885. }
  886. //
  887. // If there was no authentication protocol negotiated, fallthru and
  888. // begin NCP configurations.
  889. //
  890. case PPP_AP:
  891. //
  892. // Make sure authentication phase is completed before moving on.
  893. //
  894. if ( pPcb->AuthenticatorCb.fConfigurable )
  895. {
  896. if ( pPcb->AuthenticatorCb.State != FSM_OPENED )
  897. {
  898. break;
  899. }
  900. }
  901. if ( pPcb->AuthenticateeCb.fConfigurable )
  902. {
  903. if ( pPcb->AuthenticateeCb.State != FSM_OPENED )
  904. {
  905. break;
  906. }
  907. }
  908. NotifyCaller( pPcb, PPPDDMMSG_Authenticated, NULL );
  909. //
  910. // If we are to negotiate callback
  911. //
  912. if ( pPcb->fFlags & PCBFLAG_NEGOTIATE_CALLBACK )
  913. {
  914. CpIndex = GetCpIndexFromProtocol( PPP_CBCP_PROTOCOL );
  915. PPP_ASSERT(( CpIndex != (DWORD)-1 ));
  916. //
  917. // Start callback
  918. //
  919. PppLog( 1, "Callback phase started" );
  920. pPcb->PppPhase = PPP_NEGOTIATING_CALLBACK;
  921. pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  922. if ( NULL == pCpCb )
  923. {
  924. return( FALSE );
  925. }
  926. pCpCb->fConfigurable = TRUE;
  927. CbStart( pPcb, CpIndex );
  928. break;
  929. }
  930. else
  931. {
  932. //
  933. // If the remote peer did not negotiate callback during LCP and
  934. // the authenticated user HAS to be called back for security
  935. // reasons, we bring the link down
  936. //
  937. if ( ( pPcb->fFlags & PCBFLAG_IS_SERVER ) &&
  938. ( !(pPcb->fFlags & PCBFLAG_THIS_IS_A_CALLBACK) ) &&
  939. ( pPcb->fCallbackPrivilege & RASPRIV_AdminSetCallback ) )
  940. {
  941. pPcb->LcpCb.dwError = ERROR_NO_DIALIN_PERMISSION;
  942. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  943. //
  944. // We need to send an Accounting Stop if RADIUS sends an Access
  945. // Accept but we still drop the line.
  946. //
  947. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  948. break;
  949. }
  950. }
  951. //
  952. // Fallthru
  953. //
  954. case PPP_NEGOTIATING_CALLBACK:
  955. //
  956. // Progress to NCP phase only if we are sure that we have passed the
  957. // callback phase
  958. //
  959. if ( ( pPcb->fFlags & PCBFLAG_NEGOTIATE_CALLBACK ) &&
  960. ( CpTable[CpIndex].CpInfo.Protocol != PPP_CBCP_PROTOCOL ) )
  961. {
  962. break;
  963. }
  964. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) )
  965. {
  966. NotifyCaller( pPcb, PPPMSG_Projecting, NULL );
  967. }
  968. //
  969. // We may lose pPcb->pBcb when we call TryToBundleWithAnotherLink().
  970. // Save pPcb->pBcb->fFlags & BCBFLAG_CAN_DO_BAP first.
  971. //
  972. fCanDoBAP = pPcb->pBcb->fFlags & BCBFLAG_CAN_DO_BAP;
  973. //
  974. // If multilink was negotiated on this link check to see if this
  975. // link can be bundled and is not already bundled with another link
  976. //
  977. if ( ( pPcb->fFlags & PCBFLAG_CAN_BE_BUNDLED ) &&
  978. ( !(pPcb->fFlags & PCBFLAG_IS_BUNDLED ) ) )
  979. {
  980. //
  981. // If we are bundled with another link then skip NCP phase
  982. //
  983. dwRetCode = TryToBundleWithAnotherLink( pPcb );
  984. if ( dwRetCode != NO_ERROR )
  985. {
  986. pPcb->LcpCb.dwError = dwRetCode;
  987. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  988. return( FALSE );
  989. }
  990. }
  991. //
  992. // If we are bundled
  993. //
  994. if ( pPcb->fFlags & PCBFLAG_IS_BUNDLED )
  995. {
  996. if ( pPcb->pBcb->fFlags & BCBFLAG_CAN_DO_BAP )
  997. {
  998. if ( !fCanDoBAP )
  999. {
  1000. //
  1001. // A new link can join a bundle that does BAP only if the
  1002. // link has negotiated Link Discriminator.
  1003. //
  1004. PppLog( 1, "Link to be terminated on hPort = %d because "
  1005. "it can't do BAP.",
  1006. pPcb->hPort );
  1007. pPcb->LcpCb.dwError = ERROR_PPP_NOT_CONVERGING;
  1008. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1009. return( FALSE );
  1010. }
  1011. else
  1012. {
  1013. //
  1014. // Reset the start time for the sample period. Now that the
  1015. // bandwidth has changed, ndiswan shouldn't ask us to bring
  1016. // links up or down based on what happened in the past.
  1017. //
  1018. BapSetPolicy( pPcb->pBcb );
  1019. }
  1020. if ( !FLinkDiscriminatorIsUnique( pPcb, &dwLinkDiscrim ) )
  1021. {
  1022. PppLog( 1,
  1023. "New link discriminator %d to be negotiated for "
  1024. "port %d",
  1025. dwLinkDiscrim, pPcb->hPort );
  1026. WLinkDiscriminator = (WORD) dwLinkDiscrim;
  1027. FsmDown( pPcb, LCP_INDEX );
  1028. ((LCPCB*)
  1029. (pPcb->LcpCb.pWorkBuf))->Local.Work.dwLinkDiscriminator =
  1030. dwLinkDiscrim;
  1031. FsmUp( pPcb, LCP_INDEX );
  1032. return( FALSE );
  1033. }
  1034. }
  1035. //
  1036. // Get state of bundle NCPs
  1037. //
  1038. dwNcpState = QueryBundleNCPState( pPcb );
  1039. switch ( dwNcpState )
  1040. {
  1041. case NCP_CONFIGURING:
  1042. pPcb->PppPhase = PPP_NCP;
  1043. PppLog(2,"Bundle NCPs not done for port %d, wait", pPcb->hPort);
  1044. NotifyCaller( pPcb, PPPDDMMSG_NewLink, NULL );
  1045. break;
  1046. case NCP_DOWN:
  1047. pPcb->PppPhase = PPP_NCP;
  1048. pPcb->LcpCb.dwError = ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
  1049. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1050. return( FALSE );
  1051. case NCP_UP:
  1052. pPcb->PppPhase = PPP_NCP;
  1053. NotifyCaller( pPcb, PPPDDMMSG_NewLink, NULL );
  1054. NotifyCallerOfBundledProjection( pPcb );
  1055. RemoveFromTimerQ( pPcb->dwPortId,
  1056. 0,
  1057. 0,
  1058. FALSE,
  1059. TIMER_EVENT_NEGOTIATETIME );
  1060. StartAutoDisconnectForPort( pPcb );
  1061. StartLCPEchoForPort ( pPcb );
  1062. MakeStartAccountingCall( pPcb );
  1063. break;
  1064. case NCP_DEAD:
  1065. //
  1066. // NCPs still have not started so notify DDM that this a
  1067. // new bundle and get interface handles for this new bundle.
  1068. //
  1069. NotifyCaller( pPcb, PPPDDMMSG_NewBundle, NULL );
  1070. break;
  1071. }
  1072. return( TRUE );
  1073. }
  1074. //
  1075. // We are a client so we have all the interface handles already.
  1076. // We are not part of a bundle, so initialize all NCPs
  1077. //
  1078. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) )
  1079. {
  1080. dwRetCode = InitializeNCPs( pPcb, pPcb->ConfigInfo.dwConfigMask );
  1081. if ( dwRetCode != NO_ERROR )
  1082. {
  1083. pPcb->LcpCb.dwError = dwRetCode;
  1084. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1085. return( FALSE );
  1086. }
  1087. //
  1088. // Start NCPs
  1089. //
  1090. StartNegotiatingNCPs( pPcb );
  1091. }
  1092. else
  1093. {
  1094. //
  1095. // Take care of the RAS server policy on workstation. If we have
  1096. // already checked the policy for this link, don't check again.
  1097. //
  1098. if ( ( PppConfigInfo.fFlags & PPPCONFIG_FLAG_WKSTA )
  1099. && !( pPcb->pBcb->fFlags & BCBFLAG_WKSTA_IN ) )
  1100. {
  1101. //
  1102. // We did not bundle with another link. Allow atmost one
  1103. // dial in client in each class.
  1104. //
  1105. if ( ( (pPcb->dwDeviceType & RDT_Tunnel)
  1106. && (PppConfigInfo.fFlags & PPPCONFIG_FLAG_TUNNEL))
  1107. || ( (pPcb->dwDeviceType & RDT_Direct)
  1108. && (PppConfigInfo.fFlags & PPPCONFIG_FLAG_DIRECT))
  1109. || ( !(pPcb->dwDeviceType & RDT_Tunnel)
  1110. && !(pPcb->dwDeviceType & RDT_Direct)
  1111. && (PppConfigInfo.fFlags & PPPCONFIG_FLAG_DIALUP)))
  1112. {
  1113. pPcb->LcpCb.dwError = ERROR_USER_LIMIT;
  1114. PppLog( 2, "User limit reached. Flags: %d",
  1115. PppConfigInfo.fFlags );
  1116. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1117. return( FALSE );
  1118. }
  1119. if ( pPcb->dwDeviceType & RDT_Tunnel )
  1120. {
  1121. PppConfigInfo.fFlags |= PPPCONFIG_FLAG_TUNNEL;
  1122. }
  1123. else if ( pPcb->dwDeviceType & RDT_Direct )
  1124. {
  1125. PppConfigInfo.fFlags |= PPPCONFIG_FLAG_DIRECT;
  1126. }
  1127. else
  1128. {
  1129. PppConfigInfo.fFlags |= PPPCONFIG_FLAG_DIALUP;
  1130. }
  1131. pPcb->pBcb->fFlags |= BCBFLAG_WKSTA_IN;
  1132. }
  1133. //
  1134. // Increase client license count if we are on the recieving end
  1135. // of the call.
  1136. //
  1137. if ( pPcb->pBcb->hLicense == INVALID_HANDLE_VALUE )
  1138. {
  1139. LS_STATUS_CODE LsStatus;
  1140. NT_LS_DATA NtLSData;
  1141. NtLSData.DataType = NT_LS_USER_NAME;
  1142. NtLSData.Data = pPcb->pBcb->szLocalUserName;
  1143. NtLSData.IsAdmin = FALSE;
  1144. LsStatus = NtLicenseRequest(
  1145. "REMOTE_ACCESS",
  1146. "",
  1147. (LS_HANDLE*)&(pPcb->pBcb->hLicense),
  1148. &NtLSData );
  1149. if ( LsStatus != LS_SUCCESS )
  1150. {
  1151. pPcb->LcpCb.dwError =
  1152. ( LsStatus == LS_RESOURCES_UNAVAILABLE )
  1153. ? ERROR_OUTOFMEMORY
  1154. : ERROR_REQ_NOT_ACCEP;
  1155. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1156. return( FALSE );
  1157. }
  1158. }
  1159. //
  1160. // We are DDM and this is a new Bundle.
  1161. //
  1162. NotifyCaller( pPcb, PPPDDMMSG_NewBundle, NULL );
  1163. }
  1164. break;
  1165. case PPP_NCP:
  1166. //
  1167. // If we are a client and got rechallenged and we responded while we
  1168. // were in the NCP state then we are done.
  1169. //
  1170. pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  1171. if ( pLcpCb->Remote.Work.AP != 0 )
  1172. {
  1173. if ( CpIndex == GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP ) )
  1174. {
  1175. break;
  1176. }
  1177. }
  1178. //
  1179. // If we are a server and we got another auth request while we were
  1180. // in NCP state, we are done
  1181. //
  1182. if ( pLcpCb->Local.Work.AP != 0 )
  1183. {
  1184. if ( CpIndex == GetCpIndexFromProtocol( pLcpCb->Local.Work.AP ) )
  1185. {
  1186. break;
  1187. }
  1188. }
  1189. if ( NULL == pCpCb )
  1190. {
  1191. return( FALSE );
  1192. }
  1193. pCpCb->NcpPhase = NCP_UP;
  1194. if ( ( CpTable[CpIndex].CpInfo.Protocol == PPP_NBFCP_PROTOCOL ) ||
  1195. ( CpTable[CpIndex].CpInfo.Protocol == PPP_IPCP_PROTOCOL ) )
  1196. {
  1197. if ( !NotifyIPCPOfNBFCPProjection( pPcb, CpIndex ) )
  1198. {
  1199. return( FALSE );
  1200. }
  1201. }
  1202. dwRetCode = AreNCPsDone(pPcb, CpIndex, &ProjectionResult, &fAreCPsDone);
  1203. //
  1204. // We failed to get information from CP with CpIndex.
  1205. //
  1206. if ( dwRetCode != NO_ERROR )
  1207. {
  1208. return( FALSE );
  1209. }
  1210. if ( fAreCPsDone == TRUE )
  1211. {
  1212. RemoveFromTimerQ( pPcb->dwPortId,
  1213. 0,
  1214. 0,
  1215. FALSE,
  1216. TIMER_EVENT_NEGOTIATETIME );
  1217. //
  1218. // Notify the ras client and the ras server about the projections
  1219. //
  1220. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  1221. {
  1222. NotifyCaller( pPcb, PPPDDMMSG_PppDone, &ProjectionResult );
  1223. }
  1224. else
  1225. {
  1226. RASMAN_INFO rasmanInfo;
  1227. NotifyCaller(pPcb, PPPMSG_ProjectionResult, &ProjectionResult);
  1228. NotifyCaller(pPcb, PPPMSG_PppDone, NULL);
  1229. if ( RasGetInfo(NULL, pPcb->hPort, &rasmanInfo ) == NO_ERROR )
  1230. {
  1231. RasSetConnectionUserData(
  1232. rasmanInfo.RI_ConnectionHandle,
  1233. 1,
  1234. (PBYTE)&ProjectionResult,
  1235. sizeof( ProjectionResult ) );
  1236. }
  1237. }
  1238. StartAutoDisconnectForPort( pPcb );
  1239. StartLCPEchoForPort ( pPcb );
  1240. if ( !( pPcb->fFlags & PCBFLAG_IS_SERVER ) &&
  1241. !( pPcb->fFlags & PCBFLAG_CONNECTION_LOGGED ) )
  1242. {
  1243. LPSTR lpsSubStringArray[3];
  1244. lpsSubStringArray[0] = pPcb->pBcb->szLocalUserName;
  1245. lpsSubStringArray[1] = pPcb->pBcb->szEntryName;
  1246. lpsSubStringArray[2] = pPcb->szPortName;
  1247. PppLogInformation( ROUTERLOG_CONNECTION_ESTABLISHED,
  1248. 3,
  1249. lpsSubStringArray );
  1250. pPcb->fFlags |= PCBFLAG_CONNECTION_LOGGED;
  1251. }
  1252. //
  1253. // If we are bundled, then we need to notify all other bundled ports
  1254. // that PPP on that port is done too.
  1255. //
  1256. if ( pPcb->fFlags & PCBFLAG_IS_BUNDLED )
  1257. {
  1258. NotifyCompletionOnBundledPorts( pPcb );
  1259. }
  1260. MakeStartAccountingCall( pPcb );
  1261. }
  1262. break;
  1263. default:
  1264. break;
  1265. }
  1266. return( TRUE );
  1267. }
  1268. //**
  1269. //
  1270. // Call: FsmThisLayerDown
  1271. //
  1272. // Returns: TRUE - Success
  1273. // FALSE - Otherwise
  1274. //
  1275. // Description: Called when leaving the OPENED state.
  1276. //
  1277. BOOL
  1278. FsmThisLayerDown(
  1279. IN PCB * pPcb,
  1280. IN DWORD CpIndex
  1281. )
  1282. {
  1283. DWORD dwRetCode;
  1284. DWORD dwIndex;
  1285. LCPCB * pLcpCb;
  1286. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  1287. if ( pCpCb == NULL )
  1288. {
  1289. return( FALSE );
  1290. }
  1291. PppLog( 1, "FsmThisLayerDown called for protocol = %x, port = %d",
  1292. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort );
  1293. if ( CpTable[CpIndex].CpInfo.RasCpThisLayerDown != NULL )
  1294. {
  1295. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpThisLayerDown)(
  1296. pCpCb->pWorkBuf );
  1297. if ( dwRetCode != NO_ERROR )
  1298. {
  1299. PppLog( 1, "FsmThisLayerDown for protocol=%x,port=%d,RetCode=%d",
  1300. CpTable[CpIndex].CpInfo.Protocol,
  1301. pPcb->hPort,
  1302. dwRetCode );
  1303. if ( pCpCb->dwError != NO_ERROR )
  1304. {
  1305. pCpCb->dwError = dwRetCode;
  1306. }
  1307. }
  1308. }
  1309. if ( CpIndex == LCP_INDEX )
  1310. {
  1311. //
  1312. // If this port is not part of a bundle, or it is but is the only
  1313. // remaining link in the bundle, then bring all the NCPs down.
  1314. //
  1315. if ( (!( pPcb->fFlags & PCBFLAG_IS_BUNDLED )) ||
  1316. ( ( pPcb->fFlags & PCBFLAG_IS_BUNDLED ) &&
  1317. ( pPcb->pBcb->dwLinkCount == 1 ) ) )
  1318. {
  1319. //
  1320. // Bring all the NCPs down
  1321. //
  1322. for( dwIndex = LCP_INDEX+1;
  1323. dwIndex < PppConfigInfo.NumberOfCPs;
  1324. dwIndex++ )
  1325. {
  1326. pCpCb = GetPointerToCPCB( pPcb, dwIndex );
  1327. if ( ( NULL != pCpCb )
  1328. && ( pCpCb->fConfigurable ) )
  1329. {
  1330. FsmDown( pPcb, dwIndex );
  1331. }
  1332. }
  1333. }
  1334. pPcb->PppPhase = PPP_LCP;
  1335. pLcpCb = (LCPCB*)(pPcb->LcpCb.pWorkBuf);
  1336. dwIndex = GetCpIndexFromProtocol( pLcpCb->Local.Work.AP );
  1337. if ( dwIndex != (DWORD)-1 )
  1338. {
  1339. ApStop( pPcb, dwIndex, TRUE );
  1340. //
  1341. // Setting this will allow all outstanding request that are
  1342. // completed to be dropped
  1343. //
  1344. pPcb->dwOutstandingAuthRequestId = 0xFFFFFFFF;
  1345. }
  1346. dwIndex = GetCpIndexFromProtocol( pLcpCb->Remote.Work.AP );
  1347. if ( dwIndex != (DWORD)-1 )
  1348. {
  1349. ApStop( pPcb, dwIndex, FALSE );
  1350. }
  1351. dwIndex = GetCpIndexFromProtocol( PPP_CBCP_PROTOCOL );
  1352. if ( dwIndex != (DWORD)-1 )
  1353. {
  1354. CbStop( pPcb, dwIndex );
  1355. }
  1356. }
  1357. else
  1358. {
  1359. pCpCb->NcpPhase = NCP_CONFIGURING;
  1360. }
  1361. return( TRUE );
  1362. }
  1363. //**
  1364. //
  1365. // Call: FsmThisLayerStarted
  1366. //
  1367. // Returns: TRUE - Success
  1368. // FALSE - Otherwise
  1369. //
  1370. // Description: Called when leaving the OPENED state.
  1371. //
  1372. BOOL
  1373. FsmThisLayerStarted(
  1374. IN PCB * pPcb,
  1375. IN DWORD CpIndex
  1376. )
  1377. {
  1378. DWORD dwRetCode;
  1379. CPCB* pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  1380. if ( pCpCb == NULL )
  1381. {
  1382. return( FALSE );
  1383. }
  1384. PppLog( 1, "FsmThisLayerStarted called for protocol = %x, port = %d",
  1385. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort );
  1386. if ( CpTable[CpIndex].CpInfo.RasCpThisLayerStarted != NULL )
  1387. {
  1388. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpThisLayerStarted)(
  1389. pCpCb->pWorkBuf);
  1390. if ( dwRetCode != NO_ERROR )
  1391. {
  1392. pCpCb->dwError = dwRetCode;
  1393. FsmClose( pPcb, CpIndex );
  1394. return( FALSE );
  1395. }
  1396. }
  1397. pCpCb->NcpPhase = NCP_CONFIGURING;
  1398. return( TRUE );
  1399. }
  1400. //**
  1401. //
  1402. // Call: FsmThisLayerFinished
  1403. //
  1404. // Returns: TRUE - Success
  1405. // FALSE - Otherwise
  1406. //
  1407. // Description: Called when leaving the OPENED state.
  1408. //
  1409. BOOL
  1410. FsmThisLayerFinished(
  1411. IN PCB * pPcb,
  1412. IN DWORD CpIndex,
  1413. IN BOOL fCallCp
  1414. )
  1415. {
  1416. DWORD dwRetCode;
  1417. PPP_PROJECTION_RESULT ProjectionResult;
  1418. CPCB * pCpCb = GetPointerToCPCB( pPcb, CpIndex );
  1419. BOOL fAreCPsDone = FALSE;
  1420. if ( pCpCb == NULL )
  1421. {
  1422. return( FALSE );
  1423. }
  1424. PppLog( 1, "FsmThisLayerFinished called for protocol = %x, port = %d",
  1425. CpTable[CpIndex].CpInfo.Protocol, pPcb->hPort );
  1426. if ( ( CpTable[CpIndex].CpInfo.RasCpThisLayerFinished != NULL )
  1427. && ( fCallCp ) )
  1428. {
  1429. dwRetCode = (CpTable[CpIndex].CpInfo.RasCpThisLayerFinished)(
  1430. pCpCb->pWorkBuf);
  1431. if ( dwRetCode != NO_ERROR )
  1432. {
  1433. NotifyCallerOfFailure( pPcb, dwRetCode );
  1434. return( FALSE );
  1435. }
  1436. }
  1437. //
  1438. // Take care of special cases first.
  1439. //
  1440. switch ( CpTable[CpIndex].CpInfo.Protocol )
  1441. {
  1442. case PPP_LCP_PROTOCOL:
  1443. //
  1444. // If we are in the callback phase and LCP went down because of an
  1445. // error.
  1446. //
  1447. //
  1448. // If we LCP layer is finished and we are doing a callback
  1449. //
  1450. if ( pPcb->fFlags & PCBFLAG_DOING_CALLBACK )
  1451. {
  1452. if ( !(pPcb->fFlags & PCBFLAG_IS_SERVER) )
  1453. {
  1454. PppLog( 2, "pPcb->fFlags = %x", pPcb->fFlags ) ;
  1455. NotifyCaller( pPcb, PPPMSG_Callback, NULL );
  1456. //
  1457. // We unset this flag now because if we get another
  1458. // FsmClose, it will call FsmThisLayerFinished (this routine)
  1459. // again, and this time we will need to send a failure
  1460. // message back, not Callback, so that the client can
  1461. // clean up.
  1462. //
  1463. pPcb->fFlags &= ~PCBFLAG_DOING_CALLBACK;
  1464. return( TRUE );
  1465. }
  1466. }
  1467. else
  1468. {
  1469. //
  1470. // If this port is not part of a bundle, or it is but is the only
  1471. // remaining link in the bundle, then call ThisLayerFinished for all
  1472. // NCPs.
  1473. //
  1474. if ( (!( pPcb->fFlags & PCBFLAG_IS_BUNDLED )) ||
  1475. ( ( pPcb->fFlags & PCBFLAG_IS_BUNDLED ) &&
  1476. ( pPcb->pBcb->dwLinkCount == 1 ) ) )
  1477. {
  1478. DWORD dwIndex;
  1479. CPCB * pNcpCb;
  1480. for( dwIndex = LCP_INDEX+1;
  1481. dwIndex < PppConfigInfo.NumberOfCPs;
  1482. dwIndex++ )
  1483. {
  1484. pNcpCb = GetPointerToCPCB( pPcb, dwIndex );
  1485. if ( pNcpCb->fConfigurable )
  1486. {
  1487. if ( NULL !=
  1488. CpTable[dwIndex].CpInfo.RasCpThisLayerFinished )
  1489. {
  1490. dwRetCode =
  1491. (CpTable[dwIndex].CpInfo.RasCpThisLayerFinished)
  1492. (pNcpCb->pWorkBuf);
  1493. PppLog( 1, "FsmThisLayerFinished called for "
  1494. "protocol = %x, port = %d: %d",
  1495. CpTable[dwIndex].CpInfo.Protocol, pPcb->hPort,
  1496. dwRetCode );
  1497. dwRetCode = NO_ERROR;
  1498. }
  1499. }
  1500. }
  1501. }
  1502. pPcb->fFlags |= PCBFLAG_STOPPED_MSG_SENT;
  1503. NotifyCaller( pPcb,
  1504. ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  1505. ? PPPDDMMSG_Stopped
  1506. : PPPMSG_Stopped,
  1507. &(pPcb->LcpCb.dwError) );
  1508. return( FALSE );
  1509. }
  1510. break;
  1511. case PPP_CCP_PROTOCOL:
  1512. //
  1513. // If we need to force encryption but encryption negotiation failed
  1514. // then we drop the link
  1515. //
  1516. if ( pPcb->ConfigInfo.dwConfigMask & (PPPCFG_RequireEncryption |
  1517. PPPCFG_RequireStrongEncryption ) )
  1518. {
  1519. switch( pCpCb->dwError )
  1520. {
  1521. case ERROR_NO_LOCAL_ENCRYPTION:
  1522. case ERROR_NO_REMOTE_ENCRYPTION:
  1523. pPcb->LcpCb.dwError = pCpCb->dwError;
  1524. break;
  1525. case ERROR_PROTOCOL_NOT_CONFIGURED:
  1526. pPcb->LcpCb.dwError = ERROR_NO_LOCAL_ENCRYPTION;
  1527. break;
  1528. default:
  1529. pPcb->LcpCb.dwError = ERROR_NO_REMOTE_ENCRYPTION;
  1530. break;
  1531. }
  1532. //
  1533. // We need to send an Accounting Stop if RADIUS sends
  1534. // an Access Accept but we still drop the line.
  1535. //
  1536. pPcb->fFlags |= PCBFLAG_SERVICE_UNAVAILABLE;
  1537. NotifyCallerOfFailure( pPcb, pPcb->LcpCb.dwError );
  1538. return( FALSE );
  1539. }
  1540. break;
  1541. default:
  1542. break;
  1543. }
  1544. switch( pPcb->PppPhase )
  1545. {
  1546. case PPP_NCP:
  1547. //
  1548. // This NCP failed to be configured. If there are more then
  1549. // try to configure them.
  1550. //
  1551. pCpCb->NcpPhase = NCP_DOWN;
  1552. if ( ( CpTable[CpIndex].CpInfo.Protocol == PPP_NBFCP_PROTOCOL ) ||
  1553. ( CpTable[CpIndex].CpInfo.Protocol == PPP_IPCP_PROTOCOL ) )
  1554. {
  1555. if ( !NotifyIPCPOfNBFCPProjection( pPcb, CpIndex ) )
  1556. {
  1557. return( FALSE );
  1558. }
  1559. }
  1560. //
  1561. // Check to see if we are all done
  1562. //
  1563. dwRetCode = AreNCPsDone(pPcb, CpIndex, &ProjectionResult, &fAreCPsDone);
  1564. //
  1565. // We failed to get information from CP with CpIndex.
  1566. //
  1567. if ( dwRetCode != NO_ERROR )
  1568. {
  1569. return( FALSE );
  1570. }
  1571. if ( fAreCPsDone == TRUE )
  1572. {
  1573. RemoveFromTimerQ( pPcb->dwPortId,
  1574. 0,
  1575. 0,
  1576. FALSE,
  1577. TIMER_EVENT_NEGOTIATETIME );
  1578. //
  1579. // Notify the ras client and the ras server about the projections
  1580. //
  1581. if ( pPcb->fFlags & PCBFLAG_IS_SERVER )
  1582. {
  1583. NotifyCaller( pPcb, PPPDDMMSG_PppDone, &ProjectionResult );
  1584. }
  1585. else
  1586. {
  1587. RASMAN_INFO rasmanInfo;
  1588. NotifyCaller(pPcb, PPPMSG_ProjectionResult, &ProjectionResult);
  1589. NotifyCaller(pPcb, PPPMSG_PppDone, NULL);
  1590. //
  1591. // We call RasSetConnectionUserData in FsmThisLayerUp and
  1592. // FsmThisLayerFinished, in case an NCP is renegotiated. An
  1593. // PPPMSG_ProjectionResult sent after PPPMSG_PppDone is ignored.
  1594. // This is a bad hack. The real fix is to change RasDialMachine
  1595. // such that PPPMSG_ProjectionResult is not ignored.
  1596. //
  1597. //
  1598. // We are commenting out RasSetConnectionUserData to work
  1599. // around bug 375125. A multilink call was made and the two
  1600. // links connected to two different servers. The second link
  1601. // only should go down in this case. However, IPCP failed
  1602. // for the second link, and RasSetConnectionUserData marked
  1603. // IPCP as failed for the first link also. Both links came down.
  1604. //
  1605. #if 0
  1606. if ( RasGetInfo(NULL, pPcb->hPort, &rasmanInfo ) == NO_ERROR )
  1607. {
  1608. RasSetConnectionUserData(
  1609. rasmanInfo.RI_ConnectionHandle,
  1610. 1,
  1611. (PBYTE)&ProjectionResult,
  1612. sizeof( ProjectionResult ) );
  1613. }
  1614. #endif
  1615. }
  1616. StartAutoDisconnectForPort( pPcb );
  1617. StartLCPEchoForPort ( pPcb );
  1618. //
  1619. // If we are bundled, then we need to notify all other bundled ports
  1620. // that PPP on that port is done too.
  1621. //
  1622. if ( pPcb->fFlags & PCBFLAG_IS_BUNDLED )
  1623. {
  1624. NotifyCompletionOnBundledPorts( pPcb );
  1625. }
  1626. MakeStartAccountingCall( pPcb );
  1627. }
  1628. break;
  1629. case PPP_AP:
  1630. default:
  1631. break;
  1632. }
  1633. return( TRUE );
  1634. }