diff options
author | Mikkel Krautz <mikkel@krautz.dk> | 2011-02-02 04:20:15 +0300 |
---|---|---|
committer | Mikkel Krautz <mikkel@krautz.dk> | 2011-02-02 04:20:15 +0300 |
commit | b4aaaefc574b727d66320e2f56aaf713061a03c9 (patch) | |
tree | dcd604d7fe8dbce540f799344057118d7a6944bf | |
parent | 854c68c643fdd36a07c6d9a36f445142f8874533 (diff) |
Add concept of a 'Current Certificate'.
-rwxr-xr-x | Mumble.xcodeproj/project.pbxproj | 6 | ||||
-rw-r--r-- | Source/Classes/CertificateCreationView.m | 5 | ||||
-rw-r--r-- | Source/Classes/CertificatePreferencesViewController.h | 6 | ||||
-rw-r--r-- | Source/Classes/CertificatePreferencesViewController.m | 69 | ||||
-rw-r--r-- | Source/Classes/PreferencesViewController.m | 77 | ||||
-rw-r--r-- | Source/Classes/ServerRootViewController.h | 2 | ||||
-rw-r--r-- | Source/Classes/ServerRootViewController.m | 2 |
7 files changed, 148 insertions, 19 deletions
diff --git a/Mumble.xcodeproj/project.pbxproj b/Mumble.xcodeproj/project.pbxproj index 8160638..336c6ec 100755 --- a/Mumble.xcodeproj/project.pbxproj +++ b/Mumble.xcodeproj/project.pbxproj @@ -400,7 +400,7 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( - 2872F7C4124668880078C0B1 /* Identities */, + 2872F7C4124668880078C0B1 /* Certificates */, 28BF8E1C11D93A1900B72770 /* Database */, 2838EA0C1293165700035C5D /* Preferences */, 285C9E95116BEE1500A9A6A7 /* MainWindow-iPad.xib */, @@ -611,7 +611,7 @@ path = Resources/serverlist; sourceTree = "<group>"; }; - 2872F7C4124668880078C0B1 /* Identities */ = { + 2872F7C4124668880078C0B1 /* Certificates */ = { isa = PBXGroup; children = ( 287639F711D29D99009DB8B6 /* CertificateCreationProgressView.h */, @@ -625,7 +625,7 @@ 28942D7A12456F9200C63A07 /* CertificateCreationView.h */, 28942D7B12456F9200C63A07 /* CertificateCreationView.m */, ); - name = Identities; + name = Certificates; sourceTree = "<group>"; }; 28BF8E1C11D93A1900B72770 /* Database */ = { diff --git a/Source/Classes/CertificateCreationView.m b/Source/Classes/CertificateCreationView.m index 5f819f7..42f17b5 100644 --- a/Source/Classes/CertificateCreationView.m +++ b/Source/Classes/CertificateCreationView.m @@ -176,6 +176,11 @@ static void ShowAlertDialog(NSString *title, NSString *msg) { err = SecItemAdd((CFDictionaryRef)op, (CFTypeRef *)&data); if (err == noErr && data != nil) { // Success! + // Now, check if there's already a default certificate set. + NSData *defaultCert = [[NSUserDefaults standardUserDefaults] objectForKey:@"DefaultCertificate"]; + if (defaultCert == nil) { + [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"DefaultCertificate"]; + } // This happens when a certificate with a duplicate subject name is added. } else if (err == noErr && data == nil) { diff --git a/Source/Classes/CertificatePreferencesViewController.h b/Source/Classes/CertificatePreferencesViewController.h index 2a5f7dc..f46f611 100644 --- a/Source/Classes/CertificatePreferencesViewController.h +++ b/Source/Classes/CertificatePreferencesViewController.h @@ -28,11 +28,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + @interface CertificatePreferencesViewController : UITableViewController <UIActionSheetDelegate> { - NSMutableArray *_certificateItems; + NSMutableArray *_certificateItems; + BOOL _picker; + NSUInteger _selectedIndex; } - (id) init; +- (id) initAsPicker; - (void) dealloc; @end diff --git a/Source/Classes/CertificatePreferencesViewController.m b/Source/Classes/CertificatePreferencesViewController.m index 195c952..b35f28c 100644 --- a/Source/Classes/CertificatePreferencesViewController.m +++ b/Source/Classes/CertificatePreferencesViewController.m @@ -49,6 +49,14 @@ - (id) init { if (self = [super init]) { + _picker = NO; + } + return self; +} + +- (id) initAsPicker { + if (self = [super init]) { + _picker = YES; } return self; } @@ -62,16 +70,22 @@ #pragma mark View lifecycle - (void) viewWillAppear:(BOOL)animated { - self.navigationItem.title = @"Certificates"; + if (_picker) { + self.navigationItem.title = @"Pick Certificate"; + } else { + self.navigationItem.title = @"Certificates"; + } [[self tableView] deselectRowAtIndexPath:[[self tableView] indexPathForSelectedRow] animated:YES]; [self fetchCertificates]; [self.tableView reloadData]; - UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addButtonClicked:)]; - [self.navigationItem setRightBarButtonItem:addButton]; - [addButton release]; + if (!_picker) { + UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addButtonClicked:)]; + [self.navigationItem setRightBarButtonItem:addButton]; + [addButton release]; + } } #pragma mark - @@ -98,7 +112,18 @@ [cell setEmail:[cert emailAddress]]; [cell setIssuerText:[cert issuerName]]; [cell setExpiryText:[[cert notAfter] description]]; - [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + + if (!_picker) { + [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + } else { + [cell setAccessoryType:UITableViewCellAccessoryNone]; + NSData *persistentRef = [dict objectForKey:@"persistentRef"]; + NSData *curPersistentRef = [[NSUserDefaults standardUserDefaults] objectForKey:@"DefaultCertificate"]; + if ([persistentRef isEqualToData:curPersistentRef]) { + [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; + _selectedIndex = [indexPath row]; + } + } return (UITableViewCell *) cell; } @@ -106,13 +131,37 @@ #pragma mark - #pragma mark Table view delegate +- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + if (!_picker) + return UITableViewCellEditingStyleDelete; + else + return UITableViewCellEditingStyleNone; +} - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSDictionary *dict = [_certificateItems objectAtIndex:[indexPath row]]; - MKCertificate *cert = [dict objectForKey:@"cert"]; - CertificateViewController *certView = [[CertificateViewController alloc] initWithCertificate:cert]; - [[self navigationController] pushViewController:certView animated:YES]; - [certView release]; + + // If we're in picker mode, simply set the certificate key NSUserDefaults to the persistentRef of this cert. + if (_picker) { + NSData *persistentRef = [dict objectForKey:@"persistentRef"]; + [[NSUserDefaults standardUserDefaults] setObject:persistentRef forKey:@"DefaultCertificate"]; + + UITableViewCell *prevCell = [[self tableView] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:_selectedIndex inSection:0]]; + UITableViewCell *curCell = [[self tableView] cellForRowAtIndexPath:indexPath]; + prevCell.accessoryType = UITableViewCellAccessoryNone; + curCell.accessoryType = UITableViewCellAccessoryCheckmark; + + _selectedIndex = [indexPath row]; + + [[self tableView] deselectRowAtIndexPath:indexPath animated:YES]; + + // If not, show the detailed view. + } else { + MKCertificate *cert = [dict objectForKey:@"cert"]; + CertificateViewController *certView = [[CertificateViewController alloc] initWithCertificate:cert]; + [[self navigationController] pushViewController:certView animated:YES]; + [certView release]; + } } - (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { @@ -135,7 +184,7 @@ cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Generate New Certificate", - @"Import From Disk", + @"Import From iTunes", nil]; [sheet showInView:[self tableView]]; [sheet release]; diff --git a/Source/Classes/PreferencesViewController.m b/Source/Classes/PreferencesViewController.m index 70fd277..f3036ec 100644 --- a/Source/Classes/PreferencesViewController.m +++ b/Source/Classes/PreferencesViewController.m @@ -35,6 +35,8 @@ #import "CertificatePreferencesViewController.h" #import "DiagnosticsViewController.h" +#import <MumbleKit/MKCertificate.h> + @interface PreferencesViewController (Private) - (void) audioVolumeChanged:(UISlider *)volumeSlider; - (void) audioDuckingChanged:(UISwitch *)duckSwitch; @@ -69,6 +71,7 @@ - (void) viewWillAppear:(BOOL)animated { [self setTitle:@"Preferences"]; + [[self tableView] reloadData]; } #pragma mark - @@ -87,7 +90,7 @@ return 1; // Certificates } else if (section == 2) { - return 1; + return 2; // Beta } else if (section == 3) { return 1; @@ -148,12 +151,66 @@ [tcpSwitch release]; } - // Identities + // Certificates } else if ([indexPath section] == 2) { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PrefCertificateCell"]; + if (cell == nil) + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"PrefCertificateCell"] autorelease]; + + NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: + kSecClassIdentity, kSecClass, + kCFBooleanTrue, kSecReturnPersistentRef, + kSecMatchLimitAll, kSecMatchLimit, + nil]; + NSArray *certs = nil; + SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&certs); + [certs autorelease]; + + NSUInteger certCount = [certs count]; + if ([indexPath row] == 0) { + NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: + kSecClassIdentity, kSecClass, + kCFBooleanTrue, kSecReturnPersistentRef, + kSecMatchLimitAll, kSecMatchLimit, + nil]; + NSArray *certs = nil; + SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&certs); + [certs autorelease]; + cell.textLabel.text = @"All Certificates"; + cell.detailTextLabel.text = [NSString stringWithFormat:@"%i", certCount]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + } else if ([indexPath row] == 1) { + + NSData *persistentRef = [[NSUserDefaults standardUserDefaults] objectForKey:@"DefaultCertificate"]; + NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: + persistentRef, kSecValuePersistentRef, + kCFBooleanTrue, kSecReturnRef, + kSecMatchLimitOne, kSecMatchLimit, + nil]; + SecIdentityRef identity = NULL; + MKCertificate *cert = nil; + if (SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&identity) == noErr && identity != NULL) { + SecCertificateRef secCert; + if (SecIdentityCopyCertificate(identity, &secCert) == noErr) { + NSData *secData = (NSData *)SecCertificateCopyData(secCert); + cert = [MKCertificate certificateWithCertificate:secData privateKey:nil]; + } + } + cell.textLabel.text = @"Certificate"; + cell.detailTextLabel.text = cert ? [cert commonName] : @"None"; + if (certCount > 1) { + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + } else { + cell.accessoryType = UITableViewCellAccessoryNone; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } } + + return cell; // Beta } else if ([indexPath section] == 3) { @@ -192,10 +249,24 @@ [advAudio release]; } } else if ([indexPath section] == 2) { // Certificates - if ([indexPath row] == 0) { // Certificates + if ([indexPath row] == 0) { // All Certificates CertificatePreferencesViewController *certPref = [[CertificatePreferencesViewController alloc] init]; [self.navigationController pushViewController:certPref animated:YES]; [certPref release]; + } else if ([indexPath row] == 1) { // Certificate + NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: + kSecClassIdentity, kSecClass, + kCFBooleanTrue, kSecReturnPersistentRef, + kSecMatchLimitAll, kSecMatchLimit, + nil]; + NSArray *certs = nil; + SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&certs); + [certs autorelease]; + if ([certs count] > 1) { + CertificatePreferencesViewController *certPref = [[CertificatePreferencesViewController alloc] initAsPicker]; + [self.navigationController pushViewController:certPref animated:YES]; + [certPref release]; + } } } else if ([indexPath section] == 3) { // Beta if ([indexPath row] == 0) { diff --git a/Source/Classes/ServerRootViewController.h b/Source/Classes/ServerRootViewController.h index cf76dfe..681136e 100644 --- a/Source/Classes/ServerRootViewController.h +++ b/Source/Classes/ServerRootViewController.h @@ -48,7 +48,7 @@ ServerConnectionViewController *_progressController; } -- (id) initWithHostname:(NSString *)host port:(NSUInteger)port identity:(NSString *)username password:(NSString *)password; +- (id) initWithHostname:(NSString *)host port:(NSUInteger)port username:(NSString *)username password:(NSString *)password; - (void) dealloc; @end diff --git a/Source/Classes/ServerRootViewController.m b/Source/Classes/ServerRootViewController.m index 2467649..3a25a74 100644 --- a/Source/Classes/ServerRootViewController.m +++ b/Source/Classes/ServerRootViewController.m @@ -52,7 +52,7 @@ @implementation ServerRootViewController - (id) initWithHostname:(NSString *)host port:(NSUInteger)port username:(NSString *)username password:(NSString *)password { - NSData *certPersistentId = [[NSUserDefaults standardUserDefaults] objectForKey:@"certificate"]; + NSData *certPersistentId = [[NSUserDefaults standardUserDefaults] objectForKey:@"DefaultCertificate"]; if (certPersistentId == nil) { NSLog(@"ServerRootViewController: Cannot instantiate without a default certificate."); return nil; |