FreeRDP
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 
21 static void ios_resize_display_buffer(mfInfo *mfi);
22 static BOOL ios_ui_authenticate_raw(freerdp *instance, char **username, char **password,
23  char **domain, const char *title)
24 {
25  mfInfo *mfi = MFI_FROM_INSTANCE(instance);
26  NSMutableDictionary *params = [NSMutableDictionary
27  dictionaryWithObjectsAndKeys:(*username) ? [NSString stringWithUTF8String:*username] : @"",
28  @"username",
29  (*password) ? [NSString stringWithUTF8String:*password] : @"",
30  @"password",
31  (*domain) ? [NSString stringWithUTF8String:*domain] : @"",
32  @"domain",
33  [NSString stringWithUTF8String:freerdp_settings_get_string(
34  instance->context->settings,
35  FreeRDP_ServerHostname)],
36  @"hostname", // used for the auth prompt message; not changed
37  nil];
38  // request auth UI
39  [mfi->session performSelectorOnMainThread:@selector(sessionRequestsAuthenticationWithParams:)
40  withObject:params
41  waitUntilDone:YES];
42  // wait for UI request to be completed
43  [[mfi->session uiRequestCompleted] lock];
44  [[mfi->session uiRequestCompleted] wait];
45  [[mfi->session uiRequestCompleted] unlock];
46 
47  if (![[params valueForKey:@"result"] boolValue])
48  {
49  mfi->unwanted = YES;
50  return FALSE;
51  }
52 
53  // Free old values
54  free(*username);
55  free(*password);
56  free(*domain);
57  // set values back
58  *username = _strdup([[params objectForKey:@"username"] UTF8String]);
59  *password = _strdup([[params objectForKey:@"password"] UTF8String]);
60  *domain = _strdup([[params objectForKey:@"domain"] UTF8String]);
61 
62  if (!(*username) || !(*password) || !(*domain))
63  {
64  free(*username);
65  free(*password);
66  free(*domain);
67  return FALSE;
68  }
69 
70  return TRUE;
71 }
72 
73 BOOL ios_ui_authenticate(freerdp *instance, char **username, char **password, char **domain)
74 {
75  return ios_ui_authenticate_raw(instance, username, password, domain, "");
76 }
77 
78 BOOL ios_ui_gw_authenticate(freerdp *instance, char **username, char **password, char **domain)
79 {
80  return ios_ui_authenticate_raw(instance, username, password, domain, "gateway");
81 }
82 
83 DWORD ios_ui_verify_certificate_ex(freerdp *instance, const char *host, UINT16 port,
84  const char *common_name, const char *subject, const char *issuer,
85  const char *fingerprint, DWORD flags)
86 {
87  // check whether we accept all certificates
88  if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES)
89  return 2;
90 
91  mfInfo *mfi = MFI_FROM_INSTANCE(instance);
92  NSMutableDictionary *params = [NSMutableDictionary
93  dictionaryWithObjectsAndKeys:(subject) ? [NSString stringWithUTF8String:subject] : @"",
94  @"subject",
95  (issuer) ? [NSString stringWithUTF8String:issuer] : @"",
96  @"issuer",
97  (fingerprint) ? [NSString stringWithUTF8String:subject] : @"",
98  @"fingerprint", nil];
99  // request certificate verification UI
100  [mfi->session performSelectorOnMainThread:@selector(sessionVerifyCertificateWithParams:)
101  withObject:params
102  waitUntilDone:YES];
103  // wait for UI request to be completed
104  [[mfi->session uiRequestCompleted] lock];
105  [[mfi->session uiRequestCompleted] wait];
106  [[mfi->session uiRequestCompleted] unlock];
107 
108  if (![[params valueForKey:@"result"] boolValue])
109  {
110  mfi->unwanted = YES;
111  return 0;
112  }
113 
114  return 1;
115 }
116 
117 DWORD ios_ui_verify_changed_certificate_ex(freerdp *instance, const char *host, UINT16 port,
118  const char *common_name, const char *subject,
119  const char *issuer, const char *fingerprint,
120  const char *old_subject, const char *old_issuer,
121  const char *old_fingerprint, DWORD flags)
122 {
123  return ios_ui_verify_certificate_ex(instance, host, port, common_name, subject, issuer,
124  fingerprint, flags);
125 }
126 
127 #pragma mark -
128 #pragma mark Graphics updates
129 
130 BOOL ios_ui_begin_paint(rdpContext *context)
131 {
132  rdpGdi *gdi = context->gdi;
133  gdi->primary->hdc->hwnd->invalid->null = TRUE;
134  return TRUE;
135 }
136 
137 BOOL ios_ui_end_paint(rdpContext *context)
138 {
139  mfInfo *mfi = MFI_FROM_INSTANCE(context->instance);
140  rdpGdi *gdi = context->gdi;
141  CGRect dirty_rect =
142  CGRectMake(gdi->primary->hdc->hwnd->invalid->x, gdi->primary->hdc->hwnd->invalid->y,
143  gdi->primary->hdc->hwnd->invalid->w, gdi->primary->hdc->hwnd->invalid->h);
144 
145  if (!gdi->primary->hdc->hwnd->invalid->null)
146  [mfi->session performSelectorOnMainThread:@selector(setNeedsDisplayInRectAsValue:)
147  withObject:[NSValue valueWithCGRect:dirty_rect]
148  waitUntilDone:NO];
149 
150  return TRUE;
151 }
152 
153 BOOL ios_ui_resize_window(rdpContext *context)
154 {
155  rdpSettings *settings;
156  rdpGdi *gdi;
157 
158  if (!context || !context->settings)
159  return FALSE;
160 
161  settings = context->settings;
162  gdi = context->gdi;
163 
164  if (!gdi_resize(gdi, freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth),
165  freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight)))
166  return FALSE;
167 
168  ios_resize_display_buffer(MFI_FROM_INSTANCE(context->instance));
169  return TRUE;
170 }
171 
172 #pragma mark -
173 #pragma mark Exported
174 
175 static void ios_create_bitmap_context(mfInfo *mfi)
176 {
177  [mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextWillChange)
178  withObject:nil
179  waitUntilDone:YES];
180  rdpGdi *gdi = mfi->instance->context->gdi;
181  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
182 
183  if (FreeRDPGetBytesPerPixel(gdi->dstFormat) == 2)
184  mfi->bitmap_context = CGBitmapContextCreate(
185  gdi->primary_buffer, gdi->width, gdi->height, 5, gdi->stride, colorSpace,
186  kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
187  else
188  mfi->bitmap_context = CGBitmapContextCreate(
189  gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->stride, colorSpace,
190  kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
191 
192  CGColorSpaceRelease(colorSpace);
193  [mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextDidChange)
194  withObject:nil
195  waitUntilDone:YES];
196 }
197 
198 void ios_allocate_display_buffer(mfInfo *mfi)
199 {
200  ios_create_bitmap_context(mfi);
201 }
202 
203 void ios_resize_display_buffer(mfInfo *mfi)
204 {
205  // Release the old context in a thread-safe manner
206  CGContextRef old_context = mfi->bitmap_context;
207  mfi->bitmap_context = NULL;
208  CGContextRelease(old_context);
209  // Create the new context
210  ios_create_bitmap_context(mfi);
211 }
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.