Mercurial > trustbridge
view common/logging.c @ 623:5042ace08cba
Add certificate specific logging functions
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Fri, 20 Jun 2014 12:17:32 +0200 |
parents | bc02ee484067 |
children | 2303caf56dbb |
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #include "logging.h" #include "strhelp.h" #include <stdio.h> #include <stdarg.h> #include <stdbool.h> #include <strhelp.h> #include <certhelp.h> #include <polarssl/sha256.h> #ifdef WIN32 # include <windows.h> # include "events.h" #else # include <syslog.h> #endif #ifdef WIN32 /** @brief helper to prepare common logging information */ static void win_do_log(WORD type, WORD category, DWORD eventID, WORD numStrings, LPCWSTR *strings) { HANDLE log_src = NULL, process_token = NULL; PTOKEN_USER user_struct = NULL; PSID user_sid = NULL; BOOL success = FALSE; log_src = RegisterEventSourceW (NULL, L"" LOG_NAME); if (log_src == NULL) { PRINTLASTERROR ("Failed to open log source."); return; } /* Get the current user sid for logging */ OpenProcessToken (GetCurrentProcess(), TOKEN_READ, &process_token); if (process_token) { DWORD size = 0; // check how much space is needed GetTokenInformation (process_token, TokenUser, NULL, 0, &size); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { user_struct = xmalloc (size); GetTokenInformation (process_token, TokenUser, user_struct, size, &size); user_sid = user_struct->User.Sid; } } success = ReportEventW (log_src, type, category, eventID, user_sid, numStrings, 0, strings, NULL); if (!success) { PRINTLASTERROR ("Failed to report event."); } if (process_token) { CloseHandle(process_token); } xfree (user_struct); if (!DeregisterEventSource (log_src)) { PRINTLASTERROR ("Failed to close log source."); } } static void win_log(const char *format, va_list ap, bool error) { wchar_t *wmsg = NULL; char buffer[MAX_LOG+1]; vsnprintf (buffer, MAX_LOG, format, ap); buffer[MAX_LOG] = '\0'; wmsg = utf8_to_wchar (buffer, strlen(buffer)); if (wmsg == NULL) { ERRORPRINTF ("Failed to convert log message to utf-16"); return; } win_do_log (error ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE, EVENT_CAT_TB, error ? MSG_DEFAULT_ERROR : MSG_DEFAULT_INFO, 1, (const WCHAR **) &wmsg); xfree (wmsg); return; } char * getLastErrorMsg() { LPWSTR bufPtr = NULL; DWORD err = GetLastError(); char *retval = NULL; FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPWSTR) &bufPtr, 0, NULL); if (!bufPtr) { HMODULE hWinhttp = GetModuleHandleW (L"crypt32"); if (hWinhttp) { FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, hWinhttp, HRESULT_CODE (err), 0, (LPWSTR) &bufPtr, 0, NULL); } } if (!bufPtr) { fprintf (stderr, "Error getting last error for code: %lx \n", err); return NULL; } retval = wchar_to_utf8(bufPtr, wcslen(bufPtr)); LocalFree (bufPtr); return retval; } #else /* WIN32 */ static void linux_log (const char *format, va_list ap, bool error) { openlog (LOG_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); vsyslog ( error ? LOG_ERR : LOG_INFO, format, ap); } #endif /* WIN32 */ void log_certificate(const char* store, char *b64cert, bool install) { char subject[MAX_LOG + 1], *der_data = NULL; size_t der_size = 0; int ret = 0, i = 0; x509_crt chain; unsigned char sha256sum[32]; char fingerprint[32 * 3 + 1]; ret = str_base64_decode (&der_data, &der_size, b64cert, strlen(b64cert)); if (ret != 0) { ERRORPRINTF ("Error decoding certificate.\n"); return; } x509_crt_init(&chain); if (x509_crt_parse_der(&chain, (const unsigned char *)der_data, der_size) != 0) { ERRORPRINTF("Failed to parse cert.."); xfree (der_data); return; } ret = x509_dn_gets(subject, MAX_LOG, &(chain.subject)); if (ret == -1) { ERRORPRINTF("Failed to parse subject.."); xfree (der_data); return; } subject[MAX_LOG] = '\0'; sha256 (chain.raw.p, chain.raw.len, sha256sum, 0); for (i = 0; i < 31; i++) { snprintf (fingerprint + i * 3, 3, "%02X:", sha256sum[i]); } snprintf (fingerprint + 31 * 3, 2, "%02X", sha256sum[31]); fingerprint[32*3] = '\0'; #ifdef WIN32 { wchar_t *wstrings[3]; wstrings[0] = utf8_to_wchar (subject, strnlen (subject, MAX_LOG)); wstrings[1] = utf8_to_wchar (fingerprint, strnlen (fingerprint, MAX_LOG)); wstrings[2] = utf8_to_wchar (store, strnlen (store, MAX_LOG)); win_do_log (EVENTLOG_INFORMATION_TYPE, EVENT_CAT_CINST, install ? MSG_CERT_INSTALL : MSG_CERT_REMOVE, 3, (const WCHAR**) wstrings); xfree (wstrings[0]); xfree (wstrings[1]); xfree (wstrings[2]); } #else /* Please keep the following line in line with message from events.mc */ linux_log ("%s of root certificate: %s\nSha256 thumbprint:<%s>.\nCertificate store \"%s\"", install ? "Installation" : "Removal", subject, fingerprint, store); #endif x509_crt_free (&chain); xfree (der_data); } void syslog_info_printf(const char *format, ...) { va_list args; va_start (args, format); #ifdef WIN32 win_log (format, args, false); #else linux_log (format, args, false); #endif va_end (args); } void syslog_error_printf(const char *format, ...) { va_list args; va_start (args, format); #ifdef WIN32 win_log (format, args, true); #else linux_log (format, args, true); #endif va_end (args); }