diff options
author | rowanbeentje <rowan@beent.je> | 2010-09-13 22:26:54 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2010-09-13 22:26:54 +0000 |
commit | 92e7b9a652b0d1806d732079574aea7270b8a2c0 (patch) | |
tree | 4a05b6ecbbe2573fc53b8ac4c7de448282aaaea0 /Frameworks/MCPKit/MCPFoundationKit | |
parent | 0661135713d5c9b3a4e3e39e184ac3eb35926ac4 (diff) | |
download | sequelpro-92e7b9a652b0d1806d732079574aea7270b8a2c0.tar.gz sequelpro-92e7b9a652b0d1806d732079574aea7270b8a2c0.tar.bz2 sequelpro-92e7b9a652b0d1806d732079574aea7270b8a2c0.zip |
- Implement support for MySQL over SSL for both TCP/IP and Socket connection modes.
- Upgrade the MySQL binaries to version 5.1.50 (was 5.1.46)
- Enable SSL support in the MySQL libraries (this leads to a large increase in library size, unfortunately)
- Enable more optimisations in the MySQL libraries (especially --enable-assembler for faster in-library string processing and --with-mysqld-ldflags=-all-static)
This completes support for Issue #27.
Diffstat (limited to 'Frameworks/MCPKit/MCPFoundationKit')
-rw-r--r-- | Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h | 7 | ||||
-rw-r--r-- | Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m | 92 |
2 files changed, 94 insertions, 5 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h index 7e60ccb2..864eb413 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h @@ -139,6 +139,11 @@ NSInteger maxAllowedPacketSize; unsigned long connectionThreadId; + BOOL useSSL; + NSString *sslKeyFilePath; + NSString *sslCertificatePath; + NSString *sslCACertificatePath; + NSString *encoding, *previousEncoding; NSStringEncoding *stringEncoding; BOOL encodingUsesLatin1Transport, previousEncodingUsesLatin1Transport; @@ -207,6 +212,7 @@ // Connection details - (BOOL)setPort:(NSInteger)thePort; - (BOOL)setPassword:(NSString *)thePassword; +- (BOOL) setSSL:(BOOL)shouldUseSSL usingKeyFilePath:(NSString *)keyFilePath certificatePath:(NSString *)certificatePath certificateAuthorityCertificatePath:(NSString *)caCertificatePath; // Proxy - (BOOL)setConnectionProxy:(id <MCPConnectionProxy>)proxy; @@ -217,6 +223,7 @@ - (void)disconnect; - (BOOL)reconnect; - (BOOL)isConnected; +- (BOOL)isConnectedViaSSL; - (BOOL)userTriggeredDisconnect; - (BOOL)checkConnection; - (BOOL)pingConnection; diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index d8905d8d..362c3dc6 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -48,6 +48,7 @@ BOOL keepAliveActive; const NSUInteger kMCPConnectionDefaultOption = CLIENT_COMPRESS | CLIENT_REMEMBER_OPTIONS | CLIENT_MULTI_RESULTS; const char *kMCPConnectionDefaultSocket = MYSQL_UNIX_ADDR; +const char *kMCPSSLCipherList = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RSA-AES128-SHA:AES128-SHA:AES256-RMD:AES128-RMD:DES-CBC3-RMD:DHE-RSA-AES256-RMD:DHE-RSA-AES128-RMD:DHE-RSA-DES-CBC3-RMD:RC4-SHA:RC4-MD5:DES-CBC3-SHA:DES-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC-SHA"; const NSUInteger kMCPConnection_Not_Inited = 1000; const NSUInteger kLengthOfTruncationForLog = 100; @@ -111,6 +112,10 @@ static BOOL sTruncateLongFieldInLogs = YES; connectionLogin = nil; connectionSocket = nil; connectionPassword = nil; + useSSL = NO; + sslKeyFilePath = nil; + sslCertificatePath = nil; + sslCACertificatePath = nil; keepAliveThread = NULL; lastKeepAliveTime = 0; pingThread = NULL; @@ -298,6 +303,29 @@ static BOOL sTruncateLongFieldInLogs = YES; return YES; } +/** + * Set the connection to establish secure connections using SSL; must be + * called before connect:. + * This will always attempt to activate SSL if set, but depending on server + * setup connection may sometimes proceed without SSL enabled even if requested; + * it is suggested that after connection, -[MCPConnection isConnectedViaSSL] + * is checked to determine whether SSL is actually active. + */ +- (void) setSSL:(BOOL)shouldUseSSL usingKeyFilePath:(NSString *)keyFilePath certificatePath:(NSString *)certificatePath certificateAuthorityCertificatePath:(NSString *)caCertificatePath +{ + useSSL = shouldUseSSL; + + // Reset the old SSL details + if (sslKeyFilePath) [sslKeyFilePath release], sslKeyFilePath = nil; + if (sslCertificatePath) [sslCertificatePath release], sslCertificatePath = nil; + if (sslCACertificatePath) [sslCACertificatePath release], sslCACertificatePath = nil; + + // Set new details if provided + if (keyFilePath) sslKeyFilePath = [[NSString alloc] initWithString:[keyFilePath stringByExpandingTildeInPath]]; + if (certificatePath) sslCertificatePath = [[NSString alloc] initWithString:[certificatePath stringByExpandingTildeInPath]]; + if (caCertificatePath) sslCACertificatePath = [[NSString alloc] initWithString:[caCertificatePath stringByExpandingTildeInPath]]; +} + #pragma mark - #pragma mark Connection proxy @@ -385,7 +413,18 @@ static BOOL sTruncateLongFieldInLogs = YES; } else { theSocket = [self cStringFromString:connectionSocket]; } - + + // Apply SSL if appropriate + if (useSSL) { + NSLog(@"sdfsdfsfds SET"); + mysql_ssl_set(mConnection, + sslKeyFilePath ? [sslKeyFilePath UTF8String] : NULL, + sslCertificatePath ? [sslCertificatePath UTF8String] : NULL, + sslCACertificatePath ? [sslCACertificatePath UTF8String] : NULL, + NULL, + kMCPSSLCipherList); + } + // Select the password from the provided method if (!connectionPassword) { if (delegate && [delegate respondsToSelector:@selector(keychainPasswordForConnection:)]) { @@ -406,7 +445,7 @@ static BOOL sTruncateLongFieldInLogs = YES; return mConnected = NO; } - + mConnected = YES; userTriggeredDisconnect = NO; connectionStartTime = mach_absolute_time(); @@ -627,6 +666,15 @@ static BOOL sTruncateLongFieldInLogs = YES; } /** + * Returns YES if the MCPConnection is connected to a server via SSL, NO otherwise. + */ +- (BOOL)isConnectedViaSSL +{ + if (![self isConnected]) return NO; + return (mysql_get_ssl_cipher(mConnection))?YES:NO; +} + +/** * Returns YES if the user chose to disconnect at the last "connection failure" * prompt, NO otherwise. */ @@ -1255,6 +1303,16 @@ void performThreadedKeepAlive(void *ptr) if (theSocket == NULL) { theSocket = kMCPConnectionDefaultSocket; } + + // Apply SSL if appropriate + if (useSSL) { + mysql_ssl_set(mConnection, + sslKeyFilePath ? [sslKeyFilePath UTF8String] : NULL, + sslCertificatePath ? [sslCertificatePath UTF8String] : NULL, + sslCACertificatePath ? [sslCACertificatePath UTF8String] : NULL, + NULL, + kMCPSSLCipherList); + } theRet = mysql_real_connect(mConnection, theHost, theLogin, thePass, NULL, port, theSocket, mConnectionFlags); if (theRet != mConnection) { @@ -1833,6 +1891,14 @@ void performThreadedKeepAlive(void *ptr) } else { thePass = [self cStringFromString:connectionPassword]; } + if (useSSL) { + mysql_ssl_set(mConnection, + sslKeyFilePath ? [sslKeyFilePath UTF8String] : NULL, + sslCertificatePath ? [sslCertificatePath UTF8String] : NULL, + sslCACertificatePath ? [sslCACertificatePath UTF8String] : NULL, + NULL, + kMCPSSLCipherList); + } // Connect connectionSetupStatus = mysql_real_connect(killerConnection, theHost, theLogin, thePass, NULL, connectionPort, theSocket, mConnectionFlags); @@ -1850,13 +1916,18 @@ void performThreadedKeepAlive(void *ptr) NSData *encodedKillQueryData = NSStringDataUsingLossyEncoding(killQueryString, killerConnectionEncoding, 1); const char *killQueryCString = [encodedKillQueryData bytes]; unsigned long killQueryCStringLength = [encodedKillQueryData length]; - if (mysql_real_query(killerConnection, killQueryCString, killQueryCStringLength) == 0) { - mysql_close(killerConnection); + int killerReturnError = mysql_real_query(killerConnection, killQueryCString, killQueryCStringLength); + mysql_close(killerConnection); + if (killerReturnError == 0) { queryCancelUsedReconnect = NO; return; } - mysql_close(killerConnection); + NSLog(@"Task cancellation: kill query failed (Returned status %d)", killerReturnError); + } else { + NSLog(@"Task cancellation connection failed (error %u)", mysql_errno(killerConnection)); } + } else { + NSLog(@"Task cancelletion MySQL init failed."); } // Reset the connection @@ -2333,6 +2404,14 @@ void performThreadedKeepAlive(void *ptr) } else { theSocket = [self cStringFromString:connectionSocket]; } + if (useSSL) { + mysql_ssl_set(mConnection, + sslKeyFilePath ? [sslKeyFilePath UTF8String] : NULL, + sslCertificatePath ? [sslCertificatePath UTF8String] : NULL, + sslCACertificatePath ? [sslCACertificatePath UTF8String] : NULL, + NULL, + kMCPSSLCipherList); + } if (!connectionPassword) { if (delegate && [delegate respondsToSelector:@selector(keychainPasswordForConnection:)]) { thePass = [self cStringFromString:[delegate keychainPasswordForConnection:self]]; @@ -3135,6 +3214,9 @@ void performThreadedKeepAlive(void *ptr) if (connectionLogin) [connectionLogin release]; if (connectionSocket) [connectionSocket release]; if (connectionPassword) [connectionPassword release]; + if (sslKeyFilePath) [sslKeyFilePath release]; + if (sslCertificatePath) [sslCertificatePath release]; + if (sslCACertificatePath) [sslCACertificatePath release]; if (serverVersionString) [serverVersionString release], serverVersionString = nil; if (structure) [structure release], structure = nil; if (allKeysofDbStructure) [allKeysofDbStructure release], allKeysofDbStructure = nil; |