208 lines
7.0 KiB
Objective-C
208 lines
7.0 KiB
Objective-C
/*
|
|
RDP ui callbacks
|
|
|
|
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
|
|
|
|
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
If a copy of the MPL was not distributed with this file, You can obtain one at
|
|
http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import <freerdp/gdi/gdi.h>
|
|
#import "ios_freerdp_ui.h"
|
|
|
|
#import "RDPSession.h"
|
|
|
|
#pragma mark -
|
|
#pragma mark Certificate authentication
|
|
|
|
static void ios_resize_display_buffer(mfInfo *mfi);
|
|
static BOOL ios_ui_authenticate_raw(freerdp *instance, char **username, char **password,
|
|
char **domain, const char *title)
|
|
{
|
|
mfInfo *mfi = MFI_FROM_INSTANCE(instance);
|
|
NSMutableDictionary *params = [NSMutableDictionary
|
|
dictionaryWithObjectsAndKeys:(*username) ? [NSString stringWithUTF8String:*username] : @"",
|
|
@"username",
|
|
(*password) ? [NSString stringWithUTF8String:*password] : @"",
|
|
@"password",
|
|
(*domain) ? [NSString stringWithUTF8String:*domain] : @"",
|
|
@"domain",
|
|
[NSString
|
|
stringWithUTF8String:instance->settings->ServerHostname],
|
|
@"hostname", // used for the auth prompt message; not changed
|
|
nil];
|
|
// request auth UI
|
|
[mfi->session performSelectorOnMainThread:@selector(sessionRequestsAuthenticationWithParams:)
|
|
withObject:params
|
|
waitUntilDone:YES];
|
|
// wait for UI request to be completed
|
|
[[mfi->session uiRequestCompleted] lock];
|
|
[[mfi->session uiRequestCompleted] wait];
|
|
[[mfi->session uiRequestCompleted] unlock];
|
|
|
|
if (![[params valueForKey:@"result"] boolValue])
|
|
{
|
|
mfi->unwanted = YES;
|
|
return FALSE;
|
|
}
|
|
|
|
// Free old values
|
|
free(*username);
|
|
free(*password);
|
|
free(*domain);
|
|
// set values back
|
|
*username = strdup([[params objectForKey:@"username"] UTF8String]);
|
|
*password = strdup([[params objectForKey:@"password"] UTF8String]);
|
|
*domain = strdup([[params objectForKey:@"domain"] UTF8String]);
|
|
|
|
if (!(*username) || !(*password) || !(*domain))
|
|
{
|
|
free(*username);
|
|
free(*password);
|
|
free(*domain);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL ios_ui_authenticate(freerdp *instance, char **username, char **password, char **domain)
|
|
{
|
|
return ios_ui_authenticate_raw(instance, username, password, domain, "");
|
|
}
|
|
|
|
BOOL ios_ui_gw_authenticate(freerdp *instance, char **username, char **password, char **domain)
|
|
{
|
|
return ios_ui_authenticate_raw(instance, username, password, domain, "gateway");
|
|
}
|
|
|
|
DWORD ios_ui_verify_certificate(freerdp *instance, const char *common_name, const char *subject,
|
|
const char *issuer, const char *fingerprint, BOOL host_mismatch)
|
|
{
|
|
// check whether we accept all certificates
|
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES)
|
|
return 2;
|
|
|
|
mfInfo *mfi = MFI_FROM_INSTANCE(instance);
|
|
NSMutableDictionary *params = [NSMutableDictionary
|
|
dictionaryWithObjectsAndKeys:(subject) ? [NSString stringWithUTF8String:subject] : @"",
|
|
@"subject",
|
|
(issuer) ? [NSString stringWithUTF8String:issuer] : @"",
|
|
@"issuer",
|
|
(fingerprint) ? [NSString stringWithUTF8String:subject] : @"",
|
|
@"fingerprint", nil];
|
|
// request certificate verification UI
|
|
[mfi->session performSelectorOnMainThread:@selector(sessionVerifyCertificateWithParams:)
|
|
withObject:params
|
|
waitUntilDone:YES];
|
|
// wait for UI request to be completed
|
|
[[mfi->session uiRequestCompleted] lock];
|
|
[[mfi->session uiRequestCompleted] wait];
|
|
[[mfi->session uiRequestCompleted] unlock];
|
|
|
|
if (![[params valueForKey:@"result"] boolValue])
|
|
{
|
|
mfi->unwanted = YES;
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
DWORD ios_ui_verify_changed_certificate(freerdp *instance, const char *common_name,
|
|
const char *subject, const char *issuer,
|
|
const char *new_fingerprint, const char *old_subject,
|
|
const char *old_issuer, const char *old_fingerprint)
|
|
{
|
|
return ios_ui_verify_certificate(instance, common_name, subject, issuer, new_fingerprint,
|
|
FALSE);
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark Graphics updates
|
|
|
|
BOOL ios_ui_begin_paint(rdpContext *context)
|
|
{
|
|
rdpGdi *gdi = context->gdi;
|
|
gdi->primary->hdc->hwnd->invalid->null = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL ios_ui_end_paint(rdpContext *context)
|
|
{
|
|
mfInfo *mfi = MFI_FROM_INSTANCE(context->instance);
|
|
rdpGdi *gdi = context->gdi;
|
|
CGRect dirty_rect =
|
|
CGRectMake(gdi->primary->hdc->hwnd->invalid->x, gdi->primary->hdc->hwnd->invalid->y,
|
|
gdi->primary->hdc->hwnd->invalid->w, gdi->primary->hdc->hwnd->invalid->h);
|
|
|
|
if (!gdi->primary->hdc->hwnd->invalid->null)
|
|
[mfi->session performSelectorOnMainThread:@selector(setNeedsDisplayInRectAsValue:)
|
|
withObject:[NSValue valueWithCGRect:dirty_rect]
|
|
waitUntilDone:NO];
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL ios_ui_resize_window(rdpContext *context)
|
|
{
|
|
rdpSettings *settings;
|
|
rdpGdi *gdi;
|
|
|
|
if (!context || !context->settings)
|
|
return FALSE;
|
|
|
|
settings = context->settings;
|
|
gdi = context->gdi;
|
|
|
|
if (!gdi_resize(gdi, settings->DesktopWidth, settings->DesktopHeight))
|
|
return FALSE;
|
|
|
|
ios_resize_display_buffer(MFI_FROM_INSTANCE(context->instance));
|
|
return TRUE;
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark Exported
|
|
|
|
static void ios_create_bitmap_context(mfInfo *mfi)
|
|
{
|
|
[mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextWillChange)
|
|
withObject:nil
|
|
waitUntilDone:YES];
|
|
rdpGdi *gdi = mfi->instance->context->gdi;
|
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
|
|
if (GetBytesPerPixel(gdi->dstFormat) == 2)
|
|
mfi->bitmap_context = CGBitmapContextCreate(
|
|
gdi->primary_buffer, gdi->width, gdi->height, 5, gdi->stride, colorSpace,
|
|
kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
|
|
else
|
|
mfi->bitmap_context = CGBitmapContextCreate(
|
|
gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->stride, colorSpace,
|
|
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
|
|
|
|
CGColorSpaceRelease(colorSpace);
|
|
[mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextDidChange)
|
|
withObject:nil
|
|
waitUntilDone:YES];
|
|
}
|
|
|
|
void ios_allocate_display_buffer(mfInfo *mfi)
|
|
{
|
|
ios_create_bitmap_context(mfi);
|
|
}
|
|
|
|
void ios_resize_display_buffer(mfInfo *mfi)
|
|
{
|
|
// Release the old context in a thread-safe manner
|
|
CGContextRef old_context = mfi->bitmap_context;
|
|
mfi->bitmap_context = NULL;
|
|
CGContextRelease(old_context);
|
|
// Create the new context
|
|
ios_create_bitmap_context(mfi);
|
|
}
|