Skip to content

Commit 03740ef

Browse files
committed
Revert all MySQL auth related changes
Per bug #76651 these changes do not appear to work correctly in some cases. As no immediate fix seems to be forthcoming, I'm reverting these changes. Revert "Fixed invalid free introduced by d6e81f0 (avoid keeping "invalid" pointer)" This reverts commit 11507c0. Revert "Fix mysqlnd build without openssl" This reverts commit 6c9db02. Revert "Fix VC compilation as variable size array is not supported" This reverts commit f96df64. Revert "Fix MySQL 8 auth" This reverts commit d6e81f0.
1 parent f1f39d7 commit 03740ef

7 files changed

+29
-425
lines changed

Diff for: ext/mysqlnd/mysqlnd_auth.c

+7-286
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ mysqlnd_run_authentication(
8989
}
9090
}
9191

92-
9392
{
9493
zend_uchar * switch_to_auth_protocol_data = NULL;
9594
size_t switch_to_auth_protocol_data_len = 0;
@@ -114,11 +113,10 @@ mysqlnd_run_authentication(
114113
DBG_INF_FMT("salt(%d)=[%.*s]", plugin_data_len, plugin_data_len, plugin_data);
115114
/* The data should be allocated with malloc() */
116115
if (auth_plugin) {
117-
scrambled_data = auth_plugin->methods.get_auth_data(
118-
NULL, &scrambled_data_len, conn, user, passwd,
119-
passwd_len, plugin_data, plugin_data_len,
120-
session_options, conn->protocol_frame_codec->data,
121-
mysql_flags);
116+
scrambled_data =
117+
auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
118+
plugin_data, plugin_data_len, session_options,
119+
conn->protocol_frame_codec->data, mysql_flags);
122120
}
123121

124122
if (conn->error_info->error_no) {
@@ -129,7 +127,6 @@ mysqlnd_run_authentication(
129127
charset_no,
130128
first_call,
131129
requested_protocol,
132-
auth_plugin, plugin_data, plugin_data_len,
133130
scrambled_data, scrambled_data_len,
134131
&switch_to_auth_protocol, &switch_to_auth_protocol_len,
135132
&switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
@@ -251,9 +248,6 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
251248
unsigned int server_charset_no,
252249
zend_bool use_full_blown_auth_packet,
253250
const char * const auth_protocol,
254-
struct st_mysqlnd_authentication_plugin * auth_plugin,
255-
const zend_uchar * const orig_auth_plugin_data,
256-
const size_t orig_auth_plugin_data_len,
257251
const zend_uchar * const auth_plugin_data,
258252
const size_t auth_plugin_data_len,
259253
char ** switch_to_auth_protocol,
@@ -324,11 +318,6 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
324318
conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no);
325319
}
326320

327-
if (auth_plugin && auth_plugin->methods.handle_server_response) {
328-
auth_plugin->methods.handle_server_response(auth_plugin, conn,
329-
orig_auth_plugin_data, orig_auth_plugin_data_len, passwd, passwd_len);
330-
}
331-
332321
if (FAIL == PACKET_READ(auth_resp_packet) || auth_resp_packet->response_code >= 0xFE) {
333322
if (auth_resp_packet->response_code == 0xFE) {
334323
/* old authentication with new server !*/
@@ -624,8 +613,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_native_auth_plugin =
624613
}
625614
},
626615
{/* methods */
627-
mysqlnd_native_auth_get_auth_data,
628-
NULL
616+
mysqlnd_native_auth_get_auth_data
629617
}
630618
};
631619

@@ -674,8 +662,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin
674662
}
675663
},
676664
{/* methods */
677-
mysqlnd_pam_auth_get_auth_data,
678-
NULL
665+
mysqlnd_pam_auth_get_auth_data
679666
}
680667
};
681668

@@ -859,283 +846,17 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_sha256_authentication_plu
859846
}
860847
},
861848
{/* methods */
862-
mysqlnd_sha256_auth_get_auth_data,
863-
NULL
849+
mysqlnd_sha256_auth_get_auth_data
864850
}
865851
};
866852
#endif
867853

