2
0
mirror of https://github.com/boostorg/mysql.git synced 2026-02-15 01:02:17 +00:00
Files
mysql/test/integration/handshake.cpp
ruben 745064c009 Corrected handshake algorithm
Added integ tests for caching_sha256_password
2020-04-06 13:21:05 +01:00

143 lines
3.4 KiB
C++

/*
* handshake.cpp
*
* Created on: Oct 22, 2019
* Author: ruben
*/
#include "boost/mysql/connection.hpp"
#include "integration_test_common.hpp"
#include "test_common.hpp"
#include <boost/asio/use_future.hpp>
#include <cstdlib>
namespace net = boost::asio;
using namespace testing;
using namespace boost::mysql::test;
using boost::mysql::detail::make_error_code;
using boost::mysql::error_info;
using boost::mysql::errc;
using boost::mysql::error_code;
namespace
{
bool skip_sha256()
{
return std::getenv("MYSQL_SKIP_SHA256_TESTS") != nullptr;
}
struct HandshakeTest : public IntegTest,
public testing::WithParamInterface<network_testcase>
{
auto do_handshake()
{
connection_params.set_ssl(boost::mysql::ssl_options(GetParam().ssl));
return GetParam().net->handshake(conn, connection_params);
}
void set_credentials(std::string_view user, std::string_view password)
{
connection_params.set_username(user);
connection_params.set_password(password);
}
// does handshake and verifies it went OK
void do_handshake_ok()
{
auto result = do_handshake();
result.validate_no_error();
validate_ssl(GetParam().ssl);
}
};
TEST_P(HandshakeTest, MysqlNativePassword_SuccessfulLogin)
{
set_credentials("mysqlnp_user", "mysqlnp_password");
do_handshake_ok();
}
TEST_P(HandshakeTest, MysqlNativePasswordEmptyPassword_SuccessfulLogin)
{
set_credentials("mysqlnp_empty_password_user", "");
do_handshake_ok();
}
TEST_P(HandshakeTest, CachingSha256PasswordCacheHit_SuccessfulLogin)
{
if (skip_sha256())
{
GTEST_SKIP();
}
set_credentials("csha2p_user", "csha2p_password");
// Force the server load the user into the cache
// Note: this should succeed even for non-TLS connections, as
// it uses the initial challenge, and does NOT send any plaintext password
check_call("mysql -u csha2p_user -pcsha2p_password -e \"\"");
do_handshake_ok();
}
TEST_P(HandshakeTest, CachingSha256PasswordCacheMiss_SuccessfulLogin)
{
if (skip_sha256())
{
GTEST_SKIP();
}
set_credentials("csha2p_user", "csha2p_password");
// Force the server clear the user cache
check_call("mysql -u root -e \"FLUSH PRIVILEGES\"");
if (should_use_ssl(GetParam().ssl))
{
do_handshake_ok();
}
else
{
// A cache miss would force us send a plaintext password over
// a non-TLS connection, so we fail
auto result = do_handshake();
result.validate_error(errc::auth_plugin_requires_ssl, {});
}
}
TEST_P(HandshakeTest, NoDatabase_SuccessfulLogin)
{
connection_params.set_database("");
do_handshake_ok();
}
TEST_P(HandshakeTest, BadUser)
{
connection_params.set_username("non_existing_user");
auto result = do_handshake();
EXPECT_NE(result.err, error_code());
// TODO: if default auth plugin is unknown, unknown auth plugin is returned instead of access denied
// EXPECT_EQ(errc, make_error_code(mysql::errc::access_denied_error));
}
TEST_P(HandshakeTest, BadPassword)
{
connection_params.set_password("bad_password");
auto result = do_handshake();
result.validate_error(errc::access_denied_error, {"access denied", "integ_user"});
}
TEST_P(HandshakeTest, BadDatabase)
{
connection_params.set_database("bad_database");
auto result = do_handshake();
result.validate_error(errc::dbaccess_denied_error, {"database", "bad_database"});
}
// This will run the handshake tests over all ssl_mode options available,
// including ssl_mode::enable. We expect the same results as for ssl_mode::require
MYSQL_NETWORK_TEST_SUITE_EX(HandshakeTest, true);
} // anon namespace