Blame client/iOS/FreeRDP/ios_freerdp_ui.m

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