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.

826 lines
20 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1999
  6. //
  7. // File: events.c
  8. //
  9. // Contents: Schannel event log functions.
  10. //
  11. // Functions: SchInitializeEvents
  12. // SchReportEvent
  13. // SchShutdownEvents
  14. //
  15. // History: 03-05-99 jbanes Created
  16. //
  17. //------------------------------------------------------------------------
  18. #include "sslp.h"
  19. #include <lsapmsgs.h>
  20. #include <netlib.h>
  21. HANDLE g_hEventLog = NULL;
  22. HANDLE g_hDiscardDupEventLog = NULL;
  23. WCHAR EventSourceName[] = TEXT("Schannel");
  24. #define MAX_EVENT_STRINGS 8
  25. #define SCH_MESSAGE_FILENAME TEXT("%SystemRoot%\\system32\\lsasrv.dll")
  26. LPWSTR pszClientString = NULL;
  27. LPWSTR pszServerString = NULL;
  28. NTSTATUS
  29. SchGetMessageString(
  30. LPVOID Resource,
  31. DWORD Index,
  32. LPWSTR * pRetString);
  33. //+---------------------------------------------------------------------------
  34. //
  35. // Function: SchInitializeEvents
  36. //
  37. // Synopsis: Connects to event log service.
  38. //
  39. // Arguments: (none)
  40. //
  41. // History: 03-05-99 jbanes Created
  42. //
  43. // Notes:
  44. //
  45. //----------------------------------------------------------------------------
  46. BOOL
  47. SchInitializeEvents(void)
  48. {
  49. HKEY hKey;
  50. int err;
  51. DWORD disp;
  52. HMODULE hResource;
  53. //
  54. // Create registry entries, whether event logging is currently
  55. // enabled or not.
  56. //
  57. err = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  58. TEXT("System\\CurrentControlSet\\Services\\EventLog\\System\\Schannel"),
  59. 0,
  60. TEXT(""),
  61. REG_OPTION_NON_VOLATILE,
  62. KEY_WRITE,
  63. NULL,
  64. &hKey,
  65. &disp);
  66. if(err)
  67. {
  68. return(FALSE);
  69. }
  70. if (disp == REG_CREATED_NEW_KEY)
  71. {
  72. RegSetValueEx( hKey,
  73. TEXT("EventMessageFile"),
  74. 0,
  75. REG_EXPAND_SZ,
  76. (PBYTE)SCH_MESSAGE_FILENAME,
  77. sizeof(SCH_MESSAGE_FILENAME) );
  78. // RegSetValueEx( hKey,
  79. // TEXT("CategoryMessageFile"),
  80. // 0,
  81. // REG_EXPAND_SZ,
  82. // (PBYTE)SCH_MESSAGE_FILENAME,
  83. // sizeof(SCH_MESSAGE_FILENAME) );
  84. disp = 7;
  85. RegSetValueEx( hKey,
  86. TEXT("TypesSupported"),
  87. 0,
  88. REG_DWORD,
  89. (PBYTE) &disp,
  90. sizeof(DWORD) );
  91. // disp = CATEGORY_MAX_CATEGORY - 1;
  92. // RegSetValueEx( hKey,
  93. // TEXT("CategoryCount"),
  94. // 0,
  95. // REG_DWORD,
  96. // (PBYTE) &disp,
  97. // sizeof(DWORD) );
  98. RegFlushKey(hKey);
  99. }
  100. RegCloseKey(hKey);
  101. //
  102. // Read the event text strings from the resource file.
  103. //
  104. hResource = (HMODULE)LoadLibrary(TEXT("lsasrv.dll"));
  105. if(hResource == NULL)
  106. {
  107. return(FALSE);
  108. }
  109. SchGetMessageString(hResource,
  110. SSLEVENTTEXT_CLIENT,
  111. &pszClientString);
  112. SchGetMessageString(hResource,
  113. SSLEVENTTEXT_SERVER,
  114. &pszServerString);
  115. FreeLibrary(hResource);
  116. return(TRUE);
  117. }
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Function: SchReportEvent
  121. //
  122. // Synopsis: Reports an event to the event log
  123. //
  124. // Arguments: [EventType] -- EventType (ERROR, WARNING, etc.)
  125. // [EventId] -- Event ID
  126. // [SizeOfRawData] -- Size of raw data
  127. // [RawData] -- Raw data
  128. // [NumberOfStrings] -- number of strings
  129. // ... -- PWSTRs to string data
  130. //
  131. // History: 03-05-99 jbanes Created
  132. //
  133. // Notes:
  134. //
  135. //----------------------------------------------------------------------------
  136. DWORD
  137. SchReportEvent(
  138. IN DWORD LogLevel,
  139. IN DWORD EventType,
  140. IN DWORD EventId,
  141. IN DWORD Category,
  142. IN DWORD SizeOfRawData,
  143. IN PVOID RawData,
  144. IN DWORD NumberOfStrings,
  145. ...
  146. )
  147. {
  148. va_list arglist;
  149. ULONG i;
  150. PWSTR Strings[ MAX_EVENT_STRINGS ];
  151. DWORD Status;
  152. BOOL fDiscardDuplicates = TRUE;
  153. BOOL fSuccess;
  154. //
  155. // Is this event supposed to be logged?
  156. //
  157. if ((g_dwEventLogging & LogLevel) == 0)
  158. {
  159. return ERROR_SUCCESS;
  160. }
  161. //
  162. // Open the event log if necessary.
  163. //
  164. if(g_dwEventLogging == DEFAULT_EVENT_LOGGING_SETTING)
  165. {
  166. // Only log identical event once per day.
  167. if(g_hDiscardDupEventLog == NULL)
  168. {
  169. g_hDiscardDupEventLog = NetpEventlogOpen(EventSourceName, 60000*60*24);
  170. if(g_hDiscardDupEventLog == NULL)
  171. {
  172. Status = GetLastError();
  173. DebugLog((DEB_ERROR, "Could not open duplicate discard event log, error %d\n", Status));
  174. return Status;
  175. }
  176. }
  177. }
  178. else
  179. {
  180. // Log all events.
  181. if(g_hEventLog == NULL)
  182. {
  183. g_hEventLog = RegisterEventSource(NULL, EventSourceName);
  184. if(g_hEventLog == NULL)
  185. {
  186. Status = GetLastError();
  187. DebugLog((DEB_ERROR, "Could not open duplicate discard event log, error %d\n", Status));
  188. return Status;
  189. }
  190. }
  191. fDiscardDuplicates = FALSE;
  192. }
  193. //
  194. // Look at the strings, if they were provided
  195. //
  196. va_start( arglist, NumberOfStrings );
  197. if (NumberOfStrings > MAX_EVENT_STRINGS) {
  198. NumberOfStrings = MAX_EVENT_STRINGS;
  199. }
  200. for (i=0; i<NumberOfStrings; i++)
  201. {
  202. Strings[ i ] = va_arg( arglist, PWSTR );
  203. }
  204. //
  205. // Report the event to the eventlog service
  206. //
  207. if(fDiscardDuplicates)
  208. {
  209. fSuccess = NetpEventlogWriteEx(
  210. g_hDiscardDupEventLog,
  211. (WORD) EventType,
  212. (WORD) Category,
  213. EventId,
  214. (WORD)NumberOfStrings,
  215. SizeOfRawData,
  216. Strings,
  217. RawData);
  218. }
  219. else
  220. {
  221. fSuccess = ReportEvent(
  222. g_hEventLog,
  223. (WORD) EventType,
  224. (WORD) Category,
  225. EventId,
  226. NULL,
  227. (WORD)NumberOfStrings,
  228. SizeOfRawData,
  229. Strings,
  230. RawData);
  231. }
  232. if(!fSuccess)
  233. {
  234. Status = GetLastError();
  235. DebugLog((DEB_ERROR, "ReportEvent( %u ) failed - %u\n", EventId, Status));
  236. }
  237. else
  238. {
  239. Status = ERROR_SUCCESS;
  240. }
  241. return Status;
  242. }
  243. void
  244. SchShutdownEvents(void)
  245. {
  246. if(g_hDiscardDupEventLog != NULL)
  247. {
  248. NetpEventlogClose(g_hDiscardDupEventLog);
  249. g_hDiscardDupEventLog = NULL;
  250. }
  251. if(g_hEventLog != NULL)
  252. {
  253. DeregisterEventSource(g_hEventLog);
  254. g_hEventLog = NULL;
  255. }
  256. if(pszClientString)
  257. {
  258. LocalFree(pszClientString);
  259. pszClientString = NULL;
  260. }
  261. if(pszServerString)
  262. {
  263. LocalFree(pszServerString);
  264. pszServerString = NULL;
  265. }
  266. }
  267. void
  268. LogSchannelStartedEvent(void)
  269. {
  270. SchReportEvent( DEB_TRACE,
  271. EVENTLOG_INFORMATION_TYPE,
  272. SSLEVENT_SCHANNEL_STARTED,
  273. 0,
  274. 0,
  275. NULL,
  276. 0,
  277. NULL );
  278. }
  279. void
  280. LogGlobalAcquireContextFailedEvent(
  281. LPWSTR pwszName,
  282. DWORD Status)
  283. {
  284. WCHAR wszStatus[20];
  285. _ltow(Status, wszStatus, 16);
  286. SchReportEvent( DEB_ERROR,
  287. EVENTLOG_ERROR_TYPE,
  288. SSLEVENT_GLOBAL_ACQUIRE_CONTEXT_FAILED,
  289. 0,
  290. 0,
  291. NULL,
  292. 2,
  293. pwszName,
  294. wszStatus);
  295. }
  296. void
  297. LogCreateCredEvent(
  298. DWORD dwProtocol,
  299. PLSA_SCHANNEL_CRED pSchannelCred)
  300. {
  301. SchReportEvent(DEB_TRACE,
  302. EVENTLOG_INFORMATION_TYPE,
  303. SSLEVENT_CREATE_CRED,
  304. 0,
  305. sizeof(SCHANNEL_CRED),
  306. pSchannelCred,
  307. 1,
  308. (dwProtocol & SP_PROT_SERVERS) ? pszServerString : pszClientString);
  309. }
  310. void
  311. LogCredPropertiesEvent(
  312. DWORD dwProtocol,
  313. PCRYPT_KEY_PROV_INFO pProvInfo,
  314. PCCERT_CONTEXT pCertContext)
  315. {
  316. WCHAR wszType[20];
  317. WCHAR wszFlags[20];
  318. LPWSTR pwszKeySpec;
  319. if(!(g_dwEventLogging & DEB_TRACE))
  320. {
  321. return;
  322. }
  323. _ltow(pProvInfo->dwProvType, wszType, 10);
  324. _ltow(pProvInfo->dwFlags, wszFlags, 16);
  325. switch(pProvInfo->dwKeySpec)
  326. {
  327. case AT_KEYEXCHANGE:
  328. pwszKeySpec = L"key exchange";
  329. break;
  330. case AT_SIGNATURE:
  331. pwszKeySpec = L"signature";
  332. break;
  333. default:
  334. pwszKeySpec = L"unknown";
  335. }
  336. SchReportEvent( DEB_TRACE,
  337. EVENTLOG_INFORMATION_TYPE,
  338. SSLEVENT_CRED_PROPERTIES,
  339. 0,
  340. pCertContext->cbCertEncoded,
  341. pCertContext->pbCertEncoded,
  342. 6,
  343. (dwProtocol & SP_PROT_SERVERS) ? pszServerString : pszClientString,
  344. pProvInfo->pwszProvName,
  345. wszType,
  346. pProvInfo->pwszContainerName,
  347. pwszKeySpec,
  348. wszFlags);
  349. }
  350. void
  351. LogNoPrivateKeyEvent(
  352. DWORD dwProtocol)
  353. {
  354. SchReportEvent( DEB_ERROR,
  355. EVENTLOG_ERROR_TYPE,
  356. SSLEVENT_NO_PRIVATE_KEY,
  357. 0,
  358. 0,
  359. NULL,
  360. 1,
  361. (dwProtocol & SP_PROT_SERVERS) ? pszServerString : pszClientString);
  362. }
  363. void
  364. LogCredAcquireContextFailedEvent(
  365. DWORD dwProtocol,
  366. DWORD Status)
  367. {
  368. WCHAR wszStatus[20];
  369. _ltow(Status, wszStatus, 16);
  370. SchReportEvent( DEB_ERROR,
  371. EVENTLOG_ERROR_TYPE,
  372. SSLEVENT_CRED_ACQUIRE_CONTEXT_FAILED,
  373. 0,
  374. 0,
  375. NULL,
  376. 2,
  377. (dwProtocol & SP_PROT_SERVERS) ? pszServerString : pszClientString,
  378. wszStatus);
  379. }
  380. void
  381. LogCreateCredFailedEvent(
  382. DWORD dwProtocol)
  383. {
  384. SchReportEvent(DEB_ERROR,
  385. EVENTLOG_ERROR_TYPE,
  386. SSLEVENT_CREATE_CRED_FAILED,
  387. 0,
  388. 0,
  389. NULL,
  390. 1,
  391. (dwProtocol & SP_PROT_SERVERS) ? pszServerString : pszClientString);
  392. }
  393. void
  394. LogNoDefaultServerCredEvent(void)
  395. {
  396. SchReportEvent(DEB_ERROR,
  397. EVENTLOG_WARNING_TYPE,
  398. SSLEVENT_NO_DEFAULT_SERVER_CRED,
  399. 0,
  400. 0,
  401. NULL,
  402. 0,
  403. NULL);
  404. }
  405. void
  406. LogNoCiphersSupportedEvent(void)
  407. {
  408. SchReportEvent(DEB_ERROR,
  409. EVENTLOG_ERROR_TYPE,
  410. SSLEVENT_NO_CIPHERS_SUPPORTED,
  411. 0,
  412. 0,
  413. NULL,
  414. 0,
  415. NULL);
  416. }
  417. void
  418. LogCipherMismatchEvent(void)
  419. {
  420. SchReportEvent(DEB_ERROR,
  421. EVENTLOG_ERROR_TYPE,
  422. SSLEVENT_CIPHER_MISMATCH,
  423. 0,
  424. 0,
  425. NULL,
  426. 0,
  427. NULL);
  428. }
  429. void
  430. LogNoClientCertFoundEvent(void)
  431. {
  432. SchReportEvent(DEB_WARN,
  433. EVENTLOG_WARNING_TYPE,
  434. SSLEVENT_NO_CLIENT_CERT_FOUND,
  435. 0,
  436. 0,
  437. NULL,
  438. 0,
  439. NULL);
  440. }
  441. void
  442. LogBogusServerCertEvent(
  443. PCCERT_CONTEXT pCertContext,
  444. LPWSTR pwszServerName,
  445. DWORD Status)
  446. {
  447. WCHAR wszStatus[20];
  448. if(!(g_dwEventLogging & DEB_ERROR))
  449. {
  450. return;
  451. }
  452. switch(Status)
  453. {
  454. case SEC_E_CERT_EXPIRED:
  455. SchReportEvent( DEB_ERROR,
  456. EVENTLOG_ERROR_TYPE,
  457. SSLEVENT_EXPIRED_SERVER_CERT,
  458. 0,
  459. pCertContext->cbCertEncoded,
  460. pCertContext->pbCertEncoded,
  461. 0,
  462. NULL);
  463. break;
  464. case SEC_E_UNTRUSTED_ROOT:
  465. SchReportEvent( DEB_ERROR,
  466. EVENTLOG_ERROR_TYPE,
  467. SSLEVENT_UNTRUSTED_SERVER_CERT,
  468. 0,
  469. pCertContext->cbCertEncoded,
  470. pCertContext->pbCertEncoded,
  471. 0,
  472. NULL);
  473. break;
  474. case CRYPT_E_REVOKED:
  475. SchReportEvent( DEB_ERROR,
  476. EVENTLOG_ERROR_TYPE,
  477. SSLEVENT_REVOKED_SERVER_CERT,
  478. 0,
  479. pCertContext->cbCertEncoded,
  480. pCertContext->pbCertEncoded,
  481. 0,
  482. NULL);
  483. break;
  484. case SEC_E_WRONG_PRINCIPAL:
  485. SchReportEvent( DEB_ERROR,
  486. EVENTLOG_ERROR_TYPE,
  487. SSLEVENT_NAME_MISMATCHED_SERVER_CERT,
  488. 0,
  489. pCertContext->cbCertEncoded,
  490. pCertContext->pbCertEncoded,
  491. 1,
  492. pwszServerName);
  493. break;
  494. default:
  495. _ltow(Status, wszStatus, 16);
  496. SchReportEvent( DEB_ERROR,
  497. EVENTLOG_ERROR_TYPE,
  498. SSLEVENT_BOGUS_SERVER_CERT,
  499. 0,
  500. pCertContext->cbCertEncoded,
  501. pCertContext->pbCertEncoded,
  502. 1,
  503. wszStatus);
  504. }
  505. }
  506. void
  507. LogBogusClientCertEvent(
  508. PCCERT_CONTEXT pCertContext,
  509. DWORD Status)
  510. {
  511. WCHAR wszStatus[20];
  512. if(!(g_dwEventLogging & DEB_WARN))
  513. {
  514. return;
  515. }
  516. _ltow(Status, wszStatus, 16);
  517. SchReportEvent( DEB_WARN,
  518. EVENTLOG_WARNING_TYPE,
  519. SSLEVENT_BOGUS_CLIENT_CERT,
  520. 0,
  521. pCertContext->cbCertEncoded,
  522. pCertContext->pbCertEncoded,
  523. 1,
  524. wszStatus);
  525. }
  526. void
  527. LogFastMappingFailureEvent(
  528. PCCERT_CONTEXT pCertContext,
  529. DWORD Status)
  530. {
  531. WCHAR wszStatus[20];
  532. if(!(g_dwEventLogging & DEB_WARN))
  533. {
  534. return;
  535. }
  536. _ltow(Status, wszStatus, 16);
  537. SchReportEvent( DEB_WARN,
  538. EVENTLOG_WARNING_TYPE,
  539. SSLEVENT_FAST_MAPPING_FAILURE,
  540. 0,
  541. pCertContext->cbCertEncoded,
  542. pCertContext->pbCertEncoded,
  543. 1,
  544. wszStatus);
  545. }
  546. void
  547. LogCertMappingFailureEvent(
  548. DWORD Status)
  549. {
  550. WCHAR wszStatus[20];
  551. if(!(g_dwEventLogging & DEB_WARN))
  552. {
  553. return;
  554. }
  555. _ltow(Status, wszStatus, 16);
  556. SchReportEvent( DEB_WARN,
  557. EVENTLOG_WARNING_TYPE,
  558. SSLEVENT_CERT_MAPPING_FAILURE,
  559. 0,
  560. 0,
  561. NULL,
  562. 1,
  563. wszStatus);
  564. }
  565. void
  566. LogHandshakeInfoEvent(
  567. DWORD dwProtocol,
  568. PCipherInfo pCipherInfo,
  569. PHashInfo pHashInfo,
  570. PKeyExchangeInfo pExchangeInfo,
  571. DWORD dwExchangeStrength)
  572. {
  573. WCHAR wszCipherStrength[20];
  574. WCHAR wszExchangeStrength[20];
  575. LPWSTR pwszProtocol;
  576. LPWSTR pwszCipher;
  577. LPWSTR pwszHash;
  578. LPWSTR pwszExchange;
  579. if(!(g_dwEventLogging & DEB_TRACE))
  580. {
  581. return;
  582. }
  583. switch(dwProtocol)
  584. {
  585. case SP_PROT_PCT1_SERVER:
  586. case SP_PROT_PCT1_CLIENT:
  587. pwszProtocol = L"PCT";
  588. break;
  589. case SP_PROT_SSL2_SERVER:
  590. case SP_PROT_SSL2_CLIENT:
  591. pwszProtocol = L"SSL 2.0";
  592. break;
  593. case SP_PROT_SSL3_SERVER:
  594. case SP_PROT_SSL3_CLIENT:
  595. pwszProtocol = L"SSL 3.0";
  596. break;
  597. case SP_PROT_TLS1_SERVER:
  598. case SP_PROT_TLS1_CLIENT:
  599. pwszProtocol = L"TLS (SSL 3.1)";
  600. break;
  601. default:
  602. pwszProtocol = L"unknown";
  603. }
  604. switch(pCipherInfo->aiCipher)
  605. {
  606. case CALG_RC4:
  607. pwszCipher = L"RC4";
  608. break;
  609. case CALG_3DES:
  610. pwszCipher = L"Triple-DES";
  611. break;
  612. case CALG_RC2:
  613. pwszCipher = L"RC2";
  614. break;
  615. case CALG_DES:
  616. pwszCipher = L"DES";
  617. break;
  618. case CALG_SKIPJACK:
  619. pwszCipher = L"Skipjack";
  620. break;
  621. default:
  622. pwszCipher = L"unknown";
  623. }
  624. _ltow(pCipherInfo->dwStrength, wszCipherStrength, 10);
  625. switch(pHashInfo->aiHash)
  626. {
  627. case CALG_MD5:
  628. pwszHash = L"MD5";
  629. break;
  630. case CALG_SHA:
  631. pwszHash = L"SHA";
  632. break;
  633. default:
  634. pwszHash = L"unknown";
  635. }
  636. switch(pExchangeInfo->aiExch)
  637. {
  638. case CALG_RSA_SIGN:
  639. case CALG_RSA_KEYX:
  640. pwszExchange = L"RSA";
  641. break;
  642. case CALG_KEA_KEYX:
  643. pwszExchange = L"KEA";
  644. break;
  645. case CALG_DH_EPHEM:
  646. pwszExchange = L"Ephemeral DH";
  647. break;
  648. default:
  649. pwszExchange = L"unknown";
  650. }
  651. _ltow(dwExchangeStrength, wszExchangeStrength, 10);
  652. SchReportEvent( DEB_TRACE,
  653. EVENTLOG_INFORMATION_TYPE,
  654. SSLEVENT_HANDSHAKE_INFO,
  655. 0,
  656. 0,
  657. NULL,
  658. 7,
  659. (dwProtocol & SP_PROT_SERVERS) ? pszServerString : pszClientString,
  660. pwszProtocol,
  661. pwszCipher,
  662. wszCipherStrength,
  663. pwszHash,
  664. pwszExchange,
  665. wszExchangeStrength);
  666. }
  667. void
  668. LogIssuerOverflowEvent(void)
  669. {
  670. SchReportEvent( DEB_ERROR,
  671. EVENTLOG_WARNING_TYPE,
  672. SSLEVENT_ISSUER_LIST_OVERFLOW_FAILURE,
  673. 0,
  674. 0,
  675. NULL,
  676. 0,
  677. NULL);
  678. }
  679. NTSTATUS
  680. SchGetMessageString(
  681. LPVOID Resource,
  682. DWORD Index,
  683. LPWSTR * pRetString)
  684. {
  685. DWORD Length;
  686. *pRetString = NULL;
  687. Length = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
  688. FORMAT_MESSAGE_ALLOCATE_BUFFER,
  689. Resource,
  690. Index,
  691. 0, // Use caller's language
  692. (LPWSTR)pRetString,
  693. 0,
  694. NULL);
  695. if(Length == 0 || *pRetString == NULL)
  696. {
  697. return(STATUS_RESOURCE_DATA_NOT_FOUND);
  698. }
  699. //
  700. // Note that we are retrieving a message from a message file.
  701. // This message will have a cr/lf tacked on the end of it
  702. // (0x0d 0x0a) that we don't want to be part of our returned
  703. // strings. However, we do need to null terminate our string
  704. // so we will convert the 0x0d into a null terminator.
  705. //
  706. // Also note that FormatMessage() returns a character count,
  707. // not a byte count. So, we have to do some adjusting to make
  708. // the string lengths correct.
  709. //
  710. ASSERT(Length >= 2); // We always expect cr/lf on our strings
  711. //
  712. // Adjust character count
  713. //
  714. Length -= 1; // For the lf - we'll convert the cr.
  715. //
  716. // Set null terminator
  717. //
  718. (*pRetString)[Length - 1] = 0;
  719. return(STATUS_SUCCESS);
  720. }