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.

456 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: ras.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 2-09-96 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "msgina.h"
  18. #include <wchar.h>
  19. #include <wincrypt.h>
  20. #include <sclogon.h>
  21. #include <raserror.h>
  22. #define NP_Nbf 0x1
  23. #define NP_Ipx 0x2
  24. #define NP_Ip 0x4
  25. HANDLE hRasApi ;
  26. VOID WINAPI
  27. MyRasCallback(
  28. IN DWORD_PTR dwCallbackId,
  29. IN DWORD dwEventCode,
  30. IN LPWSTR pszEntry,
  31. IN LPVOID pEventArgs )
  32. /* RasPhonebookDlg callback. 'DwCallbackId' is the ID provided in
  33. ** parameters to RasPhonebookDlg. 'DwEventCode' indicates the
  34. ** RASPBDEVENT_* event that has occurred. 'PszEntry' is the name of the
  35. ** entry on which the event occurred. 'PEventArgs' is the event-specific
  36. ** parameter block passed to us during RasPhonebookDlg callback.
  37. */
  38. {
  39. RASNOUSERW* pInfo;
  40. PGLOBALS pGlobals;
  41. DebugLog((DEB_TRACE, "RasCallback: %#x, %#x, %ws, %#x\n",
  42. dwCallbackId, dwEventCode, pszEntry, pEventArgs ));
  43. /* Fill in information about the not yet logged on user.
  44. */
  45. pInfo = (RASNOUSERW* )pEventArgs;
  46. pGlobals = (PGLOBALS) dwCallbackId;
  47. if (dwEventCode == RASPBDEVENT_NoUserEdit)
  48. {
  49. if (pInfo->szUserName[0])
  50. {
  51. wcscpy( pGlobals->UserName, pInfo->szUserName );
  52. }
  53. if (pInfo->szPassword[0])
  54. {
  55. wcscpy( pGlobals->Password, pInfo->szPassword );
  56. RtlInitUnicodeString( &pGlobals->PasswordString, pGlobals->Password );
  57. pGlobals->Seed = 0;
  58. HidePassword( &pGlobals->Seed, &pGlobals->PasswordString );
  59. }
  60. }
  61. else if (dwEventCode == RASPBDEVENT_NoUser)
  62. {
  63. ZeroMemory( pInfo, sizeof( RASNOUSERW ) );
  64. pInfo->dwTimeoutMs = 2 * 60 * 1000;
  65. pInfo->dwSize = sizeof( RASNOUSERW );
  66. wcsncpy( pInfo->szUserName, pGlobals->UserName, UNLEN );
  67. wcsncpy( pInfo->szDomain, pGlobals->Domain, DNLEN );
  68. RevealPassword( &pGlobals->PasswordString );
  69. wcsncpy( pInfo->szPassword, pGlobals->Password, PWLEN );
  70. HidePassword( &pGlobals->Seed, &pGlobals->PasswordString );
  71. }
  72. if( pGlobals->SmartCardLogon
  73. && (NULL != pInfo))
  74. {
  75. pInfo->dwFlags |= RASNOUSER_SmartCard;
  76. }
  77. }
  78. DWORD
  79. GetRasDialOutProtocols(
  80. void )
  81. /* Returns a bit field containing NP_<protocol> flags for the installed
  82. ** PPP protocols. The term "installed" here includes enabling in RAS
  83. ** Setup.
  84. */
  85. {
  86. //
  87. // Since after the connections checkin, RAS is always installed
  88. // and there is no way to uninstall it, all we need to check here
  89. // is if there are protocols installed that can be used by RAS to
  90. // dial out. By default any protocol installed is available for RAS
  91. // to dial out on. This can be overridden from the phonebook entry.
  92. //
  93. static const TCHAR c_szRegKeyIp[] =
  94. TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip");
  95. static const TCHAR c_szRegKeyIpx[] =
  96. TEXT("SYSTEM\\CurrentControlSet\\Services\\NwlnkIpx");
  97. static const TCHAR c_szRegKeyNbf[] =
  98. TEXT("SYSTEM\\CurrentControlSet\\Services\\Nbf");
  99. struct PROTOCOL_INFO
  100. {
  101. DWORD dwFlag;
  102. LPCTSTR pszRegkey;
  103. };
  104. static const struct PROTOCOL_INFO c_aProtocolInfo[] =
  105. {
  106. {
  107. NP_Ip,
  108. c_szRegKeyIp,
  109. },
  110. {
  111. NP_Ipx,
  112. c_szRegKeyIpx,
  113. },
  114. {
  115. NP_Nbf,
  116. c_szRegKeyNbf,
  117. },
  118. };
  119. DWORD dwfInstalledProtocols = 0;
  120. DWORD dwNumProtocols = sizeof(c_aProtocolInfo)/sizeof(c_aProtocolInfo[0]);
  121. DWORD i;
  122. HKEY hkey;
  123. DebugLog(( DEB_TRACE, "GetRasDialOutProtocols...\n" ));
  124. for(i = 0; i < dwNumProtocols; i++)
  125. {
  126. if(0 == RegOpenKey(HKEY_LOCAL_MACHINE,
  127. c_aProtocolInfo[i].pszRegkey,
  128. &hkey))
  129. {
  130. dwfInstalledProtocols |= c_aProtocolInfo[i].dwFlag;
  131. RegCloseKey(hkey);
  132. }
  133. }
  134. DebugLog(( DEB_TRACE, "GetRasDialOutProtocols: dwfInstalledProtocols=0x%x\n",
  135. dwfInstalledProtocols));
  136. return dwfInstalledProtocols;
  137. }
  138. BOOL
  139. PopupRasPhonebookDlg(
  140. IN HWND hwndOwner,
  141. IN PGLOBALS pGlobals,
  142. OUT BOOL* pfTimedOut
  143. )
  144. /* Popup the RAS common phonebook dialog to let user establish connection.
  145. ** 'HwndOwner' is the window to own the RAS dialog or NULL if none. '*PfTimedOut' is
  146. ** set TRUE if the dialog timed out, false otherwise.
  147. **
  148. ** Returns true if user made a connection, false if not, i.e. an error
  149. ** occurred, RAS is not installed or user could not or chose not to
  150. ** connect.
  151. */
  152. {
  153. BOOL fConnected;
  154. RASPBDLG info;
  155. DWORD Protocols;
  156. PUCHAR pvScData = NULL;
  157. struct EAPINFO
  158. {
  159. DWORD dwSizeofEapInfo;
  160. PBYTE pbEapInfo;
  161. DWORD dwSizeofPINInfo;
  162. PBYTE pbPINInfo;
  163. };
  164. struct EAPINFO eapinfo;
  165. struct EAPINFO *pEapInfo = NULL;
  166. *pfTimedOut = FALSE;
  167. Protocols = GetRasDialOutProtocols();
  168. if (Protocols == 0)
  169. {
  170. return( FALSE );
  171. }
  172. if(pGlobals->SmartCardLogon)
  173. {
  174. PULONG pulScData;
  175. struct FLAT_UNICODE_STRING
  176. {
  177. USHORT Length;
  178. USHORT MaximumLength;
  179. BYTE abdata[1];
  180. };
  181. struct FLAT_UNICODE_STRING *pFlatUnicodeString;
  182. PWLX_SC_NOTIFICATION_INFO ScInfo = NULL ;
  183. //
  184. // Get the set of strings indicating the reader and CSP
  185. // to be used for the smart card. We will pass this info
  186. // down to RAS.
  187. //
  188. pWlxFuncs->WlxGetOption( pGlobals->hGlobalWlx,
  189. WLX_OPTION_SMART_CARD_INFO,
  190. (ULONG_PTR *) &ScInfo);
  191. if ( !ScInfo )
  192. {
  193. return FALSE;
  194. }
  195. //
  196. // Validate the SC info against some common user
  197. // errors
  198. //
  199. if ( ( ScInfo->pszReader ) &&
  200. ( ScInfo->pszCard == NULL ) )
  201. {
  202. //
  203. // The card could not be read. Might not be
  204. // inserted correctly.
  205. //
  206. LocalFree(ScInfo);
  207. return FALSE;
  208. }
  209. if ( ( ScInfo->pszReader ) &&
  210. ( ScInfo->pszCryptoProvider == NULL ) )
  211. {
  212. //
  213. // Got a card, but the CSP for it could not be
  214. // found.
  215. //
  216. LocalFree(ScInfo);
  217. return FALSE;
  218. }
  219. pvScData = ScBuildLogonInfo(ScInfo->pszCard,
  220. ScInfo->pszReader,
  221. ScInfo->pszContainer,
  222. ScInfo->pszCryptoProvider );
  223. LocalFree(ScInfo);
  224. if ( ! pvScData )
  225. {
  226. return FALSE ;
  227. }
  228. pulScData = (PULONG) pvScData;
  229. ZeroMemory(&eapinfo, sizeof(struct EAPINFO));
  230. eapinfo.dwSizeofEapInfo = *pulScData;
  231. eapinfo.pbEapInfo = (BYTE *) pvScData;
  232. eapinfo.dwSizeofPINInfo = sizeof(UNICODE_STRING) +
  233. (sizeof(TCHAR) *
  234. (1 + lstrlen(pGlobals->PasswordString.Buffer)));
  235. //
  236. // Flatten out the unicode string.
  237. //
  238. pFlatUnicodeString = LocalAlloc(LPTR, eapinfo.dwSizeofPINInfo);
  239. if(NULL == pFlatUnicodeString)
  240. {
  241. if(NULL != pvScData)
  242. {
  243. LocalFree(pvScData);
  244. }
  245. return (FALSE);
  246. }
  247. pFlatUnicodeString->Length = pGlobals->PasswordString.Length;
  248. pFlatUnicodeString->MaximumLength = pGlobals->PasswordString.MaximumLength;
  249. lstrcpy((LPTSTR) pFlatUnicodeString->abdata,
  250. (LPTSTR) pGlobals->PasswordString.Buffer);
  251. eapinfo.pbPINInfo = (BYTE *) pFlatUnicodeString;
  252. pEapInfo = &eapinfo;
  253. }
  254. ZeroMemory( &info, sizeof(info) );
  255. info.dwSize = sizeof(info);
  256. info.hwndOwner = hwndOwner;
  257. info.dwFlags = RASPBDFLAG_NoUser;
  258. info.pCallback = MyRasCallback;
  259. info.dwCallbackId = (ULONG_PTR) pGlobals;
  260. info.reserved2 = (ULONG_PTR) pEapInfo;
  261. fConnected = RasPhonebookDlg( NULL, NULL, &info );
  262. if (info.dwError == STATUS_TIMEOUT)
  263. *pfTimedOut = TRUE;
  264. if( (pEapInfo)
  265. && (pEapInfo->pbPINInfo))
  266. {
  267. LocalFree(pEapInfo->pbPINInfo);
  268. }
  269. if(NULL != pvScData)
  270. {
  271. LocalFree(pvScData);
  272. }
  273. return fConnected;
  274. }
  275. BOOL
  276. IsRASServiceRunning()
  277. {
  278. BOOL bRet = FALSE; // assume the service is not running
  279. SC_HANDLE hServiceMgr;
  280. hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
  281. if (hServiceMgr != NULL)
  282. {
  283. SC_HANDLE hService = OpenService(hServiceMgr, TEXT("RASMAN"), SERVICE_QUERY_STATUS);
  284. if (hService != NULL)
  285. {
  286. SERVICE_STATUS status;
  287. if (QueryServiceStatus(hService, &status) &&
  288. (status.dwCurrentState == SERVICE_RUNNING))
  289. {
  290. // the RAS service is running
  291. bRet = TRUE;
  292. }
  293. CloseServiceHandle(hService);
  294. }
  295. CloseServiceHandle(hServiceMgr);
  296. }
  297. return bRet;
  298. }
  299. // we need to treat RAS connections made by the system luid as created by the user.
  300. // this allows us to "do the right thing" when a connection is made from the C-A-D dialog
  301. // before any user is logged in
  302. __inline BOOL IsEqualOrSystemLuid(PLUID pLuid, PLUID pUserLuid)
  303. {
  304. BOOL bRet = FALSE;
  305. static LUID luidSystem = SYSTEM_LUID;
  306. if (RtlEqualLuid(pLuid, pUserLuid) || RtlEqualLuid(pLuid, &luidSystem))
  307. {
  308. // return true if pLuid matches the users luid or the system luid
  309. bRet = TRUE;
  310. }
  311. return bRet;
  312. }
  313. BOOL
  314. HangupRasConnections(
  315. PGLOBALS pGlobals
  316. )
  317. {
  318. DWORD dwError;
  319. RASCONN rasconn;
  320. RASCONN* prc;
  321. DWORD cbSize;
  322. DWORD cConnections;
  323. HLOCAL pBuffToFree = NULL;
  324. if (!IsRASServiceRunning())
  325. {
  326. return TRUE;
  327. }
  328. prc = &rasconn;
  329. prc->dwSize = sizeof(RASCONN);
  330. cbSize = sizeof(RASCONN);
  331. dwError = RasEnumConnections(prc, &cbSize, &cConnections);
  332. if (dwError == ERROR_BUFFER_TOO_SMALL)
  333. {
  334. pBuffToFree = LocalAlloc(LPTR, cbSize);
  335. prc = (RASCONN*)pBuffToFree;
  336. if (prc)
  337. {
  338. prc->dwSize = sizeof(RASCONN);
  339. dwError = RasEnumConnections(prc, &cbSize, &cConnections);
  340. }
  341. }
  342. if (dwError == ERROR_SUCCESS)
  343. {
  344. UINT i;
  345. for (i = 0; i < cConnections; i++)
  346. {
  347. if (IsEqualOrSystemLuid(&prc[i].luid, &pGlobals->LogonId))
  348. {
  349. RasHangUp(prc[i].hrasconn);
  350. }
  351. }
  352. }
  353. if (pBuffToFree)
  354. {
  355. LocalFree(pBuffToFree);
  356. }
  357. return (dwError == ERROR_SUCCESS);
  358. }