diff options
Diffstat (limited to 'Frameworks/SPMySQLFramework/Source')
9 files changed, 63 insertions, 29 deletions
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Copying.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Copying.m index 022708b8..32efa375 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Copying.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Copying.m @@ -54,6 +54,7 @@ [copy setSocketPath:socketPath]; [copy setUseSSL:useSSL]; [copy setSslKeyFilePath:sslKeyFilePath]; + [copy setSslCipherList:sslCipherList]; [copy setSslCertificatePath:sslCertificatePath]; [copy setSslCACertificatePath:sslCACertificatePath]; [copy setTimeout:timeout]; diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m index 85b2db9b..be6d054b 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m @@ -111,7 +111,7 @@ // Trigger a reconnect depending on connection usage recently. If the connection has // actively been used in the last couple of minutes, trigger a full reconnection attempt. if (_elapsedSecondsSinceAbsoluteTime(lastConnectionUsedTime) < 60 * 2) { - reconnectionThread = [[[NSThread alloc] initWithTarget:self selector:@selector(_reconnectAllowingRetries:) object:[NSNumber numberWithBool:YES]] autorelease]; + reconnectionThread = [[[NSThread alloc] initWithTarget:self selector:@selector(_reconnectAllowingRetries:) object:@YES] autorelease]; [reconnectionThread setName:@"SPMySQL reconnection thread (full)"]; [reconnectionThread start]; diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h index 34b21043..1720fcf6 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h @@ -51,6 +51,7 @@ NSString *sslKeyFilePath; NSString *sslCertificatePath; NSString *sslCACertificatePath; + NSString *sslCipherList; // MySQL connection details and state struct st_mysql *mySQLConnection; @@ -143,6 +144,15 @@ @property (readwrite, retain) NSString *sslCertificatePath; @property (readwrite, retain) NSString *sslCACertificatePath; +/** + * List of supported ciphers for SSL/TLS connections. + * This is a colon-separated string of names as used by + * `openssl ciphers`. The order of entries specifies + * their preference (earlier = better). + * A value of nil (default) means SPMySQL will use its built-in cipher list. + */ +@property (readwrite, retain) NSString *sslCipherList; + @property (readwrite, assign) NSUInteger timeout; @property (readwrite, assign) BOOL useKeepAlive; @property (readwrite, assign) CGFloat keepAliveInterval; diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m index 79d5060a..9fa5a9c8 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m @@ -65,6 +65,7 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS @synthesize sslKeyFilePath; @synthesize sslCertificatePath; @synthesize sslCACertificatePath; +@synthesize sslCipherList; @synthesize timeout; @synthesize useKeepAlive; @synthesize keepAliveInterval; @@ -217,6 +218,8 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS [proxy setConnectionStateChangeSelector:NULL delegate:nil]; [proxy release]; } + + [self setSslCipherList:nil]; // Ensure the query lock is unlocked, thereafter setting to nil in case of pending calls if ([connectionLock condition] != SPMySQLConnectionIdle) { @@ -377,20 +380,20 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS { NSFileManager *fileManager = [NSFileManager defaultManager]; - NSArray *possibleSocketLocations = [NSArray arrayWithObjects: - @"/tmp/mysql.sock", // Default - @"/Applications/MAMP/tmp/mysql/mysql.sock", // MAMP default location - @"/Applications/xampp/xamppfiles/var/mysql/mysql.sock", // XAMPP default location - @"/var/mysql/mysql.sock", // Mac OS X Server default - @"/opt/local/var/run/mysqld/mysqld.sock", // Darwinports MySQL - @"/opt/local/var/run/mysql4/mysqld.sock", // Darwinports MySQL 4 - @"/opt/local/var/run/mysql5/mysqld.sock", // Darwinports MySQL 5 - @"/usr/local/zend/mysql/tmp/mysql.sock", // Zend Server CE (see Issue #1251) - @"/var/run/mysqld/mysqld.sock", // As used on Debian/Gentoo - @"/var/tmp/mysql.sock", // As used on FreeBSD - @"/var/lib/mysql/mysql.sock", // As used by Fedora - @"/opt/local/lib/mysql/mysql.sock", // Alternate fedora - nil]; + NSArray *possibleSocketLocations = @[ + @"/tmp/mysql.sock", // Default + @"/Applications/MAMP/tmp/mysql/mysql.sock", // MAMP default location + @"/Applications/xampp/xamppfiles/var/mysql/mysql.sock", // XAMPP default location + @"/var/mysql/mysql.sock", // Mac OS X Server default + @"/opt/local/var/run/mysqld/mysqld.sock", // Darwinports MySQL + @"/opt/local/var/run/mysql4/mysqld.sock", // Darwinports MySQL 4 + @"/opt/local/var/run/mysql5/mysqld.sock", // Darwinports MySQL 5 + @"/usr/local/zend/mysql/tmp/mysql.sock", // Zend Server CE (see Issue #1251) + @"/var/run/mysqld/mysqld.sock", // As used on Debian/Gentoo + @"/var/tmp/mysql.sock", // As used on FreeBSD + @"/var/lib/mysql/mysql.sock", // As used by Fedora + @"/opt/local/lib/mysql/mysql.sock" + ]; for (NSUInteger i = 0; i < [possibleSocketLocations count]; i++) { if ([fileManager fileExistsAtPath:[possibleSocketLocations objectAtIndex:i]]) @@ -546,6 +549,7 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS const char *theSSLKeyFilePath = NULL; const char *theSSLCertificatePath = NULL; const char *theCACertificatePath = NULL; + const char *theSSLCiphers = SPMySQLSSLPermissibleCiphers; if (sslKeyFilePath) { theSSLKeyFilePath = [[sslKeyFilePath stringByExpandingTildeInPath] UTF8String]; @@ -556,8 +560,11 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS if (sslCACertificatePath) { theCACertificatePath = [[sslCACertificatePath stringByExpandingTildeInPath] UTF8String]; } + if(sslCipherList) { + theSSLCiphers = [sslCipherList UTF8String]; + } - mysql_ssl_set(theConnection, theSSLKeyFilePath, theSSLCertificatePath, theCACertificatePath, NULL, SPMySQLSSLPermissibleCiphers); + mysql_ssl_set(theConnection, theSSLKeyFilePath, theSSLCertificatePath, theCACertificatePath, NULL, theSSLCiphers); } MYSQL *connectionStatus = mysql_real_connect(theConnection, theHost, theUsername, thePassword, NULL, (unsigned int)port, theSocket, SPMySQLConnectionOptions); diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionProxy.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionProxy.h index a6f84567..3622b312 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionProxy.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionProxy.h @@ -33,11 +33,12 @@ * Connection proxy state constants. */ typedef enum { - SPMySQLProxyIdle = 0, - SPMySQLProxyConnecting = 1, - SPMySQLProxyWaitingForAuth = 2, - SPMySQLProxyConnected = 3, - SPMySQLProxyForwardingFailed = 4 + SPMySQLProxyIdle = 0, + SPMySQLProxyConnecting = 1, + SPMySQLProxyWaitingForAuth = 2, + SPMySQLProxyConnected = 3, + SPMySQLProxyForwardingFailed = 4, + SPMySQLProxyLaunchFailed = 5 } SPMySQLConnectionProxyState; diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m index 357eb53f..639ff0b9 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Data Conversion.m @@ -247,9 +247,9 @@ static inline NSString * _convertStringData(const void *dataBytes, NSUInteger da { // Fast case - if not using a preview length, or if the data length is shorter, return the requested data. - if (previewLength == NSNotFound || dataLength <= previewLength) { - return [[[NSString alloc] initWithBytes:dataBytes length:dataLength encoding:aStringEncoding] autorelease]; - } + if (previewLength == NSNotFound || dataLength <= previewLength) { + return [NSString stringForDataBytes:dataBytes length:dataLength encoding:aStringEncoding]; + } NSUInteger i = 0, characterLength = 0, byteLength = previewLength; uint16_t continuationStart, continuationEnd; @@ -394,7 +394,7 @@ static inline NSString * _convertStringData(const void *dataBytes, NSUInteger da // If returning the full string, use a fast path if (byteLength >= dataLength) { - return [[[NSString alloc] initWithBytes:dataBytes length:dataLength encoding:aStringEncoding] autorelease]; + return [NSString stringForDataBytes:dataBytes length:dataLength encoding:aStringEncoding]; } // Get a string using the calculated details diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m index 447cf19b..86a6b2b5 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m @@ -630,8 +630,8 @@ static inline void SPMySQLStreamingResultStoreFreeRowData(SPMySQLStreamingResult { // Throw an exception if the range is out of bounds - if (rangeToRemove.location + rangeToRemove.length > numberOfRows) { - [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)(rangeToRemove.location + rangeToRemove.length), (unsigned long long)numberOfRows]; + if (NSMaxRange(rangeToRemove) > numberOfRows) { + [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)(NSMaxRange(rangeToRemove)), (unsigned long long)numberOfRows]; } // Lock the data mutex @@ -639,14 +639,14 @@ static inline void SPMySQLStreamingResultStoreFreeRowData(SPMySQLStreamingResult // Free rows in the range NSUInteger i; - for (i = rangeToRemove.location; i < rangeToRemove.location + rangeToRemove.length; i++) { + for (i = rangeToRemove.location; i < NSMaxRange(rangeToRemove); i++) { SPMySQLStreamingResultStoreFreeRowData(dataStorage[i]); } numberOfRows -= rangeToRemove.length; // Renumber all subsequent indices to fill the gap size_t pointerSize = sizeof(SPMySQLStreamingResultStoreRowData *); - memmove(dataStorage + rangeToRemove.location, dataStorage + rangeToRemove.location + rangeToRemove.length, (numberOfRows - rangeToRemove.location) * pointerSize); + memmove(dataStorage + rangeToRemove.location, dataStorage + NSMaxRange(rangeToRemove), (numberOfRows - rangeToRemove.location) * pointerSize); // Unlock the mutex pthread_mutex_unlock(&dataLock); diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.h b/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.h index bb29c02b..60832c53 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.h @@ -33,5 +33,6 @@ - (NSString *)mySQLBacktickQuotedString; - (NSString *)mySQLTickQuotedString; ++ (NSString *)stringForDataBytes:(const void *)dataBytes length:(NSUInteger)dataLength encoding:(NSStringEncoding)aStringEncoding; @end diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.m b/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.m index 39688ea8..f987c98b 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLStringAdditions.m @@ -52,4 +52,18 @@ return [NSString stringWithFormat: @"'%@'", [self stringByReplacingOccurrencesOfString:@"'" withString:@"''"]]; } +/** + * Returns the string for the bytes according to the encoding, decode in ASCII if failed + */ ++ (NSString *) stringForDataBytes:(const void *)dataBytes length:(NSUInteger)dataLength encoding:(NSStringEncoding)aStringEncoding +{ + NSString * string = [[[NSString alloc] initWithBytes:dataBytes length:dataLength encoding:aStringEncoding] autorelease]; + + if (string == nil) { + return [[[NSString alloc] initWithBytes:dataBytes length:dataLength encoding:NSASCIIStringEncoding] autorelease]; + } + + return string; +} + @end |