FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
sdl_webview.cpp
1
20#include <string>
21#include <sstream>
22#include <cstdlib>
23#include <winpr/string.h>
24#include <freerdp/log.h>
25#include <freerdp/utils/aad.h>
26
27#include "sdl_webview.hpp"
28#include "webview_impl.hpp"
29
30#define TAG CLIENT_TAG("SDL.webview")
31
32static std::string from_settings(const rdpSettings* settings, FreeRDP_Settings_Keys_String id)
33{
34 auto val = freerdp_settings_get_string(settings, id);
35 if (!val)
36 {
37 WLog_WARN(TAG, "Settings key %s is NULL", freerdp_settings_get_name_for_key(id));
38 return "";
39 }
40 return val;
41}
42
43static std::string from_aad_wellknown(rdpContext* context, AAD_WELLKNOWN_VALUES which)
44{
45 auto val = freerdp_utils_aad_get_wellknown_string(context, which);
46
47 if (!val)
48 {
49 WLog_WARN(TAG, "[wellknown] key %s is NULL", freerdp_utils_aad_wellknwon_value_name(which));
50 return "";
51 }
52 return val;
53}
54
55static BOOL sdl_webview_get_rdsaad_access_token(freerdp* instance, const char* scope,
56 const char* req_cnf, char** token)
57{
58 WINPR_ASSERT(instance);
59 WINPR_ASSERT(scope);
60 WINPR_ASSERT(req_cnf);
61 WINPR_ASSERT(token);
62
63 WINPR_UNUSED(instance);
64 WINPR_UNUSED(instance->context);
65
66 auto client_id = from_settings(instance->context->settings, FreeRDP_GatewayAvdClientID);
67 std::string redirect_uri = "ms-appx-web%3a%2f%2fMicrosoft.AAD.BrokerPlugin%2f" + client_id;
68
69 *token = nullptr;
70
71 auto ep = from_aad_wellknown(instance->context, AAD_WELLKNOWN_authorization_endpoint);
72 auto url = ep + "?client_id=" + client_id + "&response_type=code&scope=" + scope +
73 "&redirect_uri=" + redirect_uri;
74
75 const std::string title = "FreeRDP WebView - AAD access token";
76 std::string code;
77 auto rc = webview_impl_run(title, url, code);
78 if (!rc || code.empty())
79 return FALSE;
80
81 auto token_request = "grant_type=authorization_code&code=" + code + "&client_id=" + client_id +
82 "&scope=" + scope + "&redirect_uri=" + redirect_uri +
83 "&req_cnf=" + req_cnf;
84 return client_common_get_access_token(instance, token_request.c_str(), token);
85}
86
87static BOOL sdl_webview_get_avd_access_token(freerdp* instance, char** token)
88{
89 WINPR_ASSERT(token);
90 WINPR_ASSERT(instance);
91 WINPR_ASSERT(instance->context);
92
93 auto client_id = from_settings(instance->context->settings, FreeRDP_GatewayAvdClientID);
94 std::string redirect_uri = "ms-appx-web%3a%2f%2fMicrosoft.AAD.BrokerPlugin%2f" + client_id;
95 std::string scope = "https%3A%2F%2Fwww.wvd.microsoft.com%2F.default";
96
97 *token = nullptr;
98
99 auto ep = from_aad_wellknown(instance->context, AAD_WELLKNOWN_authorization_endpoint);
100 auto url = ep + "?client_id=" + client_id + "&response_type=code&scope=" + scope +
101 "&redirect_uri=" + redirect_uri;
102 const std::string title = "FreeRDP WebView - AVD access token";
103 std::string code;
104 auto rc = webview_impl_run(title, url, code);
105 if (!rc || code.empty())
106 return FALSE;
107
108 auto token_request = "grant_type=authorization_code&code=" + code + "&client_id=" + client_id +
109 "&scope=" + scope + "&redirect_uri=" + redirect_uri;
110 return client_common_get_access_token(instance, token_request.c_str(), token);
111}
112
113BOOL sdl_webview_get_access_token(freerdp* instance, AccessTokenType tokenType, char** token,
114 size_t count, ...)
115{
116 WINPR_ASSERT(instance);
117 WINPR_ASSERT(token);
118 switch (tokenType)
119 {
120 case ACCESS_TOKEN_TYPE_AAD:
121 {
122 if (count < 2)
123 {
124 WLog_ERR(TAG,
125 "ACCESS_TOKEN_TYPE_AAD expected 2 additional arguments, but got %" PRIuz
126 ", aborting",
127 count);
128 return FALSE;
129 }
130 else if (count > 2)
131 WLog_WARN(TAG,
132 "ACCESS_TOKEN_TYPE_AAD expected 2 additional arguments, but got %" PRIuz
133 ", ignoring",
134 count);
135 va_list ap = {};
136 va_start(ap, count);
137 const char* scope = va_arg(ap, const char*);
138 const char* req_cnf = va_arg(ap, const char*);
139 const BOOL rc = sdl_webview_get_rdsaad_access_token(instance, scope, req_cnf, token);
140 va_end(ap);
141 return rc;
142 }
143 case ACCESS_TOKEN_TYPE_AVD:
144 if (count != 0)
145 WLog_WARN(TAG,
146 "ACCESS_TOKEN_TYPE_AVD expected 0 additional arguments, but got %" PRIuz
147 ", ignoring",
148 count);
149 return sdl_webview_get_avd_access_token(instance, token);
150 default:
151 WLog_ERR(TAG, "Unexpected value for AccessTokenType [%" PRIuz "], aborting", tokenType);
152 return FALSE;
153 }
154}
FREERDP_API const char * freerdp_settings_get_name_for_key(SSIZE_T key)
Returns the type name for a key.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.