/* {{{ 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;
RETURN_TRUE;
}
-#endif
/* }}} */
/* {{{ proto mixed mysqli_stat(object link)
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)
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)
'select_db' => true,
'set_charset' => true,
'set_opt' => true,
+ 'ssl_set' => true,
'stat' => true,
'stmt_init' => true,
'store_result' => true,
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
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
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 */
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);
}
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;
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 !*/
}
/* }}} */
+/* {{{ 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
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:
#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;
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;
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)
#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,
#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;
#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))
/* 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);
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");
}
/* }}} */
+/*
+ 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
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;
}
/* }}} */
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*/
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 */
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;
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
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;
};
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
{
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;
};
memset(p, 0, 23); /* filler */
p+= 23;
- 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++;
- }
+ 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++;
+ }
- 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));
}
/* +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 */
"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);
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) {
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 */
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;
}