ssl_set( $server['ssl_key'] ?? '', $server['ssl_cert'] ?? '', $server['ssl_ca'] ?? '', $server['ssl_ca_path'] ?? '', $server['ssl_ciphers'] ?? '' ); } /* * disables SSL certificate validation on mysqlnd for MySQL 5.6 or later * @link https://bugs.php.net/bug.php?id=68344 * @link https://github.com/phpmyadmin/phpmyadmin/pull/11838 */ if (! $server['ssl_verify']) { $mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, (int) $server['ssl_verify']); $client_flags |= MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT; } } if ($GLOBALS['cfg']['PersistentConnections']) { $host = 'p:' . $server['host']; } else { $host = $server['host']; } if ($server['hide_connection_errors']) { $return_value = @$mysqli->real_connect( $host, $user, $password, '', $server['port'], (string) $server['socket'], $client_flags ); } else { $return_value = $mysqli->real_connect( $host, $user, $password, '', $server['port'], (string) $server['socket'], $client_flags ); } if ($return_value === false) { /* * Switch to SSL if server asked us to do so, unfortunately * there are more ways MySQL server can tell this: * * - MySQL 8.0 and newer should return error 3159 * - #2001 - SSL Connection is required. Please specify SSL options and retry. * - #9002 - SSL connection is required. Please specify SSL options and retry. */ // phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps $error_number = $mysqli->connect_errno; $error_message = $mysqli->connect_error; // phpcs:enable if ( ! $server['ssl'] && ($error_number == 3159 || (($error_number == 2001 || $error_number == 9002) && stripos($error_message, 'SSL Connection is required') !== false)) ) { trigger_error( __('SSL connection enforced by server, automatically enabling it.'), E_USER_WARNING ); $server['ssl'] = true; return self::connect($user, $password, $server); } if ($error_number === 1045 && $server['hide_connection_errors']) { trigger_error( sprintf( __( 'Error 1045: Access denied for user. Additional error information' . ' may be available, but is being hidden by the %s configuration directive.' ), '[code][doc@cfg_Servers_hide_connection_errors]' . '$cfg[\'Servers\'][$i][\'hide_connection_errors\'][/doc][/code]' ), E_USER_ERROR ); } return false; } $mysqli->options(MYSQLI_OPT_LOCAL_INFILE, (int) defined('PMA_ENABLE_LDI')); return $mysqli; } /** * selects given database * * @param string|DatabaseName $databaseName database name to select * @param mysqli $link the mysqli object */ public function selectDb($databaseName, $link): bool { return $link->select_db((string) $databaseName); } /** * runs a query and returns the result * * @param string $query query to execute * @param mysqli $link mysqli object * @param int $options query options * * @return MysqliResult|false */ public function realQuery(string $query, $link, int $options) { $method = MYSQLI_STORE_RESULT; if ($options == ($options | DatabaseInterface::QUERY_UNBUFFERED)) { $method = MYSQLI_USE_RESULT; } $result = $link->query($query, $method); if ($result === false) { return false; } return new MysqliResult($result); } /** * Run the multi query and output the results * * @param mysqli $link mysqli object * @param string $query multi query statement to execute */ public function realMultiQuery($link, $query): bool { return $link->multi_query($query); } /** * Check if there are any more query results from a multi query * * @param mysqli $link the mysqli object */ public function moreResults($link): bool { return $link->more_results(); } /** * Prepare next result from multi_query * * @param mysqli $link the mysqli object */ public function nextResult($link): bool { return $link->next_result(); } /** * Store the result returned from multi query * * @param mysqli $link the mysqli object * * @return MysqliResult|false false when empty results / result set when not empty */ public function storeResult($link) { $result = $link->store_result(); return $result === false ? false : new MysqliResult($result); } /** * Returns a string representing the type of connection used * * @param mysqli $link mysql link * * @return string type of connection used */ public function getHostInfo($link) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps return $link->host_info; } /** * Returns the version of the MySQL protocol used * * @param mysqli $link mysql link * * @return string version of the MySQL protocol used */ public function getProtoInfo($link) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps return $link->protocol_version; } /** * returns a string that represents the client library version * * @return string MySQL client library version */ public function getClientInfo() { return mysqli_get_client_info(); } /** * Returns last error message or an empty string if no errors occurred. * * @param mysqli|false|null $link mysql link */ public function getError($link): string { $GLOBALS['errno'] = 0; if ($link !== null && $link !== false) { $error_number = $link->errno; $error_message = $link->error; } else { $error_number = mysqli_connect_errno(); $error_message = (string) mysqli_connect_error(); } if ($error_number === 0 || $error_message === '') { return ''; } // keep the error number for further check after // the call to getError() $GLOBALS['errno'] = $error_number; return Utilities::formatError($error_number, $error_message); } /** * returns the number of rows affected by last query * * @param mysqli $link the mysqli object * * @return int|string * @psalm-return int|numeric-string */ public function affectedRows($link) { // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps return $link->affected_rows; } /** * returns properly escaped string for use in MySQL queries * * @param mysqli $link database link * @param string $string string to be escaped * * @return string a MySQL escaped string */ public function escapeString($link, $string) { return $link->real_escape_string($string); } /** * Prepare an SQL statement for execution. * * @param mysqli $link database link * @param string $query The query, as a string. * * @return mysqli_stmt|false A statement object or false. */ public function prepare($link, string $query) { return $link->prepare($query); } }