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.

664 lines
17 KiB

  1. /*
  2. Copyright (c) 1997, Microsoft Corporation, all rights reserved
  3. Description:
  4. History:
  5. */
  6. #include <nt.h> // Required by windows.h
  7. #include <ntrtl.h> // Required by windows.h
  8. #include <nturtl.h> // Required by windows.h
  9. #include <windows.h> // Win32 base API's
  10. #include <schannel.h>
  11. #define SECURITY_WIN32
  12. #include <sspi.h> // For CredHandle
  13. #include <wincrypt.h> // Required by sclogon.h
  14. #include <eaptypeid.h>
  15. #include <rasauth.h> // Required by raseapif.h
  16. #include <eaptypeid.h>
  17. #include <raseapif.h>
  18. #include <rasman.h> // For EAPLOGONINFO
  19. #include "eaptls.h"
  20. #include "ceapcfg.h"
  21. extern "C"
  22. DWORD
  23. InvokeServerConfigUI(
  24. IN HWND hWnd,
  25. IN WCHAR* pwszMachineName,
  26. IN BOOL fConfigInRegistry,
  27. IN const BYTE* pConfigDataIn,
  28. IN DWORD dwSizeofConfigDataIn,
  29. OUT PBYTE* ppConfigDataOut,
  30. OUT DWORD* pdwSizeofConfigDataOut
  31. );
  32. extern "C"
  33. DWORD
  34. DwGetGlobalConfig(
  35. IN DWORD dwEapTypeId,
  36. OUT PBYTE* ppbData,
  37. OUT DWORD* pdwData);
  38. extern "C"
  39. DWORD
  40. WINAPI PeapInvokeServerConfigUI(
  41. IN HWND hWnd,
  42. IN WCHAR* pwszMachineName,
  43. IN BOOL fConfigInRegistry,
  44. IN const BYTE* pConfigDataIn,
  45. IN DWORD pdwSizeofConfigDataIn,
  46. OUT PBYTE* ppConfigDataOut,
  47. OUT DWORD* pdwConfigDataOut
  48. );
  49. extern "C"
  50. DWORD
  51. EapTlsInvokeIdentityUI(
  52. IN BOOL fServer,
  53. IN BOOL fRouterConfig,
  54. IN DWORD dwFlags,
  55. IN WCHAR* pszStoreName,
  56. IN const WCHAR* pwszPhonebook,
  57. IN const WCHAR* pwszEntry,
  58. IN HWND hwndParent,
  59. IN BYTE* pConnectionDataIn,
  60. IN DWORD dwSizeOfConnectionDataIn,
  61. IN BYTE* pUserDataIn,
  62. IN DWORD dwSizeOfUserDataIn,
  63. OUT BYTE** ppUserDataOut,
  64. OUT DWORD* pdwSizeOfUserDataOut,
  65. OUT WCHAR** ppwszIdentity
  66. );
  67. extern "C"
  68. DWORD
  69. RasEapInvokeConfigUI(
  70. IN DWORD dwEapTypeId,
  71. IN HWND hwndParent,
  72. IN DWORD dwFlags,
  73. IN BYTE* pConnectionDataIn,
  74. IN DWORD dwSizeOfConnectionDataIn,
  75. OUT BYTE** ppConnectionDataOut,
  76. OUT DWORD* pdwSizeOfConnectionDataOut
  77. );
  78. extern "C"
  79. DWORD
  80. RasEapFreeMemory(
  81. IN BYTE* pMemory
  82. );
  83. /*
  84. Returns:
  85. Notes:
  86. Implementation of IEAPProviderConfig::Initialize
  87. */
  88. STDMETHODIMP
  89. CEapCfg::Initialize(
  90. LPCOLESTR pwszMachineName,
  91. DWORD dwEapTypeId,
  92. ULONG_PTR* puConnectionParam
  93. )
  94. {
  95. size_t size;
  96. WCHAR* pwsz = NULL;
  97. DWORD dwErr = NO_ERROR;
  98. *puConnectionParam = NULL;
  99. if (dwEapTypeId != PPP_EAP_TLS && dwEapTypeId != PPP_EAP_PEAP)
  100. {
  101. dwErr = ERROR_NOT_SUPPORTED;
  102. goto LDone;
  103. }
  104. size = wcslen(pwszMachineName);
  105. pwsz = (WCHAR*) LocalAlloc(LPTR, (size + 1)*sizeof(WCHAR));
  106. if (NULL == pwsz)
  107. {
  108. dwErr = GetLastError();
  109. goto LDone;
  110. }
  111. CopyMemory(pwsz, pwszMachineName, (size + 1)*sizeof(WCHAR));
  112. *puConnectionParam = (ULONG_PTR)pwsz;
  113. pwsz = NULL;
  114. LDone:
  115. LocalFree(pwsz);
  116. return(HRESULT_FROM_WIN32(dwErr));
  117. }
  118. /*
  119. Returns:
  120. Notes:
  121. Implementation of IEAPProviderConfig::Uninitialize
  122. */
  123. STDMETHODIMP
  124. CEapCfg::Uninitialize(
  125. DWORD dwEapTypeId,
  126. ULONG_PTR uConnectionParam
  127. )
  128. {
  129. LocalFree((VOID*)uConnectionParam);
  130. return(HRESULT_FROM_WIN32(NO_ERROR));
  131. }
  132. /*
  133. Returns:
  134. Notes:
  135. Implementation of IEAPProviderConfig::ServerInvokeConfigUI
  136. hWnd - handle to the parent window
  137. dwRes1 - reserved parameter (ignore)
  138. dwRes2 - reserved parameter (ignore)
  139. */
  140. STDMETHODIMP
  141. CEapCfg::ServerInvokeConfigUI(
  142. DWORD dwEapTypeId,
  143. ULONG_PTR uConnectionParam,
  144. HWND hWnd,
  145. DWORD_PTR dwRes1,
  146. DWORD_PTR dwRes2
  147. )
  148. {
  149. WCHAR* pwszMachineName;
  150. HRESULT hr;
  151. DWORD dwErr;
  152. if (dwEapTypeId != PPP_EAP_TLS
  153. #ifdef IMPL_PEAP
  154. && dwEapTypeId != PPP_EAP_PEAP
  155. #endif
  156. )
  157. {
  158. dwErr = ERROR_NOT_SUPPORTED;
  159. goto LDone;
  160. }
  161. pwszMachineName = (WCHAR*)uConnectionParam;
  162. if (NULL == pwszMachineName)
  163. {
  164. dwErr = E_FAIL;
  165. }
  166. else
  167. {
  168. if ( dwEapTypeId == PPP_EAP_TLS )
  169. {
  170. dwErr = InvokeServerConfigUI(hWnd, pwszMachineName,
  171. TRUE, NULL, 0,
  172. NULL, NULL);
  173. }
  174. #ifdef IMPL_PEAP
  175. else
  176. {
  177. dwErr = PeapInvokeServerConfigUI(hWnd, pwszMachineName,
  178. TRUE, NULL, 0,
  179. NULL, NULL);
  180. }
  181. #endif
  182. }
  183. LDone:
  184. hr = HRESULT_FROM_WIN32(dwErr);
  185. return(hr);
  186. }
  187. /*
  188. Returns:
  189. Notes:
  190. Implementation of IEAPProviderConfig::RouterInvokeConfigUI
  191. */
  192. STDMETHODIMP
  193. CEapCfg::RouterInvokeConfigUI(
  194. DWORD dwEapTypeId,
  195. ULONG_PTR uConnectionParam,
  196. HWND hwndParent,
  197. DWORD dwFlags,
  198. BYTE* pConnectionDataIn,
  199. DWORD dwSizeOfConnectionDataIn,
  200. BYTE** ppConnectionDataOut,
  201. DWORD* pdwSizeOfConnectionDataOut
  202. )
  203. {
  204. DWORD dwErr = NO_ERROR;
  205. BYTE* pConnectionDataOut = NULL;
  206. DWORD dwSizeOfConnectionDataOut = 0;
  207. *ppConnectionDataOut = NULL;
  208. *pdwSizeOfConnectionDataOut = 0;
  209. if (dwEapTypeId != PPP_EAP_TLS )
  210. {
  211. dwErr = ERROR_NOT_SUPPORTED;
  212. goto LDone;
  213. }
  214. dwErr = RasEapInvokeConfigUI(
  215. dwEapTypeId,
  216. hwndParent,
  217. dwFlags,
  218. pConnectionDataIn,
  219. dwSizeOfConnectionDataIn,
  220. &pConnectionDataOut,
  221. &dwSizeOfConnectionDataOut);
  222. if ( (NO_ERROR == dwErr)
  223. && (0 != dwSizeOfConnectionDataOut))
  224. {
  225. *ppConnectionDataOut = (BYTE*)CoTaskMemAlloc(dwSizeOfConnectionDataOut);
  226. if (NULL == *ppConnectionDataOut)
  227. {
  228. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  229. goto LDone;
  230. }
  231. CopyMemory(*ppConnectionDataOut, pConnectionDataOut,
  232. dwSizeOfConnectionDataOut);
  233. *pdwSizeOfConnectionDataOut = dwSizeOfConnectionDataOut;
  234. }
  235. LDone:
  236. RasEapFreeMemory(pConnectionDataOut);
  237. return(HRESULT_FROM_WIN32(dwErr));
  238. }
  239. /*
  240. Returns:
  241. Notes:
  242. Implementation of IEAPProviderConfig::RouterInvokeCredentialsUI
  243. */
  244. STDMETHODIMP
  245. CEapCfg::RouterInvokeCredentialsUI(
  246. DWORD dwEapTypeId,
  247. ULONG_PTR uConnectionParam,
  248. HWND hwndParent,
  249. DWORD dwFlags,
  250. BYTE* pConnectionDataIn,
  251. DWORD dwSizeOfConnectionDataIn,
  252. BYTE* pUserDataIn,
  253. DWORD dwSizeOfUserDataIn,
  254. BYTE** ppUserDataOut,
  255. DWORD* pdwSizeOfUserDataOut
  256. )
  257. {
  258. #define MAX_STORE_NAME_LENGTH MAX_COMPUTERNAME_LENGTH + 20
  259. WCHAR awszStoreName[MAX_STORE_NAME_LENGTH + 1];
  260. DWORD dwErr;
  261. DWORD dwSizeOfUserDataOut;
  262. BYTE* pUserDataOut = NULL;
  263. WCHAR* pwszIdentityOut = NULL;
  264. WCHAR* pwszMachineName;
  265. BOOL fLocal = FALSE;
  266. *ppUserDataOut = NULL;
  267. *pdwSizeOfUserDataOut = 0;
  268. if (dwEapTypeId != PPP_EAP_TLS )
  269. {
  270. dwErr = ERROR_NOT_SUPPORTED;
  271. goto LDone;
  272. }
  273. pwszMachineName = (WCHAR*)uConnectionParam;
  274. if (0 == *pwszMachineName)
  275. {
  276. fLocal = TRUE;
  277. }
  278. wcscpy(awszStoreName, L"\\\\");
  279. wcsncat(awszStoreName, pwszMachineName, MAX_COMPUTERNAME_LENGTH);
  280. wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY"));
  281. if ( dwEapTypeId == PPP_EAP_TLS )
  282. {
  283. dwErr = EapTlsInvokeIdentityUI(
  284. FALSE /* fServer */,
  285. TRUE /* fRouterConfig */,
  286. dwFlags,
  287. fLocal ? L"MY" : awszStoreName,
  288. L"",
  289. L"",
  290. hwndParent,
  291. pConnectionDataIn,
  292. dwSizeOfConnectionDataIn,
  293. pUserDataIn,
  294. dwSizeOfUserDataIn,
  295. &pUserDataOut,
  296. &dwSizeOfUserDataOut,
  297. &pwszIdentityOut);
  298. if ( (NO_ERROR == dwErr)
  299. && (0 != dwSizeOfUserDataOut))
  300. {
  301. *ppUserDataOut = (BYTE*)CoTaskMemAlloc(dwSizeOfUserDataOut);
  302. if (NULL == *ppUserDataOut)
  303. {
  304. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  305. goto LDone;
  306. }
  307. CopyMemory(*ppUserDataOut, pUserDataOut, dwSizeOfUserDataOut);
  308. *pdwSizeOfUserDataOut = dwSizeOfUserDataOut;
  309. }
  310. }
  311. else
  312. {
  313. //Show PEAP dialog to get identity for router...
  314. }
  315. LDone:
  316. RasEapFreeMemory(pUserDataOut);
  317. RasEapFreeMemory((BYTE*)pwszIdentityOut);
  318. return(HRESULT_FROM_WIN32(dwErr));
  319. }
  320. STDMETHODIMP
  321. CEapCfg::ServerInvokeConfigUI2(
  322. DWORD dwEapTypeId,
  323. ULONG_PTR uConnectionParam,
  324. HWND hWnd,
  325. const BYTE* pConfigDataIn,
  326. DWORD dwSizeOfConfigDataIn,
  327. BYTE** ppConfigDataOut,
  328. DWORD* pdwSizeOfConfigDataOut
  329. )
  330. {
  331. WCHAR *pwszMachineName = (WCHAR *)uConnectionParam;
  332. DWORD dwErr = NO_ERROR;
  333. PBYTE pbConfigDataOut = NULL;
  334. DWORD dwSizeofConfigDataOut;
  335. if( ((PPP_EAP_TLS != dwEapTypeId)
  336. && (PPP_EAP_PEAP != dwEapTypeId))
  337. || (NULL == pwszMachineName)
  338. || (NULL == ppConfigDataOut)
  339. || (NULL == pdwSizeOfConfigDataOut))
  340. {
  341. dwErr = E_INVALIDARG;
  342. goto done;
  343. }
  344. *ppConfigDataOut = NULL;
  345. *pdwSizeOfConfigDataOut = 0;
  346. if(PPP_EAP_TLS == dwEapTypeId)
  347. {
  348. dwErr = InvokeServerConfigUI(
  349. hWnd,
  350. pwszMachineName,
  351. FALSE,
  352. pConfigDataIn,
  353. dwSizeOfConfigDataIn,
  354. &pbConfigDataOut,
  355. &dwSizeofConfigDataOut);
  356. }
  357. else
  358. {
  359. dwErr = PeapInvokeServerConfigUI(
  360. hWnd,
  361. pwszMachineName,
  362. FALSE,
  363. pConfigDataIn,
  364. dwSizeOfConfigDataIn,
  365. &pbConfigDataOut,
  366. &dwSizeofConfigDataOut);
  367. }
  368. if( (NO_ERROR != dwErr)
  369. || (NULL == pbConfigDataOut)
  370. || (0 == dwSizeofConfigDataOut))
  371. {
  372. goto done;
  373. }
  374. *ppConfigDataOut = (BYTE *)CoTaskMemAlloc(dwSizeofConfigDataOut);
  375. if(NULL == *ppConfigDataOut)
  376. {
  377. dwErr = E_INVALIDARG;
  378. goto done;
  379. }
  380. CopyMemory(*ppConfigDataOut, pbConfigDataOut, dwSizeofConfigDataOut);
  381. *pdwSizeOfConfigDataOut = dwSizeofConfigDataOut;
  382. done:
  383. if(NULL != pbConfigDataOut)
  384. {
  385. RtlSecureZeroMemory(pbConfigDataOut, dwSizeofConfigDataOut);
  386. RasEapFreeMemory(pbConfigDataOut);
  387. }
  388. return HRESULT_FROM_WIN32(dwErr);
  389. }
  390. STDMETHODIMP
  391. CEapCfg::GetGlobalConfig(
  392. DWORD dwEapTypeId,
  393. BYTE** ppConfigDataOut,
  394. DWORD* pdwSizeofConfigDataOut
  395. )
  396. {
  397. DWORD dwErr = NO_ERROR;
  398. DWORD dwSize = 0;
  399. PBYTE pbData = NULL;
  400. if( ((PPP_EAP_TLS != dwEapTypeId)
  401. && (PPP_EAP_PEAP != dwEapTypeId))
  402. || (NULL == ppConfigDataOut)
  403. || (NULL == pdwSizeofConfigDataOut))
  404. {
  405. dwErr = E_INVALIDARG;
  406. goto done;
  407. }
  408. *ppConfigDataOut = NULL;
  409. *pdwSizeofConfigDataOut = 0;
  410. dwErr = DwGetGlobalConfig(dwEapTypeId,
  411. &pbData,
  412. &dwSize);
  413. if(NO_ERROR != dwErr)
  414. {
  415. goto done;
  416. }
  417. *ppConfigDataOut = (BYTE *) CoTaskMemAlloc(dwSize);
  418. if(NULL == *ppConfigDataOut)
  419. {
  420. dwErr = E_OUTOFMEMORY;
  421. goto done;
  422. }
  423. CopyMemory(*ppConfigDataOut, pbData, dwSize);
  424. *pdwSizeofConfigDataOut = dwSize;
  425. done:
  426. if(NULL != pbData)
  427. {
  428. RtlSecureZeroMemory(pbData, dwSize);
  429. LocalFree(pbData);
  430. }
  431. return HRESULT_FROM_WIN32(dwErr);
  432. }
  433. extern "C"
  434. {
  435. //utility function kept here so that we dont have to get the COM junk in other files
  436. DWORD PeapEapInfoInvokeServerConfigUI (
  437. HWND hWndParent,
  438. LPWSTR lpwszMachineName,
  439. PPEAP_EAP_INFO pEapInfo,
  440. const BYTE* pbConfigDataIn,
  441. DWORD dwSizeOfConfigDataIn,
  442. PBYTE* ppbConfigDataOut,
  443. DWORD* pdwSizeOfConfigDataOut
  444. )
  445. {
  446. DWORD dwRetCode = NO_ERROR;
  447. GUID guid;
  448. HRESULT hr = S_OK;
  449. ULONG_PTR uConnection = 0;
  450. CComPtr<IEAPProviderConfig> spEAPConfig;
  451. CComPtr<IEAPProviderConfig2> spEAPConfig2;
  452. if ( NULL == ppbConfigDataOut ||
  453. NULL == pdwSizeOfConfigDataOut
  454. )
  455. {
  456. hr = E_INVALIDARG;
  457. goto L_ERR;
  458. }
  459. hr = CLSIDFromString(pEapInfo->lpwszConfigClsId, &guid);
  460. if (FAILED(hr)) goto L_ERR;
  461. //
  462. // First try and see if the eap supports IEAPProviderConfig2
  463. // interface. If this fails, try IEAPProviderConfig interface.
  464. //
  465. hr = CoCreateInstance(
  466. guid,
  467. NULL,
  468. CLSCTX_INPROC_SERVER,
  469. __uuidof(IEAPProviderConfig2),
  470. (LPVOID *)&spEAPConfig2);
  471. if(FAILED(hr))
  472. {
  473. // Create the EAP provider object
  474. // ----------------------------------------------------------------
  475. hr = CoCreateInstance( guid,
  476. NULL,
  477. CLSCTX_INPROC_SERVER,
  478. __uuidof(IEAPProviderConfig),
  479. (LPVOID *) &spEAPConfig);
  480. if (FAILED(hr )) goto L_ERR;
  481. // Configure this EAP provider
  482. // ----------------------------------------------------------------
  483. // EAP configure displays its own error message, so no hr is kept
  484. if ( !FAILED(spEAPConfig->Initialize(lpwszMachineName,
  485. pEapInfo->dwTypeId, &uConnection)))
  486. {
  487. spEAPConfig->ServerInvokeConfigUI(pEapInfo->dwTypeId,
  488. uConnection, hWndParent, 0, 0);
  489. spEAPConfig->Uninitialize(pEapInfo->dwTypeId,
  490. uConnection);
  491. }
  492. if ( hr == E_NOTIMPL )
  493. hr = S_OK;
  494. }
  495. else
  496. {
  497. if(!FAILED(spEAPConfig2->Initialize(lpwszMachineName,
  498. pEapInfo->dwTypeId,
  499. &uConnection)))
  500. {
  501. PBYTE pbConfigDataOut = NULL;
  502. DWORD dwSizeOfConfigDataOut = 0;
  503. if(!FAILED(spEAPConfig2->ServerInvokeConfigUI2(
  504. pEapInfo->dwTypeId,
  505. uConnection,
  506. hWndParent,
  507. pbConfigDataIn,
  508. dwSizeOfConfigDataIn,
  509. &pbConfigDataOut,
  510. &dwSizeOfConfigDataOut)))
  511. {
  512. if( (NULL == pbConfigDataOut)
  513. || (0 == dwSizeOfConfigDataOut))
  514. {
  515. //
  516. // we are done
  517. //
  518. goto L_ERR;
  519. }
  520. //
  521. // Copy over the data
  522. //
  523. *ppbConfigDataOut = (BYTE *) LocalAlloc(LPTR, dwSizeOfConfigDataOut);
  524. if(NULL == *ppbConfigDataOut)
  525. {
  526. CoTaskMemFree(pbConfigDataOut);
  527. dwRetCode = E_OUTOFMEMORY;
  528. }
  529. CopyMemory(*ppbConfigDataOut,
  530. pbConfigDataOut,
  531. dwSizeOfConfigDataOut);
  532. *pdwSizeOfConfigDataOut = dwSizeOfConfigDataOut;
  533. CoTaskMemFree(pbConfigDataOut);
  534. }
  535. spEAPConfig2->Uninitialize(pEapInfo->dwTypeId,
  536. uConnection);
  537. }
  538. }
  539. L_ERR:
  540. if ( FAILED(hr) )
  541. {
  542. dwRetCode = hr;
  543. }
  544. return dwRetCode;
  545. }
  546. }