Fix for bug#49234 method not found ssl_set

Patch was tested and compiles on Windows. (Thanks Kalle)
This commit is contained in:
Andrey Hristov 2010-04-15 11:01:30 +00:00
parent 29aff0a595
commit c04f752625
15 changed files with 338 additions and 66 deletions

View File

@ -2121,7 +2121,6 @@ PHP_FUNCTION(mysqli_sqlstate)
/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U
*/
#if !defined(MYSQLI_USE_MYSQLND)
PHP_FUNCTION(mysqli_ssl_set)
{
MY_MYSQL *mysql;
@ -2144,7 +2143,6 @@ PHP_FUNCTION(mysqli_ssl_set)
RETURN_TRUE;
}
#endif
/* }}} */
/* {{{ proto mixed mysqli_stat(object link)

View File

@ -156,9 +156,7 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_stmt_reset, NULL)
PHP_FE(mysqli_stmt_param_count, NULL)
PHP_FE(mysqli_sqlstate, NULL)
#if !defined(MYSQLI_USE_MYSQLND)
PHP_FE(mysqli_ssl_set, NULL)
#endif
PHP_FE(mysqli_stat, NULL)
PHP_FE(mysqli_stmt_affected_rows, NULL)
PHP_FE(mysqli_stmt_close, NULL)
@ -246,9 +244,7 @@ const zend_function_entry mysqli_link_methods[] = {
PHP_FALIAS(set_charset,mysqli_set_charset,NULL)
#endif
PHP_FALIAS(set_opt, mysqli_options,NULL)
#if !defined(MYSQLI_USE_MYSQLND)
PHP_FALIAS(ssl_set,mysqli_ssl_set,NULL)
#endif
PHP_FALIAS(stat,mysqli_stat,NULL)
PHP_FALIAS(stmt_init,mysqli_stmt_init, NULL)
PHP_FALIAS(store_result,mysqli_store_result,NULL)

View File

@ -50,6 +50,7 @@ require_once('skipifconnectfailure.inc');
'select_db' => true,
'set_charset' => true,
'set_opt' => true,
'ssl_set' => true,
'stat' => true,
'stmt_init' => true,
'store_result' => true,

View File

@ -615,6 +615,22 @@ Modifiers: 256
Number of Parameters: 0
Number of Required Parameters: 0
Inspecting method 'ssl_set'
isFinal: no
isAbstract: no
isPublic: yes
isPrivate: no
isProtected: no
isStatic: no
isConstructor: no
isDestructor: no
isInternal: yes
isUserDefined: no
returnsReference: no
Modifiers: 256
Number of Parameters: 0
Number of Required Parameters: 0
Inspecting method 'stat'
isFinal: no
isAbstract: no

View File

@ -36,6 +36,7 @@ if test "$PHP_MYSQLND_ENABLED" = "yes"; then
MYSQLND_LIBS="$MYSQLND_LIBS -lz"
fi
fi
AC_DEFINE([MYSQLND_SSL_SUPPORTED], 1, [Enable SSL support])
fi
if test "$PHP_MYSQLND_ENABLED" = "yes" || test "$PHP_MYSQLI" != "no"; then

View File

@ -109,27 +109,8 @@ MYSQLND_METHOD(mysqlnd_conn, free_options)(MYSQLND *conn TSRMLS_DC)
mnd_pefree(conn->options.cfg_section, pers);
conn->options.cfg_section = NULL;
}
if (conn->options.ssl_key) {
mnd_pefree(conn->options.ssl_key, pers);
conn->options.ssl_key = NULL;
}
if (conn->options.ssl_cert) {
mnd_pefree(conn->options.ssl_cert, pers);
conn->options.ssl_cert = NULL;
}
if (conn->options.ssl_ca) {
mnd_pefree(conn->options.ssl_ca, pers);
conn->options.ssl_ca = NULL;
}
if (conn->options.ssl_capath) {
mnd_pefree(conn->options.ssl_capath, pers);
conn->options.ssl_capath = NULL;
}
if (conn->options.ssl_cipher) {
mnd_pefree(conn->options.ssl_cipher, pers);
conn->options.ssl_cipher = NULL;
}
}
/* }}} */
/* {{{ mysqlnd_conn::free_contents */
@ -356,9 +337,8 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command)(MYSQLND *conn, enum php_mysqlnd_ser
DBG_ERR("Server is gone");
DBG_RETURN(FAIL);
default:
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE,
mysqlnd_out_of_sync);
DBG_ERR("Command out of sync");
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
DBG_ERR_FMT("Command out of sync. State=%d", CONN_GET_STATE(conn));
DBG_RETURN(FAIL);
}
@ -597,7 +577,20 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
mysql_flags &= ~CLIENT_COMPRESS;
}
#endif
#ifndef MYSQLND_SSL_SUPPORTED
if (mysql_flags & CLIENT_SSL) {
mysql_flags &= ~CLIENT_SSL;
}
#else
if (conn->net->options.ssl_key || conn->net->options.ssl_cert ||
conn->net->options.ssl_ca || conn->net->options.ssl_capath || conn->net->options.ssl_cipher)
{
mysql_flags |= CLIENT_SSL;
}
if ((greet_packet->server_capabilities & CLIENT_SSL) && (mysql_flags & CLIENT_SSL)) {
auth_packet->send_half_packet = TRUE;
}
#endif
auth_packet->user = user;
auth_packet->password = passwd;
@ -619,12 +612,33 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
conn->scramble = auth_packet->server_scramble_buf = mnd_pemalloc(SCRAMBLE_LENGTH, conn->persistent);
memcpy(auth_packet->server_scramble_buf, greet_packet->scramble_buf, SCRAMBLE_LENGTH);
if (!PACKET_WRITE(auth_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto err;
}
#ifdef MYSQLND_SSL_SUPPORTED
if (auth_packet->send_half_packet) {
zend_bool verify = mysql_flags & CLIENT_SSL_VERIFY_SERVER_CERT? TRUE:FALSE;
DBG_INF("Switching to SSL");
conn->net->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
if (FAIL == conn->net->m.enable_ssl(conn->net TSRMLS_CC)) {
goto err;
}
auth_packet->send_half_packet = FALSE;
if (!PACKET_WRITE(auth_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto err;
}
}
#endif
if (FAIL == PACKET_READ(ok_packet, conn) || ok_packet->field_count >= 0xFE) {
if (ok_packet->field_count == 0xFE) {
/* old authentication with new server !*/
@ -1178,6 +1192,18 @@ PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, size
}
/* }}} */
/* {{{ mysqlnd_conn::ssl_set */
void
MYSQLND_METHOD(mysqlnd_conn, ssl_set)(MYSQLND * const conn, const char * key, const char * const cert, const char * const ca, const char * const capath, const char * const cipher TSRMLS_DC)
{
conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_KEY, key TSRMLS_CC);
conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CERT, cert TSRMLS_CC);
conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CA, ca TSRMLS_CC);
conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CAPATH, capath TSRMLS_CC);
conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CIPHER, cipher TSRMLS_CC);
}
/* }}} */
/* {{{ mysqlnd_conn::escape_string */
static ulong
@ -1875,6 +1901,12 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
case MYSQL_OPT_READ_TIMEOUT:
case MYSQL_OPT_WRITE_TIMEOUT:
#endif
case MYSQLND_OPT_SSL_KEY:
case MYSQLND_OPT_SSL_CERT:
case MYSQLND_OPT_SSL_CA:
case MYSQLND_OPT_SSL_CAPATH:
case MYSQLND_OPT_SSL_CIPHER:
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
case MYSQL_OPT_CONNECT_TIMEOUT:
case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
@ -1913,7 +1945,6 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
#ifdef WHEN_SUPPORTED_BY_MYSQLI
case MYSQL_SET_CLIENT_IP:
case MYSQL_REPORT_DATA_TRUNCATION:
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
#endif
/* currently not supported. Todo!! */
break;
@ -2100,7 +2131,9 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn)
MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response),
MYSQLND_METHOD(mysqlnd_conn, restart_psession),
MYSQLND_METHOD(mysqlnd_conn, end_psession),
MYSQLND_METHOD(mysqlnd_conn, send_close)
MYSQLND_METHOD(mysqlnd_conn, send_close),
MYSQLND_METHOD(mysqlnd_conn, ssl_set)
MYSQLND_CLASS_METHODS_END;