868-
/*************************************** CACHING SHA2 Password *******************************/
869-
870-
#undef L64
871-
872-
#include "ext/hash/php_hash.h"
873-
#include "ext/hash/php_hash_sha.h"
874-
875-
#define SHA256_LENGTH 32
876-
877-
/* {{{ php_mysqlnd_scramble_sha2 */
878-
void php_mysqlnd_scramble_sha2(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const password, const size_t password_len)
879-
{
880-
PHP_SHA256_CTX context;
881-
zend_uchar sha1[SHA256_LENGTH];
882-
zend_uchar sha2[SHA256_LENGTH];
883-
884-
/* Phase 1: hash password */
885-
PHP_SHA256Init(&context);
886-
PHP_SHA256Update(&context, password, password_len);
887-
PHP_SHA256Final(sha1, &context);
888-
889-
/* Phase 2: hash sha1 */
890-
PHP_SHA256Init(&context);
891-
PHP_SHA256Update(&context, (zend_uchar*)sha1, SHA256_LENGTH);
892-
PHP_SHA256Final(sha2, &context);
893-
894-
/* Phase 3: hash scramble + sha2 */
895-
PHP_SHA256Init(&context);
896-
PHP_SHA256Update(&context, (zend_uchar*)sha2, SHA256_LENGTH);
897-
PHP_SHA256Update(&context, scramble, SCRAMBLE_LENGTH);
898-
PHP_SHA256Final(buffer, &context);
899-
900-
/* let's crypt buffer now */
901-
php_mysqlnd_crypt(buffer, (const zend_uchar *)sha1, (const zend_uchar *)buffer, SHA256_LENGTH);
902-
}
903-
/* }}} */
904-
905-
906-
/* {{{ mysqlnd_native_auth_get_auth_data */
907-
static zend_uchar *
908-
mysqlnd_caching_sha2_get_auth_data(struct st_mysqlnd_authentication_plugin * self,
909-
size_t * auth_data_len,
910-
MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd,
911-
const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
912-
const MYSQLND_SESSION_OPTIONS * const session_options,
913-
const MYSQLND_PFC_DATA * const pfc_data,
914-
zend_ulong mysql_flags
915-
)
916-
{
917-
zend_uchar * ret = NULL;
918-
DBG_ENTER("mysqlnd_caching_sha2_get_auth_data");
919-
DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data);
920-
*auth_data_len = 0;
921-
922-
DBG_INF("First auth step: send hashed password");
923-
/* copy scrambled pass*/
924-
if (passwd && passwd_len) {
925-
ret = malloc(SHA256_LENGTH + 1);
926-
*auth_data_len = SHA256_LENGTH;
927-
php_mysqlnd_scramble_sha2((zend_uchar*)ret, auth_plugin_data, (zend_uchar*)passwd, passwd_len);
928-
ret[SHA256_LENGTH] = '\0';
929-
DBG_INF_FMT("hash(%d)=[%.*s]", *auth_data_len, *auth_data_len, ret);
930-
}
931-
932-
DBG_RETURN(ret);
933-
}
934-
/* }}} */
935-
936-
#ifdef MYSQLND_HAVE_SSL
937-
static RSA *
938-
mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn)
939-
{
940-
RSA * ret = NULL;
941-
const MYSQLND_PFC_DATA * const pfc_data = conn->protocol_frame_codec->data;
942-
const char * fname = (pfc_data->sha256_server_public_key && pfc_data->sha256_server_public_key[0] != '\0')?
943-
pfc_data->sha256_server_public_key:
944-
MYSQLND_G(sha256_server_public_key);
945-
php_stream * stream;
946-
DBG_ENTER("mysqlnd_cached_sha2_get_key");
947-
DBG_INF_FMT("options_s256_pk=[%s] MYSQLND_G(sha256_server_public_key)=[%s]",
948-
pfc_data->sha256_server_public_key? pfc_data->sha256_server_public_key:"n/a",
949-
MYSQLND_G(sha256_server_public_key)? MYSQLND_G(sha256_server_public_key):"n/a");
950-
if (!fname || fname[0] == '\0') {
951-
MYSQLND_PACKET_CACHED_SHA2_RESULT *req_packet = NULL;
952-
MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *pk_resp_packet = NULL;
953-
954-
do {
955-
DBG_INF("requesting the public key from the server");
956-
req_packet = conn->payload_decoder_factory->m.get_cached_sha2_result_packet(conn->payload_decoder_factory, FALSE);
957-
pk_resp_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_response_packet(conn->payload_decoder_factory, FALSE);
958-
req_packet->request = 1;
959-
960-
if (! PACKET_WRITE(req_packet)) {
961-
DBG_ERR_FMT("Error while sending public key request packet");
962-
php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid());
963-
SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
964-
break;
965-
}
966-
if (FAIL == PACKET_READ(pk_resp_packet) || NULL == pk_resp_packet->public_key) {
967-
DBG_ERR_FMT("Error while receiving public key");
968-
php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid());
969-
SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
970-
break;
971-
}
972-
DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet->public_key_len, pk_resp_packet->public_key);
973-
/* now extract the public key */
974-
{
975-
BIO * bio = BIO_new_mem_buf(pk_resp_packet->public_key, pk_resp_packet->public_key_len);
976-
ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
977-
BIO_free(bio);
978-
}
979-
} while (0);
980-
PACKET_FREE(req_packet);
981-
PACKET_FREE(pk_resp_packet);
982-
983-
DBG_INF_FMT("ret=%p", ret);
984-
DBG_RETURN(ret);
985-
986-
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE,
987-
"caching_sha2_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key");
988-
DBG_ERR("server_public_key is not set");
989-
DBG_RETURN(NULL);
990-
} else {
991-
zend_string * key_str;
992-
DBG_INF_FMT("Key in a file. [%s]", fname);
993-
stream = php_stream_open_wrapper((char *) fname, "rb", REPORT_ERRORS, NULL);
994-
995-
if (stream) {
996-
if ((key_str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) {
997-
BIO * bio = BIO_new_mem_buf(ZSTR_VAL(key_str), ZSTR_LEN(key_str));
998-
ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
999-
BIO_free(bio);
1000-
DBG_INF("Successfully loaded");
1001-
DBG_INF_FMT("Public key:%*.s", ZSTR_LEN(key_str), ZSTR_VAL(key_str));
1002-
zend_string_release(key_str);
1003-
}
1004-
php_stream_close(stream);
1005-
}
1006-
}
1007-
DBG_RETURN(ret);
1008-
1009-
}
1010-
#endif
1011-
1012-
1013-
/* {{{ mysqlnd_caching_sha2_get_key */
1014-
static size_t
1015-
mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn,
1016-
const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
1017-
unsigned char **crypted,
1018-
const char * const passwd,
1019-
const size_t passwd_len)
1020-
{
1021-
#ifdef MYSQLND_HAVE_SSL
1022-
static RSA *server_public_key;
1023-
server_public_key = mysqlnd_caching_sha2_get_key(conn);
1024-
1025-
DBG_ENTER("mysqlnd_caching_sha2_get_and_use_key(");
1026-
1027-
if (server_public_key) {
1028-
int server_public_key_len;
1029-
char xor_str[passwd_len + 1];
1030-
memcpy(xor_str, passwd, passwd_len);
1031-
xor_str[passwd_len] = '\0';
1032-
mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len);
1033-
1034-
server_public_key_len = RSA_size(server_public_key);
1035-
/*
1036-
Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
1037-
RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
1038-
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
1039-
*/
1040-
if ((size_t) server_public_key_len - 41 <= passwd_len) {
1041-
/* password message is to long */
1042-
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
1043-
DBG_ERR("password is too long");
1044-
DBG_RETURN(0);
1045-
}
1046-
1047-
*crypted = emalloc(server_public_key_len);
1048-
RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, *crypted, server_public_key, RSA_PKCS1_OAEP_PADDING);
1049-
DBG_RETURN(server_public_key_len);
1050-
}
1051-
DBG_RETURN(0);
1052-
#else
1053-
DBG_ENTER("mysqlnd_caching_sha2_get_and_use_key(");
1054-
php_error_docref(NULL, E_WARNING, "PHP was built without openssl extension, can't send password encrypted");
1055-
DBG_RETURN(0);
1056-
#endif
1057-
}
1058-
/* }}} */
1059-
1060-
/* {{{ mysqlnd_native_auth_get_auth_data */
1061-
static void
1062-
mysqlnd_caching_sha2_handle_server_response(struct st_mysqlnd_authentication_plugin *self,
1063-
MYSQLND_CONN_DATA * conn,
1064-
const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
1065-
const char * const passwd,
1066-
const size_t passwd_len)
1067-
{
1068-
DBG_ENTER("mysqlnd_caching_sha2_handle_server_response");
1069-
MYSQLND_PACKET_CACHED_SHA2_RESULT *result_packet;
1070-
result_packet = conn->payload_decoder_factory->m.get_cached_sha2_result_packet(conn->payload_decoder_factory, FALSE);
1071-
1072-
if (FAIL == PACKET_READ(result_packet)) {
1073-
DBG_VOID_RETURN;
1074-
}
1075-
1076-
switch (result_packet->response_code) {
1077-
case 3:
1078-
DBG_INF("fast path suceeded");
1079-
PACKET_FREE(result_packet);
1080-
DBG_VOID_RETURN;
1081-
case 4:
1082-
if (conn->vio->data->ssl || conn->unix_socket.s) {
1083-
DBG_INF("fast path failed, doing full auth via SSL");
1084-
result_packet->password = (zend_uchar *)passwd;
1085-
result_packet->password_len = passwd_len + 1;
1086-
PACKET_WRITE(result_packet);
1087-
} else {
1088-
DBG_INF("fast path failed, doing full auth without SSL");
1089-
result_packet->password_len = mysqlnd_caching_sha2_get_and_use_key(conn, auth_plugin_data, auth_plugin_data_len, &result_packet->password, passwd, passwd_len);
1090-
PACKET_WRITE(result_packet);
1091-
efree(result_packet->password);
1092-
}
1093-
PACKET_FREE(result_packet);
1094-
DBG_VOID_RETURN;
1095-
case 2:
1096-
// The server tried to send a key, which we didn't expect
1097-
// fall-through
1098-
default:
1099-
php_error_docref(NULL, E_WARNING, "Unexpected server respose while doing caching_sha2 auth: %i", result_packet->response_code);
1100-
}
1101-
1102-
PACKET_FREE(result_packet);
1103-
1104-
DBG_VOID_RETURN;
1105-
}
1106-
/* }}} */
1107-
1108-
static struct st_mysqlnd_authentication_plugin mysqlnd_caching_sha2_auth_plugin =
1109-
{
1110-
{
1111-
MYSQLND_PLUGIN_API_VERSION,
1112-
"auth_plugin_caching_sha2_password",
1113-
MYSQLND_VERSION_ID,
1114-
PHP_MYSQLND_VERSION,
1115-
"PHP License 3.01",
1116-
"Johannes Schlüter <[email protected]>",
1117-
{
1118-
NULL, /* no statistics , will be filled later if there are some */
1119-
NULL, /* no statistics */
1120-
},
1121-
{
1122-
NULL /* plugin shutdown */
1123-
}
1124-
},
1125-
{/* methods */
1126-
mysqlnd_caching_sha2_get_auth_data,
1127-
mysqlnd_caching_sha2_handle_server_response
1128-
}
1129-
};
1130-
1131-
1132854
/* {{{ mysqlnd_register_builtin_authentication_plugins */
1133855
void
1134856
mysqlnd_register_builtin_authentication_plugins(void)
1135857
{
1136858
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_native_auth_plugin);
1137859
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_pam_authentication_plugin);
1138-
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_caching_sha2_auth_plugin);
1139860
#ifdef MYSQLND_HAVE_SSL
1140861
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_sha256_authentication_plugin);
1141862
#endif

