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