From 02860c5fac3244ad86d2699611f220746aef2f56 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Sun, 16 Oct 2011 14:07:18 +0000 Subject: - Improve the favourites editing process to edit keychain items, rather than deleting and recreating them. This has two advantages: firstly, it matches the Apple recommendation, as it preserves keychain item access lists and comments for keychain items when they are edited; secondly, it works around a bug in 10.7 which appears to be a Keychain cacheing issue, causing password retrievals to return the original keychain item on launch - which is no longer valid after deletion/recreation. This addresses Issue #1197. --- Source/SPKeychain.m | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'Source/SPKeychain.m') diff --git a/Source/SPKeychain.m b/Source/SPKeychain.m index 931f14d7..aa38f7b5 100644 --- a/Source/SPKeychain.m +++ b/Source/SPKeychain.m @@ -231,6 +231,66 @@ return (numberOfItemsFound > 0); } +/** + * Change the password for a keychain item. This should be used instead of + * deleting and recreating the keychain item, as it allows preservation of + * access lists and works around Lion cacheing issues. + */ +- (void)updateItemWithName:(NSString *)name account:(NSString *)account toPassword:(NSString *)password +{ + [self updateItemWithName:name account:account toName:password account:name password:account]; +} + +/** + * Change the details for a keychain item. This should be used instead of + * deleting and recreating the keychain item, as it allows preservation of + * access lists and works around Lion cacheing issues. + */ +- (void)updateItemWithName:(NSString *)name account:(NSString *)account toName:(NSString *)newName account:(NSString *)newAccount password:(NSString *)password +{ + OSStatus status; + SecKeychainItemRef itemRef; + SecKeychainAttribute attributes[2]; + SecKeychainAttributeList attList; + + // Retrieve a reference to the keychain item + status = SecKeychainFindGenericPassword(NULL, // Default keychain + (UInt32)strlen([name UTF8String]), [name UTF8String], // Service name and length + (UInt32)strlen([account UTF8String]), [account UTF8String], // Account name and length + NULL, NULL, // No password retrieval required + &itemRef); // The item reference + + if (status != noErr) { + NSLog(@"Error (%i) while trying to find keychain item to edit for name: %@ account: %@", (int)status, name, account); + SPBeginAlertSheet(NSLocalizedString(@"Error retrieving Keychain item to edit", @"error finding keychain item to edit message"), + NSLocalizedString(@"OK", @"OK button"), + nil, nil, [NSApp mainWindow], self, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to retrieve the Keychain item you're trying to edit. Repairing your Keychain might resolve this, but if it doesn't please report it to the Sequel Pro team, supplying the error code %i.", @"error finding keychain item to edit informative message"), status]); + return; + } + + // Set up the attributes to modify + attributes[0].tag = kSecAccountItemAttr; + attributes[0].data = (unichar *)[newAccount UTF8String]; + attributes[0].length = (UInt32)strlen([newAccount UTF8String]); + attributes[1].tag = kSecServiceItemAttr; + attributes[1].data = (unichar *)[newName UTF8String]; + attributes[1].length = (UInt32)strlen([newName UTF8String]); + attList.count = 2; + attList.attr = attributes; + + // Amend the keychain item + status = SecKeychainItemModifyAttributesAndData(itemRef, &attList, (UInt32)strlen([password UTF8String]), [password UTF8String]); + + if (status != noErr) { + NSLog(@"Error (%i) while updating keychain item for name: %@ account: %@", (int)status, name, account); + SPBeginAlertSheet(NSLocalizedString(@"Error updating Keychain item", @"error updating keychain item message"), + NSLocalizedString(@"OK", @"OK button"), + nil, nil, [NSApp mainWindow], self, nil, nil, + [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to update the Keychain item. Repairing your Keychain might resolve this, but if it doesn't please report it to the Sequel Pro team, supplying the error code %i.", @"error updating keychain item informative message"), status]); + } +} + /** * Retrieve the keychain item name for a supplied name and id. */ -- cgit v1.2.3