mirror of
https://github.com/php/php-src.git
synced 2024-12-12 03:15:29 +08:00
Merge branch 'PHP-7.4'
* PHP-7.4: Handle empty password fast path in caching_sha2_password Handle error response during caching_sha2_password auth Add support for caching_sha2_password in change user authentication Fix unix socket check during caching_sha2_password Support auth switch request during caching sha2 auth
This commit is contained in:
commit
184f118d3f
@ -136,6 +136,7 @@ mysqlnd_run_authentication(
|
||||
ret = mysqlnd_auth_change_user(conn, user, strlen(user), passwd, passwd_len, db, db_len, silent,
|
||||
first_call,
|
||||
requested_protocol,
|
||||
auth_plugin, plugin_data, plugin_data_len,
|
||||
scrambled_data, scrambled_data_len,
|
||||
&switch_to_auth_protocol, &switch_to_auth_protocol_len,
|
||||
&switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
|
||||
@ -318,8 +319,12 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
|
||||
}
|
||||
|
||||
if (auth_plugin && auth_plugin->methods.handle_server_response) {
|
||||
auth_plugin->methods.handle_server_response(auth_plugin, conn,
|
||||
orig_auth_plugin_data, orig_auth_plugin_data_len, passwd, passwd_len);
|
||||
if (FAIL == auth_plugin->methods.handle_server_response(auth_plugin, conn,
|
||||
orig_auth_plugin_data, orig_auth_plugin_data_len, passwd, passwd_len,
|
||||
switch_to_auth_protocol, switch_to_auth_protocol_len,
|
||||
switch_to_auth_protocol_data, switch_to_auth_protocol_data_len)) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAIL == PACKET_READ(conn, &auth_resp_packet) || auth_resp_packet.response_code >= 0xFE) {
|
||||
@ -371,6 +376,9 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
|
||||
const zend_bool silent,
|
||||
const zend_bool use_full_blown_auth_packet,
|
||||
const char * const auth_protocol,
|
||||
struct st_mysqlnd_authentication_plugin * auth_plugin,
|
||||
const zend_uchar * const orig_auth_plugin_data,
|
||||
const size_t orig_auth_plugin_data_len,
|
||||
const zend_uchar * const auth_plugin_data,
|
||||
const size_t auth_plugin_data_len,
|
||||
char ** switch_to_auth_protocol,
|
||||
@ -436,6 +444,15 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
|
||||
PACKET_FREE(&auth_packet);
|
||||
}
|
||||
|
||||
if (auth_plugin && auth_plugin->methods.handle_server_response) {
|
||||
if (FAIL == auth_plugin->methods.handle_server_response(auth_plugin, conn,
|
||||
orig_auth_plugin_data, orig_auth_plugin_data_len, passwd, passwd_len,
|
||||
switch_to_auth_protocol, switch_to_auth_protocol_len,
|
||||
switch_to_auth_protocol_data, switch_to_auth_protocol_data_len)) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = PACKET_READ(conn, &chg_user_resp);
|
||||
COPY_CLIENT_ERROR(conn->error_info, chg_user_resp.error_info);
|
||||
|
||||
@ -1026,39 +1043,69 @@ mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mysqlnd_native_auth_get_auth_data */
|
||||
static void
|
||||
static int is_secure_transport(MYSQLND_CONN_DATA *conn) {
|
||||
if (conn->vio->data->ssl) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return strcmp(conn->vio->data->stream->ops->label, "unix_socket") == 0;
|
||||
}
|
||||
|
||||
/* {{{ mysqlnd_caching_sha2_handle_server_response */
|
||||
static enum_func_status
|
||||
mysqlnd_caching_sha2_handle_server_response(struct st_mysqlnd_authentication_plugin *self,
|
||||
MYSQLND_CONN_DATA * conn,
|
||||
const zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len,
|
||||
const char * const passwd,
|
||||
const size_t passwd_len)
|
||||
const size_t passwd_len,
|
||||
char **new_auth_protocol, size_t *new_auth_protocol_len,
|
||||
zend_uchar **new_auth_protocol_data, size_t *new_auth_protocol_data_len
|
||||
)
|
||||
{
|
||||
DBG_ENTER("mysqlnd_caching_sha2_handle_server_response");
|
||||
MYSQLND_PACKET_CACHED_SHA2_RESULT result_packet;
|
||||
conn->payload_decoder_factory->m.init_cached_sha2_result_packet(&result_packet);
|
||||
|
||||
if (passwd_len == 0) {
|
||||
DBG_INF("empty password fast path");
|
||||
DBG_RETURN(PASS);
|
||||
}
|
||||
|
||||
conn->payload_decoder_factory->m.init_cached_sha2_result_packet(&result_packet);
|
||||
if (FAIL == PACKET_READ(conn, &result_packet)) {
|
||||
DBG_VOID_RETURN;
|
||||
DBG_RETURN(PASS);
|
||||
}
|
||||
|
||||
switch (result_packet.response_code) {
|
||||
case 0xFF:
|
||||
if (result_packet.sqlstate[0]) {
|
||||
strlcpy(conn->error_info->sqlstate, result_packet.sqlstate, sizeof(conn->error_info->sqlstate));
|
||||
DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", result_packet.error_no, result_packet.sqlstate, result_packet.error);
|
||||
}
|
||||
SET_CLIENT_ERROR(conn->error_info, result_packet.error_no, UNKNOWN_SQLSTATE, result_packet.error);
|
||||
DBG_RETURN(FAIL);
|
||||
case 0xFE:
|
||||
DBG_INF("auth switch response");
|
||||
*new_auth_protocol = result_packet.new_auth_protocol;
|
||||
*new_auth_protocol_len = result_packet.new_auth_protocol_len;
|
||||
*new_auth_protocol_data = result_packet.new_auth_protocol_data;
|
||||
*new_auth_protocol_data_len = result_packet.new_auth_protocol_data_len;
|
||||
DBG_RETURN(FAIL);
|
||||
case 3:
|
||||
DBG_INF("fast path succeeded");
|
||||
DBG_VOID_RETURN;
|
||||
DBG_RETURN(PASS);
|
||||
case 4:
|
||||
if (conn->vio->data->ssl || conn->unix_socket.s) {
|
||||
DBG_INF("fast path failed, doing full auth via SSL");
|
||||
if (is_secure_transport(conn)) {
|
||||
DBG_INF("fast path failed, doing full auth via secure transport");
|
||||
result_packet.password = (zend_uchar *)passwd;
|
||||
result_packet.password_len = passwd_len + 1;
|
||||
PACKET_WRITE(conn, &result_packet);
|
||||
} else {
|
||||
DBG_INF("fast path failed, doing full auth without SSL");
|
||||
DBG_INF("fast path failed, doing full auth via insecure transport");
|
||||
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);
|
||||
PACKET_WRITE(conn, &result_packet);
|
||||
efree(result_packet.password);
|
||||
}
|
||||
DBG_VOID_RETURN;
|
||||
DBG_RETURN(PASS);
|
||||
case 2:
|
||||
// The server tried to send a key, which we didn't expect
|
||||
// fall-through
|
||||
@ -1066,7 +1113,7 @@ mysqlnd_caching_sha2_handle_server_response(struct st_mysqlnd_authentication_plu
|
||||
php_error_docref(NULL, E_WARNING, "Unexpected server response while doing caching_sha2 auth: %i", result_packet.response_code);
|
||||
}
|
||||
|
||||
DBG_VOID_RETURN;
|
||||
DBG_RETURN(PASS);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -51,6 +51,9 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
|
||||
const zend_bool silent,
|
||||
const zend_bool use_full_blown_auth_packet,
|
||||
const char * const auth_protocol,
|
||||
struct st_mysqlnd_authentication_plugin * auth_plugin,
|
||||
const zend_uchar * const orig_auth_plugin_data,
|
||||
const size_t orig_auth_plugin_data_len,
|
||||
const zend_uchar * auth_plugin_data,
|
||||
const size_t auth_plugin_data_len,
|
||||
char ** switch_to_auth_protocol,
|
||||
|
@ -669,13 +669,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
|
||||
|
||||
{
|
||||
const MYSQLND_CSTRING scheme = { transport.s, transport.l };
|
||||
/* This will be overwritten below with a copy, but we can use it during authentication */
|
||||
conn->unix_socket.s = (char *)socket_or_pipe.s;
|
||||
if (FAIL == conn->m->connect_handshake(conn, &scheme, &username, &password, &database, mysql_flags)) {
|
||||
conn->unix_socket.s = NULL;
|
||||
goto err;
|
||||
}
|
||||
conn->unix_socket.s = NULL;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1381,11 +1381,14 @@ typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authen
|
||||
const MYSQLND_PFC_DATA * const pfc_data, const zend_ulong mysql_flags
|
||||
);
|
||||
|
||||
typedef void (*func_auth_plugin__handle_server_response)(struct st_mysqlnd_authentication_plugin * self,
|
||||
typedef enum_func_status (*func_auth_plugin__handle_server_response)(struct st_mysqlnd_authentication_plugin * self,
|
||||
MYSQLND_CONN_DATA * conn,
|
||||
const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
|
||||
const char * const passwd,
|
||||
const size_t passwd_len);
|
||||
const size_t passwd_len,
|
||||
char **new_auth_protocol, size_t *new_auth_protocol_len,
|
||||
zend_uchar **new_auth_protocol_data, size_t *new_auth_protocol_data_len
|
||||
);
|
||||
|
||||
struct st_mysqlnd_authentication_plugin
|
||||
{
|
||||
|
@ -2183,11 +2183,44 @@ php_mysqlnd_cached_sha2_result_read(MYSQLND_CONN_DATA * conn, void * _packet)
|
||||
}
|
||||
BAIL_IF_NO_MORE_DATA;
|
||||
|
||||
p++;
|
||||
packet->response_code = uint1korr(p);
|
||||
p++;
|
||||
BAIL_IF_NO_MORE_DATA;
|
||||
|
||||
if (ERROR_MARKER == packet->response_code) {
|
||||
php_mysqlnd_read_error_from_line(p, packet->header.size - 1,
|
||||
packet->error, sizeof(packet->error),
|
||||
&packet->error_no, packet->sqlstate
|
||||
);
|
||||
DBG_RETURN(PASS);
|
||||
}
|
||||
if (0xFE == packet->response_code) {
|
||||
/* Authentication Switch Response */
|
||||
if (packet->header.size > (size_t) (p - buf)) {
|
||||
packet->new_auth_protocol = mnd_pestrdup((char *)p, FALSE);
|
||||
packet->new_auth_protocol_len = strlen(packet->new_auth_protocol);
|
||||
p+= packet->new_auth_protocol_len + 1; /* +1 for the \0 */
|
||||
|
||||
packet->new_auth_protocol_data_len = packet->header.size - (size_t) (p - buf);
|
||||
if (packet->new_auth_protocol_data_len) {
|
||||
packet->new_auth_protocol_data = mnd_emalloc(packet->new_auth_protocol_data_len);
|
||||
memcpy(packet->new_auth_protocol_data, p, packet->new_auth_protocol_data_len);
|
||||
}
|
||||
DBG_INF_FMT("The server requested switching auth plugin to : %s", packet->new_auth_protocol);
|
||||
DBG_INF_FMT("Server salt : [%d][%.*s]", packet->new_auth_protocol_data_len, packet->new_auth_protocol_data_len, packet->new_auth_protocol_data);
|
||||
}
|
||||
DBG_RETURN(PASS);
|
||||
}
|
||||
|
||||
if (0x1 != packet->response_code) {
|
||||
DBG_ERR_FMT("Unexpected response code %d", packet->response_code);
|
||||
}
|
||||
|
||||
/* This is not really the response code, but we reuse the field. */
|
||||
packet->response_code = uint1korr(p);
|
||||
p++;
|
||||
BAIL_IF_NO_MORE_DATA;
|
||||
|
||||
packet->result = uint1korr(p);
|
||||
BAIL_IF_NO_MORE_DATA;
|
||||
|
||||
|
@ -286,6 +286,15 @@ typedef struct st_mysqlnd_packet_cached_sha2_result {
|
||||
uint8_t request;
|
||||
zend_uchar * password;
|
||||
size_t password_len;
|
||||
/* Used for auth switch request */
|
||||
char *new_auth_protocol;
|
||||
size_t new_auth_protocol_len;
|
||||
zend_uchar *new_auth_protocol_data;
|
||||
size_t new_auth_protocol_data_len;
|
||||
/* Used for error result */
|
||||
char error[MYSQLND_ERRMSG_SIZE+1];
|
||||
char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
|
||||
unsigned int error_no;
|
||||
} MYSQLND_PACKET_CACHED_SHA2_RESULT;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user