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.

663 lines
14 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 2001
  6. //
  7. // File: certreqd.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <windows.h>
  11. #include <stdio.h>
  12. #include <certsrv.h>
  13. #include <certreqd.h>
  14. #include <locale.h>
  15. #include <io.h>
  16. #include <fcntl.h>
  17. EXTERN_C const CLSID CLSID_CCertRequestD;
  18. #define WM_DOCERTREQDMAIN WM_USER+0
  19. WCHAR const wszAppName[] = L"CertReqDApp";
  20. WCHAR const *g_pwszProg = L"CertReqD";
  21. HINSTANCE g_hInstance;
  22. #define cmdNONE MAXDWORD
  23. #define cmdPING 0
  24. #define _PrintIfError(hr, pszFunc) \
  25. if (S_OK != (hr)) wprintf(L"certreqd.cpp(%u): %hs: 0x%x\n", __LINE__, (pszFunc), (hr))
  26. HRESULT
  27. OpenDComConnection(
  28. IN WCHAR const *pwszConfig,
  29. IN CLSID const *pclsid,
  30. IN IID const *piid,
  31. OUT WCHAR const **ppwszAuthority,
  32. OUT IUnknown **ppUnknown)
  33. {
  34. HRESULT hr;
  35. WCHAR *pwsz;
  36. WCHAR *pwszServerName = NULL;
  37. DWORD cwc;
  38. COSERVERINFO ComponentInfo;
  39. MULTI_QI mq;
  40. WCHAR *pwcDot = NULL;
  41. mq.pItf = NULL;
  42. if (NULL == pwszConfig ||
  43. NULL == pclsid ||
  44. NULL == piid ||
  45. NULL == ppwszAuthority ||
  46. NULL == ppUnknown)
  47. {
  48. hr = E_POINTER;
  49. _PrintIfError(hr, "NULL parm");
  50. goto error;
  51. }
  52. *ppwszAuthority = NULL;
  53. *ppUnknown = NULL;
  54. // Allow UNC-style config strings: \\server\CaName
  55. while (L'\\' == *pwszConfig)
  56. {
  57. pwszConfig++;
  58. }
  59. pwsz = wcschr(pwszConfig, L'\\');
  60. if (NULL == pwsz)
  61. {
  62. cwc = wcslen(pwszConfig);
  63. *ppwszAuthority = &pwszConfig[cwc];
  64. }
  65. else
  66. {
  67. cwc = (DWORD) (ULONG_PTR) (pwsz - pwszConfig);
  68. *ppwszAuthority = &pwsz[1];
  69. }
  70. pwszServerName = (WCHAR *) LocalAlloc(
  71. LMEM_FIXED,
  72. (cwc + 1) * sizeof(WCHAR));
  73. if (NULL == pwszServerName)
  74. {
  75. hr = E_OUTOFMEMORY;
  76. _PrintIfError(hr, "LocalAlloc");
  77. goto error;
  78. }
  79. CopyMemory(pwszServerName, pwszConfig, cwc * sizeof(WCHAR));
  80. pwszServerName[cwc] = L'\0';
  81. if (0 < cwc && L'.' == pwszServerName[cwc - 1])
  82. {
  83. pwszServerName[cwc - 1] = L'\0';
  84. cwc--;
  85. }
  86. ZeroMemory(&ComponentInfo, sizeof(COSERVERINFO));
  87. ComponentInfo.pwszName = pwszServerName;
  88. //ComponentInfo.pAuthInfo = NULL;
  89. mq.pIID = piid;
  90. mq.pItf = NULL;
  91. mq.hr = S_OK;
  92. while (TRUE)
  93. {
  94. hr = CoCreateInstanceEx(
  95. *pclsid,
  96. NULL,
  97. CLSCTX_SERVER,
  98. &ComponentInfo,
  99. 1,
  100. &mq);
  101. _PrintIfError(hr, "CoCreateInstanceEx");
  102. if (HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) == hr &&
  103. 0 < cwc &&
  104. L'.' == pwszServerName[cwc - 1])
  105. {
  106. pwcDot = &pwszServerName[cwc - 1];
  107. *pwcDot = L'\0';
  108. continue;
  109. }
  110. break;
  111. }
  112. if (NULL != pwcDot)
  113. {
  114. *pwcDot = L'.';
  115. }
  116. _PrintIfError(hr, "CoCreateInstanceEx");
  117. if (S_OK != hr)
  118. {
  119. goto error;
  120. }
  121. hr = CoSetProxyBlanket(
  122. mq.pItf,
  123. RPC_C_AUTHN_DEFAULT, // use NT default security
  124. RPC_C_AUTHZ_DEFAULT, // use NT default authentication
  125. COLE_DEFAULT_PRINCIPAL,
  126. RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, // call
  127. RPC_C_IMP_LEVEL_IMPERSONATE,
  128. NULL,
  129. EOAC_STATIC_CLOAKING);
  130. _PrintIfError(hr, "CoSetProxyBlanket");
  131. if (S_OK != hr)
  132. {
  133. goto error;
  134. }
  135. *ppUnknown = mq.pItf;
  136. mq.pItf = NULL;
  137. hr = S_OK;
  138. error:
  139. if (NULL != pwszServerName)
  140. {
  141. LocalFree(pwszServerName);
  142. }
  143. if (NULL != mq.pItf)
  144. {
  145. mq.pItf->Release();
  146. }
  147. return(hr);
  148. }
  149. HRESULT
  150. OpenRequestDComConnection(
  151. IN WCHAR const *pwszConfig,
  152. OUT WCHAR const **ppwszAuthority,
  153. OUT ICertRequestD2 **ppICertRequestD)
  154. {
  155. HRESULT hr;
  156. hr = OpenDComConnection(
  157. pwszConfig,
  158. &CLSID_CCertRequestD,
  159. &IID_ICertRequestD2,
  160. ppwszAuthority,
  161. (IUnknown **) ppICertRequestD);
  162. _PrintIfError(hr, "OpenDComConnection");
  163. //error:
  164. return(hr);
  165. }
  166. HRESULT
  167. PingCA(
  168. IN WCHAR const *pwszConfig)
  169. {
  170. HRESULT hr;
  171. WCHAR const *pwszAuthority;
  172. ICertRequestD2 *pICertRequestD = NULL;
  173. CERTTRANSBLOB ctbCAAuthName;
  174. CERTTRANSBLOB ctbCADNS;
  175. CERTTRANSBLOB ctbCAInfo;
  176. CAINFO CAInfo;
  177. DWORD cb;
  178. ctbCAAuthName.pb = NULL;
  179. ctbCADNS.pb = NULL;
  180. ctbCAInfo.pb = NULL;
  181. hr = OpenRequestDComConnection(pwszConfig, &pwszAuthority, &pICertRequestD);
  182. _PrintIfError(hr, "OpenRequestDComConnection");
  183. if (S_OK != hr)
  184. {
  185. goto error;
  186. }
  187. __try
  188. {
  189. hr = pICertRequestD->Ping(pwszAuthority);
  190. }
  191. __except(
  192. hr = (GetExceptionInformation())->ExceptionRecord->ExceptionCode,
  193. EXCEPTION_EXECUTE_HANDLER)
  194. {
  195. }
  196. _PrintIfError(hr, "Ping");
  197. if (S_OK != hr)
  198. {
  199. goto error;
  200. }
  201. wprintf(L"CA is responding\n");
  202. __try
  203. {
  204. hr = pICertRequestD->GetCAProperty(
  205. pwszAuthority,
  206. CR_PROP_CANAME,
  207. 0, // PropIndex
  208. PROPTYPE_STRING,
  209. &ctbCAAuthName);
  210. }
  211. __except(
  212. hr = (GetExceptionInformation())->ExceptionRecord->ExceptionCode,
  213. EXCEPTION_EXECUTE_HANDLER)
  214. {
  215. }
  216. _PrintIfError(hr, "GetCAProperty");
  217. if (S_OK != hr)
  218. {
  219. goto error;
  220. }
  221. pwszAuthority = (WCHAR const *) ctbCAAuthName.pb;
  222. wprintf(L"CA name = %ws\n", pwszAuthority);
  223. __try
  224. {
  225. hr = pICertRequestD->GetCAProperty(
  226. pwszAuthority,
  227. CR_PROP_DNSNAME,
  228. 0, // PropIndex
  229. PROPTYPE_STRING,
  230. &ctbCADNS);
  231. }
  232. __except(
  233. hr = (GetExceptionInformation())->ExceptionRecord->ExceptionCode,
  234. EXCEPTION_EXECUTE_HANDLER)
  235. {
  236. }
  237. _PrintIfError(hr, "GetCAProperty");
  238. if (S_OK != hr)
  239. {
  240. goto error;
  241. }
  242. wprintf(L"DNS name = %ws\n", (WCHAR const *) ctbCADNS.pb);
  243. __try
  244. {
  245. hr = pICertRequestD->GetCAProperty(
  246. pwszAuthority,
  247. CR_PROP_CATYPE,
  248. 0, // PropIndex
  249. PROPTYPE_LONG,
  250. &ctbCAInfo);
  251. }
  252. __except(
  253. hr = (GetExceptionInformation())->ExceptionRecord->ExceptionCode,
  254. EXCEPTION_EXECUTE_HANDLER)
  255. {
  256. }
  257. _PrintIfError(hr, "GetCAProperty");
  258. if (S_OK != hr)
  259. {
  260. goto error;
  261. }
  262. wprintf(L"Fetched CAInfo\n");
  263. ZeroMemory(&CAInfo, sizeof(CAInfo));
  264. cb = sizeof(CAInfo);
  265. if (cb > ctbCAInfo.cb)
  266. {
  267. cb = ctbCAInfo.cb;
  268. }
  269. CopyMemory(&CAInfo, ctbCAInfo.pb, cb);
  270. wprintf(L"CAType = %u\n", CAInfo.CAType);
  271. wprintf(L"cCASignatureCerts = %u\n", CAInfo.cCASignatureCerts);
  272. wprintf(L"cCAExchangeCerts = %u\n", CAInfo.cCAExchangeCerts);
  273. wprintf(L"cExitModules = %u\n", CAInfo.cExitModules);
  274. wprintf(L"lPropIdMax = %u\n", CAInfo.lPropIdMax);
  275. wprintf(L"lRoleSeparationEnabled = %u\n", CAInfo.lRoleSeparationEnabled);
  276. wprintf(L"cKRACertUsedCount = %u\n", CAInfo.cKRACertUsedCount);
  277. wprintf(L"cKRACertCount = %u\n", CAInfo.cKRACertCount);
  278. wprintf(L"fAdvancedServer = %u\n", CAInfo.fAdvancedServer);
  279. hr = S_OK;
  280. error:
  281. if (NULL != ctbCAAuthName.pb)
  282. {
  283. CoTaskMemFree(ctbCAAuthName.pb);
  284. }
  285. if (NULL != ctbCADNS.pb)
  286. {
  287. CoTaskMemFree(ctbCADNS.pb);
  288. }
  289. if (NULL != ctbCAInfo.pb)
  290. {
  291. CoTaskMemFree(ctbCAInfo.pb);
  292. }
  293. if (NULL != pICertRequestD)
  294. {
  295. pICertRequestD->Release();
  296. }
  297. return(hr);
  298. }
  299. HRESULT
  300. PrintErrorMessageText(
  301. IN HRESULT hrMsg)
  302. {
  303. HRESULT hr;
  304. ICertRequest2 *pReq = NULL;
  305. BSTR strError = NULL;
  306. hr = CoCreateInstance(
  307. CLSID_CCertRequest,
  308. NULL, // pUnkOuter
  309. CLSCTX_INPROC_SERVER,
  310. IID_ICertRequest2,
  311. (VOID **) &pReq);
  312. _PrintIfError(hr, "CoCreateInstance");
  313. if (S_OK != hr)
  314. {
  315. goto error;
  316. }
  317. hr = pReq->GetErrorMessageText(
  318. hrMsg,
  319. S_OK == hr? 0 : CR_GEMT_HRESULT_STRING,
  320. &strError);
  321. _PrintIfError(hr, "GetErrorMessageText");
  322. if (S_OK == hr)
  323. {
  324. wprintf(L"%ws: %ws\n", g_pwszProg, strError);
  325. }
  326. error:
  327. if (NULL != strError)
  328. {
  329. SysFreeString(strError);
  330. }
  331. if (NULL != pReq)
  332. {
  333. pReq->Release();
  334. }
  335. return(hr);
  336. }
  337. HRESULT
  338. ArgvMain(
  339. int argc,
  340. WCHAR *argv[],
  341. HWND hWndOwner)
  342. {
  343. HRESULT hr;
  344. DWORD cmd = cmdNONE;
  345. DWORD cArgAllowed = 0;
  346. while (1 < argc &&
  347. (L'-' == argv[1][0] || L'/' == argv[1][0]) &&
  348. L'\0' != argv[1][1])
  349. {
  350. if (0 == _wcsicmp(&argv[1][1], L"ping"))
  351. {
  352. cmd = cmdPING;
  353. cArgAllowed = 1;
  354. }
  355. else
  356. {
  357. //Usage(NULL);
  358. hr = E_INVALIDARG;
  359. _PrintIfError(hr, "bad command");
  360. goto error;
  361. }
  362. argc--;
  363. argv++;
  364. }
  365. if (argc != cArgAllowed + 1)
  366. {
  367. hr = E_INVALIDARG;
  368. _PrintIfError(hr, "arg count");
  369. goto error;
  370. }
  371. switch (cmd)
  372. {
  373. case cmdPING:
  374. hr = PingCA(argv[1]);
  375. _PrintIfError(hr, "PingCA");
  376. break;
  377. default:
  378. hr = E_INVALIDARG;
  379. _PrintIfError(hr, "missing command");
  380. break;
  381. }
  382. error:
  383. return(hr);
  384. }
  385. //**************************************************************************
  386. // FUNCTION: CertReqDPreMain
  387. // NOTES: Takes an LPSTR command line and chews it up into argc/argv form
  388. // so that it can be passed on to a traditional C style main.
  389. //**************************************************************************
  390. #define ISBLANK(wc) (L' ' == (wc) || L'\t' == (wc))
  391. HRESULT
  392. CertReqDPreMain(
  393. IN WCHAR const *pwszCmdLine,
  394. IN HWND hWndOwner)
  395. {
  396. HRESULT hr;
  397. BOOL fCoInit = FALSE;
  398. WCHAR *pbuf = NULL;
  399. WCHAR *apszArg[20];
  400. int cArg = 0;
  401. WCHAR *p;
  402. WCHAR const *pchQuote;
  403. int carg;
  404. hr = CoInitialize(NULL);
  405. if (S_OK != hr && S_FALSE != hr)
  406. {
  407. _PrintIfError(hr, "CoInitialize");
  408. goto error;
  409. }
  410. fCoInit = TRUE;
  411. pbuf = (WCHAR *) LocalAlloc(
  412. LMEM_FIXED,
  413. (wcslen(pwszCmdLine) + 1) * sizeof(WCHAR));
  414. if (NULL == pbuf)
  415. {
  416. hr = E_OUTOFMEMORY;
  417. _PrintIfError(hr, "LocalAlloc");
  418. goto error;
  419. }
  420. p = pbuf;
  421. apszArg[cArg++] = TEXT("CertReqD");
  422. while (*pwszCmdLine != TEXT('\0'))
  423. {
  424. while (ISBLANK(*pwszCmdLine))
  425. {
  426. pwszCmdLine++;
  427. }
  428. if (*pwszCmdLine != TEXT('\0'))
  429. {
  430. apszArg[cArg++] = p;
  431. if (sizeof(apszArg)/sizeof(apszArg[0]) <= cArg)
  432. {
  433. hr = E_INVALIDARG;
  434. _PrintIfError(hr, "too many args");
  435. goto error;
  436. }
  437. pchQuote = NULL;
  438. while (*pwszCmdLine != L'\0')
  439. {
  440. if (NULL != pchQuote)
  441. {
  442. if (*pwszCmdLine == *pchQuote)
  443. {
  444. pwszCmdLine++;
  445. pchQuote = NULL;
  446. continue;
  447. }
  448. }
  449. else
  450. {
  451. if (ISBLANK(*pwszCmdLine))
  452. {
  453. break;
  454. }
  455. if (L'"' == *pwszCmdLine)
  456. {
  457. pchQuote = pwszCmdLine++;
  458. continue;
  459. }
  460. }
  461. *p++ = *pwszCmdLine++;
  462. }
  463. *p++ = TEXT('\0');
  464. if (*pwszCmdLine != TEXT('\0'))
  465. {
  466. pwszCmdLine++; // skip whitespace or quote character
  467. }
  468. }
  469. }
  470. apszArg[cArg] = NULL;
  471. hr = ArgvMain(cArg, apszArg, hWndOwner);
  472. _PrintIfError(hr, "ArgvMain");
  473. goto error;
  474. error:
  475. PrintErrorMessageText(hr);
  476. if (NULL != pbuf)
  477. {
  478. LocalFree(pbuf);
  479. }
  480. if (fCoInit)
  481. {
  482. CoUninitialize();
  483. }
  484. return(hr);
  485. }
  486. //**************************************************************************
  487. // FUNCTION: MainWndProc(...)
  488. // ARGUMENTS:
  489. //**************************************************************************
  490. LRESULT APIENTRY
  491. MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  492. {
  493. HRESULT hr;
  494. LRESULT lr = 0;
  495. WCHAR *pwszCmdLine;
  496. switch (msg)
  497. {
  498. case WM_CREATE:
  499. case WM_SIZE:
  500. break;
  501. case WM_DESTROY:
  502. PostQuitMessage(0);
  503. break;
  504. case WM_DOCERTREQDMAIN:
  505. pwszCmdLine = (WCHAR *) lParam;
  506. hr = CertReqDPreMain(pwszCmdLine, hWnd);
  507. PostQuitMessage(hr);
  508. break;
  509. default:
  510. lr = DefWindowProc(hWnd, msg, wParam, lParam);
  511. break;
  512. }
  513. return(lr);
  514. }
  515. //+------------------------------------------------------------------------
  516. //
  517. // Function: wWinMain()
  518. //
  519. // Synopsis: Entry Point
  520. //
  521. // Arguments: [hInstance] -- Instance handle
  522. // [hPrevInstance] -- Obsolete
  523. // [pwszCmdLine] -- App command line
  524. // [nCmdShow] -- Starting show state
  525. //
  526. // History: 12/07/96 JerryK Added this Comment
  527. //
  528. //-------------------------------------------------------------------------
  529. extern "C" int APIENTRY
  530. wWinMain(
  531. HINSTANCE hInstance,
  532. HINSTANCE hPrevInstance,
  533. LPWSTR pwszCmdLine,
  534. int nCmdShow)
  535. {
  536. MSG msg;
  537. WNDCLASS wcApp;
  538. HWND hWndMain;
  539. _setmode(_fileno(stdout), _O_TEXT);
  540. _wsetlocale(LC_ALL, L".OCP");
  541. // Save the current instance
  542. g_hInstance = hInstance;
  543. // Set up the application's window class
  544. wcApp.style = 0;
  545. wcApp.lpfnWndProc = MainWndProc;
  546. wcApp.cbClsExtra = 0;
  547. wcApp.cbWndExtra = 0;
  548. wcApp.hInstance = hInstance;
  549. wcApp.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  550. wcApp.hCursor = LoadCursor(NULL, IDC_ARROW);
  551. wcApp.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  552. wcApp.lpszMenuName = NULL;
  553. wcApp.lpszClassName = wszAppName;
  554. if (!RegisterClass(&wcApp))
  555. {
  556. return(FALSE);
  557. }
  558. // Create Main Window
  559. hWndMain = CreateWindow(
  560. wszAppName,
  561. L"CertReqD Application",
  562. WS_OVERLAPPEDWINDOW,
  563. CW_USEDEFAULT, CW_USEDEFAULT,
  564. CW_USEDEFAULT, CW_USEDEFAULT,
  565. NULL,
  566. NULL,
  567. hInstance,
  568. NULL);
  569. if (NULL == hWndMain)
  570. {
  571. return(FALSE);
  572. }
  573. // Make window visible
  574. // ShowWindow(hWndMain, nCmdShow);
  575. // Update window client area
  576. UpdateWindow(hWndMain);
  577. // Send off the message to get things started
  578. PostMessage(hWndMain, WM_DOCERTREQDMAIN, 0, (LPARAM) pwszCmdLine);
  579. // Message Loop
  580. while (GetMessage(&msg, NULL, 0, 0))
  581. {
  582. TranslateMessage(&msg);
  583. DispatchMessage(&msg);
  584. }
  585. return((int) msg.wParam);
  586. }