FreeRDP
Loading...
Searching...
No Matches
ios_freerdp_ui.m
1/*
2 RDP ui callbacks
3
4 Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
5
6 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
7 If a copy of the MPL was not distributed with this file, You can obtain one at
8 http://mozilla.org/MPL/2.0/.
9 */
10
11#import <Foundation/Foundation.h>
12
13#import <freerdp/gdi/gdi.h>
14#import "ios_freerdp_ui.h"
15
16#import "RDPSession.h"
17
18#pragma mark -
19#pragma mark Certificate authentication
20
21static void ios_resize_display_buffer(mfInfo *mfi);
22
23BOOL ios_ui_authenticate_ex(freerdp *instance, char **username, char **password, char **domain,
24 rdp_auth_reason reason)
25{
26 const char *target = freerdp_settings_get_server_name(instance->context->settings);
27 switch (reason)
28 {
29 case AUTH_RDSTLS:
30 case AUTH_NLA:
31 break;
32
33 case AUTH_TLS:
34 case AUTH_RDP:
35 case AUTH_SMARTCARD_PIN: /* in this case password is pin code */
36 case AUTH_FIDO_PIN:
37 if ((*username) && (*password))
38 return TRUE;
39 break;
40 case GW_AUTH_HTTP:
41 case GW_AUTH_RDG:
42 case GW_AUTH_RPC:
43 target =
44 freerdp_settings_get_string(instance->context->settings, FreeRDP_GatewayHostname);
45 break;
46 default:
47 break;
48 }
49
50 mfInfo *mfi = MFI_FROM_INSTANCE(instance);
51 NSMutableDictionary *params = [NSMutableDictionary
52 dictionaryWithObjectsAndKeys:(*username) ? [NSString stringWithUTF8String:*username] : @"",
53 @"username",
54 (*password) ? [NSString stringWithUTF8String:*password] : @"",
55 @"password",
56 (*domain) ? [NSString stringWithUTF8String:*domain] : @"",
57 @"domain", [NSString stringWithUTF8String:target],
58 @"hostname", // used for the auth prompt message; not changed
59 nil];
60 // request auth UI
61 [mfi->session performSelectorOnMainThread:@selector(sessionRequestsAuthenticationWithParams:)
62 withObject:params
63 waitUntilDone:YES];
64 // wait for UI request to be completed
65 [[mfi->session uiRequestCompleted] lock];
66 [[mfi->session uiRequestCompleted] wait];
67 [[mfi->session uiRequestCompleted] unlock];
68
69 if (![[params valueForKey:@"result"] boolValue])
70 {
71 mfi->unwanted = YES;
72 return FALSE;
73 }
74
75 // Free old values
76 free(*username);
77 free(*password);
78 free(*domain);
79 // set values back
80 *username = _strdup([[params objectForKey:@"username"] UTF8String]);
81 *password = _strdup([[params objectForKey:@"password"] UTF8String]);
82 *domain = _strdup([[params objectForKey:@"domain"] UTF8String]);
83
84 if (!(*username) || !(*password) || !(*domain))
85 {
86 free(*username);
87 free(*password);
88 free(*domain);
89 return FALSE;
90 }
91
92 return TRUE;
93}
94
95DWORD ios_ui_verify_certificate_ex(freerdp *instance, const char *host, UINT16 port,
96 const char *common_name, const char *subject, const char *issuer,
97 const char *fingerprint, DWORD flags)
98{
99 // check whether we accept all certificates
100 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES)
101 return 2;
102
103 mfInfo *mfi = MFI_FROM_INSTANCE(instance);
104 NSMutableDictionary *params = [NSMutableDictionary
105 dictionaryWithObjectsAndKeys:(subject) ? [NSString stringWithUTF8String:subject] : @"",
106 @"subject",
107 (issuer) ? [NSString stringWithUTF8String:issuer] : @"",
108 @"issuer",
109 (fingerprint) ? [NSString stringWithUTF8String:subject] : @"",
110 @"fingerprint", nil];
111 // request certificate verification UI
112 [mfi->session performSelectorOnMainThread:@selector(sessionVerifyCertificateWithParams:)
113 withObject:params
114 waitUntilDone:YES];
115 // wait for UI request to be completed
116 [[mfi->session uiRequestCompleted] lock];
117 [[mfi->session uiRequestCompleted] wait];
118 [[mfi->session uiRequestCompleted] unlock];
119
120 if (![[params valueForKey:@"result"] boolValue])
121 {
122 mfi->unwanted = YES;
123 return 0;
124 }
125
126 return 1;
127}
128
129DWORD ios_ui_verify_changed_certificate_ex(freerdp *instance, const char *host, UINT16 port,
130 const char *common_name, const char *subject,
131 const char *issuer, const char *fingerprint,
132 const char *old_subject, const char *old_issuer,
133 const char *old_fingerprint, DWORD flags)
134{
135 return ios_ui_verify_certificate_ex(instance, host, port, common_name, subject, issuer,
136 fingerprint, flags);
137}
138
139#pragma mark -
140#pragma mark Graphics updates
141
142BOOL ios_ui_begin_paint(rdpContext *context)
143{
144 WINPR_ASSERT(context);
145
146 rdpGdi *gdi = context->gdi;
147 WINPR_ASSERT(gdi);
148 WINPR_ASSERT(gdi->primary);
149
150 HGDI_DC hdc = gdi->primary->hdc;
151 WINPR_ASSERT(hdc);
152 if (!hdc->hwnd)
153 return TRUE;
154
155 HGDI_WND hwnd = hdc->hwnd;
156 if (!hwnd->invalid)
157 return TRUE;
158 hwnd->invalid->null = TRUE;
159 return TRUE;
160}
161
162BOOL ios_ui_end_paint(rdpContext *context)
163{
164 WINPR_ASSERT(context);
165
166 mfInfo *mfi = MFI_FROM_INSTANCE(context->instance);
167 WINPR_ASSERT(mfi);
168
169 rdpGdi *gdi = context->gdi;
170 WINPR_ASSERT(gdi);
171 WINPR_ASSERT(gdi->primary);
172
173 HGDI_DC hdc = gdi->primary->hdc;
174 WINPR_ASSERT(hdc);
175 if (!hdc->hwnd)
176 return TRUE;
177
178 HGDI_WND hwnd = hdc->hwnd;
179 WINPR_ASSERT(hwnd->invalid || (hwnd->ninvalid == 0));
180
181 if (hwnd->invalid->null)
182 return TRUE;
183
184 CGRect dirty_rect =
185 CGRectMake(hwnd->invalid->x, hwnd->invalid->y, hwnd->invalid->w, hwnd->invalid->h);
186
187 if (!hwnd->invalid->null)
188 [mfi->session performSelectorOnMainThread:@selector(setNeedsDisplayInRectAsValue:)
189 withObject:[NSValue valueWithCGRect:dirty_rect]
190 waitUntilDone:NO];
191
192 return TRUE;
193}
194
195BOOL ios_ui_resize_window(rdpContext *context)
196{
197 rdpSettings *settings;
198 rdpGdi *gdi;
199
200 if (!context || !context->settings)
201 return FALSE;
202
203 settings = context->settings;
204 gdi = context->gdi;
205
206 if (!gdi_resize(gdi, freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth),
207 freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight)))
208 return FALSE;
209
210 ios_resize_display_buffer(MFI_FROM_INSTANCE(context->instance));
211 return TRUE;
212}
213
214#pragma mark -
215#pragma mark Exported
216
217static void ios_create_bitmap_context(mfInfo *mfi)
218{
219 [mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextWillChange)
220 withObject:nil
221 waitUntilDone:YES];
222 rdpGdi *gdi = mfi->instance->context->gdi;
223 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
224
225 if (FreeRDPGetBytesPerPixel(gdi->dstFormat) == 2)
226 mfi->bitmap_context = CGBitmapContextCreate(
227 gdi->primary_buffer, gdi->width, gdi->height, 5, gdi->stride, colorSpace,
228 kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
229 else
230 mfi->bitmap_context = CGBitmapContextCreate(
231 gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->stride, colorSpace,
232 kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
233
234 CGColorSpaceRelease(colorSpace);
235 [mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextDidChange)
236 withObject:nil
237 waitUntilDone:YES];
238}
239
240void ios_allocate_display_buffer(mfInfo *mfi)
241{
242 ios_create_bitmap_context(mfi);
243}
244
245void ios_resize_display_buffer(mfInfo *mfi)
246{
247 // Release the old context in a thread-safe manner
248 CGContextRef old_context = mfi->bitmap_context;
249 mfi->bitmap_context = nullptr;
250 CGContextRelease(old_context);
251 // Create the new context
252 ios_create_bitmap_context(mfi);
253}
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.