]> granicus.if.org Git - php/commitdiff
Update on the mysqlnd auth plugins, changed the plugin
authorAndrey Hristov <andrey@php.net>
Fri, 14 Jan 2011 20:04:17 +0000 (20:04 +0000)
committerAndrey Hristov <andrey@php.net>
Fri, 14 Jan 2011 20:04:17 +0000 (20:04 +0000)
structure and where they load themselves.
0xFE packets (method switch) needs to be done, additional
wire-level packet to be created to be parsed and the packet
doesn't fit the PACKET_OK structure anymore.

ext/mysqlnd/mysqlnd.c
ext/mysqlnd/mysqlnd_auth.c
ext/mysqlnd/mysqlnd_priv.h
ext/mysqlnd/mysqlnd_structs.h
ext/mysqlnd/mysqlnd_wireprotocol.c
ext/mysqlnd/mysqlnd_wireprotocol.h

index abf33e178833daee795e557e9c6eac11f4133c94..96ff3fbaf6efa97210993ab1b12bd6709e9824dd 100644 (file)
@@ -177,10 +177,10 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND * conn TSRMLS_DC)
                mnd_pefree(conn->host_info, pers);
                conn->host_info = NULL;
        }
-       if (conn->scramble) {
-               DBG_INF("Freeing scramble");
-               mnd_pefree(conn->scramble, pers);
-               conn->scramble = NULL;
+       if (conn->auth_plugin_data) {
+               DBG_INF("Freeing auth_plugin_data");
+               mnd_pefree(conn->auth_plugin_data, pers);
+               conn->auth_plugin_data = NULL;
        }
        if (conn->last_message) {
                mnd_pefree(conn->last_message, pers);
@@ -524,15 +524,15 @@ mysqlnd_connect_run_authentication(
                        auth_plugin = mysqlnd_plugin_find(plugin_name);
                        efree(plugin_name);
                        if (!auth_plugin) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server requested authentication method uknown to the client [%s]", requested_protocol);
-                               SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Server requested authentication method uknown to the client");
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method uknown to the client [%s]", requested_protocol);
+                               SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method uknown to the client");
                                break;
                        }
 
                        DBG_INF("plugin found");
 
-                       ret = auth_plugin->methods.auth_handshake(conn, user, passwd, db, db_len, passwd_len, greet_packet, options, mysql_flags,
-                                                                                                         &switch_to_auth_protocol TSRMLS_CC);
+                       ret = mysqlnd_auth_handshake(conn, user, passwd, db, db_len, passwd_len, greet_packet, options, mysql_flags,
+                                                                                auth_plugin, &switch_to_auth_protocol TSRMLS_CC);
                        DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
                } while (ret == FAIL && switch_to_auth_protocol != NULL);
 
@@ -1942,6 +1942,7 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
                db = "";
        }
 
