aboutsummaryrefslogtreecommitdiffstats
path: root/Source/KeyChain.m
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-05-28 01:14:26 +0000
committerrowanbeentje <rowan@beent.je>2009-05-28 01:14:26 +0000
commit1979b7c94813e8278b4b7616aeafecd5a406f7a1 (patch)
tree108669de904ec9ee85806e5f91ec17b23cda1f7e /Source/KeyChain.m
parenta316ba498cf3300d05c8c2ba3223fa2c625d1717 (diff)
downloadsequelpro-1979b7c94813e8278b4b7616aeafecd5a406f7a1.tar.gz
sequelpro-1979b7c94813e8278b4b7616aeafecd5a406f7a1.tar.bz2
sequelpro-1979b7c94813e8278b4b7616aeafecd5a406f7a1.zip
Add support for SSH tunnels, improve password security, and tweaks:
- Implementation of a new SPSSHTunnel class, designed to closely integrate SSH tunnels within Sequel Pro. - Integration of SPSSHTunnel - new connection methods using callbacks, and CMMCPConnection integration - Keychain class upgrade to include the new SPSSHTunnel keychain password helper on the trusted access list for new passwords - Keychain passwords are now held in memory/UI for only as long as necessary, increasing password security - Updated interface to enable/add SSH tunnel functionality - Remove old SSHTunnel class - Addition of new target for the SSH Tunnel password assistant, addition as a dependency of the main target, and addition to build script to copy into resources directory - Fix a keychain password deletion crash
Diffstat (limited to 'Source/KeyChain.m')
-rw-r--r--Source/KeyChain.m56
1 files changed, 45 insertions, 11 deletions
diff --git a/Source/KeyChain.m b/Source/KeyChain.m
index ef3afba3..032db61e 100644
--- a/Source/KeyChain.m
+++ b/Source/KeyChain.m
@@ -35,20 +35,54 @@
- (void)addPassword:(NSString *)password forName:(NSString *)name account:(NSString *)account
{
OSStatus status;
+ SecTrustedApplicationRef sequelProRef, sequelProHelperRef;
+ SecAccessRef passwordAccessRef;
+ SecKeychainAttribute attributes[4];
+ SecKeychainAttributeList attList;
// Check if password already exists before adding
if (![self passwordExistsForName:name account:account]) {
- status = SecKeychainAddGenericPassword(
- NULL, // default keychain
- strlen([name UTF8String]), // length of service name
- [name UTF8String], // service name
- strlen([account UTF8String]), // length of account name
- [account UTF8String], // account name
- strlen([password UTF8String]), // length of password
- [password UTF8String], // pointer to password data
- NULL // the item reference
- );
+
+ // Create a trusted access list with two items - ourselves and the SSH pass app.
+ NSString *helperPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"TunnelPassphraseRequester"];
+ if ((SecTrustedApplicationCreateFromPath(NULL, &sequelProRef) == noErr) &&
+ (SecTrustedApplicationCreateFromPath([helperPath UTF8String], &sequelProHelperRef) == noErr)) {
+
+ NSArray *trustedApps = [NSArray arrayWithObjects:(id)sequelProRef, (id)sequelProHelperRef, nil];
+ status = SecAccessCreate((CFStringRef)name, (CFArrayRef)trustedApps, &passwordAccessRef);
+ if (status != noErr) {
+ NSLog(@"Error (%i) while trying to create access list for name: %@ account: %@", status, name, account);
+ passwordAccessRef = NULL;
+ }
+ }
+ // Set up the item attributes
+ attributes[0].tag = kSecGenericItemAttr;
+ attributes[0].data = "application password";
+ attributes[0].length = 20;
+ attributes[1].tag = kSecLabelItemAttr;
+ attributes[1].data = (unichar *)[name UTF8String];
+ attributes[1].length = strlen([name UTF8String]);
+ attributes[2].tag = kSecAccountItemAttr;
+ attributes[2].data = (unichar *)[account UTF8String];
+ attributes[2].length = strlen([account UTF8String]);
+ attributes[3].tag = kSecServiceItemAttr;
+ attributes[3].data = (unichar *)[name UTF8String];
+ attributes[3].length = strlen([name UTF8String]);
+ attList.count = 4;
+ attList.attr = attributes;
+
+ // Create the keychain item
+ status = SecKeychainItemCreateFromContent(
+ kSecGenericPasswordItemClass, // Generic password type
+ &attList, // The attribute list created for the keychain item
+ strlen([password UTF8String]), // Length of password
+ [password UTF8String], // Password data
+ NULL, // Default keychain
+ passwordAccessRef, // Access list for this keychain
+ NULL); // The item reference
+
+ if (passwordAccessRef) CFRelease(passwordAccessRef);
if (status != noErr) {
NSLog(@"Error (%i) while trying to add password for name: %@ account: %@", status, name, account);
}
@@ -120,7 +154,7 @@
}
}
- CFRelease(itemRef);
+ if (itemRef) CFRelease(itemRef);
}
}