diff --git a/include/redis3m/connection_pool.h b/include/redis3m/connection_pool.h index ee53ee0..bc490de 100644 --- a/include/redis3m/connection_pool.h +++ b/include/redis3m/connection_pool.h @@ -18,6 +18,8 @@ namespace redis3m { REDIS3M_EXCEPTION(too_much_retries) REDIS3M_EXCEPTION(wrong_database) REDIS3M_EXCEPTION(role_dont_match) + REDIS3M_EXCEPTION(authentication_error) + /** * @brief Manages a connection pool, using a Redis Sentinel * to get instances ip, managing also failover @@ -95,6 +97,13 @@ namespace redis3m { */ inline void set_database(unsigned int value) { _database = value; } + /** + * @brief Set authentication password to use on every new master/slave + * connection object created by the pool. + * @param value The password to use + */ + inline void set_password(const std::string& value) { password = value; } + private: connection_pool(const std::string& sentinel_host, const std::string& master_name, @@ -103,12 +112,15 @@ namespace redis3m { connection::ptr_t create_master_connection(); connection::ptr_t sentinel_connection(); static connection::role_t get_role(connection::ptr_t conn); + bool authenticate(connection::ptr_t conn); + std::mutex access_mutex; std::set connections; std::vector sentinel_hosts; unsigned int sentinel_port; std::string master_name; + std::string password; unsigned int _database; }; diff --git a/src/connection_pool.cpp b/src/connection_pool.cpp index 457c120..2dd3e1e 100644 --- a/src/connection_pool.cpp +++ b/src/connection_pool.cpp @@ -30,6 +30,7 @@ connection_pool::connection_pool(const std::string& sentinel_host, unsigned int sentinel_port): master_name(master_name), sentinel_port(sentinel_port), +password(""), _database(0) { #ifndef NO_BOOST @@ -201,6 +202,11 @@ connection::role_t connection_pool::get_role(connection::ptr_t conn) } } +bool connection_pool::authenticate(connection::ptr_t conn) +{ + return (conn->run(command("AUTH") << password).type() != reply::type_t::ERROR); +} + connection::ptr_t connection_pool::create_slave_connection() { connection::ptr_t sentinel = sentinel_connection(); @@ -220,6 +226,11 @@ connection::ptr_t connection_pool::create_slave_connection() try { connection::ptr_t conn = connection::create(host, port); + if (password != "" && !authenticate(conn)) + { + throw authentication_error("Invalid authentication credentials specified"); + } + connection::role_t role = get_role(conn); if (role == connection::SLAVE) { @@ -263,6 +274,11 @@ connection::ptr_t connection_pool::create_master_connection() try { connection::ptr_t conn = connection::create(master_ip, master_port); + if (password != "" && !authenticate(conn)) + { + throw authentication_error("Invalid authentication credentials specified"); + } + connection::role_t role = get_role(conn); if (role == connection::MASTER) {