aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-06-06 23:25:06 +0000
committerrowanbeentje <rowan@beent.je>2009-06-06 23:25:06 +0000
commitab4d3557db6d823275b688ccb7210830f029fd5c (patch)
treecf0ba9733d03868c22d81904d4486ed2de350f4c
parent2f5c4b9bab18b54f2d37f4b4a05afa116cfd0c44 (diff)
downloadsequelpro-ab4d3557db6d823275b688ccb7210830f029fd5c.tar.gz
sequelpro-ab4d3557db6d823275b688ccb7210830f029fd5c.tar.bz2
sequelpro-ab4d3557db6d823275b688ccb7210830f029fd5c.zip
Further SSH tunnel improvements:
- Redesigned SSH key authentication dialog - Added ability to add SSH key passphrases to keychain (sharing details with system SSH) - SSH tunnels with keys which fail are now correctly restarted, interacting with the GUI as necessary - GUI interaction now performed on the main thread for increased stability
-rw-r--r--Interfaces/SSHQuestionDialog.xib149
-rw-r--r--Source/CMMCPConnection.m8
-rw-r--r--Source/KeyChain.h1
-rw-r--r--Source/KeyChain.m14
-rw-r--r--Source/SPSSHTunnel.h5
-rw-r--r--Source/SPSSHTunnel.m58
-rw-r--r--Source/TunnelPassphraseRequester.m19
-rw-r--r--sequel-pro.xcodeproj/project.pbxproj4
8 files changed, 209 insertions, 49 deletions
diff --git a/Interfaces/SSHQuestionDialog.xib b/Interfaces/SSHQuestionDialog.xib
index d0c4e2e3..1697b41d 100644
--- a/Interfaces/SSHQuestionDialog.xib
+++ b/Interfaces/SSHQuestionDialog.xib
@@ -8,6 +8,7 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="469"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -44,7 +45,7 @@
<nil key="NSViewClass"/>
<string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
<object class="NSView" key="NSWindowView" id="414427165">
- <reference key="NSNextResponder"/>
+ <nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -53,13 +54,12 @@
<int key="NSvFlags">274</int>
<string key="NSFrame">{{126, 60}, {477, 129}}</string>
<reference key="NSSuperview" ref="414427165"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="296218965">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">272891904</int>
<string key="NSContents"/>
- <object class="NSFont" key="NSSupport" id="535233726">
+ <object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">1.300000e+01</double>
<int key="NSfFlags">16</int>
@@ -90,7 +90,6 @@
<int key="NSvFlags">289</int>
<string key="NSFrame">{{510, 12}, {96, 32}}</string>
<reference key="NSSuperview" ref="414427165"/>
- <reference key="NSWindow"/>
<int key="NSTag">1</int>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="915366670">
@@ -128,7 +127,6 @@
</object>
<string key="NSFrame">{{20, 115}, {75, 74}}</string>
<reference key="NSSuperview" ref="414427165"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="490596046">
<int key="NSCellFlags">130560</int>
@@ -149,7 +147,6 @@
<int key="NSvFlags">289</int>
<string key="NSFrame">{{414, 12}, {96, 32}}</string>
<reference key="NSSuperview" ref="414427165"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="382904691">
<int key="NSCellFlags">67239424</int>
@@ -182,12 +179,11 @@
</object>
<string key="NSFrame">{{68, 113}, {32, 32}}</string>
<reference key="NSSuperview" ref="414427165"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="406303847">
<int key="NSCellFlags">130560</int>
<int key="NSCellFlags2">33554432</int>
- <object class="NSCustomResource" key="NSContents">
+ <object class="NSCustomResource" key="NSContents" id="127199858">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">toolbar-preferences-network</string>
</object>
@@ -200,8 +196,6 @@
</object>
</object>
<string key="NSFrameSize">{620, 209}</string>
- <reference key="NSSuperview"/>
- <reference key="NSWindow"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
@@ -209,7 +203,7 @@
<object class="NSWindowTemplate" id="317330000">
<int key="NSWindowStyleMask">1</int>
<int key="NSWindowBacking">2</int>
- <string key="NSWindowRect">{{196, 301}, {620, 209}}</string>
+ <string key="NSWindowRect">{{196, 301}, {471, 209}}</string>
<int key="NSWTFlags">603979776</int>
<string key="NSWindowTitle">SSH Tunnel Password Query</string>
<string key="NSWindowClass">NSWindow</string>
@@ -222,16 +216,19 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTextField" id="882917083">
<reference key="NSNextResponder" ref="800993241"/>
- <int key="NSvFlags">274</int>
- <string key="NSFrame">{{126, 113}, {477, 76}}</string>
+ <int key="NSvFlags">278</int>
+ <string key="NSFrame">{{126, 113}, {328, 76}}</string>
<reference key="NSSuperview" ref="800993241"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="324489195">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">272891904</int>
<string key="NSContents"/>
- <reference key="NSSupport" ref="535233726"/>
+ <object class="NSFont" key="NSSupport">
+ <string key="NSName">LucidaGrande-Bold</string>
+ <double key="NSSize">1.300000e+01</double>
+ <int key="NSfFlags">16</int>
+ </object>
<reference key="NSControlView" ref="882917083"/>
<reference key="NSBackgroundColor" ref="759566909"/>
<reference key="NSTextColor" ref="1062846423"/>
@@ -240,9 +237,8 @@
<object class="NSButton" id="881553485">
<reference key="NSNextResponder" ref="800993241"/>
<int key="NSvFlags">289</int>
- <string key="NSFrame">{{510, 12}, {96, 32}}</string>
+ <string key="NSFrame">{{361, 12}, {96, 32}}</string>
<reference key="NSSuperview" ref="800993241"/>
- <reference key="NSWindow"/>
<int key="NSTag">1</int>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="171126067">
@@ -276,7 +272,6 @@
</object>
<string key="NSFrame">{{20, 115}, {75, 74}}</string>
<reference key="NSSuperview" ref="800993241"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="70636684">
<int key="NSCellFlags">130560</int>
@@ -292,9 +287,8 @@
<object class="NSButton" id="920337090">
<reference key="NSNextResponder" ref="800993241"/>
<int key="NSvFlags">289</int>
- <string key="NSFrame">{{414, 12}, {96, 32}}</string>
+ <string key="NSFrame">{{265, 12}, {96, 32}}</string>
<reference key="NSSuperview" ref="800993241"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="811201853">
<int key="NSCellFlags">67239424</int>
@@ -327,15 +321,11 @@
</object>
<string key="NSFrame">{{68, 113}, {32, 32}}</string>
<reference key="NSSuperview" ref="800993241"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="169063774">
<int key="NSCellFlags">130560</int>
<int key="NSCellFlags2">33554432</int>
- <object class="NSCustomResource" key="NSContents">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">toolbar-preferences-network</string>
- </object>
+ <reference key="NSContents" ref="127199858"/>
<int key="NSAlign">0</int>
<int key="NSScale">0</int>
<int key="NSStyle">0</int>
@@ -345,10 +335,9 @@
</object>
<object class="NSSecureTextField" id="951010250">
<reference key="NSNextResponder" ref="800993241"/>
- <int key="NSvFlags">294</int>
- <string key="NSFrame">{{129, 70}, {261, 22}}</string>
+ <int key="NSvFlags">291</int>
+ <string key="NSFrame">{{199, 83}, {252, 22}}</string>
<reference key="NSSuperview" ref="800993241"/>
- <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSecureTextFieldCell" key="NSCell" id="709544507">
<int key="NSCellFlags">343014976</int>
@@ -378,10 +367,52 @@
</object>
</object>
</object>
+ <object class="NSTextField" id="11923336">
+ <reference key="NSNextResponder" ref="800993241"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{126, 85}, {68, 17}}</string>
+ <reference key="NSSuperview" ref="800993241"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="613771853">
+ <int key="NSCellFlags">68288064</int>
+ <int key="NSCellFlags2">272630784</int>
+ <string key="NSContents">Password:</string>
+ <reference key="NSSupport" ref="313221240"/>
+ <reference key="NSControlView" ref="11923336"/>
+ <reference key="NSBackgroundColor" ref="759566909"/>
+ <reference key="NSTextColor" ref="1062846423"/>
+ </object>
+ </object>
+ <object class="NSButton" id="107237198">
+ <reference key="NSNextResponder" ref="800993241"/>
+ <int key="NSvFlags">289</int>
+ <string key="NSFrame">{{197, 59}, {253, 18}}</string>
+ <reference key="NSSuperview" ref="800993241"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="680760632">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Remember password in my keychain</string>
+ <reference key="NSSupport" ref="313221240"/>
+ <reference key="NSControlView" ref="107237198"/>
+ <int key="NSButtonFlags">1211912703</int>
+ <int key="NSButtonFlags2">130</int>
+ <object class="NSCustomResource" key="NSNormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSSwitch</string>
+ </object>
+ <object class="NSButtonImageSource" key="NSAlternateImage">
+ <string key="NSImageName">NSSwitch</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
</object>
- <string key="NSFrameSize">{620, 209}</string>
+ <string key="NSFrameSize">{471, 209}</string>
<reference key="NSSuperview"/>
- <reference key="NSWindow"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
@@ -462,6 +493,14 @@
</object>
<int key="connectionID">488</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">sshPasswordKeychainCheckbox</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="107237198"/>
+ </object>
+ <int key="connectionID">493</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -598,12 +637,14 @@
<reference key="object" ref="800993241"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="920337090"/>
- <reference ref="881553485"/>
<reference ref="823624076"/>
<reference ref="882917083"/>
<reference ref="736278290"/>
+ <reference ref="881553485"/>
+ <reference ref="920337090"/>
<reference ref="951010250"/>
+ <reference ref="11923336"/>
+ <reference ref="107237198"/>
</object>
<reference key="parent" ref="317330000"/>
</object>
@@ -691,6 +732,34 @@
<reference key="object" ref="709544507"/>
<reference key="parent" ref="951010250"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">489</int>
+ <reference key="object" ref="11923336"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="613771853"/>
+ </object>
+ <reference key="parent" ref="800993241"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">490</int>
+ <reference key="object" ref="613771853"/>
+ <reference key="parent" ref="11923336"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">491</int>
+ <reference key="object" ref="107237198"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="680760632"/>
+ </object>
+ <reference key="parent" ref="800993241"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">492</int>
+ <reference key="object" ref="680760632"/>
+ <reference key="parent" ref="107237198"/>
+ </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -724,6 +793,10 @@
<string>479.IBPluginDependency</string>
<string>484.IBPluginDependency</string>
<string>485.IBPluginDependency</string>
+ <string>489.IBPluginDependency</string>
+ <string>490.IBPluginDependency</string>
+ <string>491.IBPluginDependency</string>
+ <string>492.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -741,8 +814,8 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{187, 404}, {620, 209}}</string>
- <string>{{187, 404}, {620, 209}}</string>
+ <string>{{218, 467}, {471, 209}}</string>
+ <string>{{218, 467}, {471, 209}}</string>
<reference ref="6"/>
<string>{{11, 666}, {480, 270}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -754,6 +827,10 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -776,7 +853,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">488</int>
+ <int key="maxID">493</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -828,6 +905,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>sshPasswordDialog</string>
<string>sshPasswordField</string>
+ <string>sshPasswordKeychainCheckbox</string>
<string>sshPasswordText</string>
<string>sshQuestionDialog</string>
<string>sshQuestionText</string>
@@ -836,6 +914,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSWindow</string>
<string>NSSecureTextField</string>
+ <string>NSButton</string>
<string>NSTextField</string>
<string>NSWindow</string>
<string>NSTextField</string>
diff --git a/Source/CMMCPConnection.m b/Source/CMMCPConnection.m
index 478d5684..8fbf948d 100644
--- a/Source/CMMCPConnection.m
+++ b/Source/CMMCPConnection.m
@@ -355,7 +355,7 @@ static void forcePingTimeout(int signalNumber);
[connectionTunnel setConnectionStateChangeSelector:nil delegate:nil];
if ([connectionTunnel state] != SPSSH_STATE_IDLE) [connectionTunnel disconnect];
[connectionTunnel connect];
- NSDate *tunnelStartDate = [NSDate date];
+ NSDate *tunnelStartDate = [NSDate date], *interfaceInteractionTimer;
// Allow the tunnel to attempt to connect in a loop
while (1) {
@@ -367,7 +367,11 @@ static void forcePingTimeout(int signalNumber);
[connectionTunnel disconnect];
break;
}
- [NSThread sleepForTimeInterval:0.25];
+
+ // Process events for a short time, allowing dialogs to be shown but waiting for the tunnel
+ interfaceInteractionTimer = [NSDate date];
+ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
+ tunnelStartDate = [tunnelStartDate addTimeInterval:([[NSDate date] timeIntervalSinceDate:interfaceInteractionTimer] - 0.25)];
}
currentSSHTunnelState = [connectionTunnel state];
[connectionTunnel setConnectionStateChangeSelector:@selector(sshTunnelStateChange:) delegate:self];
diff --git a/Source/KeyChain.h b/Source/KeyChain.h
index 966a8c04..ca95d09f 100644
--- a/Source/KeyChain.h
+++ b/Source/KeyChain.h
@@ -29,6 +29,7 @@
@interface KeyChain : NSObject
- (void)addPassword:(NSString *)password forName:(NSString *)name account:(NSString *)account;
+- (void)addPassword:(NSString *)password forName:(NSString *)name account:(NSString *)account withLabel:(NSString *)label;
- (NSString *)getPasswordForName:(NSString *)name account:(NSString *)account;
- (void)deletePasswordForName:(NSString *)name account:(NSString *)account;
- (BOOL)passwordExistsForName:(NSString *)name account:(NSString *)account;
diff --git a/Source/KeyChain.m b/Source/KeyChain.m
index ec5ee03f..ad0251f7 100644
--- a/Source/KeyChain.m
+++ b/Source/KeyChain.m
@@ -34,6 +34,14 @@
*/
- (void)addPassword:(NSString *)password forName:(NSString *)name account:(NSString *)account
{
+ [self addPassword:password forName:name account:account withLabel:name];
+}
+
+/**
+ * Add the supplied password to the user's Keychain using the supplied name, account, and label.
+ */
+- (void)addPassword:(NSString *)password forName:(NSString *)name account:(NSString *)account withLabel:(NSString *)label;
+{
OSStatus status;
SecTrustedApplicationRef sequelProRef, sequelProHelperRef;
SecAccessRef passwordAccessRef;
@@ -61,8 +69,8 @@
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[1].data = (unichar *)[label UTF8String];
+ attributes[1].length = strlen([label UTF8String]);
attributes[2].tag = kSecAccountItemAttr;
attributes[2].data = (unichar *)[account UTF8String];
attributes[2].length = strlen([account UTF8String]);
@@ -173,7 +181,7 @@
attributes[0].data = (void *)[account UTF8String];
attributes[0].length = [account length];
- attributes[1].tag = kSecLabelItemAttr;
+ attributes[1].tag = kSecServiceItemAttr;
attributes[1].data = (void *)[name UTF8String];
attributes[1].length = [name length];
diff --git a/Source/SPSSHTunnel.h b/Source/SPSSHTunnel.h
index 4486685a..0c34f4f9 100644
--- a/Source/SPSSHTunnel.h
+++ b/Source/SPSSHTunnel.h
@@ -19,6 +19,7 @@ enum spsshtunnel_password_modes
{
IBOutlet NSWindow *sshQuestionDialog;
IBOutlet NSTextField *sshQuestionText;
+ IBOutlet NSButton *sshPasswordKeychainCheckbox;
IBOutlet NSWindow *sshPasswordDialog;
IBOutlet NSTextField *sshPasswordText;
IBOutlet NSSecureTextField *sshPasswordField;
@@ -38,6 +39,8 @@ enum spsshtunnel_password_modes
NSString *password;
NSString *keychainName;
NSString *keychainAccount;
+ NSString *requestedPassphrase;
+ BOOL requestedResponse;
BOOL passwordInKeychain;
int sshPort;
int remotePort;
@@ -59,7 +62,9 @@ enum spsshtunnel_password_modes
- (void) standardErrorHandler:(NSNotification*)aNotification;
- (NSString *) getPasswordWithVerificationHash:(NSString *)theHash;
- (BOOL) getResponseForQuestion:(NSString *)theQuestion;
+- (void) workerGetResponseForQuestion:(NSString *)theQuestion;
- (NSString *) getPasswordForQuery:(NSString *)theQuery verificationHash:(NSString *)theHash;
+- (void) workerGetPasswordForQuery:(NSString *)theQuery;
- (IBAction) closeSheet:(id)sender;
@end
diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m
index d8332c14..6df20d2e 100644
--- a/Source/SPSSHTunnel.m
+++ b/Source/SPSSHTunnel.m
@@ -22,6 +22,8 @@
// More info at <http://code.google.com/p/sequel-pro/>
#import "SPSSHTunnel.h"
+#import "RegexKitLite.h"
+#import "KeyChain.h"
#import <netinet/in.h>
@@ -69,6 +71,8 @@
keychainName = nil;
keychainAccount = nil;
passwordInKeychain = NO;
+ requestedPassphrase = nil;
+ requestedResponse = NO;
task = nil;
localPort = 0;
connectionState = SPSSH_STATE_IDLE;
@@ -226,7 +230,7 @@
// [taskArguments addObject:@"-C"]; // TODO: compression?
[taskArguments addObject:@"-o ExitOnForwardFailure=yes"];
[taskArguments addObject:[NSString stringWithFormat:@"-o ConnectTimeout=%i", connectionTimeout]];
- [taskArguments addObject:@"-o NumberOfPasswordPrompts=1"];
+ [taskArguments addObject:@"-o NumberOfPasswordPrompts=3"];
if (useKeepAlive && keepAliveInterval) {
[taskArguments addObject:@"-o TCPKeepAlive=no"];
[taskArguments addObject:[NSString stringWithFormat:@"-o ServerAliveInterval=%i", (int)ceil(keepAliveInterval)]];
@@ -403,6 +407,13 @@
*/
- (BOOL) getResponseForQuestion:(NSString *)theQuestion
{
+ [self performSelectorOnMainThread:@selector(workerGetResponseForQuestion:) withObject:theQuestion waitUntilDone:YES];
+
+ return requestedResponse;
+}
+- (void) workerGetResponseForQuestion:(NSString *)theQuestion
+{
+
NSSize questionTextSize;
NSRect windowFrameRect;
@@ -410,7 +421,7 @@
[sshQuestionText setStringValue:theQuestion];
questionTextSize = [[sshQuestionText cell] cellSizeForBounds:NSMakeRect(0, 0, [sshQuestionText bounds].size.width, 500)];
windowFrameRect = [sshQuestionDialog frame];
- windowFrameRect.size.height = ((questionTextSize.height < 100)?100:questionTextSize.height) + 90;
+ windowFrameRect.size.height = ((questionTextSize.height < 100)?100:questionTextSize.height) + 70 + ([sshPasswordDialog isSheet]?0:22);
[sshQuestionDialog setFrame:windowFrameRect display:NO];
[NSApp beginSheet:sshQuestionDialog modalForWindow:parentWindow modalDelegate:self didEndSelector:nil contextInfo:nil];
int sshQueryResponseCode = [NSApp runModalForWindow:sshQuestionDialog];
@@ -421,11 +432,13 @@
// Yes
case 1:
- return YES;
+ requestedResponse = YES;
+ return;
// No
default:
- return NO;
+ requestedResponse = NO;
+ return;
}
}
@@ -437,15 +450,36 @@
{
if (![theHash isEqualToString:tunnelConnectionVerifyHash]) return nil;
+ NSString *thePassword;
+
+ [self performSelectorOnMainThread:@selector(workerGetPasswordForQuery:) withObject:theQuery waitUntilDone:YES];
+
+ if (!requestedPassphrase) return nil;
+ thePassword = [NSString stringWithString:requestedPassphrase];
+ [requestedPassphrase release], requestedPassphrase = nil;
+ return thePassword;
+}
+- (void) workerGetPasswordForQuery:(NSString *)theQuery
+{
NSSize queryTextSize;
NSRect windowFrameRect;
NSString *thePassword;
+ KeyChain *keychain;
+
+ // Work out whether a passphrase is being requested, extracting the key name
+ NSString *keyName = [theQuery stringByMatching:@"^\\s*Enter passphrase for key \\'(.*)\\':\\s*$" capture:1L];
+ if (keyName) {
+ [sshPasswordText setStringValue:[NSString stringWithFormat:@"Enter your password for the SSH key\n\"%@\"", keyName]];
+ [sshPasswordKeychainCheckbox setHidden:NO];
+ } else {
+ [sshPasswordText setStringValue:theQuery];
+ [sshPasswordKeychainCheckbox setHidden:YES];
+ }
// Request the password, sizing the window appropriately to fit the query
- [sshPasswordText setStringValue:theQuery];
queryTextSize = [[sshPasswordText cell] cellSizeForBounds:NSMakeRect(0, 0, [sshPasswordText bounds].size.width, 500)];
windowFrameRect = [sshPasswordDialog frame];
- windowFrameRect.size.height = ((queryTextSize.height < 40)?40:queryTextSize.height) + 143;
+ windowFrameRect.size.height = ((queryTextSize.height < 40)?40:queryTextSize.height) + 140 + ([sshPasswordDialog isSheet]?0:22);
[sshPasswordDialog setFrame:windowFrameRect display:NO];
[NSApp beginSheet:sshPasswordDialog modalForWindow:parentWindow modalDelegate:self didEndSelector:nil contextInfo:nil];
int sshQueryResponseCode = [NSApp runModalForWindow:sshPasswordDialog];
@@ -459,11 +493,19 @@
thePassword = [NSString stringWithString:[sshPasswordField stringValue]];
[sshPasswordField setStringValue:@""];
[[delegate undoManager] removeAllActionsWithTarget:sshPasswordField];
- return thePassword;
+ requestedPassphrase = [[NSString alloc] initWithString:thePassword];
+
+ // Add to keychain if appropriate
+ if (keyName && [sshPasswordKeychainCheckbox state] == NSOnState) {
+ keychain = [[KeyChain alloc] init];
+ [keychain addPassword:thePassword forName:@"SSH" account:keyName withLabel:[NSString stringWithFormat:@"SSH: %@", keyName]];
+ [keychain release];
+ }
+ return;
// Cancel
default:
- return nil;
+ return;
}
}
diff --git a/Source/TunnelPassphraseRequester.m b/Source/TunnelPassphraseRequester.m
index 31c4b54a..11665449 100644
--- a/Source/TunnelPassphraseRequester.m
+++ b/Source/TunnelPassphraseRequester.m
@@ -23,6 +23,7 @@
#import <Cocoa/Cocoa.h>
#import "KeyChain.h"
#import "SPSSHTunnel.h"
+#import "RegexKitLite.h"
int main(int argc, const char *argv[])
{
@@ -120,9 +121,25 @@ int main(int argc, const char *argv[])
}
}
- // Check whether we're being asked for a SSH key passphrase, forward requests to the GUI
+ // Check whether we're being asked for a SSH key passphrase
if (argument && [[argument lowercaseString] rangeOfString:@"enter passphrase for"].location != NSNotFound ) {
NSString *passphrase;
+ NSString *keyName = [argument stringByMatching:@"^\\s*Enter passphrase for key \\'(.*)\\':\\s*$" capture:1L];
+
+ if (keyName) {
+
+ // Check whether the passphrase is in the keychain, using standard OS X sshagent name and account
+ KeyChain *keychain = [[KeyChain alloc] init];
+ if ([keychain passwordExistsForName:@"SSH" account:keyName]) {
+ printf("%s\n", [[keychain getPasswordForName:@"SSH" account:keyName] UTF8String]);
+ [keychain release];
+ [pool release];
+ return 0;
+ }
+ [keychain release];
+ }
+
+ // Not found in the keychain - we need to ask the GUI.
if (!verificationHash) {
NSLog(@"SSH Tunnel: key passphrase authentication required but insufficient details supplied to connect to GUI");
diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj
index 0a8ce9f2..4a7fdf16 100644
--- a/sequel-pro.xcodeproj/project.pbxproj
+++ b/sequel-pro.xcodeproj/project.pbxproj
@@ -88,6 +88,8 @@
5841423F0F97E11000A34B47 /* NoodleLineNumberView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5841423E0F97E11000A34B47 /* NoodleLineNumberView.m */; };
584F5F8F0F50ACD800036517 /* table-view-small.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 584F5F8E0F50ACD800036517 /* table-view-small.tiff */; };
586F432B0FD74CFC00B428D7 /* SSHQuestionDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 586F432A0FD74CFC00B428D7 /* SSHQuestionDialog.xib */; };
+ 586F457B0FDB269E00B428D7 /* RegexKitLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 296DC8AB0F909194002A3258 /* RegexKitLite.m */; };
+ 586F457E0FDB280100B428D7 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 296DC8BE0F9091DF002A3258 /* libicucore.dylib */; };
5885940F0F7AEE6000ED0E67 /* sparkle-public-key.pem in Resources */ = {isa = PBXBuildFile; fileRef = 5885940E0F7AEE6000ED0E67 /* sparkle-public-key.pem */; };
58C56EF50F438E120035701E /* SPDataCellFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C56EF40F438E120035701E /* SPDataCellFormatter.m */; };
58CB20ED0F79A75D005EA204 /* button_edit_mode_selected.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 58CB20EC0F79A75D005EA204 /* button_edit_mode_selected.tiff */; };
@@ -409,6 +411,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 586F457E0FDB280100B428D7 /* libicucore.dylib in Frameworks */,
58CDB3400FCE13EF00F8ACA3 /* Security.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1075,6 +1078,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 586F457B0FDB269E00B428D7 /* RegexKitLite.m in Sources */,
58CDB3410FCE141900F8ACA3 /* TunnelPassphraseRequester.m in Sources */,
58CDB3420FCE142500F8ACA3 /* KeyChain.m in Sources */,
);