diff --git a/client/SDL/common/aad/sdl_webview.cpp b/client/SDL/common/aad/sdl_webview.cpp index a2de52ffa..f5f37b514 100644 --- a/client/SDL/common/aad/sdl_webview.cpp +++ b/client/SDL/common/aad/sdl_webview.cpp @@ -20,6 +20,8 @@ #include #include #include +#include + #include #include #include @@ -68,25 +70,21 @@ static BOOL sdl_webview_get_rdsaad_access_token(freerdp* instance, const char* s auto settings = context->settings; WINPR_ASSERT(settings); - auto client_id = from_settings(settings, FreeRDP_GatewayAvdClientID); - std::string redirect_uri = "ms-appx-web%3a%2f%2fMicrosoft.AAD.BrokerPlugin%2f" + client_id; - - *token = nullptr; - - auto ep = from_aad_wellknown(context, AAD_WELLKNOWN_authorization_endpoint); - auto url = ep + "?client_id=" + client_id + "&response_type=code&scope=" + scope + - "&redirect_uri=" + redirect_uri; - + std::shared_ptr request(freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_AUTH_REQUEST, + scope), + free); const std::string title = "FreeRDP WebView - AAD access token"; std::string code; - auto rc = webview_impl_run(title, url, code); + auto rc = webview_impl_run(title, request.get(), code); if (!rc || code.empty()) return FALSE; - auto token_request = "grant_type=authorization_code&code=" + code + "&client_id=" + client_id + - "&scope=" + scope + "&redirect_uri=" + redirect_uri + - "&req_cnf=" + req_cnf; - return client_common_get_access_token(instance, token_request.c_str(), token); + std::shared_ptr token_request( + freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_TOKEN_REQUEST, scope, code.c_str(), req_cnf), + free); + return client_common_get_access_token(instance, token_request.get(), token); } static BOOL sdl_webview_get_avd_access_token(freerdp* instance, char** token) @@ -95,24 +93,21 @@ static BOOL sdl_webview_get_avd_access_token(freerdp* instance, char** token) WINPR_ASSERT(instance); WINPR_ASSERT(instance->context); - auto client_id = from_settings(instance->context->settings, FreeRDP_GatewayAvdClientID); - std::string redirect_uri = "ms-appx-web%3a%2f%2fMicrosoft.AAD.BrokerPlugin%2f" + client_id; - std::string scope = "https%3A%2F%2Fwww.wvd.microsoft.com%2F.default"; + std::shared_ptr request(freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_AVD_AUTH_REQUEST), + free); - *token = nullptr; - - auto ep = from_aad_wellknown(instance->context, AAD_WELLKNOWN_authorization_endpoint); - auto url = ep + "?client_id=" + client_id + "&response_type=code&scope=" + scope + - "&redirect_uri=" + redirect_uri; const std::string title = "FreeRDP WebView - AVD access token"; std::string code; - auto rc = webview_impl_run(title, url, code); + auto rc = webview_impl_run(title, request.get(), code); if (!rc || code.empty()) return FALSE; - auto token_request = "grant_type=authorization_code&code=" + code + "&client_id=" + client_id + - "&scope=" + scope + "&redirect_uri=" + redirect_uri; - return client_common_get_access_token(instance, token_request.c_str(), token); + std::shared_ptr token_request( + freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_AVD_TOKEN_REQUEST, code.c_str()), + free); + return client_common_get_access_token(instance, token_request.get(), token); } BOOL sdl_webview_get_access_token(freerdp* instance, AccessTokenType tokenType, char** token, diff --git a/client/common/client.c b/client/common/client.c index 4fdb60c7f..78666ff5f 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -1015,7 +1015,7 @@ BOOL client_cli_present_gateway_message(freerdp* instance, UINT32 type, BOOL isD return TRUE; } -static char* extract_authorization_code(char* url) +static const char* extract_authorization_code(char* url) { WINPR_ASSERT(url); @@ -1057,35 +1057,24 @@ static BOOL client_cli_get_rdsaad_access_token(freerdp* instance, const char* sc BOOL rc = FALSE; *token = NULL; - const char* client_id = - freerdp_settings_get_string(instance->context->settings, FreeRDP_GatewayAvdClientID); - if (!client_id) - goto cleanup; + char* request = freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_AUTH_REQUEST, scope); - winpr_asprintf(&redirect_uri, &redirec_uri_len, - "ms-appx-web%%3a%%2f%%2fMicrosoft.AAD.BrokerPlugin%%2f%s", client_id); - if (!redirect_uri) - goto cleanup; - - const char* ep = freerdp_utils_aad_get_wellknown_string(instance->context, - AAD_WELLKNOWN_authorization_endpoint); - printf("Browse to: %s?client_id=%s&response_type=" - "code&scope=%s&redirect_uri=%s" - "\n", - ep, client_id, scope, redirect_uri); + printf("Browse to: %s\n", request); + free(request); printf("Paste redirect URL here: \n"); if (freerdp_interruptible_get_line(instance->context, &url, &size, stdin) < 0) goto cleanup; - char* code = extract_authorization_code(url); + const char* code = extract_authorization_code(url); if (!code) goto cleanup; - if (winpr_asprintf(&token_request, &size, - "grant_type=authorization_code&code=%s&client_id=%s&scope=%s&redirect_uri=%" - "s&req_cnf=%s", - code, client_id, scope, redirect_uri, req_cnf) <= 0) + token_request = + freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_TOKEN_REQUEST, scope, code, req_cnf); + if (!token_request) goto cleanup; rc = client_common_get_access_token(instance, token_request, token); @@ -1106,8 +1095,6 @@ static BOOL client_cli_get_avd_access_token(freerdp* instance, char** token) char* url = NULL; char* token_request = NULL; char* redirect_uri = NULL; - size_t redirec_uri_len = 0; - const char* scope = "https%3A%2F%2Fwww.wvd.microsoft.com%2F.default"; WINPR_ASSERT(token); @@ -1115,43 +1102,25 @@ static BOOL client_cli_get_avd_access_token(freerdp* instance, char** token) *token = NULL; - const char* client_id = - freerdp_settings_get_string(instance->context->settings, FreeRDP_GatewayAvdClientID); - const char* base = freerdp_settings_get_string(instance->context->settings, - FreeRDP_GatewayAzureActiveDirectory); - const BOOL useTenant = - freerdp_settings_get_bool(instance->context->settings, FreeRDP_GatewayAvdUseTenantid); - const char* tenantid = "common"; - if (useTenant) - tenantid = - freerdp_settings_get_string(instance->context->settings, FreeRDP_GatewayAvdAadtenantid); - if (!base || !tenantid || !client_id) - goto cleanup; - - winpr_asprintf(&redirect_uri, &redirec_uri_len, - "https%%3A%%2F%%2F%s%%2F%s%%2Foauth2%%2Fnativeclient", base, tenantid); - if (!redirect_uri) - goto cleanup; - - const char* ep = freerdp_utils_aad_get_wellknown_string(instance->context, - AAD_WELLKNOWN_authorization_endpoint); - printf("Browse to: %s?client_id=%s&response_type=" - "code&scope=%s&redirect_uri=%s" - "\n", - ep, client_id, scope, redirect_uri); + char* request = freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_AVD_AUTH_REQUEST); + if (!request) + return FALSE; + printf("Browse to: %s\n", request); + free(request); printf("Paste redirect URL here: \n"); if (freerdp_interruptible_get_line(instance->context, &url, &size, stdin) < 0) goto cleanup; - char* code = extract_authorization_code(url); + const char* code = extract_authorization_code(url); if (!code) goto cleanup; - if (winpr_asprintf( - &token_request, &size, - "grant_type=authorization_code&code=%s&client_id=%s&scope=%s&redirect_uri=%s", code, - client_id, scope, redirect_uri) <= 0) + token_request = freerdp_client_get_aad_url((rdpClientContext*)instance->context, + FREERDP_CLIENT_AAD_AVD_TOKEN_REQUEST, code); + + if (!token_request) goto cleanup; rc = client_common_get_access_token(instance, token_request, token); @@ -2266,3 +2235,162 @@ BOOL freerdp_client_use_relative_mouse_events(rdpClientContext* ccontext) return useRelative && (haveRelative || ainput); } + +static char* avd_auth_request(rdpClientContext* cctx, WINPR_ATTR_UNUSED va_list ap) +{ + const rdpSettings* settings = cctx->context.settings; + const char* client_id = freerdp_settings_get_string(settings, FreeRDP_GatewayAvdClientID); + const char* ep = freerdp_utils_aad_get_wellknown_string(&cctx->context, + AAD_WELLKNOWN_authorization_endpoint); + const char* redirect_fmt = + freerdp_settings_get_string(settings, FreeRDP_GatewayAvdAccessTokenFormat); + const char* scope = freerdp_settings_get_string(settings, FreeRDP_GatewayAvdScope); + + if (!client_id || !ep || !redirect_fmt || !scope) + return NULL; + + char* redirect_uri = NULL; + size_t redirect_len = 0; + winpr_asprintf(&redirect_uri, &redirect_len, redirect_fmt, client_id); + + if (!redirect_uri) + return NULL; + + char* url = NULL; + size_t urllen = 0; + winpr_asprintf(&url, &urllen, "%s?client_id=%s&response_type=code&scope=%s&redirect_uri=%s", ep, + client_id, scope, redirect_uri); + free(redirect_uri); + return url; +} + +static char* avd_token_request(rdpClientContext* cctx, WINPR_ATTR_UNUSED va_list ap) +{ + const rdpSettings* settings = cctx->context.settings; + const char* client_id = freerdp_settings_get_string(settings, FreeRDP_GatewayAvdClientID); + const char* ep = freerdp_utils_aad_get_wellknown_string(&cctx->context, + AAD_WELLKNOWN_authorization_endpoint); + const char* redirect_fmt = + freerdp_settings_get_string(settings, FreeRDP_GatewayAvdAccessTokenFormat); + const char* scope = freerdp_settings_get_string(settings, FreeRDP_GatewayAvdScope); + + if (!client_id || !ep || !redirect_fmt || !scope) + return NULL; + + char* redirect_uri = NULL; + size_t redirect_len = 0; + winpr_asprintf(&redirect_uri, &redirect_len, redirect_fmt, client_id); + + if (!redirect_uri) + return NULL; + + char* url = NULL; + size_t urllen = 0; + + const char* code = va_arg(ap, const char*); + winpr_asprintf(&url, &urllen, + "grant_type=authorization_code&code=%s&client_id=%s&scope=%s&redirect_uri=%s", + code, client_id, scope, redirect_uri); + free(redirect_uri); + return url; +} + +static char* aad_auth_request(rdpClientContext* cctx, WINPR_ATTR_UNUSED va_list ap) +{ + const rdpSettings* settings = cctx->context.settings; + char* url = NULL; + size_t urllen = 0; + char* redirect_uri = NULL; + size_t redirect_len = 0; + + const char* client_id = freerdp_settings_get_string(settings, FreeRDP_GatewayAvdClientID); + if (!client_id) + goto cleanup; + const char* base = freerdp_settings_get_string(settings, FreeRDP_GatewayAzureActiveDirectory); + const char* urlFormatString = + freerdp_settings_get_string(settings, FreeRDP_GatewayAvdAccessTokenFormat); + const char* scope = va_arg(ap, const char*); + if (!urlFormatString || !scope) + goto cleanup; + + const BOOL useTenant = freerdp_settings_get_bool(settings, FreeRDP_GatewayAvdUseTenantid); + const char* tenantid = "common"; + if (useTenant) + tenantid = freerdp_settings_get_string(settings, FreeRDP_GatewayAvdAadtenantid); + if (!base || !tenantid || !client_id) + goto cleanup; + + winpr_asprintf(&redirect_uri, &redirect_len, urlFormatString, base, tenantid); + if (!redirect_uri) + goto cleanup; + + const char* ep = freerdp_utils_aad_get_wellknown_string(&cctx->context, + AAD_WELLKNOWN_authorization_endpoint); + + winpr_asprintf(&url, &urllen, "%s?client_id=%s&response_type=code&scope=%s&redirect_uri=%s", ep, + client_id, scope, redirect_uri); +cleanup: + free(redirect_uri); + return url; +} + +static char* aad_token_request(rdpClientContext* cctx, WINPR_ATTR_UNUSED va_list ap) +{ + const rdpSettings* settings = cctx->context.settings; + const char* client_id = freerdp_settings_get_string(settings, FreeRDP_GatewayAvdClientID); + const char* ep = freerdp_utils_aad_get_wellknown_string(&cctx->context, + AAD_WELLKNOWN_authorization_endpoint); + const char* redirect_fmt = + freerdp_settings_get_string(settings, FreeRDP_GatewayAvdAccessTokenFormat); + const char* scope = va_arg(ap, const char*); + const char* code = va_arg(ap, const char*); + const char* req_cnf = va_arg(ap, const char*); + + if (!client_id || !ep || !redirect_fmt || !scope || !code || !req_cnf) + return NULL; + + char* redirect_uri = NULL; + size_t redirect_len = 0; + winpr_asprintf(&redirect_uri, &redirect_len, redirect_fmt, client_id); + + if (!redirect_uri) + return NULL; + + char* url = NULL; + size_t urllen = 0; + + winpr_asprintf( + &url, &urllen, + "grant_type=authorization_code&code=%s&client_id=%s&scope=%s&redirect_uri=%s&req_cnf=%s", + code, client_id, scope, redirect_uri, req_cnf); + free(redirect_uri); + return url; +} + +char* freerdp_client_get_aad_url(rdpClientContext* cctx, freerdp_client_aad_type type, ...) +{ + WINPR_ASSERT(cctx); + char* str = NULL; + + va_list ap; + va_start(ap, type); + switch (type) + { + case FREERDP_CLIENT_AAD_AUTH_REQUEST: + str = aad_auth_request(cctx, ap); + break; + case FREERDP_CLIENT_AAD_TOKEN_REQUEST: + str = aad_token_request(cctx, ap); + break; + case FREERDP_CLIENT_AAD_AVD_AUTH_REQUEST: + str = avd_auth_request(cctx, ap); + break; + case FREERDP_CLIENT_AAD_AVD_TOKEN_REQUEST: + str = avd_token_request(cctx, ap); + break; + default: + break; + } + va_end(ap); + return str; +} diff --git a/client/common/cmdline.c b/client/common/cmdline.c index bf3f1d9b6..0d5561037 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -3730,9 +3730,14 @@ static int parse_aad_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_ SSIZE_T id; int (*fkt)(rdpSettings* settings, const char* value); }; - const struct app_map amap[] = { { "tenantid:", FreeRDP_GatewayAvdAadtenantid, - parse_app_option_program }, - { "ad:", FreeRDP_GatewayAzureActiveDirectory, NULL } }; + const struct app_map amap[] = { + { "tenantid:", FreeRDP_GatewayAvdAadtenantid, parse_app_option_program }, + { "ad:", FreeRDP_GatewayAzureActiveDirectory, NULL }, + { "avd-access:", FreeRDP_GatewayAvdAccessAadFormat, NULL }, + { "avd-token:", FreeRDP_GatewayAvdAccessTokenFormat, NULL }, + { "avd-scope:", FreeRDP_GatewayAvdScope, NULL } + + }; for (size_t x = 0; x < count; x++) { BOOL handled = FALSE; diff --git a/client/common/cmdline.h b/client/common/cmdline.h index bd33840cf..c6a838e77 100644 --- a/client/common/cmdline.h +++ b/client/common/cmdline.h @@ -26,7 +26,9 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = { { "a", COMMAND_LINE_VALUE_REQUIRED, "[,]", NULL, NULL, -1, "addin", "Addin" }, - { "azure", COMMAND_LINE_VALUE_REQUIRED, "[tenantid:],[use-tenantid[:[on|off]],[ad:]", + { "azure", COMMAND_LINE_VALUE_REQUIRED, + "[tenantid:],[use-tenantid[:[on|off]],[ad:]" + "[avd-access:],[avd-token:],[avd-scope:]", NULL, NULL, -1, NULL, "AzureAD options" }, { "action-script", COMMAND_LINE_VALUE_REQUIRED, "", "~/.config/freerdp/action.sh", NULL, -1, NULL, "Action script" }, diff --git a/include/freerdp/client.h b/include/freerdp/client.h index 60411d9c6..40adba717 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -318,6 +318,27 @@ extern "C" BOOL control); #endif + /** @brief type of AAD request + * @since version 3.16.0 + */ + typedef enum + { + FREERDP_CLIENT_AAD_AUTH_REQUEST, + FREERDP_CLIENT_AAD_TOKEN_REQUEST, + FREERDP_CLIENT_AAD_AVD_AUTH_REQUEST, + FREERDP_CLIENT_AAD_AVD_TOKEN_REQUEST, + } freerdp_client_aad_type; + + /** @brief helper function to construct a connection URL for AAD authentication + * + * @param cctx The client context to use + * @return An allocated string that can be used to connect + * @since version 3.16.0 + */ + WINPR_ATTR_MALLOC(free, 1) + FREERDP_API char* freerdp_client_get_aad_url(rdpClientContext* cctx, + freerdp_client_aad_type type, ...); + #ifdef __cplusplus } #endif diff --git a/include/freerdp/settings_types_private.h b/include/freerdp/settings_types_private.h index 2cc00d761..88dbd6720 100644 --- a/include/freerdp/settings_types_private.h +++ b/include/freerdp/settings_types_private.h @@ -502,7 +502,16 @@ struct rdp_settings SETTINGS_DEPRECATED(ALIGN64 BOOL GatewayAvdUseTenantid); /** 2020 * @since version 3.10.0 */ - UINT64 padding2112[2112 - 2021]; /* 2021 */ + SETTINGS_DEPRECATED(ALIGN64 char* GatewayAvdScope); /** 2021 + * @since version 3.14.1 + */ + SETTINGS_DEPRECATED(ALIGN64 char* GatewayAvdAccessTokenFormat); /** 2022 + * @since version 3.14.1 + */ + SETTINGS_DEPRECATED(ALIGN64 char* GatewayAvdAccessAadFormat); /** 2023 + * @since version 3.14.1 + */ + UINT64 padding2112[2112 - 2024]; /* 2024 */ /** * RemoteApp diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c index 23ffde07f..90c4996cb 100644 --- a/libfreerdp/common/settings_getters.c +++ b/libfreerdp/common/settings_getters.c @@ -2821,6 +2821,12 @@ const char* freerdp_settings_get_string(WINPR_ATTR_UNUSED const rdpSettings* set case FreeRDP_GatewayAvdAadtenantid: return settings->GatewayAvdAadtenantid; + case FreeRDP_GatewayAvdAccessAadFormat: + return settings->GatewayAvdAccessAadFormat; + + case FreeRDP_GatewayAvdAccessTokenFormat: + return settings->GatewayAvdAccessTokenFormat; + case FreeRDP_GatewayAvdActivityhint: return settings->GatewayAvdActivityhint; @@ -2839,6 +2845,9 @@ const char* freerdp_settings_get_string(WINPR_ATTR_UNUSED const rdpSettings* set case FreeRDP_GatewayAvdHubdiscoverygeourl: return settings->GatewayAvdHubdiscoverygeourl; + case FreeRDP_GatewayAvdScope: + return settings->GatewayAvdScope; + case FreeRDP_GatewayAvdWvdEndpointPool: return settings->GatewayAvdWvdEndpointPool; @@ -3136,6 +3145,12 @@ char* freerdp_settings_get_string_writable(rdpSettings* settings, FreeRDP_Settin case FreeRDP_GatewayAvdAadtenantid: return settings->GatewayAvdAadtenantid; + case FreeRDP_GatewayAvdAccessAadFormat: + return settings->GatewayAvdAccessAadFormat; + + case FreeRDP_GatewayAvdAccessTokenFormat: + return settings->GatewayAvdAccessTokenFormat; + case FreeRDP_GatewayAvdActivityhint: return settings->GatewayAvdActivityhint; @@ -3154,6 +3169,9 @@ char* freerdp_settings_get_string_writable(rdpSettings* settings, FreeRDP_Settin case FreeRDP_GatewayAvdHubdiscoverygeourl: return settings->GatewayAvdHubdiscoverygeourl; + case FreeRDP_GatewayAvdScope: + return settings->GatewayAvdScope; + case FreeRDP_GatewayAvdWvdEndpointPool: return settings->GatewayAvdWvdEndpointPool; @@ -3462,6 +3480,12 @@ BOOL freerdp_settings_set_string_(WINPR_ATTR_UNUSED rdpSettings* settings, case FreeRDP_GatewayAvdAadtenantid: return update_string_(&settings->GatewayAvdAadtenantid, cnv.c, len); + case FreeRDP_GatewayAvdAccessAadFormat: + return update_string_(&settings->GatewayAvdAccessAadFormat, cnv.c, len); + + case FreeRDP_GatewayAvdAccessTokenFormat: + return update_string_(&settings->GatewayAvdAccessTokenFormat, cnv.c, len); + case FreeRDP_GatewayAvdActivityhint: return update_string_(&settings->GatewayAvdActivityhint, cnv.c, len); @@ -3480,6 +3504,9 @@ BOOL freerdp_settings_set_string_(WINPR_ATTR_UNUSED rdpSettings* settings, case FreeRDP_GatewayAvdHubdiscoverygeourl: return update_string_(&settings->GatewayAvdHubdiscoverygeourl, cnv.c, len); + case FreeRDP_GatewayAvdScope: + return update_string_(&settings->GatewayAvdScope, cnv.c, len); + case FreeRDP_GatewayAvdWvdEndpointPool: return update_string_(&settings->GatewayAvdWvdEndpointPool, cnv.c, len); @@ -3804,6 +3831,13 @@ BOOL freerdp_settings_set_string_copy_(WINPR_ATTR_UNUSED rdpSettings* settings, case FreeRDP_GatewayAvdAadtenantid: return update_string_copy_(&settings->GatewayAvdAadtenantid, cnv.cc, len, cleanup); + case FreeRDP_GatewayAvdAccessAadFormat: + return update_string_copy_(&settings->GatewayAvdAccessAadFormat, cnv.cc, len, cleanup); + + case FreeRDP_GatewayAvdAccessTokenFormat: + return update_string_copy_(&settings->GatewayAvdAccessTokenFormat, cnv.cc, len, + cleanup); + case FreeRDP_GatewayAvdActivityhint: return update_string_copy_(&settings->GatewayAvdActivityhint, cnv.cc, len, cleanup); @@ -3824,6 +3858,9 @@ BOOL freerdp_settings_set_string_copy_(WINPR_ATTR_UNUSED rdpSettings* settings, return update_string_copy_(&settings->GatewayAvdHubdiscoverygeourl, cnv.cc, len, cleanup); + case FreeRDP_GatewayAvdScope: + return update_string_copy_(&settings->GatewayAvdScope, cnv.cc, len, cleanup); + case FreeRDP_GatewayAvdWvdEndpointPool: return update_string_copy_(&settings->GatewayAvdWvdEndpointPool, cnv.cc, len, cleanup); diff --git a/libfreerdp/common/settings_str.h b/libfreerdp/common/settings_str.h index dea577748..8d6b70a0a 100644 --- a/libfreerdp/common/settings_str.h +++ b/libfreerdp/common/settings_str.h @@ -491,6 +491,10 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_GatewayAccessToken, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAccessToken" }, { FreeRDP_GatewayAvdAadtenantid, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdAadtenantid" }, + { FreeRDP_GatewayAvdAccessAadFormat, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayAvdAccessAadFormat" }, + { FreeRDP_GatewayAvdAccessTokenFormat, FREERDP_SETTINGS_TYPE_STRING, + "FreeRDP_GatewayAvdAccessTokenFormat" }, { FreeRDP_GatewayAvdActivityhint, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdActivityhint" }, { FreeRDP_GatewayAvdArmpath, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdArmpath" }, @@ -500,6 +504,7 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_GatewayAvdGeo, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdGeo" }, { FreeRDP_GatewayAvdHubdiscoverygeourl, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdHubdiscoverygeourl" }, + { FreeRDP_GatewayAvdScope, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdScope" }, { FreeRDP_GatewayAvdWvdEndpointPool, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_GatewayAvdWvdEndpointPool" }, { FreeRDP_GatewayAzureActiveDirectory, FREERDP_SETTINGS_TYPE_STRING, diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 8d83d7c5b..1d741b77e 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -1881,7 +1881,7 @@ BOOL gcc_read_client_network_data(wStream* s, rdpMcs* mcs) Stream_Read_UINT32(s, mcs->channelCount); /* channelCount */ - if (!Stream_CheckAndLogRequiredLengthWLog(mcs->log, s, mcs->channelCount * 12)) + if (!Stream_CheckAndLogRequiredLengthOfSizeWLog(mcs->log, s, mcs->channelCount, 12ull)) return FALSE; if (mcs->channelCount > CHANNEL_MAX_COUNT) diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index d52626480..296dc532c 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -795,6 +795,19 @@ rdpSettings* freerdp_settings_new(DWORD flags) if (!server && !remote) { + if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdScope, + "https%%3A%%2F%%2F%s%%2F%s%%2Foauth2%%2Fnativeclient")) + goto out_fail; + if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdAccessTokenFormat, + "ms-appx-web%%3a%%2f%%2fMicrosoft.AAD.BrokerPlugin%%2f%s")) + goto out_fail; + if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdAccessAadFormat, + "https%%3A%%2F%%2F%s%%2F%s%%2Foauth2%%2Fnativeclient")) + goto out_fail; + if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdScope, + "https%3A%2F%2Fwww.wvd.microsoft.com%2F.default")) + + goto out_fail; if (!freerdp_settings_set_string(settings, FreeRDP_GatewayAvdClientID, "a85cf173-4192-42f8-81fa-777a763e6e2c")) goto out_fail; diff --git a/libfreerdp/core/test/settings_property_lists.h b/libfreerdp/core/test/settings_property_lists.h index bafe09386..b2a9a2bc0 100644 --- a/libfreerdp/core/test/settings_property_lists.h +++ b/libfreerdp/core/test/settings_property_lists.h @@ -391,12 +391,15 @@ static const size_t string_list_indices[] = { FreeRDP_GatewayAcceptedCert, FreeRDP_GatewayAccessToken, FreeRDP_GatewayAvdAadtenantid, + FreeRDP_GatewayAvdAccessAadFormat, + FreeRDP_GatewayAvdAccessTokenFormat, FreeRDP_GatewayAvdActivityhint, FreeRDP_GatewayAvdArmpath, FreeRDP_GatewayAvdClientID, FreeRDP_GatewayAvdDiagnosticserviceurl, FreeRDP_GatewayAvdGeo, FreeRDP_GatewayAvdHubdiscoverygeourl, + FreeRDP_GatewayAvdScope, FreeRDP_GatewayAvdWvdEndpointPool, FreeRDP_GatewayAzureActiveDirectory, FreeRDP_GatewayDomain, diff --git a/libfreerdp/utils/smartcard_call.c b/libfreerdp/utils/smartcard_call.c index b66030664..3f5ffaa8c 100644 --- a/libfreerdp/utils/smartcard_call.c +++ b/libfreerdp/utils/smartcard_call.c @@ -1319,6 +1319,7 @@ static LONG smartcard_StatusW_Call(scard_call_context* smartcard, wStream* out, if ((ret.ReturnCode == SCARD_S_SUCCESS) && (ret.cBytes == SCARD_AUTOALLOCATE)) return SCARD_F_UNKNOWN_ERROR; + size_t blen = 0; if (status == SCARD_S_SUCCESS) { if (!call->fmszReaderNamesIsNULL) @@ -1327,11 +1328,14 @@ static LONG smartcard_StatusW_Call(scard_call_context* smartcard, wStream* out, ret.cbAtrLen = cbAtrLen; } - /* SCardStatusW returns number of characters, we need number of bytes */ - WINPR_ASSERT(ret.cBytes < SCARD_AUTOALLOCATE / sizeof(WCHAR)); - const size_t blen = sizeof(WCHAR) * ret.cBytes; - WINPR_ASSERT(blen <= UINT32_MAX); - ret.cBytes = (UINT32)blen; + if (ret.cBytes != SCARD_AUTOALLOCATE) + { + /* SCardStatusW returns number of characters, we need number of bytes */ + WINPR_ASSERT(ret.cBytes < SCARD_AUTOALLOCATE / sizeof(WCHAR)); + blen = sizeof(WCHAR) * ret.cBytes; + WINPR_ASSERT(blen <= UINT32_MAX); + ret.cBytes = (UINT32)blen; + } status = smartcard_pack_status_return(out, &ret, TRUE); if (status != SCARD_S_SUCCESS)