diff options
author | rowanbeentje <rowan@beent.je> | 2009-06-05 00:32:42 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2009-06-05 00:32:42 +0000 |
commit | 4e6c8e557f6dd132e159ff4841900d1b72331eea (patch) | |
tree | bd972c23c05f09be246f436b3bd511c4f5dbf23e | |
parent | 905dd61bd91f3dce22655bf942302739544dd86c (diff) | |
download | sequelpro-4e6c8e557f6dd132e159ff4841900d1b72331eea.tar.gz sequelpro-4e6c8e557f6dd132e159ff4841900d1b72331eea.tar.bz2 sequelpro-4e6c8e557f6dd132e159ff4841900d1b72331eea.zip |
Further SSH tunnel improvements:
- SSH Public/private keys are now supported, even if they are password-protected. The user and password fields can be left blank where appropriate.
- SSH yes/no queries (ie host key mismatch) and password requests (eg key passphrases) dialogs now automatically resize to match the content from the SSH process.
-rw-r--r-- | Interfaces/SSHQuestionDialog.xib | 390 | ||||
-rw-r--r-- | Source/SPSSHTunnel.h | 4 | ||||
-rw-r--r-- | Source/SPSSHTunnel.m | 61 | ||||
-rw-r--r-- | Source/TunnelPassphraseRequester.m | 95 |
4 files changed, 494 insertions, 56 deletions
diff --git a/Interfaces/SSHQuestionDialog.xib b/Interfaces/SSHQuestionDialog.xib index bbb00fe3..3b18a91c 100644 --- a/Interfaces/SSHQuestionDialog.xib +++ b/Interfaces/SSHQuestionDialog.xib @@ -8,7 +8,8 @@ <string key="IBDocument.HIToolboxVersion">353.00</string> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <bool key="EncodedWithXMLCoder">YES</bool> - <integer value="367"/> + <integer value="469"/> + <integer value="368"/> </object> <object class="NSArray" key="IBDocument.PluginDependencies"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -38,7 +39,7 @@ <object class="NSWindowTemplate" id="513744381"> <int key="NSWindowStyleMask">1</int> <int key="NSWindowBacking">2</int> - <string key="NSWindowRect">{{196, 301}, {536, 209}}</string> + <string key="NSWindowRect">{{196, 301}, {620, 209}}</string> <int key="NSWTFlags">603979776</int> <string key="NSWindowTitle">SSH Tunnel Query</string> <string key="NSWindowClass">NSWindow</string> @@ -52,20 +53,20 @@ <object class="NSTextField" id="958459073"> <reference key="NSNextResponder" ref="414427165"/> <int key="NSvFlags">274</int> - <string key="NSFrame">{{126, 46}, {393, 143}}</string> + <string key="NSFrame">{{126, 60}, {477, 129}}</string> <reference key="NSSuperview" ref="414427165"/> <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"> + <object class="NSFont" key="NSSupport" id="926333026"> <string key="NSName">LucidaGrande</string> <double key="NSSize">1.300000e+01</double> <int key="NSfFlags">16</int> </object> <reference key="NSControlView" ref="958459073"/> - <object class="NSColor" key="NSBackgroundColor"> + <object class="NSColor" key="NSBackgroundColor" id="440063573"> <int key="NSColorSpace">6</int> <string key="NSCatalogName">System</string> <string key="NSColorName">controlColor</string> @@ -74,11 +75,11 @@ <bytes key="NSWhite">MC42NjY2NjY2OQA</bytes> </object> </object> - <object class="NSColor" key="NSTextColor"> + <object class="NSColor" key="NSTextColor" id="857180797"> <int key="NSColorSpace">6</int> <string key="NSCatalogName">System</string> <string key="NSColorName">controlTextColor</string> - <object class="NSColor" key="NSColor"> + <object class="NSColor" key="NSColor" id="587031165"> <int key="NSColorSpace">3</int> <bytes key="NSWhite">MAA</bytes> </object> @@ -88,7 +89,7 @@ <object class="NSButton" id="819605912"> <reference key="NSNextResponder" ref="414427165"/> <int key="NSvFlags">289</int> - <string key="NSFrame">{{426, 12}, {96, 32}}</string> + <string key="NSFrame">{{510, 12}, {96, 32}}</string> <reference key="NSSuperview" ref="414427165"/> <int key="NSTag">1</int> <bool key="NSEnabled">YES</bool> @@ -112,7 +113,7 @@ </object> <object class="NSImageView" id="346757277"> <reference key="NSNextResponder" ref="414427165"/> - <int key="NSvFlags">256</int> + <int key="NSvFlags">268</int> <object class="NSMutableSet" key="NSDragTypes"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMutableArray" key="set.sortedObjects"> @@ -131,7 +132,7 @@ <object class="NSImageCell" key="NSCell" id="490596046"> <int key="NSCellFlags">130560</int> <int key="NSCellFlags2">33554432</int> - <object class="NSCustomResource" key="NSContents"> + <object class="NSCustomResource" key="NSContents" id="493872852"> <string key="NSClassName">NSImage</string> <string key="NSResourceName">appicon</string> </object> @@ -145,7 +146,7 @@ <object class="NSButton" id="472545742"> <reference key="NSNextResponder" ref="414427165"/> <int key="NSvFlags">289</int> - <string key="NSFrame">{{330, 12}, {96, 32}}</string> + <string key="NSFrame">{{414, 12}, {96, 32}}</string> <reference key="NSSuperview" ref="414427165"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="382904691"> @@ -164,7 +165,7 @@ </object> <object class="NSImageView" id="205963577"> <reference key="NSNextResponder" ref="414427165"/> - <int key="NSvFlags">256</int> + <int key="NSvFlags">268</int> <object class="NSMutableSet" key="NSDragTypes"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMutableArray" key="set.sortedObjects"> @@ -195,12 +196,185 @@ <bool key="NSEditable">YES</bool> </object> </object> - <string key="NSFrameSize">{536, 209}</string> + <string key="NSFrameSize">{620, 209}</string> <reference key="NSSuperview"/> </object> <string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string> <string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string> </object> + <object class="NSWindowTemplate" id="638910821"> + <int key="NSWindowStyleMask">1</int> + <int key="NSWindowBacking">2</int> + <string key="NSWindowRect">{{196, 301}, {620, 209}}</string> + <int key="NSWTFlags">603979776</int> + <string key="NSWindowTitle">SSH Tunnel Password Query</string> + <string key="NSWindowClass">NSWindow</string> + <nil key="NSViewClass"/> + <string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string> + <object class="NSView" key="NSWindowView" id="69459762"> + <reference key="NSNextResponder"/> + <int key="NSvFlags">256</int> + <object class="NSMutableArray" key="NSSubviews"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSTextField" id="596781589"> + <reference key="NSNextResponder" ref="69459762"/> + <int key="NSvFlags">274</int> + <string key="NSFrame">{{126, 113}, {477, 76}}</string> + <reference key="NSSuperview" ref="69459762"/> + <bool key="NSEnabled">YES</bool> + <object class="NSTextFieldCell" key="NSCell" id="994843376"> + <int key="NSCellFlags">67239424</int> + <int key="NSCellFlags2">272891904</int> + <string key="NSContents"/> + <reference key="NSSupport" ref="926333026"/> + <reference key="NSControlView" ref="596781589"/> + <reference key="NSBackgroundColor" ref="440063573"/> + <reference key="NSTextColor" ref="857180797"/> + </object> + </object> + <object class="NSButton" id="292904434"> + <reference key="NSNextResponder" ref="69459762"/> + <int key="NSvFlags">289</int> + <string key="NSFrame">{{510, 12}, {96, 32}}</string> + <reference key="NSSuperview" ref="69459762"/> + <int key="NSTag">1</int> + <bool key="NSEnabled">YES</bool> + <object class="NSButtonCell" key="NSCell" id="918476288"> + <int key="NSCellFlags">67239424</int> + <int key="NSCellFlags2">134217728</int> + <string key="NSContents">OK</string> + <reference key="NSSupport" ref="313221240"/> + <reference key="NSControlView" ref="292904434"/> + <int key="NSButtonFlags">-2038284033</int> + <int key="NSButtonFlags2">129</int> + <string key="NSAlternateContents"/> + <string type="base64-UTF8" key="NSKeyEquivalent">DQ</string> + <int key="NSPeriodicDelay">200</int> + <int key="NSPeriodicInterval">25</int> + </object> + </object> + <object class="NSImageView" id="464904462"> + <reference key="NSNextResponder" ref="69459762"/> + <int key="NSvFlags">268</int> + <object class="NSMutableSet" key="NSDragTypes"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="set.sortedObjects"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>Apple PDF pasteboard type</string> + <string>Apple PICT pasteboard type</string> + <string>Apple PNG pasteboard type</string> + <string>NSFilenamesPboardType</string> + <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string> + <string>NeXT TIFF v4.0 pasteboard type</string> + </object> + </object> + <string key="NSFrame">{{20, 115}, {75, 74}}</string> + <reference key="NSSuperview" ref="69459762"/> + <bool key="NSEnabled">YES</bool> + <object class="NSImageCell" key="NSCell" id="1038501330"> + <int key="NSCellFlags">130560</int> + <int key="NSCellFlags2">33554432</int> + <reference key="NSContents" ref="493872852"/> + <int key="NSAlign">0</int> + <int key="NSScale">0</int> + <int key="NSStyle">0</int> + <bool key="NSAnimates">YES</bool> + </object> + <bool key="NSEditable">YES</bool> + </object> + <object class="NSButton" id="421245814"> + <reference key="NSNextResponder" ref="69459762"/> + <int key="NSvFlags">289</int> + <string key="NSFrame">{{414, 12}, {96, 32}}</string> + <reference key="NSSuperview" ref="69459762"/> + <bool key="NSEnabled">YES</bool> + <object class="NSButtonCell" key="NSCell" id="934536740"> + <int key="NSCellFlags">67239424</int> + <int key="NSCellFlags2">134217728</int> + <string key="NSContents">Cancel</string> + <reference key="NSSupport" ref="313221240"/> + <reference key="NSControlView" ref="421245814"/> + <int key="NSButtonFlags">-2038284033</int> + <int key="NSButtonFlags2">129</int> + <string key="NSAlternateContents"/> + <string key="NSKeyEquivalent"/> + <int key="NSPeriodicDelay">200</int> + <int key="NSPeriodicInterval">25</int> + </object> + </object> + <object class="NSImageView" id="331556700"> + <reference key="NSNextResponder" ref="69459762"/> + <int key="NSvFlags">268</int> + <object class="NSMutableSet" key="NSDragTypes"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="set.sortedObjects"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>Apple PDF pasteboard type</string> + <string>Apple PICT pasteboard type</string> + <string>Apple PNG pasteboard type</string> + <string>NSFilenamesPboardType</string> + <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string> + <string>NeXT TIFF v4.0 pasteboard type</string> + </object> + </object> + <string key="NSFrame">{{68, 113}, {32, 32}}</string> + <reference key="NSSuperview" ref="69459762"/> + <bool key="NSEnabled">YES</bool> + <object class="NSImageCell" key="NSCell" id="510630540"> + <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> + <int key="NSAlign">0</int> + <int key="NSScale">0</int> + <int key="NSStyle">0</int> + <bool key="NSAnimates">YES</bool> + </object> + <bool key="NSEditable">YES</bool> + </object> + <object class="NSSecureTextField" id="408102217"> + <reference key="NSNextResponder" ref="69459762"/> + <int key="NSvFlags">294</int> + <string key="NSFrame">{{129, 70}, {261, 22}}</string> + <reference key="NSSuperview" ref="69459762"/> + <bool key="NSEnabled">YES</bool> + <object class="NSSecureTextFieldCell" key="NSCell" id="938809700"> + <int key="NSCellFlags">343014976</int> + <int key="NSCellFlags2">272630784</int> + <string key="NSContents"/> + <reference key="NSSupport" ref="313221240"/> + <reference key="NSControlView" ref="408102217"/> + <bool key="NSDrawsBackground">YES</bool> + <object class="NSColor" key="NSBackgroundColor"> + <int key="NSColorSpace">6</int> + <string key="NSCatalogName">System</string> + <string key="NSColorName">textBackgroundColor</string> + <object class="NSColor" key="NSColor"> + <int key="NSColorSpace">3</int> + <bytes key="NSWhite">MQA</bytes> + </object> + </object> + <object class="NSColor" key="NSTextColor"> + <int key="NSColorSpace">6</int> + <string key="NSCatalogName">System</string> + <string key="NSColorName">textColor</string> + <reference key="NSColor" ref="587031165"/> + </object> + <object class="NSArray" key="NSAllowedInputLocales"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>NSAllRomanInputSourcesLocaleIdentifier</string> + </object> + </object> + </object> + </object> + <string key="NSFrameSize">{620, 209}</string> + <reference key="NSSuperview"/> + </object> + <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string> + <string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string> + </object> </object> <object class="IBObjectContainer" key="IBDocument.Objects"> <object class="NSMutableArray" key="connectionRecords"> @@ -237,6 +411,46 @@ </object> <int key="connectionID">467</int> </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">closeSheet:</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="292904434"/> + </object> + <int key="connectionID">480</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">closeSheet:</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="421245814"/> + </object> + <int key="connectionID">481</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">sshPasswordDialog</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="638910821"/> + </object> + <int key="connectionID">482</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">sshPasswordText</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="596781589"/> + </object> + <int key="connectionID">483</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">sshPasswordField</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="408102217"/> + </object> + <int key="connectionID">488</int> + </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> @@ -283,9 +497,9 @@ <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="205963577"/> <reference ref="958459073"/> + <reference ref="346757277"/> <reference ref="819605912"/> <reference ref="472545742"/> - <reference ref="346757277"/> </object> <reference key="parent" ref="513744381"/> </object> @@ -359,6 +573,113 @@ <reference key="object" ref="490596046"/> <reference key="parent" ref="346757277"/> </object> + <object class="IBObjectRecord"> + <int key="objectID">468</int> + <reference key="object" ref="638910821"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="69459762"/> + </object> + <reference key="parent" ref="1049"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">469</int> + <reference key="object" ref="69459762"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="421245814"/> + <reference ref="292904434"/> + <reference ref="464904462"/> + <reference ref="596781589"/> + <reference ref="331556700"/> + <reference ref="408102217"/> + </object> + <reference key="parent" ref="638910821"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">470</int> + <reference key="object" ref="421245814"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="934536740"/> + </object> + <reference key="parent" ref="69459762"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">471</int> + <reference key="object" ref="292904434"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="918476288"/> + </object> + <reference key="parent" ref="69459762"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">472</int> + <reference key="object" ref="464904462"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="1038501330"/> + </object> + <reference key="parent" ref="69459762"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">473</int> + <reference key="object" ref="596781589"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="994843376"/> + </object> + <reference key="parent" ref="69459762"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">474</int> + <reference key="object" ref="331556700"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="510630540"/> + </object> + <reference key="parent" ref="69459762"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">475</int> + <reference key="object" ref="510630540"/> + <reference key="parent" ref="331556700"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">476</int> + <reference key="object" ref="994843376"/> + <reference key="parent" ref="596781589"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">477</int> + <reference key="object" ref="1038501330"/> + <reference key="parent" ref="464904462"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">478</int> + <reference key="object" ref="918476288"/> + <reference key="parent" ref="292904434"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">479</int> + <reference key="object" ref="934536740"/> + <reference key="parent" ref="421245814"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">484</int> + <reference key="object" ref="408102217"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="938809700"/> + </object> + <reference key="parent" ref="69459762"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">485</int> + <reference key="object" ref="938809700"/> + <reference key="parent" ref="408102217"/> + </object> </object> </object> <object class="NSMutableDictionary" key="flattenedProperties"> @@ -379,15 +700,28 @@ <string>459.IBPluginDependency</string> <string>460.IBPluginDependency</string> <string>461.IBPluginDependency</string> + <string>468.IBEditorWindowLastContentRect</string> + <string>468.IBWindowTemplateEditedContentRect</string> + <string>468.NSWindowTemplate.visibleAtLaunch</string> + <string>468.editorWindowContentRectSynchronizationRect</string> + <string>469.IBPluginDependency</string> + <string>470.IBPluginDependency</string> + <string>471.IBPluginDependency</string> + <string>473.IBPluginDependency</string> + <string>476.IBPluginDependency</string> + <string>478.IBPluginDependency</string> + <string>479.IBPluginDependency</string> + <string>484.IBPluginDependency</string> + <string>485.IBPluginDependency</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilderKit</string> <string>com.apple.InterfaceBuilderKit</string> - <string>{{187, 404}, {536, 209}}</string> - <string>{{187, 404}, {536, 209}}</string> - <boolean value="NO"/> + <string>{{187, 404}, {620, 209}}</string> + <string>{{187, 404}, {620, 209}}</string> + <boolean value="NO" id="6"/> <string>{{11, 666}, {480, 270}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> @@ -396,6 +730,19 @@ <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> + <reference ref="6"/> + <string>{{11, 666}, {480, 270}}</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> + <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"> @@ -418,13 +765,14 @@ </object> </object> <nil key="sourceID"/> - <int key="maxID">467</int> + <int key="maxID">488</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBPartialClassDescription"> <string key="className">NSApplication</string> + <string key="superclassName">NSResponder</string> <object class="NSMutableDictionary" key="outlets"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMutableArray" key="dict.sortedKeys"> @@ -467,12 +815,18 @@ <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMutableArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> + <string>sshPasswordDialog</string> + <string>sshPasswordField</string> + <string>sshPasswordText</string> <string>sshQuestionDialog</string> <string>sshQuestionText</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>NSWindow</string> + <string>NSSecureTextField</string> + <string>NSTextField</string> + <string>NSWindow</string> <string>NSTextField</string> </object> </object> diff --git a/Source/SPSSHTunnel.h b/Source/SPSSHTunnel.h index 612ef595..4486685a 100644 --- a/Source/SPSSHTunnel.h +++ b/Source/SPSSHTunnel.h @@ -19,6 +19,9 @@ enum spsshtunnel_password_modes { IBOutlet NSWindow *sshQuestionDialog; IBOutlet NSTextField *sshQuestionText; + IBOutlet NSWindow *sshPasswordDialog; + IBOutlet NSTextField *sshPasswordText; + IBOutlet NSSecureTextField *sshPasswordField; NSWindow *parentWindow; NSTask *task; @@ -56,6 +59,7 @@ enum spsshtunnel_password_modes - (void) standardErrorHandler:(NSNotification*)aNotification; - (NSString *) getPasswordWithVerificationHash:(NSString *)theHash; - (BOOL) getResponseForQuestion:(NSString *)theQuestion; +- (NSString *) getPasswordForQuery:(NSString *)theQuery verificationHash:(NSString *)theHash; - (IBAction) closeSheet:(id)sender; @end diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m index 83beb8a7..79ea780c 100644 --- a/Source/SPSSHTunnel.m +++ b/Source/SPSSHTunnel.m @@ -55,6 +55,7 @@ // Set up a connection for use by the tunnel process tunnelConnectionName = [NSString stringWithFormat:@"SequelPro-%f", [[NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970]] hash]]; + tunnelConnectionVerifyHash = [NSString stringWithFormat:@"%f", [[NSString stringWithFormat:@"%f%i", [[NSDate date] timeIntervalSince1970]] hash]]; tunnelConnection = [[NSConnection defaultConnection] retain]; [tunnelConnection runInNewThread]; [tunnelConnection removeRunLoop:[NSRunLoop currentRunLoop]]; @@ -107,7 +108,6 @@ { if (passwordInKeychain) return NO; password = [[NSString alloc] initWithString:thePassword]; - tunnelConnectionVerifyHash = [NSString stringWithFormat:@"%f", [[NSString stringWithFormat:@"%f%i", [[NSDate date] timeIntervalSince1970]] hash]]; return YES; } @@ -225,7 +225,6 @@ // [taskArguments addObject:@"-C"]; // TODO: compression? [taskArguments addObject:@"-o ExitOnForwardFailure=yes"]; [taskArguments addObject:[NSString stringWithFormat:@"-o ConnectTimeout=%i", connectionTimeout]]; - [taskArguments addObject:@"-o PubkeyAuthentication=yes"]; [taskArguments addObject:@"-o NumberOfPasswordPrompts=1"]; if (useKeepAlive && keepAliveInterval) { [taskArguments addObject:@"-o TCPKeepAlive=no"]; @@ -233,7 +232,11 @@ [taskArguments addObject:@"-o ServerAliveCountMax=1"]; } [taskArguments addObject:[NSString stringWithFormat:@"-p %i", sshPort]]; - [taskArguments addObject:[NSString stringWithFormat:@"%@@%@", sshLogin, sshHost]]; + if ([sshLogin length]) { + [taskArguments addObject:[NSString stringWithFormat:@"%@@%@", sshLogin, sshHost]]; + } else { + [taskArguments addObject:sshHost]; + } [taskArguments addObject:[NSString stringWithFormat:@"-L %i/%@/%i", localPort, remoteHost, remotePort]]; [task setArguments:taskArguments]; @@ -245,13 +248,13 @@ [taskEnvironment setObject:authenticationAppPath forKey:@"SSH_ASKPASS"]; [taskEnvironment setObject:@":0" forKey:@"DISPLAY"]; [taskEnvironment setObject:tunnelConnectionName forKey:@"SP_CONNECTION_NAME"]; + [taskEnvironment setObject:tunnelConnectionVerifyHash forKey:@"SP_CONNECTION_VERIFY_HASH"]; if (passwordInKeychain) { [taskEnvironment setObject:[[NSNumber numberWithInt:SPSSH_PASSWORD_USES_KEYCHAIN] stringValue] forKey:@"SP_PASSWORD_METHOD"]; [taskEnvironment setObject:keychainName forKey:@"SP_KEYCHAIN_ITEM_NAME"]; [taskEnvironment setObject:keychainAccount forKey:@"SP_KEYCHAIN_ITEM_ACCOUNT"]; } else { [taskEnvironment setObject:[[NSNumber numberWithInt:SPSSH_PASSWORD_ASKS_UI] stringValue] forKey:@"SP_PASSWORD_METHOD"]; - [taskEnvironment setObject:tunnelConnectionVerifyHash forKey:@"SP_CONNECTION_VERIFY_HASH"]; } [task setEnvironment:taskEnvironment]; @@ -282,6 +285,8 @@ // Listen for output [task waitUntilExit]; + + // If the task closed unexpectedly, alert appropriately if (connectionState != SPSSH_STATE_IDLE) { connectionState = SPSSH_STATE_IDLE; lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel has unexpectedly closed.", @"SSH tunnel unexpectedly closed")]; @@ -343,7 +348,7 @@ lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was closed 'by the remote host'. This may indicate a networking issue or a network timeout.", @"SSH tunnel was closed by remote host message")]; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; } - if ([message rangeOfString:@"Permission denied (" ].location != NSNotFound) { + if ([message rangeOfString:@"Permission denied (" ].location != NSNotFound || [message rangeOfString:@"No more authentication methods to try" ].location != NSNotFound) { connectionState = SPSSH_STATE_IDLE; [task terminate]; if (lastError) [lastError release]; @@ -394,9 +399,15 @@ */ - (BOOL) getResponseForQuestion:(NSString *)theQuestion { + NSSize questionTextSize; + NSRect windowFrameRect; - // Ask how to proceed + // Ask how to proceed, sizing the window appropriately to fit the question [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; + [sshQuestionDialog setFrame:windowFrameRect display:NO]; [NSApp beginSheet:sshQuestionDialog modalForWindow:parentWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; int sshQueryResponseCode = [NSApp runModalForWindow:sshQuestionDialog]; [NSApp endSheet:sshQuestionDialog]; @@ -415,6 +426,44 @@ } /* + * Method to allow an SSH tunnel to request a password. This is used by the program set by the + * SSH_ASKPASS environment setting to request passphrases for SSH keys. + */ +- (NSString *) getPasswordForQuery:(NSString *)theQuery verificationHash:(NSString *)theHash +{ + if (![theHash isEqualToString:tunnelConnectionVerifyHash]) return nil; + + NSSize queryTextSize; + NSRect windowFrameRect; + NSString *thePassword; + + // 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; + [sshPasswordDialog setFrame:windowFrameRect display:NO]; + [NSApp beginSheet:sshPasswordDialog modalForWindow:parentWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; + int sshQueryResponseCode = [NSApp runModalForWindow:sshPasswordDialog]; + [NSApp endSheet:sshPasswordDialog]; + [sshPasswordDialog orderOut:nil]; + + switch (sshQueryResponseCode) { + + // OK + case 1: + thePassword = [NSString stringWithString:[sshPasswordField stringValue]]; + [sshPasswordField setStringValue:@""]; + [[delegate undoManager] removeAllActionsWithTarget:sshPasswordField]; + return thePassword; + + // Cancel + default: + return nil; + } +} + +/* * Ends an existing modal session */ - (IBAction) closeSheet:(id)sender diff --git a/Source/TunnelPassphraseRequester.m b/Source/TunnelPassphraseRequester.m index 4391e3e7..360af00d 100644 --- a/Source/TunnelPassphraseRequester.m +++ b/Source/TunnelPassphraseRequester.m @@ -31,6 +31,7 @@ int main(int argc, const char *argv[]) NSString *argument = nil; SPSSHTunnel *sequelProTunnel; NSString *connectionName = [environment objectForKey:@"SP_CONNECTION_NAME"]; + NSString *verificationHash = [environment objectForKey:@"SP_CONNECTION_VERIFY_HASH"]; if (![environment objectForKey:@"SP_PASSWORD_METHOD"]) { [pool release]; @@ -38,7 +39,7 @@ int main(int argc, const char *argv[]) } if (argc > 1) { - argument = [[NSString alloc] initWithCString:argv[1] encoding:NSUTF8StringEncoding]; + argument = [[[NSString alloc] initWithCString:argv[1] encoding:NSUTF8StringEncoding] autorelease]; } // Check if we're being asked a question and respond if so @@ -59,57 +60,87 @@ int main(int argc, const char *argv[]) return 0; } - // If the password method is set to use the keychain, use the supplied keychain name to - // request the password - if ([[environment objectForKey:@"SP_PASSWORD_METHOD"] intValue] == SPSSH_PASSWORD_USES_KEYCHAIN) { - KeyChain *keychain; - NSString *keychainName = [environment objectForKey:@"SP_KEYCHAIN_ITEM_NAME"]; - NSString *keychainAccount = [environment objectForKey:@"SP_KEYCHAIN_ITEM_ACCOUNT"]; - - if (!keychainName || !keychainAccount) { - NSLog(@"SSH Tunnel: keychain authentication specified but insufficient internal details supplied"); + // Check whether we're being asked for a standard SSH password - if so, use the app-entered value. + if (argument && [[argument lowercaseString] rangeOfString:@"password:"].location != NSNotFound ) { + + // If the password method is set to use the keychain, use the supplied keychain name to + // request the password + if ([[environment objectForKey:@"SP_PASSWORD_METHOD"] intValue] == SPSSH_PASSWORD_USES_KEYCHAIN) { + KeyChain *keychain; + NSString *keychainName = [environment objectForKey:@"SP_KEYCHAIN_ITEM_NAME"]; + NSString *keychainAccount = [environment objectForKey:@"SP_KEYCHAIN_ITEM_ACCOUNT"]; + + if (!keychainName || !keychainAccount) { + NSLog(@"SSH Tunnel: keychain authentication specified but insufficient internal details supplied"); + [pool release]; + return 1; + } + + keychain = [[KeyChain alloc] init]; + if (![keychain passwordExistsForName:keychainName account:keychainAccount]) { + NSLog(@"SSH Tunnel: specified keychain password not found"); + [pool release]; + return 1; + } + + printf("%s\n", [[keychain getPasswordForName:keychainName account:keychainAccount] UTF8String]); [pool release]; - return 1; + return 0; } - keychain = [[KeyChain alloc] init]; - if (![keychain passwordExistsForName:keychainName account:keychainAccount]) { - NSLog(@"SSH Tunnel: specified keychain password not found"); + // If the password method is set to request the password from the tunnel instance, do so. + if ([[environment objectForKey:@"SP_PASSWORD_METHOD"] intValue] == SPSSH_PASSWORD_ASKS_UI) { + NSString *password; + + if (!connectionName || !verificationHash) { + NSLog(@"SSH Tunnel: internal authentication specified but insufficient details supplied"); + [pool release]; + return 1; + } + + sequelProTunnel = (SPSSHTunnel *)[NSConnection rootProxyForConnectionWithRegisteredName:connectionName host:nil]; + if (!sequelProTunnel) { + NSLog(@"SSH Tunnel: unable to connect to Sequel Pro for internal authentication"); + [pool release]; + return 1; + } + + password = [sequelProTunnel getPasswordWithVerificationHash:verificationHash]; + if (!password) { + NSLog(@"SSH Tunnel: unable to successfully request password from Sequel Pro for internal authentication"); + [pool release]; + return 1; + } + + printf("%s\n", [password UTF8String]); [pool release]; - return 1; + return 0; } - - printf("%s\n", [[keychain getPasswordForName:keychainName account:keychainAccount] UTF8String]); - [pool release]; - return 0; } - // If the password method is set to request the password from the tunnel instance, do so. - if ([[environment objectForKey:@"SP_PASSWORD_METHOD"] intValue] == SPSSH_PASSWORD_ASKS_UI) { - NSString *password; - NSString *verificationHash = [environment objectForKey:@"SP_CONNECTION_VERIFY_HASH"]; - - if (!connectionName || !verificationHash) { - NSLog(@"SSH Tunnel: internal authentication specified but insufficient details supplied"); + // Check whether we're being asked for a SSH key passphrase, forward requests to the GUI + if (argument && [[argument lowercaseString] rangeOfString:@"enter passphrase for"].location != NSNotFound ) { + NSString *passphrase; + + if (!verificationHash) { + NSLog(@"SSH Tunnel: key passphrase authentication required but insufficient details supplied to connect to GUI"); [pool release]; return 1; } sequelProTunnel = (SPSSHTunnel *)[NSConnection rootProxyForConnectionWithRegisteredName:connectionName host:nil]; if (!sequelProTunnel) { - NSLog(@"SSH Tunnel: unable to connect to Sequel Pro for internal authentication"); + NSLog(@"SSH Tunnel: unable to connect to Sequel Pro to show SSH question"); [pool release]; return 1; } - - password = [sequelProTunnel getPasswordWithVerificationHash:verificationHash]; - if (!password) { - NSLog(@"SSH Tunnel: unable to successfully request password from Sequel Pro for internal authentication"); + passphrase = [sequelProTunnel getPasswordForQuery:argument verificationHash:verificationHash]; + if (!passphrase) { [pool release]; return 1; } - printf("%s\n", [password UTF8String]); + printf("%s\n", [passphrase UTF8String]); [pool release]; return 0; } |