From 0311db3d073af618f625b81c9bb5e7e06104ae5e Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Sun, 19 Aug 2012 21:13:28 +0000 Subject: - Use a short hashed form of the connection path for SSH ControlPath settings, to aid length issues with the new sandbox-safe temporary folders being used - Clean up SSH argument code --- Source/SPDataAdditions.h | 2 ++ Source/SPDataAdditions.m | 17 +++++++++++++++++ Source/SPFileManagerAdditions.m | 4 +++- Source/SPSSHTunnel.m | 37 ++++++++++++++++++++++++++++++++----- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Source/SPDataAdditions.h b/Source/SPDataAdditions.h index 55a16551..d3fe5440 100644 --- a/Source/SPDataAdditions.h +++ b/Source/SPDataAdditions.h @@ -37,7 +37,9 @@ - (NSData *)compress; - (NSData *)decompress; +- (NSString *)dataToHexString; - (NSString *)dataToFormattedHexString; + - (NSString *)stringRepresentationUsingEncoding:(NSStringEncoding)encoding; - (NSString *)shortStringRepresentationUsingEncoding:(NSStringEncoding)encoding; diff --git a/Source/SPDataAdditions.m b/Source/SPDataAdditions.m index c12f0781..ab0bfb01 100644 --- a/Source/SPDataAdditions.m +++ b/Source/SPDataAdditions.m @@ -196,6 +196,23 @@ return [NSData dataWithData: zipData]; } +/** + * Returns the hex representation of the given data. + */ +- (NSString *)dataToHexString +{ + NSUInteger i; + const unsigned char *bytes = (const unsigned char *)[self bytes]; + NSUInteger dataLength = [self length]; + NSMutableString *hexString = [NSMutableString string]; + + for (i = 0; i < dataLength; i++) { + [hexString appendFormat:@"%02X", bytes[i]]; + } + + return hexString; +} + /** * Returns the hex representation of the given data. */ diff --git a/Source/SPFileManagerAdditions.m b/Source/SPFileManagerAdditions.m index 779ed8ba..2e63b120 100644 --- a/Source/SPFileManagerAdditions.m +++ b/Source/SPFileManagerAdditions.m @@ -159,8 +159,10 @@ static NSString *DirectoryLocationDomain = @"DirectoryLocationDomain"; if (!tempDir) { tempDir = @"/tmp"; + } else if ([tempDir characterAtIndex:([tempDir length] - 1)] == '/') { + tempDir = [tempDir substringToIndex:([tempDir length] - 1)]; } - + return tempDir; } diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m index f07448dc..66db2a9e 100644 --- a/Source/SPSSHTunnel.m +++ b/Source/SPSSHTunnel.m @@ -38,6 +38,7 @@ #import "SPAlertSheets.h" #import +#import @implementation SPSSHTunnel @@ -301,24 +302,49 @@ task = [[NSTask alloc] init]; [task setLaunchPath: @"/usr/bin/ssh"]; - // Set up the arguments for the task + // Prepare to set up the arguments for the task taskArguments = [[NSMutableArray alloc] init]; - [taskArguments addObject:@"-N"]; // Tunnel only - [taskArguments addObject:@"-v"]; // Verbose mode for messages - [taskArguments addObject:@"-o ControlMaster=auto"]; // Support 'master' mode for connection sharing - [taskArguments addObject:[NSString stringWithFormat:@"-o ControlPath=%@/SequelPro-%%r@%%h:%%p", [NSFileManager temporaryDirectory]]]; // Set a custom control path to avoid picking up existing masters without forwarding enabled + + // Enable verbose mode for message parsing + [taskArguments addObject:@"-v"]; + + // Ensure that the muxed connection can be used for only tunnels, not interactive + [taskArguments addObject:@"-N"]; + + // Enable automatic connection muxing/sharing, for faster connections + [taskArguments addObject:@"-o ControlMaster=auto"]; + + // Set a custom control path to isolate connection sharing to Sequel Pro, to prevent picking up + // existing masters without forwarding enabled and to isolate from interactive sessions. Use a short + // hashed path to aid length limit issues. + unsigned char hashedPathResult[16]; + NSString *pathString = [NSString stringWithFormat:@"%@@%@:%ld", sshLogin?sshLogin:@"", sshHost, sshPort?sshPort:0]; + CC_MD5([pathString UTF8String], (unsigned int)strlen([pathString UTF8String]), hashedPathResult); + [taskArguments addObject:[NSString stringWithFormat:@"-o ControlPath=%@/SPSSH-%@", [NSFileManager temporaryDirectory], [[[NSData dataWithBytes:hashedPathResult length:16] dataToHexString] substringToIndex:8]]]; + + // If the port forwarding fails, exit - as this is the primary use case for the instance [taskArguments addObject:@"-o ExitOnForwardFailure=yes"]; + + // Specify a connection timeout based on the preferences value [taskArguments addObject:[NSString stringWithFormat:@"-o ConnectTimeout=%ld", (long)connectionTimeout]]; + + // Allow three password prompts [taskArguments addObject:@"-o NumberOfPasswordPrompts=3"]; + + // Specify an identity file if available if (identityFilePath) { [taskArguments addObject:@"-i"]; [taskArguments addObject:identityFilePath]; } + + // If keepalive is set in the preferences, use the same value for the SSH tunnel if (useKeepAlive && keepAliveInterval) { [taskArguments addObject:@"-o TCPKeepAlive=no"]; [taskArguments addObject:[NSString stringWithFormat:@"-o ServerAliveInterval=%ld", (long)ceil(keepAliveInterval)]]; [taskArguments addObject:@"-o ServerAliveCountMax=1"]; } + + // Specify the port, host, and authentication details if (sshPort) { [taskArguments addObject:[NSString stringWithFormat:@"-p %ld", (long)sshPort]]; } @@ -333,6 +359,7 @@ } else { [taskArguments addObject:[NSString stringWithFormat:@"-L %ld/%@/%ld", (long)localPort, remoteHost, (long)remotePort]]; } + [task setArguments:taskArguments]; // Set up the environment for the task -- cgit v1.2.3