//
// ManualTests.m
// GSSTestApp
//
// Created by Love Hörnquist Åstrand on 2013-07-01.
// Copyright (c) 2013 Apple, Inc. All rights reserved.
//
#import "ManualTests.h"
#import <GSS/GSS.h>
#import <Security/SecCertificatePriv.h>
@interface ManualTests () <UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate>
@property (retain) NSArray *identities;
@property (assign) NSInteger selectedRow;
@property (retain) UIActionSheet *actionSheet;
@end
@implementation ManualTests
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component > 0) abort();
return [self.identities count];
}
- (UIView *)pickerView:(UIPickerView *)pickerView
viewForRow:(NSInteger)row
forComponent:(NSInteger)component
reusingView:(UIView *)view
{
UILabel* label = (UILabel*)view;
if (label == nil) {
label = [[UILabel alloc] init];
label.minimumScaleFactor = 0.75;
label.adjustsFontSizeToFitWidth = YES;
}
label.text = self.identities[row][@"name"];
return label;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.certificateLabel.text = self.identities[row][@"name"];
self.selectedRow = row;
}
- (void)viewDidLoad {
self.selectedRow = -1;
}
- (void)viewDidAppear:(BOOL)animated {
static CFDataRef smartcardLogon;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
smartcardLogon = CFDataCreate(NULL, (void *)"\x2b\x06\x01\x04\x01\x82\x37\x14\x02\x02", 10);
});
NSDictionary *params = @{
(__bridge id)kSecClass : (__bridge id)kSecClassIdentity,
(__bridge id)kSecReturnRef : (__bridge id)kCFBooleanTrue,
(__bridge id)kSecMatchLimit : (__bridge id) kSecMatchLimitAll,
};
CFTypeRef result = NULL;
OSStatus status;
status = SecItemCopyMatching((__bridge CFDictionaryRef)params, &result);
if (status) {
NSLog(@"SecItemCopyMatching returned: return;
}
NSArray *array = CFBridgingRelease(result);
NSMutableArray *items = [NSMutableArray array];
NSLog(@"found:
self.selectedRow = 0;
for (id identity in array) {
SecIdentityRef ident = (__bridge SecIdentityRef)identity;
CFArrayRef eku = NULL;
NSLog(@"SecIdentityRef :
SecCertificateRef cert = NULL;
NSString *name;
SecIdentityCopyCertificate(ident, &cert);
if (cert) {
name = CFBridgingRelease(SecCertificateCopySubjectSummary(cert));
eku = SecCertificateCopyExtendedKeyUsage(cert);
CFRelease(cert);
} else {
name = @"<noname>";
}
NSLog(@"SecIdentityRef:
[items addObject:@{
@"name" : name,
@"value" : identity,
}];
if (eku) {
if (CFArrayContainsValue(eku, CFRangeMake(0, CFArrayGetCount(eku)), smartcardLogon))
self.selectedRow = [items count] - 1;
CFRelease(eku);
}
}
self.identities = items;
if ([items count] > 0) {
[self.certificateLabel setHidden:NO];
[self.doCertificate setHidden:NO];
self.certificateLabel.text = self.identities[self.selectedRow][@"name"];
} else {
[self.certificateLabel setHidden:YES];
[self.doCertificate setHidden:YES];
self.selectedRow = -1;
}
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(certificateTapped)];
tap.numberOfTapsRequired = 1;
[self.certificateLabel addGestureRecognizer:tap];
}
- (IBAction)doAcquire:(id)sender {
NSLog(@"acquire");
CFErrorRef error = NULL;
gss_cred_id_t cred = NULL;
OM_uint32 maj_stat;
gss_name_t gname = GSSCreateName((__bridge CFStringRef)self.username.text, GSS_C_NT_USER_NAME, &error);
if (gname == NULL) {
self.statusLabel.text = [NSString stringWithFormat:@"import failed with: NSLog(@"CreateName failed with: if (error) CFRelease(error);
return;
}
NSMutableDictionary *options = [NSMutableDictionary dictionary];
if (self.doPassword.on)
[options setObject:self.password.text forKey:(id)kGSSICPassword];
if (self.doCertificate.on && self.selectedRow >= 0) {
SecIdentityRef ident = (__bridge SecIdentityRef)self.identities[self.selectedRow][@"value"];
if (ident == NULL) {
NSLog(@"picked cert never existed ?");
return;
}
[options setObject:(__bridge id)ident forKey:(id)kGSSICCertificate];
}
NSString *hostname = self.kdchostname.text;
if (hostname && [hostname length] > 0) {
[options setObject:hostname forKey:(id)kGSSICLKDCHostname];
}
self.statusLabel.text = @"acquiring...";
maj_stat = gss_aapl_initial_cred(gname, GSS_KRB5_MECHANISM, (__bridge CFDictionaryRef)options, &cred, &error);
CFRelease(gname);
if (maj_stat) {
self.statusLabel.text = [NSString stringWithFormat:@"failed: NSLog(@"gss_aapl_initial_cred failed with: if (error)
CFRelease(error);
} else if (cred) {
self.statusLabel.text = [NSString stringWithFormat:@"got cred: NSLog(@"got cred: } else {
self.statusLabel.text = [NSString stringWithFormat:@"got no error, but also didn't get a cred!?"];
}
if (cred)
CFRelease(cred);
}
- (void)dismissActionSheet:(id)sender {
if (self.selectedRow >= 0)
self.certificateLabel.text = self.identities[self.selectedRow][@"name"];
[self.actionSheet dismissWithClickedButtonIndex:0 animated:YES];
self.actionSheet = nil;
}
- (void)certificateTapped {
self.actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[self.actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
UIPickerView *certifiatePicker = [[UIPickerView alloc] initWithFrame:pickerFrame];
certifiatePicker.showsSelectionIndicator = YES;
certifiatePicker.dataSource = self;
certifiatePicker.delegate = self;
if (self.selectedRow >= 0)
[certifiatePicker selectRow:self.selectedRow inComponent:0 animated:NO];
[self.actionSheet addSubview:certifiatePicker];
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Close"]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:@selector(dismissActionSheet:) forControlEvents:UIControlEventValueChanged];
[self.actionSheet addSubview:closeButton];
[self.actionSheet showInView:self.view];
[self.actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
-(BOOL)textFieldShouldReturn:(UITextField *)sender {
[sender resignFirstResponder];
return YES;
}
@end