]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: checks: mysql-check: Add support for v4.1+ authentication
authorNenad Merdanovic <nimzo@nimzo.info>
Fri, 30 May 2014 12:26:32 +0000 (14:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 11 Jun 2014 16:13:46 +0000 (18:13 +0200)
MySQL will in stop supporting pre-4.1 authentication packets in the future
and is already giving us a hard time regarding non-silencable warnings
which are logged on each health check. Warnings look like the following:

"[Warning] Client failed to provide its character set. 'latin1' will be used
as client character set."

This patch adds basic support for post-4.1 authentication by sending the proper
authentication packet with the character set, along with the QUIT command.

doc/configuration.txt
src/cfgparse.c

index d7ba2f852cca75653a6268eb23b4de97106d3780..d28c91a6e08693bd6036c5aa7c69931bfcc8160c 100644 (file)
@@ -4458,13 +4458,14 @@ no option logasap
              logging.
 
 
-option mysql-check [ user <username> ]
+option mysql-check [ user <username> [ post-41 ] ]
   Use MySQL health checks for server testing
   May be used in sections :   defaults | frontend | listen | backend
                                  yes   |    no    |   yes  |   yes
   Arguments :
     <username> This is the username which will be used when connecting to MySQL
                server.
+    post-41    Send post v4.1 client compatible checks
 
   If you specify a username, the check consists of sending two MySQL packet,
   one Client Authentication packet, and one QUIT packet, to correctly close
index 0a32df482c4d964685ab980df0ffed3f206f3134..35f1824b173e0d871fa7ca7a372ffb445c1cc6f1 100644 (file)
@@ -3869,7 +3869,7 @@ stats_error_parsing:
                        curproxy->options2 &= ~PR_O2_CHK_ANY;
                        curproxy->options2 |= PR_O2_MYSQL_CHK;
 
-                       /* This is an exemple of an MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
+                       /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
                         * const char mysql40_client_auth_pkt[] = {
                         *      "\x0e\x00\x00"  // packet length
                         *      "\x01"          // packet number
@@ -3883,6 +3883,23 @@ stats_error_parsing:
                         * };
                         */
 
+                       /* This is an example of a MySQL >=4.1  client Authentication packet provided by Nenad Merdanovic.
+                        * const char mysql41_client_auth_pkt[] = {
+                        *      "\x0e\x00\x00\"         // packet length
+                        *      "\x01"                  // packet number
+                        *      "\x00\x00\x00\x00"      // client capabilities
+                        *      "\x00\x00\x00\x01"      // max packet
+                        *      "\x21"                  // character set (UTF-8)
+                        *      char[23]                // All zeroes
+                        *      "haproxy\x00"           // username (null terminated string)
+                        *      "\x00"                  // filler (always 0x00)
+                        *      "\x01\x00\x00"          // packet length
+                        *      "\x00"                  // packet number
+                        *      "\x01"                  // COM_QUIT command
+                        * };
+                        */
+
+
                        if (*(args[2])) {
                                int cur_arg = 2;
 
@@ -3900,25 +3917,55 @@ stats_error_parsing:
                                                }
                                                mysqluser = args[cur_arg + 1];
                                                userlen   = strlen(mysqluser);
-                                               packetlen = userlen + 7;
-                                               reqlen    = packetlen + 9;
 
-                                               free(curproxy->check_req);
-                                               curproxy->check_req = (char *)calloc(1, reqlen);
-                                               curproxy->check_len = reqlen;
-
-                                               snprintf(curproxy->check_req, 4, "%c%c%c",
-                                                       ((unsigned char) packetlen & 0xff),
-                                                       ((unsigned char) (packetlen >> 8) & 0xff),
-                                                       ((unsigned char) (packetlen >> 16) & 0xff));
-
-                                               curproxy->check_req[3] = 1;
-                                               curproxy->check_req[5] = 128;
-                                               curproxy->check_req[8] = 1;
-                                               memcpy(&curproxy->check_req[9], mysqluser, userlen);
-                                               curproxy->check_req[9 + userlen + 1 + 1]     = 1;
-                                               curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
-                                               cur_arg += 2;
+                                               if (*(args[cur_arg+2])) {
+                                                       if (!strcmp(args[cur_arg+2], "post-41")) {
+                                                               packetlen = userlen + 7 + 27;
+                                                               reqlen    = packetlen + 9;
+
+                                                               free(curproxy->check_req);
+                                                               curproxy->check_req = (char *)calloc(1, reqlen);
+                                                               curproxy->check_len = reqlen;
+
+                                                               snprintf(curproxy->check_req, 4, "%c%c%c",
+                                                                       ((unsigned char) packetlen & 0xff),
+                                                                       ((unsigned char) (packetlen >> 8) & 0xff),
+                                                                       ((unsigned char) (packetlen >> 16) & 0xff));
+
+                                                               curproxy->check_req[3] = 1;
+                                                               curproxy->check_req[5] = 130;
+                                                               curproxy->check_req[11] = 1;
+                                                               curproxy->check_req[12] = 33;
+                                                               memcpy(&curproxy->check_req[36], mysqluser, userlen);
+                                                               curproxy->check_req[36 + userlen + 1 + 1]     = 1;
+                                                               curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
+                                                               cur_arg += 3;
+                                                       } else {
+                                                               Alert("parsing [%s:%d] : keyword '%s' only supports option 'post-41'.\n", file, linenum, args[cur_arg+2]);
+                                                               err_code |= ERR_ALERT | ERR_FATAL;
+                                                               goto out;
+                                                       }
+                                               } else {
+                                                       packetlen = userlen + 7;
+                                                       reqlen    = packetlen + 9;
+
+                                                       free(curproxy->check_req);
+                                                       curproxy->check_req = (char *)calloc(1, reqlen);
+                                                       curproxy->check_len = reqlen;
+
+                                                       snprintf(curproxy->check_req, 4, "%c%c%c",
+                                                               ((unsigned char) packetlen & 0xff),
+                                                               ((unsigned char) (packetlen >> 8) & 0xff),
+                                                               ((unsigned char) (packetlen >> 16) & 0xff));
+
+                                                       curproxy->check_req[3] = 1;
+                                                       curproxy->check_req[5] = 128;
+                                                       curproxy->check_req[8] = 1;
+                                                       memcpy(&curproxy->check_req[9], mysqluser, userlen);
+                                                       curproxy->check_req[9 + userlen + 1 + 1]     = 1;
+                                                       curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
+                                                       cur_arg += 2;
+                                               }
                                        } else {
                                                /* unknown suboption - catchall */
                                                Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",