Mercurial > trustbridge
view common/logging.c @ 1119:5349e2354c48
(issue54) Merge branch runafterinstall
There is now an NSIS Plugin that executes the Software after
installation using COM in the shell of the current user.
With the way over the shell there is no inheritance /
token management required. As it is impossible to
drop all privileges of a token granted by UAC and
still be able to reelevate the Token again with another
RunAs call later this round trip over the Shell was
necessary.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Tue, 16 Sep 2014 19:48:22 +0200 |
parents | 698b6a9bd75e |
children |
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); }