summaryrefslogtreecommitdiff
path: root/ext/mysqlnd/mysqlnd.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mysqlnd/mysqlnd.c')
-rw-r--r--ext/mysqlnd/mysqlnd.c85
1 files changed, 59 insertions, 26 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index 078d2e6afa..bb26c4cd5c 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -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;