diff --git a/libs/libmysqlxx/include/mysqlxx/Connection.h b/libs/libmysqlxx/include/mysqlxx/Connection.h index 1eb6b93692c..46e37eaeb48 100644 --- a/libs/libmysqlxx/include/mysqlxx/Connection.h +++ b/libs/libmysqlxx/include/mysqlxx/Connection.h @@ -13,6 +13,9 @@ #define MYSQLXX_DEFAULT_TIMEOUT 60 #define MYSQLXX_DEFAULT_RW_TIMEOUT 1800 +/// Disable LOAD DATA LOCAL INFILE because it is insecure +#define MYSQLXX_DEFAULT_ENABLE_LOCAL_INFILE false + namespace mysqlxx { @@ -72,7 +75,8 @@ public: const char * ssl_cert = "", const char * ssl_key = "", unsigned timeout = MYSQLXX_DEFAULT_TIMEOUT, - unsigned rw_timeout = MYSQLXX_DEFAULT_RW_TIMEOUT); + unsigned rw_timeout = MYSQLXX_DEFAULT_RW_TIMEOUT, + bool enable_local_infile = MYSQLXX_DEFAULT_ENABLE_LOCAL_INFILE); /// Creates connection. Can be used if Poco::Util::Application is using. /// All settings will be got from config_name section of configuration. @@ -91,7 +95,8 @@ public: const char* ssl_cert, const char* ssl_key, unsigned timeout = MYSQLXX_DEFAULT_TIMEOUT, - unsigned rw_timeout = MYSQLXX_DEFAULT_RW_TIMEOUT); + unsigned rw_timeout = MYSQLXX_DEFAULT_RW_TIMEOUT, + bool enable_local_infile = MYSQLXX_DEFAULT_ENABLE_LOCAL_INFILE); void connect(const std::string & config_name) { @@ -106,6 +111,7 @@ public: std::string ssl_ca = cfg.getString(config_name + ".ssl_ca", ""); std::string ssl_cert = cfg.getString(config_name + ".ssl_cert", ""); std::string ssl_key = cfg.getString(config_name + ".ssl_key", ""); + bool enable_local_infile = cfg.getBool(config_name + ".enable_local_infile", MYSQLXX_DEFAULT_ENABLE_LOCAL_INFILE); unsigned timeout = cfg.getInt(config_name + ".connect_timeout", @@ -128,7 +134,8 @@ public: ssl_cert.c_str(), ssl_key.c_str(), timeout, - rw_timeout); + rw_timeout, + enable_local_infile); } /// If MySQL connection was established. diff --git a/libs/libmysqlxx/include/mysqlxx/Pool.h b/libs/libmysqlxx/include/mysqlxx/Pool.h index 957d80418bf..bc7efcc06c3 100644 --- a/libs/libmysqlxx/include/mysqlxx/Pool.h +++ b/libs/libmysqlxx/include/mysqlxx/Pool.h @@ -162,10 +162,11 @@ public: unsigned connect_timeout_ = MYSQLXX_DEFAULT_TIMEOUT, unsigned rw_timeout_ = MYSQLXX_DEFAULT_RW_TIMEOUT, unsigned default_connections_ = MYSQLXX_POOL_DEFAULT_START_CONNECTIONS, - unsigned max_connections_ = MYSQLXX_POOL_DEFAULT_MAX_CONNECTIONS) + unsigned max_connections_ = MYSQLXX_POOL_DEFAULT_MAX_CONNECTIONS, + unsigned enable_local_infile_ = MYSQLXX_DEFAULT_ENABLE_LOCAL_INFILE) : default_connections(default_connections_), max_connections(max_connections_), db(db_), server(server_), user(user_), password(password_), port(port_), socket(socket_), - connect_timeout(connect_timeout_), rw_timeout(rw_timeout_) {} + connect_timeout(connect_timeout_), rw_timeout(rw_timeout_), enable_local_infile(enable_local_infile_) {} Pool(const Pool & other) : default_connections{other.default_connections}, @@ -173,7 +174,8 @@ public: db{other.db}, server{other.server}, user{other.user}, password{other.password}, port{other.port}, socket{other.socket}, - connect_timeout{other.connect_timeout}, rw_timeout{other.rw_timeout} + connect_timeout{other.connect_timeout}, rw_timeout{other.rw_timeout}, + enable_local_infile{other.enable_local_infile} {} Pool & operator=(const Pool &) = delete; @@ -224,6 +226,7 @@ private: std::string ssl_ca; std::string ssl_cert; std::string ssl_key; + bool enable_local_infile; /// True if connection was established at least once. bool was_successful{false}; diff --git a/libs/libmysqlxx/src/Connection.cpp b/libs/libmysqlxx/src/Connection.cpp index c69c735dd72..e26a067f3d1 100644 --- a/libs/libmysqlxx/src/Connection.cpp +++ b/libs/libmysqlxx/src/Connection.cpp @@ -45,10 +45,11 @@ Connection::Connection( const char* ssl_cert, const char* ssl_key, unsigned timeout, - unsigned rw_timeout) + unsigned rw_timeout, + bool enable_local_infile) : Connection() { - connect(db, server, user, password, port, socket, ssl_ca, ssl_cert, ssl_key, timeout, rw_timeout); + connect(db, server, user, password, port, socket, ssl_ca, ssl_cert, ssl_key, timeout, rw_timeout, enable_local_infile); } Connection::Connection(const std::string & config_name) @@ -73,7 +74,8 @@ void Connection::connect(const char* db, const char * ssl_cert, const char * ssl_key, unsigned timeout, - unsigned rw_timeout) + unsigned rw_timeout, + bool enable_local_infile) { if (is_connected) disconnect(); @@ -92,9 +94,9 @@ void Connection::connect(const char* db, if (mysql_options(driver.get(), MYSQL_OPT_WRITE_TIMEOUT, &rw_timeout)) throw ConnectionFailed(errorMessage(driver.get()), mysql_errno(driver.get())); - /// Disable LOAD DATA LOCAL INFILE because it is insecure. - unsigned enable_local_infile = 0; - if (mysql_options(driver.get(), MYSQL_OPT_LOCAL_INFILE, &enable_local_infile)) + /// Disable LOAD DATA LOCAL INFILE because it is insecure if necessary. + unsigned enable_local_infile_arg = static_cast(enable_local_infile); + if (mysql_options(driver.get(), MYSQL_OPT_LOCAL_INFILE, &enable_local_infile_arg)) throw ConnectionFailed(errorMessage(driver.get()), mysql_errno(driver.get())); /// Specifies particular ssl key and certificate if it needs diff --git a/libs/libmysqlxx/src/Pool.cpp b/libs/libmysqlxx/src/Pool.cpp index 9e592b4aba0..494ae267ff7 100644 --- a/libs/libmysqlxx/src/Pool.cpp +++ b/libs/libmysqlxx/src/Pool.cpp @@ -69,6 +69,9 @@ Pool::Pool(const Poco::Util::AbstractConfiguration & cfg, const std::string & co ssl_key = cfg.has(config_name + ".ssl_key") ? cfg.getString(config_name + ".ssl_key") : cfg.getString(parent_config_name + ".ssl_key", ""); + + enable_local_infile = cfg.getBool(config_name + ".enable_local_infile", + cfg.getBool(parent_config_name + ".enable_local_infile", MYSQLXX_DEFAULT_ENABLE_LOCAL_INFILE)); } else { @@ -84,6 +87,9 @@ Pool::Pool(const Poco::Util::AbstractConfiguration & cfg, const std::string & co ssl_ca = cfg.getString(config_name + ".ssl_ca", ""); ssl_cert = cfg.getString(config_name + ".ssl_cert", ""); ssl_key = cfg.getString(config_name + ".ssl_key", ""); + + enable_local_infile = cfg.getBool( + config_name + ".enable_local_infile", MYSQLXX_DEFAULT_ENABLE_LOCAL_INFILE); } connect_timeout = cfg.getInt(config_name + ".connect_timeout", @@ -192,7 +198,8 @@ void Pool::Entry::forceConnected() const pool->ssl_cert.c_str(), pool->ssl_key.c_str(), pool->connect_timeout, - pool->rw_timeout); + pool->rw_timeout, + pool->enable_local_infile); } while (!data->conn.ping()); } @@ -233,7 +240,8 @@ Pool::Connection * Pool::allocConnection(bool dont_throw_if_failed_first_time) ssl_cert.c_str(), ssl_key.c_str(), connect_timeout, - rw_timeout); + rw_timeout, + enable_local_infile); } catch (mysqlxx::ConnectionFailed & e) {