diff options
author | rowanbeentje <rowan@beent.je> | 2009-05-28 01:14:26 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2009-05-28 01:14:26 +0000 |
commit | 1979b7c94813e8278b4b7616aeafecd5a406f7a1 (patch) | |
tree | 108669de904ec9ee85806e5f91ec17b23cda1f7e /Source/SPPreferenceController.m | |
parent | a316ba498cf3300d05c8c2ba3223fa2c625d1717 (diff) | |
download | sequelpro-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/SPPreferenceController.m')
-rw-r--r-- | Source/SPPreferenceController.m | 115 |
1 files changed, 77 insertions, 38 deletions
diff --git a/Source/SPPreferenceController.m b/Source/SPPreferenceController.m index 829f887c..ce05117e 100644 --- a/Source/SPPreferenceController.m +++ b/Source/SPPreferenceController.m @@ -257,13 +257,15 @@ NSString *user = [favoritesController valueForKeyPath:@"selection.user"]; NSString *host = [favoritesController valueForKeyPath:@"selection.host"]; NSString *database = [favoritesController valueForKeyPath:@"selection.database"]; + NSString *sshUser = [favoritesController valueForKeyPath:@"selection.sshUser"]; + NSString *sshHost = [favoritesController valueForKeyPath:@"selection.sshHost"]; int favoriteid = [[favoritesController valueForKeyPath:@"selection.id"] intValue]; // Remove passwords from the Keychain [keychain deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro : %@ (%i)", name, favoriteid] account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]; [keychain deletePasswordForName:[NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@ (%i)", name, favoriteid] - account:[NSString stringWithFormat:@"%@@%@/%@", user, host, database]]; + account:[NSString stringWithFormat:@"%@@%@", sshUser, sshHost]]; // Reset last used favorite if ([favoritesTableView selectedRow] == [prefs integerForKey:@"LastFavoriteIndex"]) { @@ -288,15 +290,18 @@ - (IBAction)duplicateFavorite:(id)sender { if ([favoritesTableView numberOfSelectedRows] == 1) { - NSString *keychainName, *keychainAccount, *password; + NSString *keychainName, *keychainAccount, *password, *keychainSSHName, *keychainSSHAccount, *sshPassword; NSMutableDictionary *favorite = [NSMutableDictionary dictionaryWithDictionary:[[favoritesController arrangedObjects] objectAtIndex:[favoritesTableView selectedRow]]]; NSNumber *favoriteid = [NSNumber numberWithInt:[[NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970]] hash]]; - // Select the keychain password for duplication + // Select the keychain passwords for duplication keychainName = [NSString stringWithFormat:@"Sequel Pro : %@ (%i)", [favorite objectForKey:@"name"], [[favorite objectForKey:@"id"] intValue]]; keychainAccount = [NSString stringWithFormat:@"%@@%@/%@", [favorite objectForKey:@"user"], [favorite objectForKey:@"host"], [favorite objectForKey:@"database"]]; password = [keychain getPasswordForName:keychainName account:keychainAccount]; + keychainSSHName = [NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@ (%i)", [favorite objectForKey:@"name"], [[favorite objectForKey:@"id"] intValue]]; + keychainSSHAccount = [NSString stringWithFormat:@"%@@%@", [favorite objectForKey:@"sshUser"], [favorite objectForKey:@"sshHost"]]; + sshPassword = [keychain getPasswordForName:keychainSSHName account:keychainSSHAccount]; // Update the unique ID [favorite setObject:favoriteid forKey:@"id"]; @@ -304,12 +309,16 @@ // Alter the name for clarity [favorite setObject:[NSString stringWithFormat:@"%@ Copy", [favorite objectForKey:@"name"]] forKey:@"name"]; - // Create a new keychain item if appropriate + // Create new keychain items if appropriate if (password && [password length]) { keychainName = [NSString stringWithFormat:@"Sequel Pro : %@ (%i)", [favorite objectForKey:@"name"], [[favorite objectForKey:@"id"] intValue]]; [keychain addPassword:password forName:keychainName account:keychainAccount]; } - password = nil; + if (sshPassword && [sshPassword length]) { + keychainSSHName = [NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@ (%i)", [favorite objectForKey:@"name"], [[favorite objectForKey:@"id"] intValue]]; + [keychain addPassword:sshPassword forName:keychainSSHName account:keychainSSHAccount]; + } + password = nil, sshPassword = nil; [favoritesController addObject:favorite]; @@ -547,6 +556,7 @@ // If no selection is present, blank the field. if ([[favoritesTableView selectedRowIndexes] count] == 0) { [passwordField setStringValue:@""]; + [sshPasswordField setStringValue:@""]; return; } @@ -558,6 +568,14 @@ [favoritesController valueForKeyPath:@"selection.database"]]; [passwordField setStringValue:[keychain getPasswordForName:keychainName account:keychainAccount]]; + + // Retrieve the SSH keychain password if appropriate. + NSString *keychainSSHName = [NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@ (%i)", [favoritesController valueForKeyPath:@"selection.name"], [[favoritesController valueForKeyPath:@"selection.id"] intValue]]; + NSString *keychainSSHAccount = [NSString stringWithFormat:@"%@@%@", + [favoritesController valueForKeyPath:@"selection.sshUser"], + [favoritesController valueForKeyPath:@"selection.sshHost"]]; + + [sshPasswordField setStringValue:[keychain getPasswordForName:keychainSSHName account:keychainSSHAccount]]; } #pragma mark - @@ -651,46 +669,67 @@ { NSString *oldKeychainName, *newKeychainName; NSString *oldKeychainAccount, *newKeychainAccount; - NSString *oldPassword; - // Only proceed for name, host, user or database changes - if (control != nameField && control != hostField && control != userField && control != passwordField && control != databaseField) + // Only proceed for name, host, user or database changes, for both standard and SSH + if (control != nameField && control != hostField && control != userField && control != passwordField && control != databaseField + && control != sshHostField && control != sshUserField && control != sshPasswordField) return YES; - // Set the current keychain name and account strings - oldKeychainName = [NSString stringWithFormat:@"Sequel Pro : %@ (%i)", [favoritesController valueForKeyPath:@"selection.name"], [[favoritesController valueForKeyPath:@"selection.id"] intValue]]; - oldKeychainAccount = [NSString stringWithFormat:@"%@@%@/%@", - [favoritesController valueForKeyPath:@"selection.user"], - [favoritesController valueForKeyPath:@"selection.host"], - [favoritesController valueForKeyPath:@"selection.database"]]; - - // Retrieve the old password - oldPassword = [keychain getPasswordForName:oldKeychainName account:oldKeychainAccount]; - - // If no details have changed, skip processing - if ([nameField stringValue] == [favoritesController valueForKeyPath:@"selection.name"] - && [hostField stringValue] == [favoritesController valueForKeyPath:@"selection.host"] - && [userField stringValue] == [favoritesController valueForKeyPath:@"selection.user"] - && [databaseField stringValue] == [favoritesController valueForKeyPath:@"selection.database"] - && [passwordField stringValue] == oldPassword) { - oldPassword = nil; - return YES; + // If account/password details have changed, update the keychain to match + if ([nameField stringValue] != [favoritesController valueForKeyPath:@"selection.name"] + || [hostField stringValue] != [favoritesController valueForKeyPath:@"selection.host"] + || [userField stringValue] != [favoritesController valueForKeyPath:@"selection.user"] + || [databaseField stringValue] != [favoritesController valueForKeyPath:@"selection.database"] + || control == passwordField) { + + // Get the current keychain name and account strings + oldKeychainName = [NSString stringWithFormat:@"Sequel Pro : %@ (%i)", [favoritesController valueForKeyPath:@"selection.name"], [[favoritesController valueForKeyPath:@"selection.id"] intValue]]; + oldKeychainAccount = [NSString stringWithFormat:@"%@@%@/%@", + [favoritesController valueForKeyPath:@"selection.user"], + [favoritesController valueForKeyPath:@"selection.host"], + [favoritesController valueForKeyPath:@"selection.database"]]; + + // Set up the new keychain name and account strings + newKeychainName = [NSString stringWithFormat:@"Sequel Pro : %@ (%i)", [nameField stringValue], [[favoritesController valueForKeyPath:@"selection.id"] intValue]]; + newKeychainAccount = [NSString stringWithFormat:@"%@@%@/%@", + [userField stringValue], + [hostField stringValue], + [databaseField stringValue]]; + + // Delete the old keychain item + [keychain deletePasswordForName:oldKeychainName account:oldKeychainAccount]; + + // Add the new keychain item if the password field has a value + if ([[passwordField stringValue] length]) + [keychain addPassword:[passwordField stringValue] forName:newKeychainName account:newKeychainAccount]; } - oldPassword = nil; - // Set up the new keychain name and account strings - newKeychainName = [NSString stringWithFormat:@"Sequel Pro : %@ (%i)", [nameField stringValue], [[favoritesController valueForKeyPath:@"selection.id"] intValue]]; - newKeychainAccount = [NSString stringWithFormat:@"%@@%@/%@", - [userField stringValue], - [hostField stringValue], - [databaseField stringValue]]; - // Delete the old keychain item - [keychain deletePasswordForName:oldKeychainName account:oldKeychainAccount]; + // If SSH account/password details have changed, update the keychain to match + if ([nameField stringValue] != [favoritesController valueForKeyPath:@"selection.name"] + || [sshHostField stringValue] != [favoritesController valueForKeyPath:@"selection.sshHost"] + || [sshUserField stringValue] != [favoritesController valueForKeyPath:@"selection.sshUser"] + || control == sshPasswordField) { + + // Get the current keychain name and account strings + oldKeychainName = [NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@ (%i)", [favoritesController valueForKeyPath:@"selection.name"], [[favoritesController valueForKeyPath:@"selection.id"] intValue]]; + oldKeychainAccount = [NSString stringWithFormat:@"%@@%@", + [favoritesController valueForKeyPath:@"selection.sshUser"], + [favoritesController valueForKeyPath:@"selection.sshHost"]]; + + // Set up the new keychain name and account strings + newKeychainName = [NSString stringWithFormat:@"Sequel Pro SSHTunnel : %@ (%i)", [nameField stringValue], [[favoritesController valueForKeyPath:@"selection.id"] intValue]]; + newKeychainAccount = [NSString stringWithFormat:@"%@@%@", + [sshUserField stringValue], + [sshHostField stringValue]]; - // Add the new keychain item if the password field has a value - if ([[passwordField stringValue] length]) - [keychain addPassword:[passwordField stringValue] forName:newKeychainName account:newKeychainAccount]; + // Delete the old keychain item + [keychain deletePasswordForName:oldKeychainName account:oldKeychainAccount]; + + // Add the new keychain item if the password field has a value + if ([[sshPasswordField stringValue] length]) + [keychain addPassword:[sshPasswordField stringValue] forName:newKeychainName account:newKeychainAccount]; + } // Proceed with editing return YES; |