From 4e212e6f31767595f609d8edb710051cc797ebb6 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Wed, 10 Dec 2025 14:08:13 +0100 Subject: [PATCH 1/4] [utils,http] log http response add the full http response to the debug log --- libfreerdp/utils/http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfreerdp/utils/http.c b/libfreerdp/utils/http.c index a8da164d8..b4fb119ce 100644 --- a/libfreerdp/utils/http.c +++ b/libfreerdp/utils/http.c @@ -288,6 +288,8 @@ BOOL freerdp_http_request(const char* url, const char* body, long* status_code, } } + WLog_Print(log, WLOG_DEBUG, "response[%" PRIuz "]:\n%s", *response_length, + (const char*)(*response)); ret = TRUE; out: From acf04f1087d731f33f5d834cd035d0d9cd4cdfcb Mon Sep 17 00:00:00 2001 From: akallabeth Date: Wed, 10 Dec 2025 14:39:55 +0100 Subject: [PATCH 2/4] [winpr,platform] add C11 thread_local support --- winpr/include/winpr/platform.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/winpr/include/winpr/platform.h b/winpr/include/winpr/platform.h index e740b5351..3a07199b5 100644 --- a/winpr/include/winpr/platform.h +++ b/winpr/include/winpr/platform.h @@ -595,7 +595,12 @@ WINPR_PRAGMA_DIAG_POP // WARNING: *do not* use thread-local storage for new code because it is not portable // It is only used for VirtualChannelInit, and all FreeRDP channels use VirtualChannelInitEx // The old virtual channel API is only realistically used on Windows where TLS is available -#if defined _WIN32 || defined __CYGWIN__ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(__STDC_NO_THREADS__) // C11 +#include + +#define WINPR_TLS thread_local +#elif defined _WIN32 || defined __CYGWIN__ #ifdef __GNUC__ #define WINPR_TLS __thread #else From bbae8d1d6b585bee5640c949fda443adf18de8c5 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Wed, 10 Dec 2025 14:08:37 +0100 Subject: [PATCH 3/4] [winpr,utils] fix jansson wrapper * Fix WINPR_JSON_ParseWithLength (jansson does not like buffer sizes larger than the JSON strig) * Implement WINPR_JSON_GetErrorPtr --- winpr/libwinpr/utils/json/jansson.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/winpr/libwinpr/utils/json/jansson.c b/winpr/libwinpr/utils/json/jansson.c index ce3c23ce0..2c69712a8 100644 --- a/winpr/libwinpr/utils/json/jansson.c +++ b/winpr/libwinpr/utils/json/jansson.c @@ -30,6 +30,8 @@ #error "The library detected is too old, need >= 2.13.0" #endif +static WINPR_TLS char lasterror[256] = { 0 }; + #if defined(WITH_DEBUG_JANSSON) #include "../log.h" #define TAG WINPR_TAG("jansson") @@ -94,16 +96,28 @@ int WINPR_JSON_version(char* buffer, size_t len) return _snprintf(buffer, len, "jansson %s", jansson_version_str()); } +static WINPR_JSON* updateError(WINPR_JSON* json, const json_error_t* error) +{ + lasterror[0] = '\0'; + if (!json) + (void)_snprintf(lasterror, sizeof(lasterror), "[%d:%d:%d] %s [%s]", error->line, + error->column, error->position, error->text, error->source); + return json; +} + WINPR_JSON* WINPR_JSON_Parse(const char* value) { json_error_t error = { 0 }; - return revcast(json_loads(value, JSON_DECODE_ANY, &error)); + WINPR_JSON* json = revcast(json_loads(value, JSON_DECODE_ANY, &error)); + return updateError(json, &error); } WINPR_JSON* WINPR_JSON_ParseWithLength(const char* value, size_t buffer_length) { json_error_t error = { 0 }; - return revcast(json_loadb(value, buffer_length, JSON_DECODE_ANY, &error)); + const size_t slen = strnlen(value, buffer_length); + WINPR_JSON* json = revcast(json_loadb(value, slen, JSON_DECODE_ANY, &error)); + return updateError(json, &error); } void WINPR_JSON_Delete(WINPR_JSON* item) @@ -147,7 +161,7 @@ BOOL WINPR_JSON_HasObjectItem(const WINPR_JSON* object, const char* string) const char* WINPR_JSON_GetErrorPtr(void) { - return NULL; + return lasterror; } const char* WINPR_JSON_GetStringValue(WINPR_JSON* item) From d1ed8db7f0c599d270b926ad7df79e9193d47bb3 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Wed, 10 Dec 2025 14:22:17 +0100 Subject: [PATCH 4/4] [core,aad] log WINPR_JSON_ParseWithLength failures --- libfreerdp/core/aad.c | 19 +++++++++++++++---- libfreerdp/core/gateway/arm.c | 6 +++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/libfreerdp/core/aad.c b/libfreerdp/core/aad.c index 242891751..179003d6b 100644 --- a/libfreerdp/core/aad.c +++ b/libfreerdp/core/aad.c @@ -244,7 +244,8 @@ static BOOL aad_get_nonce(rdpAad* aad) json = WINPR_JSON_ParseWithLength((const char*)response, response_length); if (!json) { - WLog_Print(aad->log, WLOG_ERROR, "Failed to parse nonce response"); + WLog_Print(aad->log, WLOG_ERROR, "Failed to parse nonce response: %s", + WINPR_JSON_GetErrorPtr()); goto fail; } @@ -536,7 +537,11 @@ static int aad_parse_state_initial(rdpAad* aad, wStream* s) json = WINPR_JSON_ParseWithLength(jstr, jlen); if (!json) + { + WLog_Print(aad->log, WLOG_ERROR, "WINPR_JSON_ParseWithLength failed: %s", + WINPR_JSON_GetErrorPtr()); goto fail; + } if (!json_get_const_string(aad->log, json, "ts_nonce", &ts_nonce)) goto fail; @@ -561,7 +566,11 @@ static int aad_parse_state_auth(rdpAad* aad, wStream* s) json = WINPR_JSON_ParseWithLength(jstr, jlength); if (!json) + { + WLog_Print(aad->log, WLOG_ERROR, "WINPR_JSON_ParseWithLength: %s", + WINPR_JSON_GetErrorPtr()); goto fail; + } if (!json_get_number(aad->log, json, "authentication_result", &result)) goto fail; @@ -851,8 +860,9 @@ char* freerdp_utils_aad_get_access_token(wLog* log, const char* data, size_t len WINPR_JSON* json = WINPR_JSON_ParseWithLength(data, length); if (!json) { - WLog_Print(log, WLOG_ERROR, "Failed to parse access token response [got %" PRIuz " bytes", - length); + WLog_Print(log, WLOG_ERROR, + "Failed to parse access token response [got %" PRIuz " bytes: %s", length, + WINPR_JSON_GetErrorPtr()); goto cleanup; } @@ -1026,7 +1036,8 @@ WINPR_JSON* freerdp_utils_aad_get_wellknown(wLog* log, const char* base, const c free(response); if (!json) - WLog_Print(log, WLOG_ERROR, "failed to parse response as JSON"); + WLog_Print(log, WLOG_ERROR, "failed to parse response as JSON: %s", + WINPR_JSON_GetErrorPtr()); return json; } diff --git a/libfreerdp/core/gateway/arm.c b/libfreerdp/core/gateway/arm.c index c14ec11df..12264318a 100644 --- a/libfreerdp/core/gateway/arm.c +++ b/libfreerdp/core/gateway/arm.c @@ -954,7 +954,8 @@ static BOOL arm_fill_gateway_parameters(rdpArm* arm, const char* message, size_t BOOL status = FALSE; if (!json) { - WLog_Print(arm->log, WLOG_ERROR, "Response data is not valid JSON"); + WLog_Print(arm->log, WLOG_ERROR, "Response data is not valid JSON: %s", + WINPR_JSON_GetErrorPtr()); return FALSE; } @@ -1078,8 +1079,7 @@ static BOOL arm_handle_bad_request(rdpArm* arm, const HttpResponse* response, BO if (json == NULL) { const char* error_ptr = WINPR_JSON_GetErrorPtr(); - if (error_ptr != NULL) - WLog_Print(arm->log, WLOG_ERROR, "NullPoException: %s", error_ptr); + WLog_Print(arm->log, WLOG_ERROR, "WINPR_JSON_ParseWithLength: %s", error_ptr); return FALSE; }