mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
324 lines
11 KiB
324 lines
11 KiB
/**
|
|
* @file test_change_user-t.cpp
|
|
* @brief Test various mysql_change_user()
|
|
* @details Create connections with both mysql_native_password and caching_sha2_password
|
|
* and try to reset them
|
|
*/
|
|
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <stdio.h>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "mysql.h"
|
|
|
|
// copied from ma_common.h , but only the beginning
|
|
struct st_mysql_options_extension {
|
|
char *plugin_dir;
|
|
char *default_auth;
|
|
// README: the struct is more complex, but we only need default_auth
|
|
};
|
|
|
|
#include "tap.h"
|
|
#include "command_line.h"
|
|
#include "utils.h"
|
|
|
|
#include "json.hpp"
|
|
|
|
using std::pair;
|
|
using std::string;
|
|
|
|
using namespace std;
|
|
|
|
using nlohmann::json;
|
|
|
|
#define NCONNS 16
|
|
|
|
int run_queries_sets(std::vector<std::string>& queries, MYSQL *my, const std::string& message_prefix) {
|
|
for (std::vector<std::string>::iterator it = queries.begin(); it != queries.end(); it++) {
|
|
std::string q = *it;
|
|
diag("%s: %s", message_prefix.c_str(), q.c_str());
|
|
MYSQL_QUERY(my, q.c_str());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void parse_result_json_column(MYSQL_RES *result, json& j) {
|
|
if(!result) return;
|
|
MYSQL_ROW row;
|
|
|
|
while ((row = mysql_fetch_row(result))) {
|
|
j = json::parse(row[0]);
|
|
}
|
|
}
|
|
|
|
|
|
int get_internal_session(MYSQL *my, json& j) {
|
|
MYSQL_QUERY(my, "PROXYSQL INTERNAL SESSION");
|
|
MYSQL_RES* tr_res = mysql_store_result(my);
|
|
parse_result_json_column(tr_res, j);
|
|
mysql_free_result(tr_res);
|
|
return 0;
|
|
}
|
|
|
|
|
|
MYSQL* proxy[NCONNS];
|
|
MYSQL* admin = NULL;
|
|
|
|
bool create_connections(const CommandLine& cl, const char *plugin, bool use_ssl, bool check_plugin, bool check_ssl, bool incorrect_connect_password) {
|
|
diag("Calling create_connections with plugin: %s , use_ssl: %d , check_plugin: %d , check_ssl: %d , incorrect_connect_password: %d",
|
|
plugin, use_ssl, check_plugin, check_ssl, incorrect_connect_password);
|
|
MYSQL * my = NULL;
|
|
int rc = 0;
|
|
for (int i=0; i<NCONNS; i++) {
|
|
proxy[i] = mysql_init(NULL);
|
|
if (proxy[i] == NULL) {
|
|
diag("Error on mysql_init()");
|
|
return false;
|
|
}
|
|
int flags = 0;
|
|
rc = mysql_options(proxy[i], MYSQL_DEFAULT_AUTH, plugin);
|
|
my_bool enforce_tls=1;
|
|
if (use_ssl) {
|
|
mysql_ssl_set(proxy[i], NULL, NULL, NULL, NULL, NULL);
|
|
flags = CLIENT_SSL;
|
|
mysql_optionsv(proxy[i], MYSQL_OPT_SSL_ENFORCE, (void *)&enforce_tls);
|
|
}
|
|
string pass = string(cl.password); // default
|
|
if (incorrect_connect_password == true) {
|
|
if (i%2 == 0) {
|
|
pass = "a" + pass;
|
|
} else {
|
|
pass = pass + "a";
|
|
}
|
|
}
|
|
my = mysql_real_connect(proxy[i], cl.host, cl.username, pass.c_str(), NULL, cl.port, NULL, flags);
|
|
if (incorrect_connect_password == false) {
|
|
ok(my != NULL , "Connection created: %d", i);
|
|
if (my == NULL) {
|
|
diag("File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxy[i]));
|
|
return false;
|
|
}
|
|
if (use_ssl && check_ssl) {
|
|
const char * c = mysql_get_ssl_cipher(proxy[i]);
|
|
diag("Cipher in use for connection %d: %s", i, c == NULL ? "NULL" : c);
|
|
if (c == NULL) {
|
|
return false;
|
|
}
|
|
}
|
|
if (check_plugin) {
|
|
if (strcmp(plugin,proxy[i]->options.extension->default_auth) != 0) {
|
|
ok(false, "Plugin wanted: %s , used: %s", plugin, proxy[i]->options.extension->default_auth);
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
ok(my == NULL, "Connect should fail");
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void close_connections() {
|
|
for (int i=0; i<NCONNS; i++) {
|
|
mysql_close(proxy[i]);
|
|
proxy[i] = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
int TestSet1(const CommandLine& cl, const char *plugin, bool test_ssl , bool test_plugin, bool change_user,
|
|
bool incorrect_connect_password, bool incorrect_change_user_password) {
|
|
diag("%d: Starting tests with plugin: %s , test_ssl: %d , check_plugin: %d , change_user: %d , incorrect_connect_password: %d , incorrect_change_user_password: %d",
|
|
__LINE__, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password);
|
|
vector <pair<string,bool>> vec = {
|
|
{"mysql_native_password", false},
|
|
{"mysql_native_password", true},
|
|
{"caching_sha2_password", true}
|
|
};
|
|
for (auto it = vec.begin(); it != vec.end() ; it++) {
|
|
diag("%d: Starting testing plugin %s and ssl %d" , __LINE__, it->first.c_str(), it->second);
|
|
|
|
diag("Setting mysql-default_authentication_plugin='%s'", plugin);
|
|
vector<string> query_set1 = {"SET mysql-default_authentication_plugin='" + string(plugin) + "'", "LOAD MYSQL VARIABLES TO RUNTIME"};
|
|
if (run_queries_sets( query_set1 , admin, "Running on Admin"))
|
|
return exit_status();
|
|
|
|
const char *auth_plugin = it->first.c_str();
|
|
vector<string> query_set2 = {string(string("SET mysql-have_ssl='") + (it->second ? "true" : "false") + "'"), "LOAD MYSQL VARIABLES TO RUNTIME"};
|
|
if (run_queries_sets( query_set2 , admin, "Running on Admin"))
|
|
return exit_status();
|
|
if (create_connections(cl, auth_plugin, false, true, test_ssl, incorrect_connect_password) != true) {
|
|
return exit_status();
|
|
}
|
|
if (incorrect_connect_password == false) {
|
|
if (test_plugin) {
|
|
for (int i = 0; i<NCONNS; i++) {
|
|
json j = {};
|
|
get_internal_session(proxy[i], j);
|
|
// when mysql-default_authentication_plugin='mysql_native_password'
|
|
// mysql_native_password is used even if client tries caching_sha2_password
|
|
string s = string(auth_plugin);
|
|
if (it->first == "caching_sha2_password") {
|
|
s = string(plugin);
|
|
}
|
|
ok(j["client"]["prot"]["auth_plugin"] == s,
|
|
"%s: %d: Plugin wanted: %s , used: %s", plugin, __LINE__, auth_plugin, string(j["client"]["prot"]["auth_plugin"]).c_str());
|
|
}
|
|
}
|
|
if (change_user) {
|
|
for (int i = 0; i<NCONNS; i++) {
|
|
MYSQL *my = proxy[i];
|
|
string pass = string(cl.password); // default
|
|
if (incorrect_change_user_password == true) {
|
|
if (i%2 == 0) {
|
|
pass = "a" + pass;
|
|
} else {
|
|
pass = pass + "a";
|
|
}
|
|
}
|
|
int rc = mysql_change_user(my, cl.username, pass.c_str(), NULL);
|
|
if (incorrect_change_user_password == false) {
|
|
ok(rc == 0, "mysql_change_user():%d : Should succeed. Plugin(default,current): (%s,%s)" , __LINE__, plugin, auth_plugin);
|
|
} else {
|
|
ok(rc != 0, "mysql_change_user():%d : Should fail . Plugin(default,current): (%s,%s)" , __LINE__, plugin, auth_plugin);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
close_connections();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
CommandLine cl;
|
|
|
|
int p = 1; // admin connection
|
|
// with mysql-default_authentication_plugin = mysql_native_password
|
|
p += NCONNS*2*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*2*1; // caching_sha2_password with SSL
|
|
// with mysql-default_authentication_plugin = caching_sha2_password
|
|
p += NCONNS*2*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*2*1; // caching_sha2_password with SSL
|
|
|
|
// with further checks disabled, but change_user() enabled
|
|
// with mysql-default_authentication_plugin = mysql_native_password
|
|
p += NCONNS*2*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*2*1; // caching_sha2_password with SSL
|
|
// with mysql-default_authentication_plugin = caching_sha2_password
|
|
p += NCONNS*2*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*2*1; // caching_sha2_password with SSL
|
|
|
|
// with incorrect connect password
|
|
// with mysql-default_authentication_plugin = mysql_native_password
|
|
p += NCONNS*1*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*1*1; // caching_sha2_password with SSL
|
|
// with mysql-default_authentication_plugin = caching_sha2_password
|
|
p += NCONNS*1*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*1*1; // caching_sha2_password with SSL
|
|
|
|
// with incorrect change user password
|
|
// with mysql-default_authentication_plugin = mysql_native_password
|
|
p += NCONNS*2*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*2*1; // caching_sha2_password with SSL
|
|
// with mysql-default_authentication_plugin = caching_sha2_password
|
|
p += NCONNS*2*2; // mysql_native_password with and without SSL
|
|
p += NCONNS*2*1; // caching_sha2_password with SSL
|
|
|
|
plan(p);
|
|
|
|
if (cl.getEnv()) {
|
|
diag("Failed to get the required environmental variables.");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
int rc = 0;
|
|
admin = mysql_init(NULL);
|
|
{
|
|
MYSQL * my = mysql_real_connect(admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0);
|
|
ok(my != NULL , "Connected to admin");
|
|
if (my == NULL) {
|
|
diag("File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(admin));
|
|
return exit_status();
|
|
}
|
|
}
|
|
|
|
|
|
char *plugin = NULL;
|
|
bool test_ssl;
|
|
bool test_plugin;
|
|
bool change_user;
|
|
bool incorrect_connect_password;
|
|
bool incorrect_change_user_password;
|
|
|
|
|
|
test_ssl=true; test_plugin=true; change_user=false; incorrect_connect_password=false; incorrect_change_user_password=false;
|
|
|
|
// ok() NCONNS*2*2 + NCONNS*2*1
|
|
plugin = (char *)"mysql_native_password";
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
// ok() NCONNS*2*2 + NCONNS*2*1
|
|
plugin = (char *)"caching_sha2_password";
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
|
|
test_ssl=false; test_plugin=false; change_user=true; incorrect_connect_password=false; incorrect_change_user_password=false;
|
|
|
|
// ok() NCONNS*2*2 + NCONNS*2*1
|
|
plugin = (char *)"mysql_native_password";
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
// ok() NCONNS*2*2 + NCONNS*2*1
|
|
plugin = (char *)"caching_sha2_password";
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
|
|
test_ssl=false; test_plugin=false; change_user=true; incorrect_connect_password=true; incorrect_change_user_password=false;
|
|
|
|
// ok() NCONNS*1*2 + NCONNS*1*1
|
|
plugin = (char *)"mysql_native_password";
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
// ok() NCONNS*1*2 + NCONNS*1*1
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
plugin = (char *)"caching_sha2_password";
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
|
|
test_ssl=false; test_plugin=false; change_user=true; incorrect_connect_password=false; incorrect_change_user_password=true;
|
|
|
|
// ok() NCONNS*2*2 + NCONNS*2*1
|
|
plugin = (char *)"mysql_native_password";
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
// ok() NCONNS*2*2 + NCONNS*2*1
|
|
plugin = (char *)"caching_sha2_password";
|
|
diag("%d: Starting batch tests", __LINE__);
|
|
if (TestSet1(cl, plugin, test_ssl, test_plugin, change_user, incorrect_connect_password, incorrect_change_user_password)) {
|
|
return exit_status();
|
|
}
|
|
|
|
return exit_status();
|
|
|
|
cleanup:
|
|
|
|
close_connections();
|
|
return exit_status();
|
|
}
|