aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Interfaces/English.lproj/SSHQuestionDialog.xib141
-rw-r--r--Source/SPSSHTunnel.h7
-rw-r--r--Source/SPSSHTunnel.m139
3 files changed, 193 insertions, 94 deletions
diff --git a/Interfaces/English.lproj/SSHQuestionDialog.xib b/Interfaces/English.lproj/SSHQuestionDialog.xib
index 9941eddb..fc8bd36f 100644
--- a/Interfaces/English.lproj/SSHQuestionDialog.xib
+++ b/Interfaces/English.lproj/SSHQuestionDialog.xib
@@ -12,6 +12,7 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="368"/>
<integer value="469"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
@@ -30,7 +31,7 @@
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="1021">
- <string key="NSClassName">NSObject</string>
+ <string key="NSClassName">SPSSHTunnel</string>
</object>
<object class="NSCustomObject" id="1014">
<string key="NSClassName">FirstResponder</string>
@@ -48,7 +49,7 @@
<nil key="NSViewClass"/>
<string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
<object class="NSView" key="NSWindowView" id="414427165">
- <nil key="NSNextResponder"/>
+ <reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -199,6 +200,7 @@
</object>
</object>
<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>
@@ -441,38 +443,6 @@
<int key="connectionID">465</int>
</object>
<object class="IBConnectionRecord">
- <object class="IBActionConnection" key="connection">
- <string key="label">closeSheet:</string>
- <reference key="source" ref="1021"/>
- <reference key="destination" ref="819605912"/>
- </object>
- <int key="connectionID">466</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBActionConnection" key="connection">
- <string key="label">closeSheet:</string>
- <reference key="source" ref="1021"/>
- <reference key="destination" ref="472545742"/>
- </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="881553485"/>
- </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="920337090"/>
- </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"/>
@@ -504,6 +474,38 @@
</object>
<int key="connectionID">493</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">closeSSHPasswordSheet:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="881553485"/>
+ </object>
+ <int key="connectionID">494</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">closeSSHPasswordSheet:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="920337090"/>
+ </object>
+ <int key="connectionID">495</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">closeSSHQuestionSheet:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="819605912"/>
+ </object>
+ <int key="connectionID">496</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">closeSSHQuestionSheet:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="472545742"/>
+ </object>
+ <int key="connectionID">497</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -826,9 +828,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{218, 467}, {471, 209}}</string>
+ <string>{{127, 251}, {471, 209}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{218, 467}, {471, 209}}</string>
+ <string>{{127, 251}, {471, 209}}</string>
<boolean value="NO"/>
<string>{{11, 666}, {480, 270}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -866,7 +868,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">493</int>
+ <int key="maxID">497</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -991,6 +993,50 @@
<string key="minorKey">Source/SPWindowAdditions.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">SPSSHTunnel</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>closeSSHPasswordSheet:</string>
+ <string>closeSSHQuestionSheet:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>delegate</string>
+ <string>sshPasswordDialog</string>
+ <string>sshPasswordField</string>
+ <string>sshPasswordKeychainCheckbox</string>
+ <string>sshPasswordText</string>
+ <string>sshQuestionDialog</string>
+ <string>sshQuestionText</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>NSWindow</string>
+ <string>NSSecureTextField</string>
+ <string>NSButton</string>
+ <string>NSTextField</string>
+ <string>NSWindow</string>
+ <string>NSTextField</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Source/SPSSHTunnel.h</string>
+ </object>
+ </object>
</object>
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1046,6 +1092,13 @@
</object>
</object>
<object class="IBPartialClassDescription">
+ <string key="className">NSApplication</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
<string key="className">NSButton</string>
<string key="superclassName">NSControl</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -1515,6 +1568,13 @@
<reference key="sourceIdentifier" ref="295094819"/>
</object>
<object class="IBPartialClassDescription">
+ <string key="className">NSView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">BWToolkitFramework.framework/Headers/NSView+BWAdditions.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
@@ -1536,6 +1596,13 @@
<string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSWindow</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h</string>
+ </object>
+ </object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
diff --git a/Source/SPSSHTunnel.h b/Source/SPSSHTunnel.h
index 1a061619..836611f3 100644
--- a/Source/SPSSHTunnel.h
+++ b/Source/SPSSHTunnel.h
@@ -67,6 +67,10 @@ enum spsshtunnel_password_modes
NSInteger localPort;
NSInteger localPortFallback;
NSInteger connectionState;
+
+ BOOL isAnswerAvailable;
+ NSCondition *answerAvailableCondition;
+ NSString *currentKeyName;
}
- (id) initToHost:(NSString *) theHost port:(NSInteger) thePort login:(NSString *) theLogin tunnellingToPort:(NSInteger) targetPort onHost:(NSString *) targetHost;
@@ -88,6 +92,7 @@ enum spsshtunnel_password_modes
- (void) workerGetResponseForQuestion:(NSString *)theQuestion;
- (NSString *) getPasswordForQuery:(NSString *)theQuery verificationHash:(NSString *)theHash;
- (void) workerGetPasswordForQuery:(NSString *)theQuery;
-- (IBAction) closeSheet:(id)sender;
+- (IBAction) closeSSHQuestionSheet:(id)sender;
+- (IBAction) closeSSHPasswordSheet:(id)sender;
@end
diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m
index 4779e6a1..9b53adda 100644
--- a/Source/SPSSHTunnel.m
+++ b/Source/SPSSHTunnel.m
@@ -469,9 +469,24 @@
*/
- (BOOL) getResponseForQuestion:(NSString *)theQuestion
{
+ // prepare the condition
+ [answerAvailableCondition lock];
+ isAnswerAvailable = NO;
+
+ // request an answer on the main thread (UI stuff must be done on main thread)
[self performSelectorOnMainThread:@selector(workerGetResponseForQuestion:) withObject:theQuestion waitUntilDone:YES];
- return requestedResponse;
+ // wait until an answer is available
+ while (!isAnswerAvailable) [answerAvailableCondition wait];
+
+ // save the answer
+ BOOL response = requestedResponse;
+
+ //unlock condition
+ [answerAvailableCondition unlock];
+
+ //return the answer
+ return response;
}
- (void) workerGetResponseForQuestion:(NSString *)theQuestion
{
@@ -479,29 +494,28 @@
NSSize questionTextSize;
NSRect windowFrameRect;
- // Ask how to proceed, sizing the window appropriately to fit the question
+ // set up the question window
[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) + 70 + ([sshPasswordDialog isSheet]?0:22);
[sshQuestionDialog setFrame:windowFrameRect display:NO];
+
+ //show the question window
[NSApp beginSheet:sshQuestionDialog modalForWindow:parentWindow modalDelegate:self didEndSelector:nil contextInfo:nil];
- NSInteger sshQueryResponseCode = [NSApp runModalForWindow:sshQuestionDialog];
- [NSApp endSheet:sshQuestionDialog];
+}
+/*
+ * Ends an existing modal session
+ */
+- (IBAction) closeSSHQuestionSheet:(id)sender
+{
+ [answerAvailableCondition lock];
+ requestedResponse = [sender tag]==1 ? YES : NO;
+ [NSApp endSheet:sshQuestionDialog];
[sshQuestionDialog orderOut:nil];
-
- switch (sshQueryResponseCode) {
-
- // Yes
- case 1:
- requestedResponse = YES;
- return;
-
- // No
- default:
- requestedResponse = NO;
- return;
- }
+ isAnswerAvailable = YES;
+ [answerAvailableCondition signal];
+ [answerAvailableCondition unlock];
}
/*
@@ -512,30 +526,44 @@
{
if (![theHash isEqualToString:tunnelConnectionVerifyHash]) return nil;
- NSString *thePassword;
-
+ // prepare the condition
+ [answerAvailableCondition lock];
+ isAnswerAvailable = NO;
+
+ // request password on the main thread (UI stuff must be done on main thread)
[self performSelectorOnMainThread:@selector(workerGetPasswordForQuery:) withObject:theQuery waitUntilDone:YES];
- if (!requestedPassphrase) return nil;
- thePassword = [NSString stringWithString:requestedPassphrase];
- [requestedPassphrase release], requestedPassphrase = nil;
+ // wait until an answer is available
+ while (!isAnswerAvailable) [answerAvailableCondition wait];
+
+ // save the answer
+ NSString *thePassword = nil;
+ if (requestedPassphrase) {
+ thePassword = [NSString stringWithString:requestedPassphrase];
+ [requestedPassphrase release], requestedPassphrase = nil;
+ }
+
+ //unlock condition
+ [answerAvailableCondition unlock];
+
+ //return the answer
return thePassword;
}
- (void) workerGetPasswordForQuery:(NSString *)theQuery
{
NSSize queryTextSize;
NSRect windowFrameRect;
- NSString *thePassword;
- SPKeychain *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];
+ currentKeyName = [keyName retain];
} else {
[sshPasswordText setStringValue:theQuery];
- [sshPasswordKeychainCheckbox setHidden:YES];
+ [sshPasswordKeychainCheckbox setHidden:YES];
+ currentKeyName = nil;
}
// Request the password, sizing the window appropriately to fit the query
@@ -544,45 +572,44 @@
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];
- NSInteger sshQueryResponseCode = [NSApp runModalForWindow:sshPasswordDialog];
- [NSApp endSheet:sshPasswordDialog];
- [sshPasswordDialog orderOut:nil];
-
- switch (sshQueryResponseCode) {
-
- // OK
- case 1:
- thePassword = [NSString stringWithString:[sshPasswordField stringValue]];
- [sshPasswordField setStringValue:@""];
- if ([delegate respondsToSelector:@selector(setUndoManager:)] && [delegate undoManager]) {
- [[delegate undoManager] removeAllActionsWithTarget:sshPasswordField];
- } else if ([[parentWindow windowController] document] && [[[parentWindow windowController] document] undoManager]) {
- [[[[parentWindow windowController] document] undoManager] removeAllActionsWithTarget:sshPasswordField];
- }
- requestedPassphrase = [[NSString alloc] initWithString:thePassword];
-
- // Add to keychain if appropriate
- if (keyName && [sshPasswordKeychainCheckbox state] == NSOnState) {
- keychain = [[SPKeychain alloc] init];
- [keychain addPassword:thePassword forName:@"SSH" account:keyName withLabel:[NSString stringWithFormat:@"SSH: %@", keyName]];
- [keychain release];
- }
- return;
-
- // Cancel
- default:
- return;
- }
}
/*
* Ends an existing modal session
*/
-- (IBAction) closeSheet:(id)sender
+- (IBAction) closeSSHPasswordSheet:(id)sender
{
- [NSApp stopModalWithCode:[sender tag]];
+ [answerAvailableCondition lock];
+ requestedResponse = [sender tag]==1 ? YES : NO;
+ [NSApp endSheet:sshPasswordDialog];
+ [sshPasswordDialog orderOut:nil];
+
+ if (requestedResponse) {
+ NSString *thePassword = [NSString stringWithString:[sshPasswordField stringValue]];
+ [sshPasswordField setStringValue:@""];
+ if ([delegate respondsToSelector:@selector(setUndoManager:)] && [delegate undoManager]) {
+ [[delegate undoManager] removeAllActionsWithTarget:sshPasswordField];
+ } else if ([[parentWindow windowController] document] && [[[parentWindow windowController] document] undoManager]) {
+ [[[[parentWindow windowController] document] undoManager] removeAllActionsWithTarget:sshPasswordField];
+ }
+ requestedPassphrase = [[NSString alloc] initWithString:thePassword];
+
+ // Add to keychain if appropriate
+ if (currentKeyName && [sshPasswordKeychainCheckbox state] == NSOnState) {
+ SPKeychain *keychain = [[SPKeychain alloc] init];
+ [keychain addPassword:thePassword forName:@"SSH" account:currentKeyName withLabel:[NSString stringWithFormat:@"SSH: %@", currentKeyName]];
+ [keychain release];
+ [currentKeyName release];
+ currentKeyName = nil;
+ }
+ }
+
+ isAnswerAvailable = YES;
+ [answerAvailableCondition signal];
+ [answerAvailableCondition unlock];
}
+
- (void)dealloc
{
delegate = nil;