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.

609 lines
13 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. cspTrace
  5. Abstract:
  6. This program performs analysis on a CSP Function trace.
  7. Author:
  8. Doug Barlow (dbarlow) 2/19/1998
  9. Environment:
  10. Win32
  11. Notes:
  12. ?Notes?
  13. --*/
  14. #ifndef WIN32_LEAN_AND_MEAN
  15. #define WIN32_LEAN_AND_MEAN
  16. #endif
  17. #include <windows.h>
  18. #ifndef _WIN32_WINNT
  19. #define _WIN32_WINNT 0x0400
  20. #endif
  21. #include <wincrypt.h>
  22. #include <tchar.h>
  23. #include <stdlib.h>
  24. #include <iostream.h>
  25. #include <iomanip.h>
  26. #include <scardlib.h>
  27. #include "cspTrace.h"
  28. LPCTSTR g_szMajorAction = TEXT("Initialization");
  29. LPCTSTR g_szMinorAction = NULL;
  30. static const TCHAR l_szLogCsp[] = TEXT("LogCsp.dll");
  31. static const TCHAR l_szCspNames[] = TEXT("SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider");
  32. static const TCHAR l_szImagePath[] = TEXT("Image Path");
  33. static const TCHAR l_szLogCspRegistry[] = TEXT("SOFTWARE\\Microsoft\\Cryptography\\Logging Crypto Provider");
  34. static const TCHAR l_szTargetCsp[] = TEXT("Target");
  35. static const TCHAR l_szLogFile[] = TEXT("Logging File");
  36. static const TCHAR l_szDefaultFile[] = TEXT("C:\\cspTrace.log");
  37. static void
  38. ShowSyntax(
  39. ostream &outStr);
  40. static void
  41. DoInstall(
  42. IN LPCTSTR szProvider,
  43. IN LPCTSTR szInFile);
  44. static void
  45. DoRemove(
  46. void);
  47. static void
  48. DoClearLog(
  49. void);
  50. static void
  51. DoShowStatus(
  52. void);
  53. /*++
  54. main:
  55. This is the main entry point for the program.
  56. Arguments:
  57. dwArgCount supplies the number of arguments.
  58. szrgArgs supplies the argument strings.
  59. Return Value:
  60. None
  61. Author:
  62. Doug Barlow (dbarlow) 10/30/1997
  63. --*/
  64. void _cdecl
  65. main(
  66. IN DWORD dwArgCount,
  67. IN LPCTSTR szrgArgs[])
  68. {
  69. LPCTSTR szInFile = NULL;
  70. LPCTSTR szProvider = NULL;
  71. DWORD dwArgIndex = 0;
  72. enum TraceAction {
  73. Undefined = 0,
  74. Install,
  75. Remove,
  76. ClearLog,
  77. ShowStatus,
  78. ShowTrace,
  79. ScriptTrace
  80. } nTraceAction = Undefined;
  81. //
  82. // Check for command line options
  83. //
  84. while (NULL != szrgArgs[++dwArgIndex])
  85. {
  86. switch (SelectString(szrgArgs[dwArgIndex],
  87. TEXT("INSTALL"), TEXT("REMOVE"), TEXT("CLEAR"),
  88. TEXT("RESET"), TEXT("STATUS"), TEXT("PARSE"),
  89. TEXT("DISPLAY"), TEXT("SCRIPT"), TEXT("TCL"),
  90. TEXT("-FILE"), TEXT("-PROVIDER"), TEXT("-CSP"),
  91. NULL))
  92. {
  93. case 1: // install
  94. if (Undefined != nTraceAction)
  95. ShowSyntax(cerr);
  96. nTraceAction = Install;
  97. break;
  98. case 2: // remove
  99. if (Undefined != nTraceAction)
  100. ShowSyntax(cerr);
  101. nTraceAction = Remove;
  102. break;
  103. case 3: // clear
  104. case 4: // reset
  105. if (Undefined != nTraceAction)
  106. ShowSyntax(cerr);
  107. nTraceAction = ClearLog;
  108. break;
  109. case 5: // status
  110. if (Undefined != nTraceAction)
  111. ShowSyntax(cerr);
  112. nTraceAction = ShowStatus;
  113. break;
  114. case 6: // parse
  115. case 7: // display
  116. if (Undefined != nTraceAction)
  117. ShowSyntax(cerr);
  118. nTraceAction = ShowTrace;
  119. break;
  120. case 8: // script
  121. case 9: // tcl
  122. if (Undefined != nTraceAction)
  123. ShowSyntax(cerr);
  124. nTraceAction = ScriptTrace;
  125. break;
  126. case 10: // -file
  127. if (NULL != szInFile)
  128. ShowSyntax(cerr);
  129. szInFile = szrgArgs[++dwArgIndex];
  130. if (NULL == szInFile)
  131. ShowSyntax(cerr);
  132. break;
  133. case 11: // -provider
  134. case 12: // -csp
  135. if (NULL != szProvider)
  136. ShowSyntax(cerr);
  137. szProvider = szrgArgs[++dwArgIndex];
  138. if (NULL == szProvider)
  139. ShowSyntax(cerr);
  140. break;
  141. default:
  142. ShowSyntax(cerr);
  143. }
  144. }
  145. //
  146. // Perform the requested Action
  147. //
  148. try
  149. {
  150. switch (nTraceAction)
  151. {
  152. case Install:
  153. ACTION("Installation");
  154. if (NULL == szInFile)
  155. szInFile = l_szDefaultFile;
  156. DoInstall(szProvider, szInFile);
  157. break;
  158. case Remove:
  159. ACTION("Removal");
  160. DoRemove();
  161. break;
  162. case ClearLog:
  163. ACTION("Clearing Log File");
  164. DoClearLog();
  165. break;
  166. case ShowStatus:
  167. ACTION("Displaying Status");
  168. DoShowStatus();
  169. break;
  170. case Undefined:
  171. case ShowTrace:
  172. ACTION("Log File Interpretation");
  173. if (NULL == szInFile)
  174. szInFile = l_szDefaultFile;
  175. DoShowTrace(szInFile);
  176. break;
  177. case ScriptTrace:
  178. ACTION("Log File Scripting");
  179. if (NULL == szInFile)
  180. szInFile = l_szDefaultFile;
  181. DoTclTrace(szInFile);
  182. break;
  183. default:
  184. ShowSyntax(cerr);
  185. }
  186. }
  187. catch (DWORD dwError)
  188. {
  189. cerr << TEXT("ERROR: Failed during ")
  190. << g_szMajorAction
  191. << endl;
  192. if (NULL != g_szMinorAction)
  193. cerr << TEXT(" Action: ")
  194. << g_szMinorAction
  195. << endl;
  196. if (ERROR_SUCCESS != dwError)
  197. cerr << TEXT(" Error: ")
  198. << CErrorString(dwError)
  199. << endl;
  200. }
  201. exit(0);
  202. }
  203. /*++
  204. ShowSyntax:
  205. Display the command line usage model.
  206. Arguments:
  207. None
  208. Return Value:
  209. This routine calls exit(0), so it never returns.
  210. Author:
  211. Doug Barlow (dbarlow) 5/16/1998
  212. --*/
  213. static void
  214. ShowSyntax(
  215. ostream &outStr)
  216. {
  217. outStr << TEXT("Usage:\n")
  218. << TEXT("----------------------------------------------------------\n")
  219. << TEXT("install [-file <logFile] [-provider <cspName>]\n")
  220. << TEXT("remove\n")
  221. << TEXT("clear\n")
  222. << TEXT("status\n")
  223. << TEXT("display [-file <logFile]\n")
  224. << TEXT("script [-file <logFile]\n")
  225. << endl;
  226. exit(1);
  227. }
  228. /*++
  229. DoInstall:
  230. This routine performs an installation of the logging CSP.
  231. Arguments:
  232. szProvider supplies the name of the CSP to log. If this is NULL, the
  233. routine prompts for which CSP to use.
  234. szInFile supplies the name of the logging file. If this is NULL, the
  235. default file is used.
  236. Return Value:
  237. None
  238. Throws:
  239. Errors are thrown as DWORD status codes
  240. Remarks:
  241. None
  242. Author:
  243. Doug Barlow (dbarlow) 5/18/1998
  244. --*/
  245. static void
  246. DoInstall(
  247. IN LPCTSTR szProvider,
  248. IN LPCTSTR szInFile)
  249. {
  250. LPCTSTR szLogCsp = FindLogCsp();
  251. CRegistry regChosenCsp;
  252. LPCTSTR szCspImage;
  253. //
  254. // Make sure we're not already installed.
  255. //
  256. DoRemove();
  257. //
  258. // Choose the CSP to be logged.
  259. //
  260. if (NULL == szProvider)
  261. {
  262. SUBACTION("Enumerating CSPs");
  263. CRegistry regCsps(HKEY_LOCAL_MACHINE, l_szCspNames, KEY_READ);
  264. DWORD dwIndex, dwChoice;
  265. LPCTSTR szCsp;
  266. do
  267. {
  268. cout << TEXT("Choose the CSP to be logged:") << endl;
  269. for (dwIndex = 0;; dwIndex += 1)
  270. {
  271. szCsp = regCsps.Subkey(dwIndex);
  272. if (NULL == szCsp)
  273. break;
  274. cout << TEXT(" ") << dwIndex + 1 << TEXT(") ") << szCsp << endl;
  275. }
  276. cout << TEXT("Selection: ") << flush;
  277. cin >> dwChoice;
  278. } while ((0 == dwChoice) || (dwChoice > dwIndex));
  279. SUBACTION("Selecting Chosen CSP");
  280. szCsp = regCsps.Subkey(dwChoice - 1);
  281. regChosenCsp.Open(regCsps, szCsp, KEY_ALL_ACCESS);
  282. }
  283. else
  284. {
  285. SUBACTION("Selecting Specified CSP");
  286. CRegistry regCsps(HKEY_LOCAL_MACHINE, l_szCspNames, KEY_READ);
  287. regChosenCsp.Open(regCsps, szProvider, KEY_ALL_ACCESS);
  288. }
  289. //
  290. // Wedge in the Logging CSP.
  291. //
  292. SUBACTION("Wedging the Logging CSP");
  293. szCspImage = regChosenCsp.GetStringValue(l_szImagePath);
  294. CRegistry regLogCsp(
  295. HKEY_LOCAL_MACHINE,
  296. l_szLogCspRegistry,
  297. KEY_ALL_ACCESS,
  298. REG_OPTION_NON_VOLATILE);
  299. if (NULL != szInFile)
  300. regLogCsp.SetValue(l_szLogFile, szInFile);
  301. if (NULL == _tcschr(szCspImage, TEXT('%')))
  302. regLogCsp.SetValue(l_szTargetCsp, szCspImage, REG_SZ);
  303. else
  304. regLogCsp.SetValue(l_szTargetCsp, szCspImage, REG_EXPAND_SZ);
  305. regChosenCsp.SetValue(l_szImagePath, szLogCsp, REG_SZ);
  306. //
  307. // Initialize the logging file.
  308. //
  309. DoClearLog();
  310. }
  311. /*++
  312. DoRemove:
  313. This routine Removes the Logging CSP.
  314. Arguments:
  315. None
  316. Return Value:
  317. None
  318. Throws:
  319. None
  320. Remarks:
  321. None
  322. Author:
  323. Doug Barlow (dbarlow) 5/18/1998
  324. --*/
  325. static void
  326. DoRemove(
  327. void)
  328. {
  329. LPCTSTR szLoggedCsp = FindLoggedCsp();
  330. if (NULL != szLoggedCsp)
  331. {
  332. SUBACTION("Accessing Registry Keys");
  333. CRegistry regCsps(HKEY_LOCAL_MACHINE, l_szCspNames, KEY_READ);
  334. CRegistry regLoggedCsp(regCsps, szLoggedCsp);
  335. CRegistry regLogCsp(HKEY_LOCAL_MACHINE, l_szLogCspRegistry);
  336. LPCTSTR szCspImage = regLogCsp.GetStringValue(l_szTargetCsp);
  337. SUBACTION("Changing Registry Values");
  338. if (NULL == _tcschr(szCspImage, TEXT('%')))
  339. regLoggedCsp.SetValue(l_szImagePath, szCspImage, REG_SZ);
  340. else
  341. regLoggedCsp.SetValue(l_szImagePath, szCspImage, REG_EXPAND_SZ);
  342. regLogCsp.DeleteValue(l_szLogFile, TRUE);
  343. regLogCsp.DeleteValue(l_szTargetCsp);
  344. }
  345. }
  346. /*++
  347. DoClearLog:
  348. This routine resets the log file.
  349. Arguments:
  350. None
  351. Return Value:
  352. None
  353. Throws:
  354. None
  355. Remarks:
  356. None
  357. Author:
  358. Doug Barlow (dbarlow) 5/18/1998
  359. --*/
  360. static void
  361. DoClearLog(
  362. void)
  363. {
  364. SUBACTION("Getting Log File Name");
  365. CRegistry regLogCsp(HKEY_LOCAL_MACHINE, l_szLogCspRegistry, KEY_READ);
  366. LPCTSTR szLogFile = regLogCsp.GetStringValue(l_szLogFile);
  367. HANDLE hLogFile;
  368. SUBACTION("Creating Log File");
  369. hLogFile = CreateFile(
  370. szLogFile,
  371. GENERIC_WRITE,
  372. 0,
  373. NULL,
  374. CREATE_ALWAYS,
  375. FILE_ATTRIBUTE_NORMAL,
  376. NULL);
  377. if (INVALID_HANDLE_VALUE == hLogFile)
  378. throw GetLastError();
  379. CloseHandle(hLogFile);
  380. }
  381. /*++
  382. DoShowStatus:
  383. This routine displays the current status of the logging CSP.
  384. Arguments:
  385. None
  386. Return Value:
  387. None
  388. Throws:
  389. None
  390. Remarks:
  391. None
  392. Author:
  393. Doug Barlow (dbarlow) 5/18/1998
  394. --*/
  395. static void
  396. DoShowStatus(
  397. void)
  398. {
  399. LPCTSTR szLoggedCsp = NULL;
  400. TCHAR szLogFile[MAX_PATH] = TEXT("<Unavailable>");
  401. LPCTSTR szFileAccessibility = NULL;
  402. CErrorString szErrStr;
  403. DWORD dwFileSize = 0xffffffff;
  404. //
  405. // Obtain the CSP being logged.
  406. //
  407. try
  408. {
  409. szLoggedCsp = FindLoggedCsp();
  410. if (NULL == szLoggedCsp)
  411. szLoggedCsp = TEXT("<none>");
  412. }
  413. catch (DWORD)
  414. {
  415. szLoggedCsp = TEXT("<unavailable>");
  416. }
  417. //
  418. // Obtain the Logging file.
  419. //
  420. try
  421. {
  422. CRegistry regLogCsp(HKEY_LOCAL_MACHINE, l_szLogCspRegistry, KEY_READ);
  423. LPCTSTR szLogFileTmp = regLogCsp.GetStringValue(l_szLogFile);
  424. if (NULL != szLogFileTmp)
  425. {
  426. lstrcpy(szLogFile, szLogFileTmp);
  427. HANDLE hLogFile;
  428. hLogFile = CreateFile(
  429. szLogFileTmp,
  430. GENERIC_READ,
  431. FILE_SHARE_READ | FILE_SHARE_WRITE,
  432. NULL,
  433. OPEN_EXISTING,
  434. FILE_ATTRIBUTE_NORMAL,
  435. NULL);
  436. if (INVALID_HANDLE_VALUE != hLogFile)
  437. {
  438. dwFileSize = GetFileSize(hLogFile, NULL);
  439. CloseHandle(hLogFile);
  440. szFileAccessibility = TEXT("Success");
  441. }
  442. else
  443. {
  444. szErrStr.SetError(GetLastError());
  445. szFileAccessibility = szErrStr.Value();
  446. }
  447. }
  448. }
  449. catch (DWORD)
  450. {
  451. lstrcpy(szLogFile , TEXT("<Unset>"));
  452. szFileAccessibility = TEXT("N/A");
  453. }
  454. //
  455. // Tell the user what we know.
  456. //
  457. cout << TEXT("CSP Logging Status:") << endl
  458. << TEXT(" Logged CSP: ") << szLoggedCsp << endl
  459. << TEXT(" Logging File: ") << szLogFile << endl
  460. << TEXT(" File Status: ") << szFileAccessibility << endl
  461. << TEXT(" File Size: ");
  462. if (0xffffffff == dwFileSize)
  463. cout << TEXT("N/A") << endl;
  464. else
  465. cout << dwFileSize << TEXT(" bytes") << endl;
  466. }