From 3293d0d06a9c3754d54806bafa4e533fe968892b Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 16 Feb 2023 13:42:24 +0100 Subject: [PATCH] [core] add log for experimental settings Too often experimental flags had been used without the user noticing that. As bug reports are hard to analyze without proper information take this approach and inform about experimental flags in use by logging these. --- libfreerdp/core/freerdp.c | 3 + libfreerdp/core/peer.c | 2 + libfreerdp/core/rdp.c | 165 ++++++++++++++++++++++++++++++++++++++ libfreerdp/core/rdp.h | 2 + 4 files changed, 172 insertions(+) diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 436ce4fe4..cfabb078c 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -21,6 +21,7 @@ #include +#include #include #include "rdp.h" @@ -715,6 +716,8 @@ BOOL freerdp_context_new_ex(freerdp* instance, rdpSettings* settings) WINPR_ASSERT(instance); + rdp_log_build_warnings(); + instance->context = context = (rdpContext*)calloc(1, instance->ContextSize); if (!context) diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 7e373a0ec..bdbe720d9 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -1504,6 +1504,8 @@ BOOL freerdp_peer_context_new_ex(freerdp_peer* client, const rdpSettings* settin rdpContext* context; BOOL ret = TRUE; + rdp_log_build_warnings(); + if (!client) return FALSE; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 7dc929f0a..f02be272d 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -36,6 +36,7 @@ #include #include #include +#include #define TAG FREERDP_TAG("core.rdp") @@ -2559,3 +2560,167 @@ BOOL rdp_reset_runtime_settings(rdpRdp* rdp) return FALSE; return rdp_reset_remote_settings(rdp); } + +static BOOL starts_with(const char* tok, const char* val) +{ + const size_t len = strlen(val); + if (strncmp(tok, val, len) != 0) + return FALSE; + if (tok[len] != '=') + return FALSE; + return TRUE; +} + +static BOOL option_equals(const char* what, const char* val) +{ + return _stricmp(what, val) == 0; +} + +static BOOL parse_on_off_option(const char* value) +{ + WINPR_ASSERT(value); + const char* sep = strchr(value, '='); + if (!sep) + return TRUE; + if (option_equals("on", &sep[1])) + return TRUE; + if (option_equals("true", &sep[1])) + return TRUE; + if (option_equals("off", &sep[1])) + return FALSE; + if (option_equals("false", &sep[1])) + return FALSE; + + errno = 0; + long val = strtol(value, NULL, 0); + if (errno == 0) + return val == 0 ? FALSE : TRUE; + + return FALSE; +} + +#define STR(x) #x + +static BOOL option_is_experimental(const char* tok) +{ + const char* experimental[] = { STR(WITH_DSP_EXPERIMENTAL), STR(WITH_VAAPI) }; + for (size_t x = 0; x < ARRAYSIZE(experimental); x++) + { + const char* opt = experimental[x]; + if (starts_with(tok, opt)) + { + return parse_on_off_option(tok); + } + } + return FALSE; +} + +static BOOL option_is_debug(const char* tok) +{ + const char* debug[] = { STR(WITH_DEBUG_ALL), + STR(WITH_DEBUG_CERTIFICATE), + STR(WITH_DEBUG_CAPABILITIES), + STR(WITH_DEBUG_CHANNELS), + STR(WITH_DEBUG_CLIPRDR), + STR(WITH_DEBUG_CODECS), + STR(WITH_DEBUG_RDPGFX), + STR(WITH_DEBUG_DVC), + STR(WITH_DEBUG_TSMF), + STR(WITH_DEBUG_KBD), + STR(WITH_DEBUG_LICENSE), + STR(WITH_DEBUG_NEGO), + STR(WITH_DEBUG_NLA), + STR(WITH_DEBUG_TSG), + STR(WITH_DEBUG_RAIL), + STR(WITH_DEBUG_RDP), + STR(WITH_DEBUG_RDPEI), + STR(WITH_DEBUG_REDIR), + STR(WITH_DEBUG_RDPDR), + STR(WITH_DEBUG_RFX), + STR(WITH_DEBUG_SCARD), + STR(WITH_DEBUG_SND), + STR(WITH_DEBUG_SVC), + STR(WITH_DEBUG_TRANSPORT), + STR(WITH_DEBUG_TIMEZONE), + STR(WITH_DEBUG_WND), + STR(WITH_DEBUG_X11_CLIPRDR), + STR(WITH_DEBUG_X11_LOCAL_MOVESIZE), + STR(WITH_DEBUG_X11), + STR(WITH_DEBUG_XV), + STR(WITH_DEBUG_RINGBUFFER), + STR(WITH_DEBUG_SYMBOLS), + STR(WITH_DEBUG_EVENTS), + STR(WITH_DEBUG_MUTEX), + STR(WITH_DEBUG_NTLM), + STR(WITH_DEBUG_SDL_EVENTS), + STR(WITH_DEBUG_SDL_KBD_EVENTS), + STR(WITH_DEBUG_THREADS), + STR(WITH_DEBUG_URBDRC) }; + + for (size_t x = 0; x < ARRAYSIZE(debug); x++) + { + const char* opt = debug[x]; + if (starts_with(tok, opt)) + return parse_on_off_option(tok); + } + + if (starts_with(tok, "WITH_DEBUG")) + { + WLog_WARN(TAG, "[BUG] Unmapped Debug-Build option '%s'.", tok); + return parse_on_off_option(tok); + } + + return FALSE; +} + +static void log_build_warn(const char* what, const char* msg, BOOL (*cmp)(const char* tok)) +{ + size_t len = sizeof(FREERDP_BUILD_CONFIG); + char* list = calloc(len, sizeof(char)); + char* config = _strdup(FREERDP_BUILD_CONFIG); + if (config && list) + { + char* tok = strtok(config, " "); + while (tok) + { + if (cmp(tok)) + winpr_str_append(tok, list, len, " "); + + tok = strtok(NULL, " "); + } + } + free(config); + + if (list) + { + if (strlen(list) > 0) + { + WLog_WARN(TAG, "*************************************************"); + WLog_WARN(TAG, "This build is using [%s] build options:", what); + char* tok = strtok(list, " "); + while (tok) + { + WLog_WARN(TAG, "* '%s'", tok); + tok = strtok(NULL, " "); + } + WLog_WARN(TAG, ""); + WLog_WARN(TAG, "[%s] build options %s", what, msg); + WLog_WARN(TAG, "*************************************************"); + } + } + free(list); +} + +void rdp_log_build_warnings(void) +{ + static unsigned count = 0; + + /* Since this function is called in context creation routines stop logging + * this issue repetedly. This is required for proxy, which would otherwise + * spam the log with these. */ + if (count > 0) + return; + count++; + log_build_warn("experimental", "might crash the application", option_is_experimental); + log_build_warn("debug", "might leak sensitive information (credentials, ...)", option_is_debug); +} diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index 6389c8e84..5ade733f1 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -289,4 +289,6 @@ const char* rdp_security_flag_string(UINT32 securityFlags, char* buffer, size_t BOOL rdp_set_backup_settings(rdpRdp* rdp); BOOL rdp_reset_runtime_settings(rdpRdp* rdp); +void rdp_log_build_warnings(void); + #endif /* FREERDP_LIB_CORE_RDP_H */