View File

@ -172,6 +172,8 @@ PHPAPI unsigned long * _mysqlnd_fetch_lengths(MYSQLND_RES * const result TSRMLS
PHPAPI const char * mysqlnd_get_client_info();
PHPAPI unsigned int mysqlnd_get_client_version();
#define mysqlnd_ssl_set(conn, key, cert, ca, capath, cipher) (conn)->m->ssl_set((conn), (key), (cert), (ca), (capath), (cipher) TSRMLS_CC)
/* PS */
#define mysqlnd_stmt_insert_id(stmt) (stmt)->m->get_last_insert_id((stmt) TSRMLS_CC)
#define mysqlnd_stmt_affected_rows(stmt) (stmt)->m->get_affected_rows((stmt) TSRMLS_CC)

View File

@ -90,6 +90,8 @@
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
#define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
typedef enum mysqlnd_extension
{
MYSQLND_MYSQL = 0,
@ -156,6 +158,12 @@ typedef enum mysqlnd_option
#endif
MYSQLND_OPT_NET_CMD_BUFFER_SIZE = 202,
MYSQLND_OPT_NET_READ_BUFFER_SIZE = 203,
MYSQLND_OPT_SSL_KEY = 204,
MYSQLND_OPT_SSL_CERT = 205,
MYSQLND_OPT_SSL_CA = 206,
MYSQLND_OPT_SSL_CAPATH = 207,
MYSQLND_OPT_SSL_CIPHER = 208,
MYSQLND_OPT_SSL_PASSPHRASE = 209
} enum_mysqlnd_option;

View File

@ -79,6 +79,7 @@
#define mysql_set_server_option(r,o) mysqlnd_set_server_option((r), (o))
#define mysql_set_character_set(r,a) mysqlnd_set_character_set((r), (a))
#define mysql_sqlstate(r) mysqlnd_sqlstate((r))
#define mysql_ssl_set(c,key,cert,ca,capath,cipher) mysqlnd_ssl_set((c), (key), (cert), (ca), (capath), (cipher))
#define mysql_stmt_affected_rows(s) mysqlnd_stmt_affected_rows((s))
#define mysql_stmt_field_count(s) mysqlnd_stmt_field_count((s))
#define mysql_stmt_param_count(s) mysqlnd_stmt_param_count((s))

View File

@ -172,8 +172,8 @@ MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const schem
/* should always happen because read_timeout cannot be set via API */
net->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout);
}
if (net->options.timeout_read)
{
if (net->options.timeout_read) {
DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read);
tv.tv_sec = net->options.timeout_read;
tv.tv_usec = 0;
php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
@ -587,6 +587,63 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mys
DBG_INF("MYSQL_OPT_CONNECT_TIMEOUT");
net->options.timeout_connect = *(unsigned int*) value;
break;
case MYSQLND_OPT_SSL_KEY:
{
zend_bool pers = net->persistent;
if (net->options.ssl_key) {
mnd_pefree(net->options.ssl_key, pers);
}
net->options.ssl_key = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CERT:
{
zend_bool pers = net->persistent;
if (net->options.ssl_cert) {
mnd_pefree(net->options.ssl_cert, pers);
}
net->options.ssl_cert = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CA:
{
zend_bool pers = net->persistent;
if (net->options.ssl_ca) {
mnd_pefree(net->options.ssl_ca, pers);
}
net->options.ssl_ca = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CAPATH:
{
zend_bool pers = net->persistent;
if (net->options.ssl_capath) {
mnd_pefree(net->options.ssl_capath, pers);
}
net->options.ssl_capath = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CIPHER:
{
zend_bool pers = net->persistent;
if (net->options.ssl_cipher) {
mnd_pefree(net->options.ssl_cipher, pers);
}
net->options.ssl_cipher = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_PASSPHRASE:
{
zend_bool pers = net->persistent;
if (net->options.ssl_passphrase) {
mnd_pefree(net->options.ssl_passphrase, pers);
}
net->options.ssl_passphrase = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
net->options.ssl_verify_peer = value? ((*(zend_bool *)value)? TRUE:FALSE): FALSE;
break;
#ifdef WHEN_SUPPORTED_BY_MYSQLI
case MYSQL_OPT_READ_TIMEOUT:
DBG_INF("MYSQL_OPT_READ_TIMEOUT");
@ -657,12 +714,113 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum
}
/* }}} */
/*
in libmyusql, if cert and !key then key=cert
*/
/* {{{ mysqlnd_net::enable_ssl */
static enum_func_status
MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC)
{
#ifdef MYSQLND_SSL_SUPPORTED
php_stream_context *context = php_stream_context_alloc();
DBG_ENTER("mysqlnd_net::enable_ssl");
if (!context) {
DBG_RETURN(FAIL);
}
if (net->options.ssl_key) {
zval key_zval;
ZVAL_STRING(&key_zval, net->options.ssl_key, 0);
DBG_INF("key");
php_stream_context_set_option(context, "ssl", "local_pk", &key_zval);
}
if (net->options.ssl_verify_peer) {
zval verify_peer_zval;
ZVAL_TRUE(&verify_peer_zval);
DBG_INF("verify peer");
php_stream_context_set_option(context, "ssl", "verify_peer", &verify_peer_zval);
}
if (net->options.ssl_cert) {
zval cert_zval;
ZVAL_STRING(&cert_zval, net->options.ssl_cert, 0);
DBG_INF_FMT("local_cert=%s", net->options.ssl_cert);
php_stream_context_set_option(context, "ssl", "local_cert", &cert_zval);
if (!net->options.ssl_key) {
php_stream_context_set_option(context, "ssl", "local_pk", &cert_zval);
}
}
if (net->options.ssl_ca) {
zval cafile_zval;
ZVAL_STRING(&cafile_zval, net->options.ssl_ca, 0);
DBG_INF_FMT("cafile=%s", net->options.ssl_ca);
php_stream_context_set_option(context, "ssl", "cafile", &cafile_zval);
}
if (net->options.ssl_capath) {
zval capath_zval;
ZVAL_STRING(&capath_zval, net->options.ssl_capath, 0);
DBG_INF_FMT("capath=%s", net->options.ssl_capath);
php_stream_context_set_option(context, "ssl", "cafile", &capath_zval);
}
if (net->options.ssl_passphrase) {
zval passphrase_zval;
ZVAL_STRING(&passphrase_zval, net->options.ssl_passphrase, 0);
php_stream_context_set_option(context, "ssl", "passphrase", &passphrase_zval);
}
if (net->options.ssl_cipher) {
zval cipher_zval;
ZVAL_STRING(&cipher_zval, net->options.ssl_cipher, 0);
DBG_INF_FMT("ciphers=%s", net->options.ssl_cipher);
php_stream_context_set_option(context, "ssl", "ciphers", &cipher_zval);
}
php_stream_context_set(net->stream, context);
if (php_stream_xport_crypto_setup(net->stream, STREAM_CRYPTO_METHOD_TLS_CLIENT, NULL TSRMLS_CC) < 0 ||
php_stream_xport_crypto_enable(net->stream, 1 TSRMLS_CC) < 0)
{
DBG_ERR("Cannot connect to MySQL by using SSL");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot connect to MySQL by using SSL");
DBG_RETURN(FAIL);
}
/*
get rid of the context. we are persistent and if this is a real pconn used by mysql/mysqli,
then the context would not survive cleaning of EG(regular_list), where it is registered, as a
resource. What happens is that after this destruction any use of the network will mean usage
of the context, which means usage of already freed memory, bad. Actually we don't need this
context anymore after we have enabled SSL on the connection. Thus it is very simple, we remove it.
*/
php_stream_context_set(net->stream, NULL);
if (net->options.timeout_read) {
struct timeval tv;
DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read);
tv.tv_sec = net->options.timeout_read;
tv.tv_usec = 0;
php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
}
DBG_RETURN(PASS);
#else
DBG_ENTER("mysqlnd_net::enable_ssl");
DBG_RETURN(PASS);
#endif
}
/* }}} */
/* {{{ mysqlnd_net::disable_ssl */
static enum_func_status
MYSQLND_METHOD(mysqlnd_net, disable_ssl)(MYSQLND_NET * const net TSRMLS_DC)
{
DBG_ENTER("mysqlnd_net::disable_ssl");
DBG_RETURN(PASS);
}
/* }}} */
/* {{{ mysqlnd_net::set_client_option */
static void
MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC)
{
zend_bool pers = net->persistent;
DBG_ENTER("mysqlnd_net::free_contents");
#ifdef MYSQLND_COMPRESSION_ENABLED
@ -670,6 +828,27 @@ MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC)
net->uncompressed_data->free_buffer(&net->uncompressed_data TSRMLS_CC);
}
#endif
if (net->options.ssl_key) {
mnd_pefree(net->options.ssl_key, pers);
net->options.ssl_key = NULL;
}
if (net->options.ssl_cert) {
mnd_pefree(net->options.ssl_cert, pers);
net->options.ssl_cert = NULL;
}
if (net->options.ssl_ca) {
mnd_pefree(net->options.ssl_ca, pers);
net->options.ssl_ca = NULL;
}
if (net->options.ssl_capath) {
mnd_pefree(net->options.ssl_capath, pers);
net->options.ssl_capath = NULL;
}
if (net->options.ssl_cipher) {
mnd_pefree(net->options.ssl_cipher, pers);
net->options.ssl_cipher = NULL;
}
DBG_VOID_RETURN;
}
/* }}} */
@ -696,6 +875,8 @@ mysqlnd_net_init(zend_bool persistent TSRMLS_DC)
net->m.encode = MYSQLND_METHOD(mysqlnd_net, encode);
net->m.consume_uneaten_data = MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data);
net->m.free_contents = MYSQLND_METHOD(mysqlnd_net, free_contents);
net->m.enable_ssl = MYSQLND_METHOD(mysqlnd_net, enable_ssl);
net->m.disable_ssl = MYSQLND_METHOD(mysqlnd_net, disable_ssl);
{
unsigned int buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/

View File

@ -155,13 +155,17 @@ typedef struct st_mysqlnd_options
char *cfg_file;
char *cfg_section;
/* SSL information */
char *ssl_key;
char *ssl_cert;
char *ssl_ca;
char *ssl_capath;
char *ssl_cipher;
zend_bool use_ssl;
/*
We need to keep these because otherwise st_mysqlnd_conn will be changed.
The ABI will be broken and the methods structure will be somewhere else
in the memory which can crash external code. Feel free to reuse these.
*/
char * unused1;
char * unused2;
char * unused3;
char * unused4;
char * unused5;
zend_bool unused6;
char *charset_name;
/* maximum allowed packet size for communication */
@ -181,6 +185,15 @@ typedef struct st_mysqlnd_net_options
unsigned int timeout_write;
unsigned int net_read_buffer_size;
/* SSL information */
char *ssl_key;
char *ssl_cert;
char *ssl_ca;
char *ssl_capath;
char *ssl_cipher;
char *ssl_passphrase;
zend_bool ssl_verify_peer;
} MYSQLND_NET_OPTIONS;
@ -250,6 +263,8 @@ typedef enum_func_status (*func_mysqlnd_net__decode)(zend_uchar * uncompressed_d
typedef enum_func_status (*func_mysqlnd_net__encode)(zend_uchar * compress_buffer, size_t compress_buffer_len, const zend_uchar * const uncompressed_data, size_t uncompressed_data_len TSRMLS_DC);
typedef size_t (*func_mysqlnd_net__consume_uneaten_data)(MYSQLND_NET * const net, enum php_mysqlnd_server_command cmd TSRMLS_DC);
typedef void (*func_mysqlnd_net__free_contents)(MYSQLND_NET * net TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_net__enable_ssl)(MYSQLND_NET * const net TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_net__disable_ssl)(MYSQLND_NET * const net TSRMLS_DC);
struct st_mysqlnd_net_methods
@ -264,6 +279,8 @@ struct st_mysqlnd_net_methods
func_mysqlnd_net__encode encode;
func_mysqlnd_net__consume_uneaten_data consume_uneaten_data;
func_mysqlnd_net__free_contents free_contents;
func_mysqlnd_net__enable_ssl enable_ssl;
func_mysqlnd_net__disable_ssl disable_ssl;
};
@ -375,6 +392,8 @@ typedef enum_func_status (*func_mysqlnd_conn__restart_psession)(MYSQLND *conn TS
typedef enum_func_status (*func_mysqlnd_conn__end_psession)(MYSQLND *conn TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn__send_close)(MYSQLND * conn TSRMLS_DC);
typedef void (*func_mysqlnd_conn__ssl_set)(MYSQLND * const conn, const char * key, const char * const cert, const char * const ca, const char * const capath, const char * const cipher TSRMLS_DC);
struct st_mysqlnd_conn_methods
{
@ -443,6 +462,8 @@ struct st_mysqlnd_conn_methods
func_mysqlnd_conn__restart_psession restart_psession;
func_mysqlnd_conn__end_psession end_psession;
func_mysqlnd_conn__send_close send_close;
func_mysqlnd_conn__ssl_set ssl_set;
};

View File

@ -458,31 +458,33 @@ size_t php_mysqlnd_auth_write(void *_packet, MYSQLND *conn TSRMLS_DC)
memset(p, 0, 23); /* filler */
p+= 23;
len= strlen(packet->user);
memcpy(p, packet->user, len);
p+= len;
*p++ = '\0';
if (!packet->send_half_packet) {
len = strlen(packet->user);
memcpy(p, packet->user, len);
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, 20);
p++;
php_mysqlnd_scramble((zend_uchar*)p, packet->server_scramble_buf, (zend_uchar*)packet->password);
p+= 20;
} else {
/* Zero length */
int1store(p, 0);
p++;
}
/* 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, 20);
p++;
php_mysqlnd_scramble((zend_uchar*)p, packet->server_scramble_buf, (zend_uchar*)packet->password);
p+= 20;
} else {
/* Zero length */
int1store(p, 0);
p++;
}
if (packet->db) {
memcpy(p, packet->db, packet->db_len);
p+= packet->db_len;
*p++= '\0';
if (packet->db) {
memcpy(p, packet->db, packet->db_len);
p+= packet->db_len;
*p++= '\0';
}
/* Handle CLIENT_CONNECT_WITH_DB */
/* no \0 for no DB */
}
/* Handle CLIENT_CONNECT_WITH_DB */
/* no \0 for no DB */
DBG_RETURN(conn->net->m.send(conn, buffer, p - buffer - MYSQLND_HEADER_SIZE TSRMLS_CC));
}

