From 8714019703c1eaaeed45ac7e0f25a7a5b7463180 Mon Sep 17 00:00:00 2001 From: Andreas Ziegler Date: Tue, 20 May 2025 09:48:17 +0200 Subject: [PATCH] refactor: move MIBClientApp into struct rdp_client_context --- CMakeLists.txt | 12 +++++ client/common/CMakeLists.txt | 4 +- client/common/client.c | 90 ++++++++++++++++++++---------------- include/freerdp/client.h | 7 ++- 4 files changed, 69 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33847752a..72e0c7181 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ # Copyright 2011 Otavio Salvador # Copyright 2011 Marc-Andre Moreau # Copyright 2012 HP Development Company, LLC +# Copyright 2025 Siemens # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -402,6 +403,17 @@ if(NOT WITHOUT_FREERDP_3x_DEPRECATED) find_feature(Wayland ${WAYLAND_FEATURE_TYPE} ${WAYLAND_FEATURE_PURPOSE} ${WAYLAND_FEATURE_DESCRIPTION}) endif() +if(UNIX) + option(WITH_SSO_MIB "Build with sso-mib support" OFF) +else() + set(WITH_SSO_MIB OFF CACHE INTERNAL "unsupported platform") +endif() + +if(WITH_SSO_MIB) + set(SSO_MIB_EXTERNAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/sso-mib") + find_package(SSO_MIB REQUIRED) +endif() + option(WITH_LIBRESSL "build with LibreSSL" OFF) if(WITH_LIBRESSL) find_package(LibreSSL REQUIRED) diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt index 9153350ad..c7b356cbb 100644 --- a/client/common/CMakeLists.txt +++ b/client/common/CMakeLists.txt @@ -55,10 +55,8 @@ endif() include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR}) -option(WITH_SSO_MIB "Build with sso-mib support" OFF) -if(UNIX AND WITH_SSO_MIB) +if(WITH_SSO_MIB) set(SSO_MIB_EXTERNAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../external/sso-mib") - find_package(SSO_MIB REQUIRED) include_directories(${SSO_MIB_INCLUDE_DIRS}) add_compile_definitions(WITH_SSO_MIB) diff --git a/client/common/client.c b/client/common/client.c index 184102588..3279da494 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -74,8 +74,6 @@ #include #include -static MIBClientApp* sso_mib_client_app = NULL; - enum sso_mib_state { SSO_MIB_STATE_INIT = 0, @@ -83,7 +81,12 @@ enum sso_mib_state SSO_MIB_STATE_SUCCESS = 2, }; -static enum sso_mib_state sso_mib_state = SSO_MIB_STATE_INIT; +struct MIBClientWrapper +{ + MIBClientApp* app; + enum sso_mib_state state; +}; + #endif #include @@ -182,11 +185,6 @@ void freerdp_client_context_free(rdpContext* context) if (!context) return; -#ifdef WITH_SSO_MIB - if (sso_mib_client_app) - g_object_unref(sso_mib_client_app); -#endif // WITH_SSO_MIB - instance = context->instance; if (instance) @@ -212,6 +210,24 @@ int freerdp_client_start(rdpContext* context) if (freerdp_settings_get_bool(context->settings, FreeRDP_UseCommonStdioCallbacks)) set_default_callbacks(context->instance); +#ifdef WITH_SSO_MIB + rdpClientContext* client_context = (rdpClientContext*)context; + client_context->mibClientWrapper = (MIBClientWrapper*)calloc(1, sizeof(MIBClientWrapper)); + if (!client_context->mibClientWrapper) + return ERROR_NOT_ENOUGH_MEMORY; + const char* client_id = + freerdp_settings_get_string(context->settings, FreeRDP_GatewayAvdClientID); + client_context->mibClientWrapper->app = + mib_public_client_app_new(client_id, MIB_AUTHORITY_COMMON, NULL, NULL); + if (!client_context->mibClientWrapper->app) + { + free(client_context->mibClientWrapper); + client_context->mibClientWrapper = NULL; + return ERROR_INTERNAL_ERROR; + } + client_context->mibClientWrapper->state = SSO_MIB_STATE_INIT; +#endif + pEntryPoints = context->instance->pClientEntryPoints; return IFCALLRESULT(CHANNEL_RC_OK, pEntryPoints->ClientStart, context); } @@ -223,6 +239,13 @@ int freerdp_client_stop(rdpContext* context) if (!context || !context->instance || !context->instance->pClientEntryPoints) return ERROR_BAD_ARGUMENTS; +#ifdef WITH_SSO_MIB + rdpClientContext* client_context = (rdpClientContext*)context; + if (client_context->mibClientWrapper->app) + g_object_unref(client_context->mibClientWrapper->app); + free(client_context->mibClientWrapper); +#endif + pEntryPoints = context->instance->pClientEntryPoints; return IFCALLRESULT(CHANNEL_RC_OK, pEntryPoints->ClientStop, context); } @@ -1102,21 +1125,13 @@ cleanup: } #ifdef WITH_SSO_MIB -static MIBClientApp* get_or_create_mib_client_app(freerdp* instance) -{ - if (!sso_mib_client_app) - { - const char* client_id = - freerdp_settings_get_string(instance->context->settings, FreeRDP_GatewayAvdClientID); - sso_mib_client_app = mib_public_client_app_new(client_id, MIB_AUTHORITY_COMMON, NULL, NULL); - } - return sso_mib_client_app; -} static BOOL client_cli_get_avd_access_token_from_sso_mib(freerdp* instance, char** token) { WINPR_ASSERT(instance); WINPR_ASSERT(instance->context); + rdpClientContext* client_context = (rdpClientContext*)instance->context; + WINPR_ASSERT(client_context->mibClientWrapper->app); WINPR_ASSERT(token); MIBAccount* account = NULL; @@ -1125,13 +1140,7 @@ static BOOL client_cli_get_avd_access_token_from_sso_mib(freerdp* instance, char BOOL rc = FALSE; *token = NULL; - MIBClientApp* app = get_or_create_mib_client_app(instance); - if (!app) - { - goto cleanup; - } - - account = mib_client_app_get_account_by_upn(app, NULL); + account = mib_client_app_get_account_by_upn(client_context->mibClientWrapper->app, NULL); if (!account) { goto cleanup; @@ -1139,7 +1148,8 @@ static BOOL client_cli_get_avd_access_token_from_sso_mib(freerdp* instance, char scopes = g_slist_append(scopes, g_strdup("https://www.wvd.microsoft.com/.default")); - MIBPrt* prt = mib_client_app_acquire_token_silent(app, account, scopes, NULL, NULL, NULL); + MIBPrt* prt = mib_client_app_acquire_token_silent(client_context->mibClientWrapper->app, + account, scopes, NULL, NULL, NULL); if (prt) { const char* access_token = mib_prt_get_access_token(prt); @@ -1163,6 +1173,8 @@ static BOOL client_cli_get_rdsaad_access_token_from_sso_mib(freerdp* instance, c { WINPR_ASSERT(instance); WINPR_ASSERT(instance->context); + rdpClientContext* client_context = (rdpClientContext*)instance->context; + WINPR_ASSERT(client_context->mibClientWrapper->app); WINPR_ASSERT(scope); WINPR_ASSERT(token); WINPR_ASSERT(req_cnf); @@ -1176,12 +1188,6 @@ static BOOL client_cli_get_rdsaad_access_token_from_sso_mib(freerdp* instance, c BYTE* req_cnf_dec = NULL; size_t req_cnf_dec_len; - MIBClientApp* app = get_or_create_mib_client_app(instance); - if (!app) - { - goto cleanup; - } - scopes = g_slist_append(scopes, g_strdup(scope)); // Parse the "kid" element from req_cnf @@ -1209,8 +1215,8 @@ static BOOL client_cli_get_rdsaad_access_token_from_sso_mib(freerdp* instance, c params = mib_pop_params_new(MIB_AUTH_SCHEME_POP, MIB_REQUEST_METHOD_GET, ""); mib_pop_params_set_kid(params, kid); - MIBPrt* prt = mib_client_app_acquire_token_interactive(app, scopes, MIB_PROMPT_NONE, NULL, NULL, - NULL, params); + MIBPrt* prt = mib_client_app_acquire_token_interactive( + client_context->mibClientWrapper->app, scopes, MIB_PROMPT_NONE, NULL, NULL, NULL, params); if (prt) { *token = strdup(mib_prt_get_access_token(prt)); @@ -1249,19 +1255,21 @@ static BOOL client_cli_get_avd_access_token(freerdp* instance, char** token) *token = NULL; #ifdef WITH_SSO_MIB - if (sso_mib_state == SSO_MIB_STATE_INIT || sso_mib_state == SSO_MIB_STATE_SUCCESS) + rdpClientContext* client_context = (rdpClientContext*)instance->context; + if (client_context->mibClientWrapper->state == SSO_MIB_STATE_INIT || + client_context->mibClientWrapper->state == SSO_MIB_STATE_SUCCESS) { rc = client_cli_get_avd_access_token_from_sso_mib(instance, token); if (rc) { - sso_mib_state = SSO_MIB_STATE_SUCCESS; + client_context->mibClientWrapper->state = SSO_MIB_STATE_SUCCESS; return rc; } else { WLog_WARN(TAG, "Getting AVD token from identity broker failed, falling back to " "browser-based authentication."); - sso_mib_state = SSO_MIB_STATE_FAILED; + client_context->mibClientWrapper->state = SSO_MIB_STATE_FAILED; // Fall through to regular avd access token retrieval } } @@ -1350,7 +1358,9 @@ BOOL client_cli_get_access_token(freerdp* instance, AccessTokenType tokenType, c BOOL rc = FALSE; #ifdef WITH_SSO_MIB - if (sso_mib_state == SSO_MIB_STATE_INIT || sso_mib_state == SSO_MIB_STATE_SUCCESS) + rdpClientContext* client_context = (rdpClientContext*)instance->context; + if (client_context->mibClientWrapper->state == SSO_MIB_STATE_INIT || + client_context->mibClientWrapper->state == SSO_MIB_STATE_SUCCESS) { // Setup scope without URL encoding for sso-mib char* scope_copy = winpr_str_url_decode(scope, strlen(scope)); @@ -1366,7 +1376,7 @@ BOOL client_cli_get_access_token(freerdp* instance, AccessTokenType tokenType, c free(scope_copy); if (rc) { - sso_mib_state = SSO_MIB_STATE_SUCCESS; + client_context->mibClientWrapper->state = SSO_MIB_STATE_SUCCESS; va_end(ap); return rc; } @@ -1374,7 +1384,7 @@ BOOL client_cli_get_access_token(freerdp* instance, AccessTokenType tokenType, c { WLog_WARN(TAG, "Getting RDS token from identity broker failed, falling back to " "browser-based authentication."); - sso_mib_state = SSO_MIB_STATE_FAILED; + client_context->mibClientWrapper->state = SSO_MIB_STATE_FAILED; // Fall through to regular rdsaad access token retrieval } } diff --git a/include/freerdp/client.h b/include/freerdp/client.h index d5d73b3f3..60411d9c6 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -3,6 +3,7 @@ * Client Interface * * Copyright 2013 Marc-Andre Moreau + * Copyright 2025 Siemens * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +42,8 @@ #include #endif +typedef struct MIBClientWrapper MIBClientWrapper; + #ifdef __cplusplus extern "C" { @@ -136,7 +139,9 @@ extern "C" #endif ALIGN64 FreeRDP_TouchContact contacts[FREERDP_MAX_TOUCH_CONTACTS]; /**< (offset 8) */ ALIGN64 FreeRDP_PenDevice pens[FREERDP_MAX_PEN_DEVICES]; /**< (offset 9) */ - UINT64 reserved[128 - 9]; /**< (offset 9) */ + + ALIGN64 MIBClientWrapper* mibClientWrapper; /**< (offset 10) */ + UINT64 reserved[128 - 10]; /**< (offset 10) */ }; /* Common client functions */