From 030eac5e17c69e375d7724e489483db72e791b9c Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 24 Feb 2018 22:48:56 +0100 Subject: #2979, #2437, #2247, #1836: Enable mysql cleartext auth without access to keychain and with a warning to the user --- Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h | 18 ++++++++++++++++++ Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m | 10 ++++++++-- .../Source/SPMySQLConnectionDelegate.h | 2 ++ 3 files changed, 28 insertions(+), 2 deletions(-) (limited to 'Frameworks') diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h index 343d0d36..0faa3e02 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h @@ -61,6 +61,7 @@ pthread_t reconnectingThread; uint64_t initialConnectTime; unsigned long mysqlConnectionThreadId; + BOOL allowCleartextPlugin; // Connection proxy NSObject *proxy; @@ -175,6 +176,23 @@ - (void)addClientFlags:(SPMySQLClientFlags)opts; - (void)removeClientFlags:(SPMySQLClientFlags)opts; +/** + * This tells the mysql client whether the cleartext auth plugin is permitted. + * + * If enabled, and requested by the server, the password will simply be transmitted + * in plaintext, instead of hashing it on the client first, thus this plugin is + * rather risky. It is mostly used when the server has to forward the password to another + * auth backend (which it can't do with the one-way hash). + * + * If it is not enabled, but requested by the server the connection will fail with + * error "plugin not enabled (2059)" + * + * WARNING: There are 2 ways to enable this plugin: Via this property or by setting + * the envvar LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN to 1. Sadly ANY ONE of those two is + * sufficient to enable the plugin. + */ +@property (readwrite, assign, nonatomic) BOOL allowCleartextPlugin; + #pragma mark - #pragma mark Connection and disconnection diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m index 828b2478..b143db19 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m @@ -82,6 +82,7 @@ static errno_t LegacyMemsetS(void *ptr, rsize_t ignored, int value, rsize_t coun @synthesize delegateQueryLogging; @synthesize lastQueryWasCancelled; @synthesize clientFlags = clientFlags; +@synthesize allowCleartextPlugin = allowCleartextPlugin; #pragma mark - #pragma mark Getters and Setters @@ -609,6 +610,9 @@ asm(".desc ___crashreporter_info__, 0x10"); NSStringEncoding connectEncodingNS = [SPMySQLConnection stringEncodingForMySQLCharset:[encodingName UTF8String]]; mysql_options(theConnection, MYSQL_SET_CHARSET_NAME, [encodingName UTF8String]); + my_bool cleartextAllowed = [self allowCleartextPlugin] ? TRUE : FALSE; + mysql_options(theConnection, MYSQL_ENABLE_CLEARTEXT_PLUGIN, &cleartextAllowed); + // Set up the connection variables in the format MySQL needs, from the class-wide variables const char *theHost = NULL; const char *theUsername = ""; @@ -746,9 +750,11 @@ asm(".desc ___crashreporter_info__, 0x10"); passwd = [delegate passwordForConnection:self authPlugin:plugin]; } - // shortcut for empty/nil password + // shortcut for nil/empty passwords if(![passwd length]) { - inBlock(NULL); + // nil means abort, "" is a valid password: + // only invoke the block when the password is @"", otherwise we'll skip it which will make mysql abort the connection + if(passwd) inBlock(""); return; } diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionDelegate.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionDelegate.h index 0963e168..f32be742 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionDelegate.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnectionDelegate.h @@ -68,6 +68,8 @@ * the secure store (Keychain), and the other connection details (user, host) * can be used to look it up and supplied on demand. * + * NOTE: This will be called on the thread SPMySQL is running on (which *MAY* be a background thread)! + * * @param connection The connection instance to supply the password for * @param pluginName The auth plugin libmysqlclients wants to use the password with */ -- cgit v1.2.3