1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-08 14:02:17 +03:00

Added new option MARIADB_OPT_SSL_PASSWORD which allows use of

decrypted client certificate (private key only).
Currently this option is supported by GnuTLS and OpenSSL only
This commit is contained in:
Georg Richter
2015-11-13 12:41:29 +01:00
parent b936015139
commit 32f1903f97
8 changed files with 142 additions and 89 deletions

View File

@@ -674,7 +674,7 @@ static int test_wrong_bind_address(MYSQL *my)
char *bind_addr= "100.188.111.112";
MYSQL *mysql;
if (!strcmp(hostname, "localhost"))
if (!hostname || !strcmp(hostname, "localhost"))
{
diag("test doesn't work with unix sockets");
return SKIP;
@@ -702,7 +702,7 @@ static int test_bind_address(MYSQL *my)
char query[128];
int rc;
if (!strcmp(hostname, "localhost"))
if (!hostname || !strcmp(hostname, "localhost"))
{
diag("test doesn't work with unix sockets");
return SKIP;

View File

@@ -28,13 +28,14 @@ static int skip_ssl= 1;
const char *ssluser= "ssluser";
const char *sslpw= "sslpw";
char sslhost[128];
pthread_mutex_t LOCK_test;
int check_skip_ssl()
{
#ifndef HAVE_SSL
diag("client library built without SSL support -> skip");
diag("client library built without OpenSSL support -> skip");
return 1;
#endif
if (skip_ssl)
@@ -45,19 +46,58 @@ int check_skip_ssl()
return 0;
}
static int check_cipher(MYSQL *mysql)
{
char *cipher= (char *)mysql_get_ssl_cipher(mysql);
if (!cipher)
return 1;
#ifdef HAVE_GNUTLS
return strcmp(cipher, "AES-128-GCM");
#endif
#ifdef HAVE_OPENSSL
return strcmp(cipher, "DHE-RSA-AES256-SHA");
#endif
}
static int create_ssl_user(const char *ssluser, my_bool is_X509)
{
int rc;
char query[1024];
MYSQL *mysql= mysql_init(NULL);
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
port, socketname, 0), mysql_error(mysql));
sprintf(query, "DROP USER IF EXISTS '%s'@'%s'", ssluser, sslhost);
rc= mysql_query(mysql, query);
check_mysql_rc(rc,mysql);
sprintf(query, "CREATE USER '%s'@'%s' IDENTIFIED BY '%s'", ssluser, sslhost, sslpw);
rc= mysql_query(mysql, query);
check_mysql_rc(rc,mysql);
sprintf(query, "GRANT ALL ON %s.* TO '%s'@'%s' REQUIRE %s", schema, ssluser, sslhost, is_X509 ? "X509" : "SSL");
rc= mysql_query(mysql, query);
check_mysql_rc(rc,mysql);
rc= mysql_query(mysql, "FLUSH PRIVILEGES");
check_mysql_rc(rc,mysql);
return rc;
}
static int test_ssl(MYSQL *mysql)
{
int rc;
MYSQL_RES *res;
MYSQL_ROW row;
rc= mysql_query(mysql, "SELECT @@have_ssl");
rc= mysql_query(mysql, "SELECT @@have_ssl UNION SELECT @@have_openssl");
check_mysql_rc(rc, mysql);
res= mysql_store_result(mysql);
FAIL_IF(!res, mysql_error(mysql));
if ((row= mysql_fetch_row(res)))
while ((row= mysql_fetch_row(res)))
{
if (!strcmp(row[0], "YES"))
skip_ssl= 0;
@@ -65,12 +105,20 @@ static int test_ssl(MYSQL *mysql)
}
mysql_free_result(res);
sslhost[0]= 0;
if (!skip_ssl)
{
rc= mysql_query(mysql, "DROP USER 'ssluser'@'%'");
rc= mysql_query(mysql, "GRANT ALL ON test.* TO 'ssluser'@'%' IDENTIFIED BY 'sslpw' REQUIRE SSL");
rc= mysql_query(mysql, "GRANT ALL ON test.* TO 'ssluser'@'localhost' IDENTIFIED BY 'sslpw' REQUIRE SSL");
rc= mysql_query(mysql, "FLUSH PRVILEGES");
char *p;
rc= mysql_query(mysql, "SELECT CURRENT_USER()");
check_mysql_rc(rc, mysql);
res= mysql_store_result(mysql);
row= mysql_fetch_row(res);
diag("user: %s", row[0]);
if (p= strchr(row[0], '@'))
strcpy(sslhost, p+1);
mysql_free_result(res);
}
return OK;
@@ -79,7 +127,6 @@ static int test_ssl(MYSQL *mysql)
static int test_ssl_cipher(MYSQL *unused)
{
MYSQL *my;
char *cipher;
if (check_skip_ssl())
return SKIP;
@@ -92,8 +139,7 @@ static int test_ssl_cipher(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);
FAIL_IF(cipher == NULL, "used cipher is NULL");
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
mysql_close(my);
return OK;
}
@@ -101,23 +147,16 @@ static int test_ssl_cipher(MYSQL *unused)
static int test_conc95(MYSQL *my)
{
MYSQL *mysql;
int rc;
if (check_skip_ssl())
return SKIP;
rc= mysql_query(my, "DROP USER 'ssluser1'@'%'");
rc= mysql_query(my, "DROP USER 'ssluser1'@'localhost'");
rc= mysql_query(my, "GRANT ALL ON test.* TO 'ssluser1'@'%' IDENTIFIED BY 'sslpw' REQUIRE X509");
rc= mysql_query(my, "GRANT ALL ON test.* TO 'ssluser1'@'localhost' IDENTIFIED BY 'sslpw' REQUIRE X509");
check_mysql_rc(rc, my);
rc= mysql_query(my, "FLUSH PRIVILEGES");
check_mysql_rc(rc, my);
create_ssl_user("ssluser1", 1);
mysql= mysql_init(NULL);
mysql_ssl_set(mysql,
"@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/client-key.pem",
"@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/client-cert.pem",
"@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/server-key.pem",
"@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/server-cert.pem",
"@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/ca-cert.pem",
NULL,
NULL);
@@ -125,7 +164,6 @@ static int test_conc95(MYSQL *my)
if (!mysql_real_connect(mysql, hostname, "ssluser1", sslpw, schema,
port, socketname, 0))
{
diag("Error: %s", mysql_error(mysql));
mysql_close(mysql);
diag("could not establish x509 connection");
return FAIL;
@@ -137,7 +175,6 @@ static int test_conc95(MYSQL *my)
static int test_multi_ssl_connections(MYSQL *unused)
{
MYSQL *mysql[50], *my;
char *cipher;
int i, rc;
int old_connections= 0, new_connections= 0;
MYSQL_RES *res;
@@ -149,6 +186,8 @@ static int test_multi_ssl_connections(MYSQL *unused)
diag("Test doesn't work with yassl");
return SKIP;
create_ssl_user(ssluser, 0);
my= mysql_init(NULL);
FAIL_IF(!my,"mysql_init() failed");
FAIL_IF(!mysql_real_connect(my, hostname, ssluser, sslpw, schema,
@@ -177,8 +216,7 @@ static int test_multi_ssl_connections(MYSQL *unused)
return FAIL;
}
cipher= (char *)mysql_get_ssl_cipher(mysql[i]);
FAIL_IF(cipher == NULL, "used cipher is NULL");
FAIL_IF(check_cipher(mysql[i]) != 0, "Invalid cipher");
}
for (i=0; i < 50; i++)
mysql_close(mysql[i]);
@@ -307,6 +345,31 @@ static int test_phpbug51647(MYSQL *my)
return OK;
}
static int test_password_protected(MYSQL *my)
{
MYSQL* mysql;
if (check_skip_ssl())
return SKIP;
mysql= mysql_init(NULL);
FAIL_IF(!mysql, "Can't allocate memory");
mysql_ssl_set(mysql, "@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/client-key-enc.pem",
"@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/client-cert.pem",
"@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/ca-cert.pem", 0, 0);
mysql_options(mysql, MARIADB_OPT_SSL_PASSWORD, "qwerty");
FAIL_IF(!mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
port, socketname, 0), mysql_error(mysql));
diag("%s", mysql_get_ssl_cipher(mysql));
mysql_close(mysql);
return OK;
}
static int test_conc50(MYSQL *my)
{
MYSQL *mysql;
@@ -394,28 +457,18 @@ static int test_conc127(MYSQL *my)
static int test_conc50_3(MYSQL *my)
{
MYSQL *mysql;
int rc;
char query[256];
if (check_skip_ssl())
return SKIP;
mysql_query(my, "DROP USER 'ssltest'@'%'");
sprintf(query, "GRANT ALL ON %s.* TO 'ssltest'@'%' REQUIRE SSL", schema ? schema : "*");
rc= mysql_query(my, query);
sprintf(query, "GRANT ALL ON %s.* TO 'ssltest'@'localhost' REQUIRE SSL", schema ? schema : "*");
rc= mysql_query(my, query);
check_mysql_rc(rc, my);
rc= mysql_query(my, "FLUSH PRIVILEGES");
check_mysql_rc(rc, my);
create_ssl_user(ssluser, 0);
mysql= mysql_init(NULL);
FAIL_IF(!mysql, "Can't allocate memory");
mysql_ssl_set(mysql, NULL, NULL, NULL, NULL, NULL);
mysql_real_connect(mysql, hostname, (const char *)"ssltest", NULL, schema,
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
port, socketname, 0);
FAIL_IF(!mysql_errno(mysql), "Error expected, SSL connection required!");
mysql_close(mysql);
@@ -487,7 +540,7 @@ static int test_bug62743(MYSQL *my)
mysql= mysql_init(NULL);
FAIL_IF(!mysql, "Can't allocate memory");
mysql_ssl_set(mysql, "dummykey", "@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/client-cert.pem", NULL, NULL, NULL);
mysql_ssl_set(mysql, "dummykey", NULL, NULL, NULL, NULL);
mysql_real_connect(mysql, hostname, ssluser, sslpw, schema,
port, socketname, 0);
@@ -594,8 +647,6 @@ static int test_conc_102(MYSQL *mysql)
rc= mysql_query(mysql, "INSERT INTO t_conc102 VALUES (0)");
check_mysql_rc(rc, mysql);
pthread_mutex_init(&LOCK_test, 0);
for (i=0; i < 50; i++)
{
#ifndef WIN32
@@ -613,8 +664,7 @@ static int test_conc_102(MYSQL *mysql)
#else
WaitForSingleObject(hthreads[i], INFINITE);
#endif
}
pthread_mutex_destroy(&LOCK_test);
}
rc= mysql_query(mysql, "SELECT a FROM t_conc102");
check_mysql_rc(rc, mysql);
res= mysql_store_result(mysql);
@@ -630,7 +680,6 @@ const char *ssl_cert_finger_print= "@SSL_CERT_FINGER_PRINT@";
static int test_ssl_fp(MYSQL *unused)
{
MYSQL *my;
char *cipher;
if (check_skip_ssl())
return SKIP;
@@ -645,8 +694,7 @@ static int test_ssl_fp(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);
FAIL_IF(cipher == NULL, "used cipher is NULL");
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
mysql_close(my);
return OK;
}
@@ -654,7 +702,6 @@ static int test_ssl_fp(MYSQL *unused)
static int test_ssl_fp_list(MYSQL *unused)
{
MYSQL *my;
char *cipher;
if (check_skip_ssl())
return SKIP;
@@ -669,47 +716,16 @@ 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);
FAIL_IF(cipher == NULL, "used cipher is NULL");
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
mysql_close(my);
return OK;
}
static int test_ssl_long_msg(MYSQL *unused)
{
MYSQL *my;
char buffer[20000];
int rc;
if (check_skip_ssl())
return SKIP;
my= mysql_init(NULL);
FAIL_IF(!my, "mysql_init() failed");
mysql_ssl_set(my,0, 0, "@CMAKE_SOURCE_DIR@/unittest/libmariadb/certs/ca-cert.pem", 0, 0);
mysql_options(my, MARIADB_OPT_SSL_FP, ssl_cert_finger_print);
FAIL_IF(!mysql_real_connect(my, hostname, ssluser, sslpw, schema,
port, socketname, 0), mysql_error(my));
memset(buffer, 0, 20000);
strcpy(buffer, "SET @a:=");
memset(buffer + strlen(buffer), '0', 19000);
rc= mysql_query(my, buffer);
check_mysql_rc(rc, my);
mysql_close(my);
return OK;
}
struct my_tests_st my_tests[] = {
{"test_ssl", test_ssl, TEST_CONNECTION_NEW, 0, NULL, NULL},
/* conc127 must be the first test, otherwise it will fail!! */
{"test_conc127", test_conc127, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_ssl_long_msg", test_ssl_long_msg, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_ssl_fp", test_ssl_fp, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_ssl_fp_list", test_ssl_fp_list, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_conc50", test_conc50, TEST_CONNECTION_NEW, 0, NULL, NULL},
@@ -725,6 +741,7 @@ struct my_tests_st my_tests[] = {
{"test_multi_ssl_connections", test_multi_ssl_connections, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_conc_102", test_conc_102, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_ssl_threads", test_ssl_threads, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_password_protected", test_password_protected, TEST_CONNECTION_NEW, 0, NULL, NULL},
{NULL, NULL, 0, 0, NULL, NULL}
};