+
        {
                char * switch_to_auth_protocol = NULL;
                const char * requested_protocol = NULL;
@@ -1961,13 +1962,15 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
                        efree(plugin_name);
                        if (!auth_plugin) {
                                if (!silent) {
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server requested authentication method uknown to the client [%s]", requested_protocol);
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method uknown to the client [%s]", requested_protocol);
                                }
-                               SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Server requested authentication method uknown to the client");
+                               SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method uknown to the client");
                                break;
                        }       
                        DBG_INF("plugin found");
-                       ret = auth_plugin->methods.auth_change_user(conn, user, strlen(user), passwd, db, strlen(db), passwd_len, silent, &switch_to_auth_protocol TSRMLS_CC);
+                       ret = mysqlnd_auth_change_user(conn, user, strlen(user), passwd, db, strlen(db), passwd_len, silent,
+                                                                                  auth_plugin, &switch_to_auth_protocol TSRMLS_CC);
+
                        DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
                } while (ret == FAIL && switch_to_auth_protocol != NULL);
                if (ret == PASS) {
index ccf935355e599ef7c67ba360b479a3aab3343aee..9183a88b69b93df4c7195577761e1f741e88c2cf 100644 (file)
@@ -30,8 +30,8 @@
 
 
 /* {{{ mysqlnd_native_auth_handshake */
-static enum_func_status
-mysqlnd_native_auth_handshake(MYSQLND * conn,
+enum_func_status
+mysqlnd_auth_handshake(MYSQLND * conn,
                                                          const char * const user,
                                                          const char * const passwd,
                                                          const char * const db,
@@ -40,6 +40,7 @@ mysqlnd_native_auth_handshake(MYSQLND * conn,
                                                          const MYSQLND_PACKET_GREET * const greet_packet,
                                                          const MYSQLND_OPTIONS * const options,
                                                          unsigned long mysql_flags,
+                                                         struct st_mysqlnd_authentication_plugin * auth_plugin,
                                                          char ** switch_to_auth_protocol
                                                          TSRMLS_DC)
 {
@@ -50,14 +51,6 @@ mysqlnd_native_auth_handshake(MYSQLND * conn,
 
        DBG_ENTER("mysqlnd_native_auth_handshake");
 
-       /* 5.5.x reports 21 as scramble length because it needs to show the length of the data before the plugin name */
-       if (greet_packet->scramble_buf_len != SCRAMBLE_LENGTH && (greet_packet->scramble_buf_len != 21)) {
-               /* mysql_native_password only works with SCRAMBLE_LENGTH scramble */
-               SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "The server sent wrong length for scramble");
-               DBG_ERR_FMT("The server sent wrong length for scramble %u. Expected %u", greet_packet->scramble_buf_len, SCRAMBLE_LENGTH);
-               goto end;
-       }
-
        ok_packet = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
        auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC);
 
@@ -80,17 +73,21 @@ mysqlnd_native_auth_handshake(MYSQLND * conn,
 
        auth_packet->send_auth_data = TRUE;
        auth_packet->user               = user;
-       auth_packet->password   = passwd;
        auth_packet->db                 = db;
        auth_packet->db_len             = db_len;
 
-       auth_packet->server_scramble_buf_len = greet_packet->scramble_buf_len;
-       conn->scramble = auth_packet->server_scramble_buf = mnd_pemalloc(auth_packet->server_scramble_buf_len, conn->persistent);
-       if (!conn->scramble) {
+       conn->auth_plugin_data_len = greet_packet->auth_plugin_data_len;
+       conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
+       if (!conn->auth_plugin_data) {
                SET_OOM_ERROR(conn->error_info);
                goto end;
        }
-       memcpy(auth_packet->server_scramble_buf, greet_packet->scramble_buf, greet_packet->scramble_buf_len);
+       memcpy(conn->auth_plugin_data, greet_packet->auth_plugin_data, greet_packet->auth_plugin_data_len);
+
+       auth_packet->auth_data =
+               auth_plugin->methods.get_auth_data(NULL, &auth_packet->auth_data_len, conn, user, passwd, passwd_len,
+                                                                                  conn->auth_plugin_data, conn->auth_plugin_data_len, options, mysql_flags TSRMLS_CC);
+                                                       
 
        if (!PACKET_WRITE(auth_packet, conn)) {
                CONN_SET_STATE(conn, CONN_QUIT_SENT);
@@ -118,6 +115,7 @@ mysqlnd_native_auth_handshake(MYSQLND * conn,
        conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no);
        ret = PASS;
 end:
+       mnd_efree(auth_packet->auth_data);
        PACKET_FREE(auth_packet);
        PACKET_FREE(ok_packet);
        DBG_RETURN(ret);
@@ -126,8 +124,8 @@ end:
 
 
 /* {{{ mysqlnd_native_auth_change_user */
-static enum_func_status
-mysqlnd_native_auth_change_user(MYSQLND * const conn,
+enum_func_status
+mysqlnd_auth_change_user(MYSQLND * const conn,
                                                                const char * const user,
                                                                const size_t user_len,
                                                                const char * const passwd,
@@ -135,6 +133,7 @@ mysqlnd_native_auth_change_user(MYSQLND * const conn,
                                                                const size_t db_len,
                                                                const size_t passwd_len,
                                                                const zend_bool silent,
+                                                               struct st_mysqlnd_authentication_plugin * auth_plugin,
                                                                char ** switch_to_auth_protocol
                                                                TSRMLS_DC)
 {
@@ -156,13 +155,17 @@ mysqlnd_native_auth_change_user(MYSQLND * const conn,
                SET_OOM_ERROR(conn->error_info);
                goto end;
        }
+
        auth_packet->is_change_user_packet = TRUE;
        auth_packet->user               = user;
-       auth_packet->password   = passwd;
        auth_packet->db                 = db;
        auth_packet->db_len             = db_len;
-       auth_packet->server_scramble_buf = conn->scramble;
        auth_packet->silent             = silent;
+
+       auth_packet->auth_data =
+               auth_plugin->methods.get_auth_data(NULL, &auth_packet->auth_data_len, conn, user, passwd, passwd_len,
+                                                                                  conn->auth_plugin_data, conn->auth_plugin_data_len, NULL /* options */, 0 /* mysql_flags */ TSRMLS_CC);
+
        if (mysqlnd_get_server_version(conn) >= 50123) {
                auth_packet->charset_no = conn->charset->nr;
                p+=2;
@@ -225,12 +228,47 @@ mysqlnd_native_auth_change_user(MYSQLND * const conn,
                SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
        }
 end:
+       mnd_efree(auth_packet->auth_data);
        PACKET_FREE(auth_packet);
        PACKET_FREE(chg_user_resp);
        DBG_RETURN(ret);
 }
 /* }}} */
 
+
+/* {{{ mysqlnd_native_auth_get_auth_data */
+static zend_uchar *
+mysqlnd_native_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self,
+                                                                 size_t * auth_data_len,
+                                                                 MYSQLND * conn, const char * const user, const char * const passwd,
+                                                                 const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
+                                                                 const MYSQLND_OPTIONS * const options, unsigned long mysql_flags
+                                                                 TSRMLS_DC)
+{
+       zend_uchar * ret = NULL;
+       DBG_ENTER("mysqlnd_native_auth_get_auth_data");
+       *auth_data_len = 0;
+
+       /* 5.5.x reports 21 as scramble length because it needs to show the length of the data before the plugin name */
+       if (auth_plugin_data_len != SCRAMBLE_LENGTH && (auth_plugin_data_len != 21)) {
+               /* mysql_native_password only works with SCRAMBLE_LENGTH scramble */
+               SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "The server sent wrong length for scramble");
+               DBG_ERR_FMT("The server sent wrong length for scramble %u. Expected %u", auth_plugin_data_len, SCRAMBLE_LENGTH);
+               DBG_RETURN(NULL);
+       }
+
+       /* copy scrambled pass*/
+       if (passwd && passwd_len) {
+               ret = mnd_emalloc(SCRAMBLE_LENGTH);
+               *auth_data_len = SCRAMBLE_LENGTH;
+               /* In 4.1 we use CLIENT_SECURE_CONNECTION and thus the len of the buf should be passed */
+               php_mysqlnd_scramble((zend_uchar*)ret, auth_plugin_data, (zend_uchar*)passwd, passwd_len);
+       }
+       DBG_RETURN(ret);
+}
+/* }}} */
+
+
 static struct st_mysqlnd_authentication_plugin mysqlnd_native_auth_plugin =
 {
        {
@@ -249,11 +287,11 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_native_auth_plugin =
                }
        },
        {/* methods */
-               mysqlnd_native_auth_handshake,
-               mysqlnd_native_auth_change_user
+               mysqlnd_native_auth_get_auth_data
        }
 };
 
+
 /* {{{ mysqlnd_native_authentication_plugin_register */
 void
 mysqlnd_native_authentication_plugin_register(TSRMLS_D)
index f35862087da46f22cef85346897a18b801a7c647..31c382f9a18871f799e5c83632400d3c3ab1ecff 100644 (file)
@@ -196,6 +196,36 @@ void mysqlnd_native_authentication_plugin_register(TSRMLS_D);
 
 void mysqlnd_example_plugin_register(TSRMLS_D);
 
+struct st_mysqlnd_packet_greet;
+struct st_mysqlnd_authentication_plugin;
+
+enum_func_status
+mysqlnd_auth_handshake(MYSQLND * conn,
+                                               const char * const user,
+                                               const char * const passwd,
+                                               const char * const db,
+                                               const size_t db_len,
+                                               const size_t passwd_len,
+                                               const struct st_mysqlnd_packet_greet * const greet_packet,
+                                               const MYSQLND_OPTIONS * const options,
+                                               unsigned long mysql_flags,
+                                               struct st_mysqlnd_authentication_plugin * auth_plugin,
+                                               char ** switch_to_auth_protocol
+                                               TSRMLS_DC);
+
+enum_func_status
+mysqlnd_auth_change_user(MYSQLND * const conn,
+                                                               const char * const user,
+                                                               const size_t user_len,
+                                                               const char * const passwd,
+                                                               const char * const db,
+                                                               const size_t db_len,
+                                                               const size_t passwd_len,
+                                                               const zend_bool silent,
+                                                               struct st_mysqlnd_authentication_plugin * auth_plugin,
+                                                               char ** switch_to_auth_protocol
+                                                               TSRMLS_DC);
+
 #endif /* MYSQLND_PRIV_H */
 
 
index 59c7fdc8548d27a45a238adde4ffd510094f06fe..a081468ef6bd16f5eb8414ba78a85822fe6c1390 100644 (file)
@@ -736,7 +736,8 @@ struct st_mysqlnd_connection
        uint64_t                thread_id;
        char                    *server_version;
        char                    *host_info;
-       unsigned char   *scramble;
+       zend_uchar              *auth_plugin_data;
+       size_t                  auth_plugin_data_len;
        const MYSQLND_CHARSET *charset;
        const MYSQLND_CHARSET *greet_charset;
        char                    *connect_or_select_db;
@@ -964,21 +965,22 @@ struct st_mysqlnd_typeii_plugin_example
        unsigned int counter;
 };
 
-struct st_mysqlnd_packet_greet;
+struct st_mysqlnd_authentication_plugin;
+
+typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authentication_plugin * self,
+                                                                                                               size_t * auth_data_len,
+                                                                                                               MYSQLND * conn, const char * const user, const char * const passwd,
+                                                                                                               const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
+                                                                                                               const MYSQLND_OPTIONS * const options, unsigned long mysql_flags
+                                                                                                               TSRMLS_DC);
 
 struct st_mysqlnd_authentication_plugin
 {
        struct st_mysqlnd_plugin_header plugin_header;
        struct {
-               enum_func_status (*auth_handshake)(MYSQLND * conn, const char * const user, const char * const passwd, const char * const db,
-                                                                                  const size_t db_len, const size_t passwd_len, const struct st_mysqlnd_packet_greet * const greet_packet,
-                                                                                  const MYSQLND_OPTIONS * const options, unsigned long mysql_flags,
-                                                                                  char ** switch_to_auth_protocol TSRMLS_DC);
-
-               enum_func_status (*auth_change_user)(MYSQLND * const conn, const char * const user, const size_t user_len, const char * const passwd,
-                                                                                        const char * const db, const size_t db_len, const size_t passwd_len, const zend_bool silent,
-                                                                                        char ** switch_to_auth_protocol TSRMLS_DC);
+               func_auth_plugin__get_auth_data get_auth_data;
        } methods;
 };
 
+
 #endif /* MYSQLND_STRUCTS_H */
index 2ee894f639cb9adbbd3292635743db8cd8231689..e7205066f3cf63c395cfb2a02a30cdd526bbcf1f 100644 (file)
@@ -314,8 +314,8 @@ php_mysqlnd_greet_read(void *_packet, MYSQLND *conn TSRMLS_DC)
        PACKET_READ_HEADER_AND_BODY(packet, conn, buf, sizeof(buf), "greeting", PROT_GREET_PACKET);
        BAIL_IF_NO_MORE_DATA;
 
-       packet->scramble_buf = &packet->intern_scramble_buf;
-       packet->scramble_buf_len = sizeof(packet->intern_scramble_buf);
+       packet->auth_plugin_data = packet->intern_auth_plugin_data;
+       packet->auth_plugin_data_len = sizeof(packet->intern_auth_plugin_data);
 
        if (packet->header.size < sizeof(buf)) {
                /*
@@ -353,7 +353,7 @@ php_mysqlnd_greet_read(void *_packet, MYSQLND *conn TSRMLS_DC)
        p+=4;
        BAIL_IF_NO_MORE_DATA;
 
-       memcpy(packet->scramble_buf, p, SCRAMBLE_LENGTH_323);
+       memcpy(packet->auth_plugin_data, p, SCRAMBLE_LENGTH_323);
        p+= SCRAMBLE_LENGTH_323;
        BAIL_IF_NO_MORE_DATA;
 
@@ -379,8 +379,8 @@ php_mysqlnd_greet_read(void *_packet, MYSQLND *conn TSRMLS_DC)
        BAIL_IF_NO_MORE_DATA;
 
        if ((size_t) (p - buf) < packet->header.size) {
-               /* scramble_buf is split into two parts */
-               memcpy(packet->scramble_buf + SCRAMBLE_LENGTH_323, p, SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323);
+               /* auth_plugin_data is split into two parts */
+               memcpy(packet->auth_plugin_data + SCRAMBLE_LENGTH_323, p, SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323);
                p+= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323;
                p++; /* 0x0 at the end of the scramble and thus last byte in the packet in 5.1 and previous */
        } else {
@@ -395,19 +395,19 @@ php_mysqlnd_greet_read(void *_packet, MYSQLND *conn TSRMLS_DC)
        /* Additional 16 bits for server capabilities */
                packet->server_capabilities |= uint2korr(pad_start) << 16;
                /* And a length of the server scramble in one byte */
-               packet->scramble_buf_len = uint1korr(pad_start + 2);
-               if (packet->scramble_buf_len > SCRAMBLE_LENGTH) {
+               packet->auth_plugin_data_len = uint1korr(pad_start + 2);
+               if (packet->auth_plugin_data_len > SCRAMBLE_LENGTH) {
                        /* more data*/
-                       char * new_scramble_buf = emalloc(packet->scramble_buf_len);
-                       if (!new_scramble_buf) {
+                       zend_uchar * new_auth_plugin_data = emalloc(packet->auth_plugin_data_len);
+                       if (!new_auth_plugin_data) {
                                goto premature_end;
                        }
                        /* copy what we already have */
-                       memcpy(new_scramble_buf, packet->scramble_buf, SCRAMBLE_LENGTH);
+                       memcpy(new_auth_plugin_data, packet->auth_plugin_data, SCRAMBLE_LENGTH);
                        /* add additional scramble data 5.5+ sent us */
-                       memcpy(new_scramble_buf + SCRAMBLE_LENGTH, p, packet->scramble_buf_len - SCRAMBLE_LENGTH);
-                       p+= (packet->scramble_buf_len - SCRAMBLE_LENGTH);
-                       packet->scramble_buf = new_scramble_buf;
+                       memcpy(new_auth_plugin_data + SCRAMBLE_LENGTH, p, packet->auth_plugin_data_len - SCRAMBLE_LENGTH);
+                       p+= (packet->auth_plugin_data_len - SCRAMBLE_LENGTH);
+                       packet->auth_plugin_data = new_auth_plugin_data;
                }
        }
 
@@ -423,7 +423,7 @@ php_mysqlnd_greet_read(void *_packet, MYSQLND *conn TSRMLS_DC)
 
        DBG_INF_FMT("server_capabilities=%u charset_no=%u server_status=%i auth_protocol=%s scramble_length=%u",
                                packet->server_capabilities, packet->charset_no, packet->server_status,
-                               packet->auth_protocol? packet->auth_protocol:"n/a", packet->scramble_buf_len);
+                               packet->auth_protocol? packet->auth_protocol:"n/a", packet->auth_plugin_data_len);
 
        DBG_RETURN(PASS);
 premature_end:
@@ -444,9 +444,9 @@ void php_mysqlnd_greet_free_mem(void *_packet, zend_bool stack_allocation TSRMLS
                efree(p->server_version);
                p->server_version = NULL;
        }
-       if (p->scramble_buf && p->scramble_buf != &p->intern_scramble_buf) {
-               efree(p->scramble_buf);
-               p->scramble_buf = NULL;
+       if (p->auth_plugin_data && p->auth_plugin_data != p->intern_auth_plugin_data) {
+               efree(p->auth_plugin_data);
+               p->auth_plugin_data = NULL;
        }
        if (p->auth_protocol) {
                efree(p->auth_protocol);
@@ -472,7 +472,7 @@ php_mysqlnd_crypt(zend_uchar *buffer, const zend_uchar *s1, const zend_uchar *s2
 
 
 /* {{{ php_mysqlnd_scramble */
-void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const password)
+void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const password, size_t password_len)
 {
        PHP_SHA1_CTX context;
        zend_uchar sha1[SHA1_MAX_LENGTH];
@@ -480,7 +480,7 @@ void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const sc
 
        /* Phase 1: hash password */
        PHP_SHA1Init(&context);
-       PHP_SHA1Update(&context, password, strlen((char *)password));
+       PHP_SHA1Update(&context, password, password_len);
        PHP_SHA1Final(sha1, &context);
 
        /* Phase 2: hash sha1 */
@@ -500,7 +500,7 @@ void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const sc
 /* }}} */
 
 
-#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 128)
+#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 1024)
 
 /* {{{ php_mysqlnd_auth_write */
 static
@@ -533,17 +533,20 @@ size_t php_mysqlnd_auth_write(void *_packet, MYSQLND * conn TSRMLS_DC)
                p+= len;
                *p++ = '\0';
 
-               /* copy scrambled pass*/
-               if (packet->password && packet->password[0]) {
-                       /* In 4.1 we use CLIENT_SECURE_CONNECTION and thus the len of the buf should be passed */
-                       int1store(p, SCRAMBLE_LENGTH);
-                       p++;
-                       php_mysqlnd_scramble((zend_uchar*)p, packet->server_scramble_buf, (zend_uchar*)packet->password);
-                       p+= SCRAMBLE_LENGTH;
-               } else {
-                       /* Zero length */
-                       int1store(p, 0);
-                       p++;
+               /* defensive coding */
+               if (!packet->auth_data) {
+                       packet->auth_data = 0;
+               }
+               int1store(p, packet->auth_data_len);
+               ++p;
+/*!!!!! is the buffer big enough ??? */
+               if ((sizeof(buffer) - (p - buffer)) < packet->auth_data_len) {
+                       DBG_ERR("the stack buffer was not enough!!");
+                       DBG_RETURN(0);
+               }
+               if (packet->auth_data_len) {
+                       memcpy(p, packet->auth_data, packet->auth_data_len);
+                       p+= packet->auth_data_len;
                }
 
                if (packet->db) {
@@ -555,9 +558,18 @@ size_t php_mysqlnd_auth_write(void *_packet, MYSQLND * conn TSRMLS_DC)
                }
                /* no \0 for no DB */
 
-               if (packet->is_change_user_packet && packet->charset_no) {
-                       int2store(p, packet->charset_no);
-                       p+= 2;
+               if (packet->is_change_user_packet) {
+                       if (packet->charset_no) {
+                               int2store(p, packet->charset_no);
+                               p+= 2;
+                       }
+               } else {
+                       if (packet->auth_plugin_name) {
+                               size_t len = MIN(strlen(packet->auth_plugin_name), sizeof(buffer) - (p - buffer) - 1);
+                               memcpy(p, packet->auth_plugin_name, len);
+                               p+= len;
+                               *p++= '\0';
+                       }
                }
        }
        if (packet->is_change_user_packet) {
index 0f3f73e788766db23560375e23205e4fb9eb7797..eb1b418166452f8b8293bc579ffc7e4fb0f9146f 100644 (file)
@@ -70,9 +70,9 @@ typedef struct st_mysqlnd_packet_greet {
        uint8_t         protocol_version;
        char            *server_version;
        uint32_t        thread_id;
-       zend_uchar      intern_scramble_buf[SCRAMBLE_LENGTH];
-       zend_uchar      * scramble_buf;
-       size_t          scramble_buf_len;
+       zend_uchar      intern_auth_plugin_data[SCRAMBLE_LENGTH];
+       zend_uchar      * auth_plugin_data;
+       size_t          auth_plugin_data_len;
        /* 1 byte pad */
        uint32_t        server_capabilities;
        uint8_t         charset_no;
@@ -92,22 +92,18 @@ typedef struct st_mysqlnd_packet_auth {
        MYSQLND_PACKET_HEADER           header;
        uint32_t        client_flags;
        uint32_t        max_packet_size;
-       uint8_t charset_no;
-       /* 23 byte pad */
+       uint8_t         charset_no;
        const char      *user;
-       /* 8 byte scramble */
+       zend_uchar      *auth_data;
+       size_t          auth_data_len;
        const char      *db;
-       /* 12 byte scramble */
-
+       char            *auth_plugin_name;
        /* Here the packet ends. This is user supplied data */
-       const char      *password;
-       /* +1 for \0 because of scramble() */
-       unsigned char   *server_scramble_buf;
-       size_t                  server_scramble_buf_len;
-       size_t                  db_len;
-       zend_bool               send_auth_data;
-       zend_bool               is_change_user_packet;
-       zend_bool               silent;
+       size_t          db_len;
+       zend_bool       send_auth_data;
+       zend_bool       is_change_user_packet;
+       zend_bool       silent;
+
 } MYSQLND_PACKET_AUTH;
 
 /* OK packet */
@@ -255,7 +251,7 @@ typedef struct st_mysqlnd_packet_chg_user_resp {
 } MYSQLND_PACKET_CHG_USER_RESPONSE;
 
 
-PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass);
+PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass, size_t pass_len);
 
 unsigned long  php_mysqlnd_net_field_length(zend_uchar **packet);
 zend_uchar *   php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length);