You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
Fixed gnutls support
This commit is contained in:
@@ -152,8 +152,7 @@ IF(WITH_SSL STREQUAL "OPENSSL")
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
IF(OPENSSL_FOUND)
|
||||
ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_SSL)
|
||||
ADD_DEFINITIONS(-DSSL_PLUGIN=cio_openssl_plugin)
|
||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/plugins/builtin/cio_openssl.c")
|
||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/openssl.c")
|
||||
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
ELSE()
|
||||
MESSAGE(FATAL "OpenSSL not found")
|
||||
@@ -162,24 +161,23 @@ ENDIF()
|
||||
IF(WITH_SSL STREQUAL "GNUTLS")
|
||||
FIND_PACKAGE(GnuTLS)
|
||||
IF(GNUTLS_FOUND)
|
||||
ADD_DEFINITIONS(-DSSL_PLUGIN=cio_gnutls_plugin)
|
||||
ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_SSL)
|
||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/plugins/builtin/cio_gnutls.c")
|
||||
SET(SSL_LIBRARIES ${GNUTLS_LIBRARIES})
|
||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/gnutls.c")
|
||||
SET(SSL_LIBRARIES ${GNUTLS_LIBRARY})
|
||||
ELSE()
|
||||
MESSAGE(FATAL "GnuTLS not found")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(WIN32)
|
||||
IF(WITH_SSL STREQUAL "SCHANNEL")
|
||||
ADD_DEFINITIONS(-DSSL_PLUGIN=cio_schannel_plugin)
|
||||
MESSAGE(STATUS "SSL_TYPE ${SSL_TYPE}")
|
||||
ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_SSL)
|
||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/plugins/builtin/cio_schannel.c" "${CMAKE_SOURCE_DIR}/plugins/builtin/ma_schannel.c")
|
||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/schannel.c" "${CMAKE_SOURCE_DIR}/libmariadb/secure/ma_schannel.c")
|
||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/plugins/cio/")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(SSL_SOURCES)
|
||||
|
||||
|
||||
IF(WITH_SQLITE)
|
||||
@@ -206,7 +204,7 @@ IF(WIN32)
|
||||
ELSE()
|
||||
SET(SYSTEM_LIBS ${LIBPTHREAD} ${LIBDL} ${LIBM} ${LIBICONV})
|
||||
ENDIF()
|
||||
IF(OPENSSL_FOUND)
|
||||
IF(WITH_SSL)
|
||||
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${SSL_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
@@ -291,7 +289,7 @@ MESSAGE(STATUS "CPack generation: ${CPACK_GENERATOR}")
|
||||
IF(CLIENT_DOCS)
|
||||
MESSAGE(STATUS "Documentation included from ${CLIENT_DOCS}")
|
||||
ENDIF()
|
||||
MESSAGE(STATUS "SSL support: ${WITH_SSL} Sources: ${SSL_SOURCES}")
|
||||
MESSAGE(STATUS "SSL support: ${WITH_SSL} Libs: ${SSL_LIBRARIES}")
|
||||
MESSAGE(STATUS "Experimental Sqlite support: ${WITH_SQLITE}")
|
||||
IF(WITH_EXTERNAL_ZLIB)
|
||||
MESSAGE(STATUS "Zlib support: ${WITH_EXTERNAL_ZLIB}")
|
||||
|
126
include/ma_ssl.h
126
include/ma_ssl.h
@@ -1,10 +1,6 @@
|
||||
#ifndef _ma_ssl_h_
|
||||
#define _ma_ssl_h_
|
||||
|
||||
struct st_ma_cio_ssl_methods;
|
||||
typedef struct st_ma_cio_ssl_methods CIO_SSL_METHODS;
|
||||
extern int ssl_default_plugin;
|
||||
|
||||
enum enum_cio_ssl_type {
|
||||
SSL_TYPE_DEFAULT=0,
|
||||
#ifdef _WIN32
|
||||
@@ -16,23 +12,117 @@ enum enum_cio_ssl_type {
|
||||
|
||||
typedef struct st_ma_cio_ssl {
|
||||
void *data;
|
||||
enum enum_cio_ssl_type type;
|
||||
MARIADB_CIO *cio;
|
||||
CIO_SSL_METHODS *methods;
|
||||
void *ssl;
|
||||
} MARIADB_SSL;
|
||||
|
||||
struct st_ma_cio_ssl_methods
|
||||
{
|
||||
void *(*init)(MARIADB_SSL *cssl, MYSQL *mysql);
|
||||
my_bool (*connect)(MARIADB_SSL *cssl);
|
||||
size_t (*read)(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
size_t (*write)(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
my_bool (*close)(MARIADB_SSL *cssl);
|
||||
int (*verify_server_cert)(MARIADB_SSL *ssl);
|
||||
const char *(*cipher)(MARIADB_SSL *ssl);
|
||||
my_bool (*check_fp)(MARIADB_SSL *cssl, const char *fp);
|
||||
};
|
||||
/* Function prototypes */
|
||||
|
||||
/* ma_ssl_start
|
||||
initializes the ssl library
|
||||
Parameter:
|
||||
errmsg pointer to error message buffer
|
||||
errmsg_len length of error message buffer
|
||||
Returns:
|
||||
0 success
|
||||
1 if an error occured
|
||||
Notes:
|
||||
On success the global variable ma_ssl_initialized will be set to 1
|
||||
*/
|
||||
int ma_ssl_start(char *errmsg, size_t errmsg_len);
|
||||
|
||||
/* ma_ssl_end
|
||||
unloads/deinitializes ssl library and unsets global variable
|
||||
ma_ssl_initialized
|
||||
*/
|
||||
void ma_ssl_end(void);
|
||||
|
||||
/* ma_ssl_init
|
||||
creates a new SSL structure for a SSL connection and loads
|
||||
client certificates
|
||||
|
||||
Parameters:
|
||||
MYSQL a mysql structure
|
||||
Returns:
|
||||
void * a pointer to internal SSL structure
|
||||
*/
|
||||
void * ma_ssl_init(MYSQL *mysql);
|
||||
|
||||
/* ma_ssl_connect
|
||||
performs SSL handshake
|
||||
Parameters:
|
||||
MARIADB_SSL MariaDB SSL container
|
||||
Returns:
|
||||
0 success
|
||||
1 error
|
||||
*/
|
||||
my_bool ma_ssl_connect(MARIADB_SSL *cssl);
|
||||
|
||||
/* ma_ssl_read
|
||||
reads up to length bytes from socket
|
||||
Parameters:
|
||||
cssl MariaDB SSL container
|
||||
buffer read buffer
|
||||
length buffer length
|
||||
Returns:
|
||||
0-n bytes read
|
||||
-1 if an error occured
|
||||
*/
|
||||
size_t ma_ssl_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
|
||||
/* ma_ssl_write
|
||||
write buffer to socket
|
||||
Parameters:
|
||||
cssl MariaDB SSL container
|
||||
buffer write buffer
|
||||
length buffer length
|
||||
Returns:
|
||||
0-n bytes written
|
||||
-1 if an error occured
|
||||
*/
|
||||
size_t ma_ssl_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
|
||||
/* ma_ssl_close
|
||||
closes SSL connection and frees SSL structure which was previously
|
||||
created by ma_ssl_init call
|
||||
Parameters:
|
||||
MARIADB_SSL MariaDB SSL container
|
||||
Returns:
|
||||
0 success
|
||||
1 error
|
||||
*/
|
||||
my_bool ma_ssl_close(MARIADB_SSL *cssl);
|
||||
|
||||
/* ma_ssl_verify_server_cert
|
||||
validation check of server certificate
|
||||
Parameter:
|
||||
MARIADB_SSL MariaDB SSL container
|
||||
Returns:
|
||||
ß success
|
||||
1 error
|
||||
*/
|
||||
int ma_ssl_verify_server_cert(MARIADB_SSL *cssl);
|
||||
|
||||
/* ma_ssl_get_cipher
|
||||
returns cipher for current ssl connection
|
||||
Parameter:
|
||||
MARIADB_SSL MariaDB SSL container
|
||||
Returns:
|
||||
cipher in use or
|
||||
NULL on error
|
||||
*/
|
||||
const char *ma_ssl_get_cipher(MARIADB_SSL *ssl);
|
||||
|
||||
/* ma_ssl_get_finger_print
|
||||
returns SHA1 finger print of server certificate
|
||||
Parameter:
|
||||
MARIADB_SSL MariaDB SSL container
|
||||
fp buffer for fingerprint
|
||||
fp_len buffer length
|
||||
Returns:
|
||||
actual size of finger print
|
||||
*/
|
||||
unsigned int ma_ssl_get_finger_print(MARIADB_SSL *cssl, unsigned char *fp, unsigned int fp_len);
|
||||
|
||||
/* Function prototypes */
|
||||
MARIADB_SSL *ma_cio_ssl_init(MYSQL *mysql);
|
||||
@@ -42,6 +132,6 @@ size_t ma_cio_ssl_write(MARIADB_SSL *cssl, const uchar *buffer, size_t length);
|
||||
my_bool ma_cio_ssl_close(MARIADB_SSL *cssl);
|
||||
int ma_cio_ssl_verify_server_cert(MARIADB_SSL *cssl);
|
||||
const char *ma_cio_ssl_cipher(MARIADB_SSL *cssl);
|
||||
my_bool ma_cio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, size_t length);
|
||||
my_bool ma_cio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, const char *fp_list);
|
||||
|
||||
#endif /* _ma_ssl_h_ */
|
||||
|
@@ -325,11 +325,10 @@ client_plugin.c
|
||||
ma_io.c
|
||||
${CMAKE_SOURCE_DIR}/plugins/builtin/my_auth.c
|
||||
${CMAKE_SOURCE_DIR}/plugins/builtin/cio_socket.c
|
||||
${SSL_SOURCES}
|
||||
)
|
||||
|
||||
IF(SSL_SOURCES)
|
||||
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} ${SSL_SOURCES})
|
||||
ENDIF()
|
||||
MESSAGE(STATUS "${LIBMARIADB_SOURCES}")
|
||||
|
||||
IF(WIN32)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/win-iconv)
|
||||
|
@@ -84,18 +84,12 @@ extern struct st_mysql_client_plugin old_password_client_plugin;
|
||||
extern struct st_mysql_client_plugin native_password_client_plugin;
|
||||
|
||||
extern MARIADB_CIO_PLUGIN cio_socket_plugin;
|
||||
#ifdef HAVE_SSL
|
||||
extern MARIADB_CIO_PLUGIN SSL_PLUGIN;
|
||||
#endif
|
||||
|
||||
struct st_mysql_client_plugin *mysql_client_builtins[]=
|
||||
{
|
||||
(struct st_mysql_client_plugin *)&old_password_client_plugin,
|
||||
(struct st_mysql_client_plugin *)&native_password_client_plugin,
|
||||
(struct st_mysql_client_plugin *)&cio_socket_plugin,
|
||||
#ifdef HAVE_SSL
|
||||
(struct st_mysql_client_plugin *)&SSL_PLUGIN,
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
|
@@ -62,10 +62,10 @@
|
||||
#define INADDR_NONE -1
|
||||
#endif
|
||||
#include <sha1.h>
|
||||
#include <ma_cio.h>
|
||||
#ifndef _WIN32
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#include <ma_cio.h>
|
||||
#include <ma_dyncol.h>
|
||||
|
||||
#define ASYNC_CONTEXT_DEFAULT_STACK_SIZE (4096*15)
|
||||
|
@@ -116,7 +116,7 @@ MARIADB_CIO *ma_cio_init(MA_CIO_CINFO *cinfo)
|
||||
cio->methods->set_timeout(cio, CIO_WRITE_TIMEOUT, cinfo->mysql->options.write_timeout);
|
||||
}
|
||||
|
||||
if (!(cio->cache= my_malloc(CIO_READ_AHEAD_CACHE_SIZE, MYF(MY_WME))))
|
||||
if (!(cio->cache= my_malloc(CIO_READ_AHEAD_CACHE_SIZE, MYF(MY_ZEROFILL))))
|
||||
{
|
||||
CIO_SET_ERROR(cinfo->mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
||||
return NULL;
|
||||
@@ -405,7 +405,9 @@ my_bool ma_cio_start_ssl(MARIADB_CIO *cio)
|
||||
return 1;
|
||||
CLEAR_CLIENT_ERROR(cio->mysql);
|
||||
if (!(cio->cssl= ma_cio_ssl_init(cio->mysql)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (ma_cio_ssl_connect(cio->cssl))
|
||||
{
|
||||
my_free((gptr)cio->cssl);
|
||||
@@ -417,6 +419,16 @@ my_bool ma_cio_start_ssl(MARIADB_CIO *cio)
|
||||
ma_cio_ssl_verify_server_cert(cio->cssl))
|
||||
return 1;
|
||||
|
||||
if (cio->mysql->options.extension &&
|
||||
(cio->mysql->options.extension->ssl_fp || cio->mysql->options.extension->ssl_fp_list))
|
||||
{
|
||||
|
||||
if (ma_cio_ssl_check_fp(cio->cssl,
|
||||
cio->mysql->options.extension->ssl_fp,
|
||||
cio->mysql->options.extension->ssl_fp_list))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <ma_common.h>
|
||||
#include <string.h>
|
||||
//#include <ma_secure.h>
|
||||
#include <errmsg.h>
|
||||
#include <ma_cio.h>
|
||||
@@ -47,12 +48,15 @@
|
||||
*/
|
||||
|
||||
/* Errors should be handled via cio callback function */
|
||||
my_bool ma_ssl_initialized= FALSE;
|
||||
|
||||
MARIADB_SSL *ma_cio_ssl_init(MYSQL *mysql)
|
||||
{
|
||||
MARIADB_CIO_PLUGIN *cio_plugin;
|
||||
MARIADB_SSL *cssl= NULL;
|
||||
|
||||
if (!ma_ssl_initialized)
|
||||
ma_ssl_start(mysql->net.last_error, MYSQL_ERRMSG_SIZE);
|
||||
|
||||
if (!(cssl= (MARIADB_SSL *)my_malloc(sizeof(MARIADB_CIO),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
{
|
||||
@@ -60,63 +64,107 @@ MARIADB_SSL *ma_cio_ssl_init(MYSQL *mysql)
|
||||
}
|
||||
|
||||
/* register error routine and methods */
|
||||
cssl->methods= cio_plugin->ssl_methods;
|
||||
cssl->cio= mysql->net.cio;
|
||||
|
||||
if (!(cssl->ssl= cssl->methods->init(cssl, mysql)))
|
||||
if (!(cssl->ssl= ma_ssl_init(mysql)))
|
||||
{
|
||||
my_free((gptr)cssl);
|
||||
my_free(cssl);
|
||||
cssl= NULL;
|
||||
}
|
||||
return cssl;
|
||||
}
|
||||
|
||||
my_bool ma_cio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, size_t length)
|
||||
{
|
||||
if (cssl && cssl->methods->check_fp)
|
||||
return cssl->methods->check_fp(cssl, fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
my_bool ma_cio_ssl_connect(MARIADB_SSL *cssl)
|
||||
{
|
||||
if (cssl && cssl->methods->connect)
|
||||
return cssl->methods->connect(cssl);
|
||||
return 1;
|
||||
return ma_ssl_connect(cssl);
|
||||
}
|
||||
|
||||
size_t ma_cio_ssl_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
{
|
||||
if (cssl && cssl->methods->read)
|
||||
return cssl->methods->read(cssl, buffer, length);
|
||||
return -1;
|
||||
return ma_ssl_read(cssl, buffer, length);
|
||||
}
|
||||
|
||||
size_t ma_cio_ssl_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
{
|
||||
if (cssl && cssl->methods->write)
|
||||
return cssl->methods->write(cssl, buffer, length);
|
||||
return -1;
|
||||
return ma_ssl_write(cssl, buffer, length);
|
||||
}
|
||||
|
||||
my_bool ma_cio_ssl_close(MARIADB_SSL *cssl)
|
||||
{
|
||||
if (cssl && cssl->methods->close)
|
||||
return cssl->methods->close(cssl);
|
||||
return 1;
|
||||
return ma_ssl_close(cssl);
|
||||
}
|
||||
|
||||
int ma_cio_ssl_verify_server_cert(MARIADB_SSL *cssl)
|
||||
{
|
||||
if (cssl && cssl->methods->verify_server_cert)
|
||||
return cssl->methods->verify_server_cert(cssl);
|
||||
return 0;
|
||||
return ma_ssl_verify_server_cert(cssl);
|
||||
}
|
||||
|
||||
const char *ma_cio_ssl_cipher(MARIADB_SSL *cssl)
|
||||
{
|
||||
if (!cssl && !cssl->methods->cipher)
|
||||
return NULL;
|
||||
return cssl->methods->cipher(cssl);
|
||||
return ma_ssl_get_cipher(cssl);
|
||||
}
|
||||
|
||||
static my_bool ma_cio_ssl_compare_fp(char *fp1, unsigned int fp1_len,
|
||||
char *fp2, unsigned int fp2_len)
|
||||
{
|
||||
char hexstr[fp1_len * 2 + 1];
|
||||
|
||||
fp1_len= (unsigned int)mysql_hex_string(hexstr, fp1, fp1_len);
|
||||
if (strncasecmp(hexstr, fp2, fp1_len) != 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
my_bool ma_cio_ssl_check_fp(MARIADB_SSL *cssl, const char *fp, const char *fp_list)
|
||||
{
|
||||
unsigned int cert_fp_len= 64;
|
||||
unsigned char cert_fp[64];
|
||||
MYSQL *mysql;
|
||||
my_bool rc=1;
|
||||
|
||||
if (ma_ssl_get_finger_print(cssl, cert_fp, cert_fp_len) < 1)
|
||||
goto end;
|
||||
|
||||
if (fp)
|
||||
rc= ma_cio_ssl_compare_fp(cert_fp, cert_fp_len, fp, strlen(fp));
|
||||
else if (fp_list)
|
||||
{
|
||||
FILE *fp;
|
||||
char buff[255];
|
||||
|
||||
if (!(fp = fopen(fp_list, "r")))
|
||||
{
|
||||
/*
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Can't open finger print list");
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (fgets(buff, sizeof(buff)-1, fp))
|
||||
{
|
||||
/* remove trailing new line character */
|
||||
char *pos= strchr(buff, '\r');
|
||||
if (!pos)
|
||||
pos= strchr(buff, '\n');
|
||||
if (pos)
|
||||
*pos= '\0';
|
||||
|
||||
if (!ma_cio_ssl_compare_fp(cert_fp, cert_fp_len, buff, strlen(buff)))
|
||||
{
|
||||
/* finger print is valid: close file and exit */
|
||||
fclose(fp);
|
||||
rc= 0;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* No finger print matched - close file and return error */
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
@@ -164,7 +164,11 @@ static my_bool net_realloc(NET *net, size_t length)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
|
||||
if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length + 1, MYF(MY_WME))))
|
||||
/* reallocate buffer:
|
||||
size= pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE */
|
||||
if (!(buff=(uchar*) my_realloc((char*) net->buff,
|
||||
pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE,
|
||||
MYF(MY_WME))))
|
||||
{
|
||||
DBUG_PRINT("info", ("Out of memory"));
|
||||
net->error=1;
|
||||
|
@@ -29,53 +29,18 @@
|
||||
#include <my_pthread.h>
|
||||
#include <mysql/client_plugin.h>
|
||||
#include <string.h>
|
||||
#include <ma_ssl.h>
|
||||
|
||||
pthread_mutex_t LOCK_gnutls_config;
|
||||
static my_bool my_gnutls_initialized= FALSE;
|
||||
|
||||
static gnutls_certificate_credentials_t GNUTLS_xcred;
|
||||
extern my_bool ma_ssl_initialized;
|
||||
|
||||
static int my_verify_callback(gnutls_session_t ssl);
|
||||
|
||||
#define MAX_SSL_ERR_LEN 100
|
||||
|
||||
int cio_gnutls_start(char *errmsg, size_t errmsg_len, int count, va_list);
|
||||
int cio_gnutls_end();
|
||||
void *cio_gnutls_init(MARIADB_SSL *cssl, MYSQL *mysql);
|
||||
my_bool cio_gnutls_connect(MARIADB_SSL *cssl);
|
||||
size_t cio_gnutls_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
size_t cio_gnutls_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
my_bool cio_gnutls_close(MARIADB_SSL *cssl);
|
||||
int cio_gnutls_verify_server_cert(MARIADB_SSL *cssl);
|
||||
const char *cio_gnutls_cipher(MARIADB_SSL *cssl);
|
||||
static int my_verify_callback(gnutls_session_t ssl);
|
||||
|
||||
struct st_ma_cio_ssl_methods cio_gnutls_methods= {
|
||||
cio_gnutls_init,
|
||||
cio_gnutls_connect,
|
||||
cio_gnutls_read,
|
||||
cio_gnutls_write,
|
||||
cio_gnutls_close,
|
||||
cio_gnutls_verify_server_cert,
|
||||
cio_gnutls_cipher
|
||||
};
|
||||
|
||||
MARIADB_CIO_PLUGIN cio_gnutls_plugin=
|
||||
{
|
||||
MYSQL_CLIENT_CIO_PLUGIN,
|
||||
MYSQL_CLIENT_CIO_PLUGIN_INTERFACE_VERSION,
|
||||
"cio_gnutls",
|
||||
"Georg Richter",
|
||||
"MariaDB communication IO plugin for GnuTLS SSL communication",
|
||||
{1, 0, 0},
|
||||
"LGPL",
|
||||
NULL,
|
||||
cio_gnutls_start,
|
||||
cio_gnutls_end,
|
||||
NULL,
|
||||
&cio_gnutls_methods,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void cio_gnutls_set_error(MYSQL *mysql, int ssl_errno)
|
||||
static void ma_ssl_set_error(MYSQL *mysql, int ssl_errno)
|
||||
{
|
||||
char ssl_error[MAX_SSL_ERR_LEN];
|
||||
const char *ssl_error_reason;
|
||||
@@ -98,7 +63,7 @@ static void cio_gnutls_set_error(MYSQL *mysql, int ssl_errno)
|
||||
}
|
||||
|
||||
|
||||
static void cio_gnutls_get_error(char *errmsg, size_t length, int ssl_errno)
|
||||
static void ma_ssl_get_error(char *errmsg, size_t length, int ssl_errno)
|
||||
{
|
||||
const char *ssl_error_reason;
|
||||
|
||||
@@ -127,21 +92,21 @@ static void cio_gnutls_get_error(char *errmsg, size_t length, int ssl_errno)
|
||||
0 success
|
||||
1 error
|
||||
*/
|
||||
int cio_gnutls_start(char *errmsg, size_t errmsg_len, int count, va_list list)
|
||||
int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
||||
{
|
||||
int rc= 0;
|
||||
|
||||
pthread_mutex_init(&LOCK_gnutls_config,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_lock(&LOCK_gnutls_config);
|
||||
|
||||
if (!my_gnutls_initialized)
|
||||
if (!ma_ssl_initialized)
|
||||
{
|
||||
if ((rc= gnutls_global_init()) != GNUTLS_E_SUCCESS)
|
||||
{
|
||||
cio_gnutls_get_error(errmsg, errmsg_len, rc);
|
||||
ma_ssl_get_error(errmsg, errmsg_len, rc);
|
||||
goto end;
|
||||
}
|
||||
my_gnutls_initialized= TRUE;
|
||||
ma_ssl_initialized= TRUE;
|
||||
}
|
||||
/* Allocate a global context for credentials */
|
||||
rc= gnutls_certificate_allocate_credentials(&GNUTLS_xcred);
|
||||
@@ -162,10 +127,10 @@ end:
|
||||
RETURN VALUES
|
||||
void
|
||||
*/
|
||||
int cio_gnutls_end()
|
||||
void ma_ssl_end()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_gnutls_config);
|
||||
if (my_gnutls_initialized)
|
||||
if (ma_ssl_initialized)
|
||||
{
|
||||
gnutls_certificate_free_keys(GNUTLS_xcred);
|
||||
gnutls_certificate_free_cas(GNUTLS_xcred);
|
||||
@@ -173,14 +138,14 @@ int cio_gnutls_end()
|
||||
gnutls_certificate_free_ca_names(GNUTLS_xcred);
|
||||
gnutls_certificate_free_credentials(GNUTLS_xcred);
|
||||
gnutls_global_deinit();
|
||||
my_gnutls_initialized= FALSE;
|
||||
ma_ssl_initialized= FALSE;
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_gnutls_config);
|
||||
pthread_mutex_destroy(&LOCK_gnutls_config);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int cio_gnutls_set_certs(MYSQL *mysql, MARIADB_SSL *cssl)
|
||||
static int ma_ssl_set_certs(MYSQL *mysql)
|
||||
{
|
||||
char *certfile= mysql->options.ssl_cert,
|
||||
*keyfile= mysql->options.ssl_key;
|
||||
@@ -218,11 +183,11 @@ static int cio_gnutls_set_certs(MYSQL *mysql, MARIADB_SSL *cssl)
|
||||
|
||||
error:
|
||||
if (cipher)
|
||||
my_free(cipher));
|
||||
my_free(cipher);
|
||||
return ssl_error;
|
||||
}
|
||||
|
||||
void *cio_gnutls_init(MARIADB_SSL *cssl, MYSQL *mysql)
|
||||
void *ma_ssl_init(MYSQL *mysql)
|
||||
{
|
||||
gnutls_session_t ssl= NULL;
|
||||
int ssl_error= 0;
|
||||
@@ -230,7 +195,7 @@ void *cio_gnutls_init(MARIADB_SSL *cssl, MYSQL *mysql)
|
||||
|
||||
pthread_mutex_lock(&LOCK_gnutls_config);
|
||||
|
||||
if ((ssl_error= cio_gnutls_set_certs(mysql, cssl)) < 0)
|
||||
if ((ssl_error= ma_ssl_set_certs(mysql)) < 0)
|
||||
goto error;
|
||||
|
||||
if ((ssl_error = gnutls_init(&ssl, GNUTLS_CLIENT & GNUTLS_NONBLOCK)) < 0)
|
||||
@@ -244,18 +209,17 @@ void *cio_gnutls_init(MARIADB_SSL *cssl, MYSQL *mysql)
|
||||
if ((ssl_error= gnutls_credentials_set(ssl, GNUTLS_CRD_CERTIFICATE, GNUTLS_xcred)) < 0)
|
||||
goto error;
|
||||
|
||||
cssl->ssl= ssl;
|
||||
pthread_mutex_unlock(&LOCK_gnutls_config);
|
||||
return (void *)ssl;
|
||||
error:
|
||||
cio_gnutls_set_error(mysql, ssl_error);
|
||||
ma_ssl_set_error(mysql, ssl_error);
|
||||
if (ssl)
|
||||
gnutls_deinit(ssl);
|
||||
pthread_mutex_unlock(&LOCK_gnutls_config);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
my_bool cio_gnutls_connect(MARIADB_SSL *cssl)
|
||||
my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
||||
{
|
||||
gnutls_session_t ssl = (gnutls_session_t)cssl->ssl;
|
||||
my_bool blocking;
|
||||
@@ -273,7 +237,7 @@ my_bool cio_gnutls_connect(MARIADB_SSL *cssl)
|
||||
if (!(blocking= cio->methods->is_blocking(cio)))
|
||||
cio->methods->blocking(cio, TRUE, 0);
|
||||
|
||||
gnutls_transport_set_int(ssl, cio->methods->get_socket(cio));
|
||||
gnutls_transport_set_int(ssl, mysql_get_socket(mysql));
|
||||
gnutls_handshake_set_timeout(ssl, mysql->options.connect_timeout);
|
||||
|
||||
do {
|
||||
@@ -282,7 +246,7 @@ my_bool cio_gnutls_connect(MARIADB_SSL *cssl)
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
cio_gnutls_set_error(mysql, ret);
|
||||
ma_ssl_set_error(mysql, ret);
|
||||
/* restore blocking mode */
|
||||
if (!blocking)
|
||||
cio->methods->blocking(cio, FALSE, 0);
|
||||
@@ -293,17 +257,17 @@ my_bool cio_gnutls_connect(MARIADB_SSL *cssl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t cio_gnutls_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
size_t ma_ssl_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
{
|
||||
return gnutls_record_recv((gnutls_session_t )cssl->ssl, (void *)buffer, length);
|
||||
}
|
||||
|
||||
size_t cio_gnutls_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
size_t ma_ssl_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
{
|
||||
return gnutls_record_send((gnutls_session_t )cssl->ssl, (void *)buffer, length);
|
||||
}
|
||||
|
||||
my_bool cio_gnutls_close(MARIADB_SSL *cssl)
|
||||
my_bool ma_ssl_close(MARIADB_SSL *cssl)
|
||||
{
|
||||
gnutls_bye((gnutls_session_t )cssl->ssl, GNUTLS_SHUT_WR);
|
||||
gnutls_deinit((gnutls_session_t )cssl->ssl);
|
||||
@@ -312,13 +276,13 @@ my_bool cio_gnutls_close(MARIADB_SSL *cssl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cio_gnutls_verify_server_cert(MARIADB_SSL *cssl)
|
||||
int ma_ssl_verify_server_cert(MARIADB_SSL *cssl)
|
||||
{
|
||||
/* server verification is already handled before */
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *cio_gnutls_cipher(MARIADB_SSL *cssl)
|
||||
const char *ma_ssl_get_cipher(MARIADB_SSL *cssl)
|
||||
{
|
||||
if (!cssl || !cssl->ssl)
|
||||
return NULL;
|
||||
@@ -390,7 +354,6 @@ static int my_verify_callback(gnutls_session_t ssl)
|
||||
if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
|
||||
gnutls_x509_crt_check_hostname (cert, hostname) < 0)
|
||||
{
|
||||
printf("Error: %s does not match\n", hostname);
|
||||
gnutls_x509_crt_deinit (cert);
|
||||
cio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Hostname in certificate doesn't match");
|
||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||
@@ -402,4 +365,36 @@ static int my_verify_callback(gnutls_session_t ssl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int ma_ssl_get_finger_print(MARIADB_SSL *cssl, unsigned char *fp, unsigned int len)
|
||||
{
|
||||
MYSQL *mysql;
|
||||
size_t fp_len= len;
|
||||
const gnutls_datum_t *cert_list;
|
||||
unsigned int cert_list_size;
|
||||
|
||||
if (!cssl || !cssl->ssl)
|
||||
return 0;
|
||||
|
||||
mysql= (MYSQL *)gnutls_session_get_ptr(cssl->ssl);
|
||||
|
||||
cert_list = gnutls_certificate_get_peers (cssl->ssl, &cert_list_size);
|
||||
if (cert_list == NULL)
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Unable to get server certificate");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gnutls_fingerprint(GNUTLS_DIG_MD5, &cert_list[0], fp, &fp_len) > 0)
|
||||
return fp_len;
|
||||
else
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Finger print buffer too small");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_GNUTLS */
|
@@ -22,6 +22,7 @@
|
||||
#include <ma_common.h>
|
||||
#include <ma_cio.h>
|
||||
#include <errmsg.h>
|
||||
#include <string.h>
|
||||
#include <mysql/client_plugin.h>
|
||||
#include <string.h>
|
||||
#include <openssl/ssl.h> /* SSL and SSL_CTX */
|
||||
@@ -32,14 +33,14 @@
|
||||
#include <memory.h>
|
||||
#define my_malloc(A,B) malloc((A))
|
||||
#undef my_free
|
||||
#define my_free(A,B) free((A))
|
||||
#define my_free(A) free((A))
|
||||
#define my_snprintf snprintf
|
||||
#define my_vsnprintf vsnprintf
|
||||
#undef SAFE_MUTEX
|
||||
#endif
|
||||
#include <my_pthread.h>
|
||||
|
||||
static my_bool my_openssl_initialized= FALSE;
|
||||
extern my_bool ma_ssl_initialized;
|
||||
static SSL_CTX *SSL_context= NULL;
|
||||
|
||||
#define MAX_SSL_ERR_LEN 100
|
||||
@@ -47,43 +48,8 @@ static SSL_CTX *SSL_context= NULL;
|
||||
static pthread_mutex_t LOCK_openssl_config;
|
||||
static pthread_mutex_t *LOCK_crypto= NULL;
|
||||
|
||||
int cio_openssl_start(char *errmsg, size_t errmsg_len, int count, va_list);
|
||||
int cio_openssl_end();
|
||||
void *cio_openssl_init(MARIADB_SSL *cssl, MYSQL *mysql);
|
||||
my_bool cio_openssl_connect(MARIADB_SSL *cssl);
|
||||
size_t cio_openssl_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
size_t cio_openssl_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length);
|
||||
my_bool cio_openssl_close(MARIADB_SSL *cssl);
|
||||
int cio_openssl_verify_server_cert(MARIADB_SSL *cssl);
|
||||
const char *cio_openssl_cipher(MARIADB_SSL *cssl);
|
||||
|
||||
struct st_ma_cio_ssl_methods cio_openssl_methods= {
|
||||
cio_openssl_init,
|
||||
cio_openssl_connect,
|
||||
cio_openssl_read,
|
||||
cio_openssl_write,
|
||||
cio_openssl_close,
|
||||
cio_openssl_verify_server_cert,
|
||||
cio_openssl_cipher
|
||||
};
|
||||
|
||||
MARIADB_CIO_PLUGIN cio_openssl_plugin=
|
||||
{
|
||||
MYSQL_CLIENT_CIO_PLUGIN,
|
||||
MYSQL_CLIENT_CIO_PLUGIN_INTERFACE_VERSION,
|
||||
"cio_openssl",
|
||||
"Georg Richter",
|
||||
"MariaDB communication IO plugin for OpenSSL communication",
|
||||
{1, 0, 0},
|
||||
"LGPL",
|
||||
cio_openssl_start,
|
||||
cio_openssl_end,
|
||||
NULL,
|
||||
&cio_openssl_methods,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void cio_openssl_set_error(MYSQL *mysql)
|
||||
static void ma_ssl_set_error(MYSQL *mysql)
|
||||
{
|
||||
ulong ssl_errno= ERR_get_error();
|
||||
char ssl_error[MAX_SSL_ERR_LEN];
|
||||
@@ -107,7 +73,7 @@ static void cio_openssl_set_error(MYSQL *mysql)
|
||||
}
|
||||
|
||||
|
||||
static void cio_openssl_get_error(char *errmsg, size_t length)
|
||||
static void ma_ssl_get_error(char *errmsg, size_t length)
|
||||
{
|
||||
ulong ssl_errno= ERR_get_error();
|
||||
const char *ssl_error_reason;
|
||||
@@ -189,13 +155,13 @@ static int ssl_thread_init()
|
||||
0 success
|
||||
1 error
|
||||
*/
|
||||
int cio_openssl_start(char *errmsg, size_t errmsg_len, int count, va_list list)
|
||||
int ma_ssl_start(char *errmsg, size_t errmsg_len)
|
||||
{
|
||||
int rc= 1;
|
||||
/* lock mutex to prevent multiple initialization */
|
||||
pthread_mutex_init(&LOCK_openssl_config,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_lock(&LOCK_openssl_config);
|
||||
if (!my_openssl_initialized)
|
||||
if (!ma_ssl_initialized)
|
||||
{
|
||||
if (ssl_thread_init())
|
||||
{
|
||||
@@ -214,11 +180,11 @@ int cio_openssl_start(char *errmsg, size_t errmsg_len, int count, va_list list)
|
||||
|
||||
if (!(SSL_context= SSL_CTX_new(TLSv1_client_method())))
|
||||
{
|
||||
cio_openssl_get_error(errmsg, errmsg_len);
|
||||
ma_ssl_get_error(errmsg, errmsg_len);
|
||||
goto end;
|
||||
}
|
||||
rc= 0;
|
||||
my_openssl_initialized= TRUE;
|
||||
ma_ssl_initialized= TRUE;
|
||||
}
|
||||
end:
|
||||
pthread_mutex_unlock(&LOCK_openssl_config);
|
||||
@@ -237,10 +203,10 @@ end:
|
||||
RETURN VALUES
|
||||
void
|
||||
*/
|
||||
int cio_openssl_end()
|
||||
void ma_ssl_end()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_openssl_config);
|
||||
if (my_openssl_initialized)
|
||||
if (ma_ssl_initialized)
|
||||
{
|
||||
int i;
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
@@ -249,7 +215,7 @@ int cio_openssl_end()
|
||||
for (i=0; i < CRYPTO_num_locks(); i++)
|
||||
pthread_mutex_destroy(&LOCK_crypto[i]);
|
||||
|
||||
my_free((gptr)LOCK_crypto, MYF(0));
|
||||
my_free((gptr)LOCK_crypto);
|
||||
LOCK_crypto= NULL;
|
||||
|
||||
if (SSL_context)
|
||||
@@ -265,14 +231,14 @@ int cio_openssl_end()
|
||||
CONF_modules_free();
|
||||
CONF_modules_unload(1);
|
||||
sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
|
||||
my_openssl_initialized= FALSE;
|
||||
ma_ssl_initialized= FALSE;
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_openssl_config);
|
||||
pthread_mutex_destroy(&LOCK_openssl_config);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int cio_openssl_set_certs(MYSQL *mysql)
|
||||
static int ma_ssl_set_certs(MYSQL *mysql)
|
||||
{
|
||||
char *certfile= mysql->options.ssl_cert,
|
||||
*keyfile= mysql->options.ssl_key;
|
||||
@@ -331,7 +297,7 @@ static int cio_openssl_set_certs(MYSQL *mysql)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cio_openssl_set_error(mysql);
|
||||
ma_ssl_set_error(mysql);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -364,14 +330,17 @@ static int my_verify_callback(int ok, X509_STORE_CTX *ctx)
|
||||
return ok;
|
||||
}
|
||||
|
||||
void *cio_openssl_init(MARIADB_SSL *cssl, MYSQL *mysql)
|
||||
void *ma_ssl_init(MYSQL *mysql)
|
||||
{
|
||||
int verify;
|
||||
SSL *ssl= NULL;
|
||||
|
||||
pthread_mutex_lock(&LOCK_openssl_config);
|
||||
if (cio_openssl_set_certs(mysql))
|
||||
|
||||
if (ma_ssl_set_certs(mysql))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(ssl= SSL_new(SSL_context)))
|
||||
goto error;
|
||||
@@ -394,12 +363,13 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
my_bool cio_openssl_connect(MARIADB_SSL *cssl)
|
||||
my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
||||
{
|
||||
SSL *ssl = (SSL *)cssl->ssl;
|
||||
my_bool blocking;
|
||||
MYSQL *mysql;
|
||||
MARIADB_CIO *cio;
|
||||
int rc;
|
||||
|
||||
mysql= (MYSQL *)SSL_get_app_data(ssl);
|
||||
cio= mysql->net.cio;
|
||||
@@ -415,28 +385,40 @@ my_bool cio_openssl_connect(MARIADB_SSL *cssl)
|
||||
|
||||
if (SSL_connect(ssl) != 1)
|
||||
{
|
||||
cio_openssl_set_error(mysql);
|
||||
ma_ssl_set_error(mysql);
|
||||
/* restore blocking mode */
|
||||
if (!blocking)
|
||||
cio->methods->blocking(cio, FALSE, 0);
|
||||
return 1;
|
||||
}
|
||||
rc= SSL_get_verify_result(ssl);
|
||||
if (rc != X509_V_OK)
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc));
|
||||
/* restore blocking mode */
|
||||
if (!blocking)
|
||||
cio->methods->blocking(cio, FALSE, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
cio->cssl->ssl= cssl->ssl= (void *)ssl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t cio_openssl_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
size_t ma_ssl_read(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
{
|
||||
return SSL_read((SSL *)cssl->ssl, (void *)buffer, (int)length);
|
||||
}
|
||||
|
||||
size_t cio_openssl_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
size_t ma_ssl_write(MARIADB_SSL *cssl, const uchar* buffer, size_t length)
|
||||
{
|
||||
return SSL_write((SSL *)cssl->ssl, (void *)buffer, (int)length);
|
||||
}
|
||||
|
||||
my_bool cio_openssl_close(MARIADB_SSL *cssl)
|
||||
my_bool ma_ssl_close(MARIADB_SSL *cssl)
|
||||
{
|
||||
int i, rc;
|
||||
SSL *ssl;
|
||||
@@ -457,7 +439,7 @@ my_bool cio_openssl_close(MARIADB_SSL *cssl)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cio_openssl_verify_server_cert(MARIADB_SSL *cssl)
|
||||
int ma_ssl_verify_server_cert(MARIADB_SSL *cssl)
|
||||
{
|
||||
X509 *cert;
|
||||
MYSQL *mysql;
|
||||
@@ -504,9 +486,48 @@ int cio_openssl_verify_server_cert(MARIADB_SSL *cssl)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *cio_openssl_cipher(MARIADB_SSL *cssl)
|
||||
const char *ma_ssl_get_cipher(MARIADB_SSL *cssl)
|
||||
{
|
||||
if (!cssl || !cssl->ssl)
|
||||
return NULL;
|
||||
return SSL_get_cipher_name(cssl->ssl);
|
||||
}
|
||||
|
||||
unsigned int ma_ssl_get_finger_print(MARIADB_SSL *cssl, unsigned char *fp, unsigned int len)
|
||||
{
|
||||
EVP_MD *digest= (EVP_MD *)EVP_sha1();
|
||||
X509 *cert;
|
||||
MYSQL *mysql;
|
||||
unsigned int *fp_len;
|
||||
|
||||
if (!cssl || !cssl->ssl)
|
||||
return NULL;
|
||||
|
||||
mysql= SSL_get_app_data(cssl->ssl);
|
||||
|
||||
if (!(cert= SSL_get_peer_certificate(cssl->ssl)))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Unable to get server certificate");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len < EVP_MAX_MD_SIZE)
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Finger print buffer too small");
|
||||
return 0;
|
||||
}
|
||||
*fp_len= len;
|
||||
if (!X509_digest(cert, digest, fp, fp_len))
|
||||
{
|
||||
my_free(fp);
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"invalid finger print of server certificate");
|
||||
return 0;
|
||||
}
|
||||
return (*fp_len);
|
||||
}
|
@@ -243,6 +243,22 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
|
||||
if (mpvio->db)
|
||||
mysql->client_flag|= CLIENT_CONNECT_WITH_DB;
|
||||
|
||||
/* if server doesn't support SSL and verification of server certificate
|
||||
was set to mandatory, we need to return an error */
|
||||
if (mysql->options.use_ssl && !(mysql->server_capabilities & CLIENT_SSL))
|
||||
{
|
||||
if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) ||
|
||||
(mysql->options.extension && (mysql->options.extension->ssl_fp ||
|
||||
mysql->options.extension->ssl_fp_list)))
|
||||
{
|
||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||
ER(CR_SSL_CONNECTION_ERROR),
|
||||
"Server doesn't support SSL");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Remove options that server doesn't support */
|
||||
mysql->client_flag= mysql->client_flag &
|
||||
(~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)
|
||||
|
@@ -53,6 +53,7 @@ MARIADB_CIO_PLUGIN _mysql_client_plugin_declaration_ =
|
||||
"Georg Richter",
|
||||
"MariaDB communication IO plugin for named pipe communication",
|
||||
{1, 0, 0},
|
||||
"LGPL",
|
||||
NULL,
|
||||
NULL,
|
||||
&cio_npipe_methods,
|
||||
|
@@ -59,6 +59,7 @@ MARIADB_CIO_PLUGIN _mysql_client_plugin_declaration_ =
|
||||
"Georg Richter",
|
||||
"MariaDB communication IO plugin for named pipe communication",
|
||||
{1, 0, 0},
|
||||
"LGPL",
|
||||
NULL,
|
||||
NULL,
|
||||
&cio_shm_methods,
|
||||
|
Binary file not shown.
@@ -25,7 +25,7 @@ SET(API_TESTS "async" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view
|
||||
"sp" "result" "connection" "misc" "ps_new" "sqlite3" "thread" "dyncol")
|
||||
|
||||
# Get finger print from server certificate
|
||||
IF(WITH_OPENSSL)
|
||||
IF(WITH_SSL)
|
||||
|
||||
#create certificates
|
||||
IF(EXISTS "${CMAKE_SOURCE_DIR}/unittest/libmariadb/certs/server-cert.pem")
|
||||
|
@@ -33,8 +33,8 @@ pthread_mutex_t LOCK_test;
|
||||
|
||||
int check_skip_ssl()
|
||||
{
|
||||
#ifndef HAVE_OPENSSL
|
||||
diag("client library built without OpenSSL support -> skip");
|
||||
#ifndef HAVE_SSL
|
||||
diag("client library built without SSL support -> skip");
|
||||
return 1;
|
||||
#endif
|
||||
if (skip_ssl)
|
||||
@@ -92,7 +92,11 @@ static int test_ssl_cipher(MYSQL *unused)
|
||||
port, socketname, 0), mysql_error(my));
|
||||
|
||||
cipher= (char *)mysql_get_ssl_cipher(my);
|
||||
#ifdef HAVE_OPENSSL
|
||||
FAIL_IF(strcmp(cipher, "DHE-RSA-AES256-SHA") != 0, "Cipher != DHE-RSA-AES256-SHA");
|
||||
#elif defined(HAVE_HNUTLS)
|
||||
FAIL_IF(strcmp(cipher, "AES-256-CBC") != 0, "Cipher != AES-256-CBC");
|
||||
#endif
|
||||
mysql_close(my);
|
||||
return OK;
|
||||
}
|
||||
@@ -174,7 +178,11 @@ static int test_multi_ssl_connections(MYSQL *unused)
|
||||
}
|
||||
|
||||
cipher= (char *)mysql_get_ssl_cipher(mysql[i]);
|
||||
#ifdef HAVE_OPENSSL
|
||||
FAIL_IF(strcmp(cipher, "DHE-RSA-AES256-SHA") != 0, "Cipher != DHE-RSA-AES256-SHA");
|
||||
#elif defined(HAVE_HNUTLS)
|
||||
FAIL_IF(strcmp(cipher, "AES-256-CBC") != 0, "Cipher != AES-256-CBC");
|
||||
#endif
|
||||
}
|
||||
for (i=0; i < 50; i++)
|
||||
mysql_close(mysql[i]);
|
||||
@@ -637,7 +645,11 @@ static int test_ssl_fp(MYSQL *unused)
|
||||
port, socketname, 0), mysql_error(my));
|
||||
|
||||
cipher= (char *)mysql_get_ssl_cipher(my);
|
||||
#ifdef HAVE_OPENSSL
|
||||
FAIL_IF(strcmp(cipher, "DHE-RSA-AES256-SHA") != 0, "Cipher != DHE-RSA-AES256-SHA");
|
||||
#elif defined(HAVE_HNUTLS)
|
||||
FAIL_IF(strcmp(cipher, "AES-256-CBC") != 0, "Cipher != AES-256-CBC");
|
||||
#endif
|
||||
mysql_close(my);
|
||||
return OK;
|
||||
}
|
||||
@@ -660,8 +672,11 @@ static int test_ssl_fp_list(MYSQL *unused)
|
||||
FAIL_IF(!mysql_real_connect(my, hostname, ssluser, sslpw, schema,
|
||||
port, socketname, 0), mysql_error(my));
|
||||
|
||||
cipher= (char *)mysql_get_ssl_cipher(my);
|
||||
#ifdef HAVE_OPENSSL
|
||||
FAIL_IF(strcmp(cipher, "DHE-RSA-AES256-SHA") != 0, "Cipher != DHE-RSA-AES256-SHA");
|
||||
#elif defined(HAVE_HNUTLS)
|
||||
FAIL_IF(strcmp(cipher, "AES-256-CBC") != 0, "Cipher != AES-256-CBC");
|
||||
#endif
|
||||
mysql_close(my);
|
||||
return OK;
|
||||
}
|
||||
|
Reference in New Issue
Block a user