Mercurial > trustbridge
view common/logging.c @ 856:797aa8d9c785
(issue48) Fallback to HKEY_USERS on hive load failure
If the hive can not be loaded it might mean that the user
is currently logged on. In that case we can access his
registry via HKEY_USERS.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Thu, 31 Jul 2014 12:56:26 +0200 |
parents | 2303caf56dbb |
children | 698b6a9bd75e |
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 *der_data = NULL; size_t der_size = 0; int ret = 0; ret = str_base64_decode (&der_data, &der_size, b64cert, strlen(b64cert)); if (ret != 0) { ERRORPRINTF ("Error decoding certificate.\n"); return; } log_certificate_der (store, (unsigned char *) der_data, der_size, install); xfree (der_data); } void log_certificate_der(const char *store, unsigned char *der_data, size_t der_size, bool install) { char subject[MAX_LOG + 1]; int ret = 0, i = 0; x509_crt chain; unsigned char sha256sum[32]; char fingerprint[32 * 3 + 1]; x509_crt_init(&chain); if (x509_crt_parse_der(&chain, (const unsigned char *)der_data, der_size) != 0) { ERRORPRINTF("Failed to parse cert.."); return; } ret = x509_dn_gets(subject, MAX_LOG, &(chain.subject)); if (ret == -1) { ERRORPRINTF("Failed to parse subject.."); return; } subject[MAX_LOG] = '\0'; sha256 (chain.raw.p, chain.raw.len, sha256sum, 0); for (i = 0; i < 31; i++) { snprintf (fingerprint + (i * 3), 4, "%02X:", sha256sum[i]); } snprintf (fingerprint + (31 * 3), 3, "%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 */ syslog_info_printf ("%s of root certificate: %s Sha256 thumbprint:<%s>. Certificate store \"%s\"", install ? "Installation" : "Removal", subject, fingerprint, store); #endif x509_crt_free (&chain); } 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); }