Diff for: ext/mysqlnd/mysqlnd_auth.h

+20-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,26 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
3131
unsigned int server_charset_no,
3232
zend_bool use_full_blown_auth_packet,
3333
const char * const auth_protocol,
34-
struct st_mysqlnd_authentication_plugin * auth_plugin,
35-
const zend_uchar * const orig_auth_plugin_data,
36-
const size_t orig_auth_plugin_data_len,
34+
const zend_uchar * const auth_plugin_data,
35+
const size_t auth_plugin_data_len,
36+
char ** switch_to_auth_protocol,
37+
size_t * switch_to_auth_protocol_len,
38+
zend_uchar ** switch_to_auth_protocol_data,
39+
size_t * switch_to_auth_protocol_data_len
40+
);
41+
42+
enum_func_status
43+
mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
44+
const char * const user,
45+
const char * const passwd,
46+
const size_t passwd_len,
47+
const char * const db,
48+
const size_t db_len,
49+
const MYSQLND_SESSION_OPTIONS * const session_options,
50+
zend_ulong mysql_flags,
51+
unsigned int server_charset_no,
52+
zend_bool use_full_blown_auth_packet,
53+
const char * const auth_protocol,
3754
const zend_uchar * const auth_plugin_data,
3855
const size_t auth_plugin_data_len,
3956
char ** switch_to_auth_protocol,

0 commit comments

Comments
 (0)