View File

@ -101,6 +101,7 @@ typedef struct st_mysqlnd_packet_auth {
/* +1 for \0 because of scramble() */
unsigned char *server_scramble_buf;
size_t db_len;
zend_bool send_half_packet;
} MYSQLND_PACKET_AUTH;
/* OK packet */

View File

@ -107,6 +107,12 @@ PHP_MINFO_FUNCTION(mysqlnd)
"supported");
#else
"not supported");
#endif
php_info_print_table_row(2, "SSL",
#ifdef MYSQLND_SSL_SUPPORTED
"supported");
#else
"not supported");
#endif
snprintf(buf, sizeof(buf), "%ld", MYSQLND_G(net_cmd_buffer_size));
php_info_print_table_row(2, "Command buffer size", buf);

View File

@ -4433,7 +4433,9 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
if (!cipherlist) {
cipherlist = "DEFAULT";
}
SSL_CTX_set_cipher_list(ctx, cipherlist);
if (SSL_CTX_set_cipher_list(ctx, cipherlist) != 1) {
return NULL;
}
GET_VER_OPT_STRING("local_cert", certfile);
if (certfile) {
@ -4441,6 +4443,7 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
EVP_PKEY *key = NULL;
SSL *tmpssl;
char resolved_path_buff[MAXPATHLEN];
const char * private_key;
if (VCWD_REALPATH(certfile, resolved_path_buff)) {
/* a certificate to use for authentication */
@ -4449,8 +4452,10 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
return NULL;
}
if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
GET_VER_OPT_STRING("local_pk", private_key);
if (private_key && SSL_CTX_use_PrivateKey_file(ctx, private_key, SSL_FILETYPE_PEM) != 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", private_key);
return NULL;
}