// Open the database.
ctx->conn_.openDatabase();
+ // Check if we have TLS when we required it.
+ if (ctx->conn_.getTls()) {
+ std::string cipher = ctx->conn_.getTlsCipher();
+ if (cipher.empty()) {
+ LOG_ERROR(dhcpsrv_logger, DHCPSRV_MYSQL_NO_TLS);
+ } else {
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
+ DHCPSRV_MYSQL_TLS_CIPHER)
+ .arg(cipher);
+ }
+ }
+
// Prepare query statements. Those are will be only used to retrieve
// information from the database, so they can be used even if the
// database is read only for the current user.
// Open the database.
ctx->conn_.openDatabase();
+ // Check if we have TLS when we required it.
+ if (ctx->conn_.getTls()) {
+ std::string cipher = ctx->conn_.getTlsCipher();
+ if (cipher.empty()) {
+ LOG_ERROR(dhcpsrv_logger, DHCPSRV_MYSQL_NO_TLS);
+ } else {
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
+ DHCPSRV_MYSQL_TLS_CIPHER)
+ .arg(cipher);
+ }
+ }
+
// Prepare all statements likely to be used.
ctx->conn_.prepareStatements(tagged_statements.begin(),
tagged_statements.end());
#include <stdint.h>
#include <string>
#include <limits>
+#include <sys/stat.h>
+
+namespace { // anonymous namespace
+
+// C++17 has this function but Kea is still C++11 so provide it.
+bool
+isDir(const std::string& name) {
+ struct stat stats;
+ if (::stat(name.c_str(), &stats) < 0) {
+ return (false);
+ }
+ return ((stats.st_mode & S_IFMT) == S_IFDIR);
+}
+
+} // end of namespace
using namespace isc;
using namespace std;
committed_ = true;
}
-
// Open the database using the parameters passed to the constructor.
void
}
}
+ const char* ca_file(0);
+ const char* ca_dir(0);
+ string sca;
+ try {
+ sca = getParameter("trust-anchor");
+ tls_ = true;
+ if (isDir(sca)) {
+ ca_dir = sca.c_str();
+ } else {
+ ca_file = sca.c_str();
+ }
+ } catch (...) {
+ // No trust anchor
+ }
+
+ const char* cert_file(0);
+ string scert;
+ try {
+ scert = getParameter("cert-file");
+ tls_ = true;
+ cert_file = scert.c_str();
+ } catch (...) {
+ // No client certificate file
+ }
+
+ const char* key_file(0);
+ string skey;
+ try {
+ skey = getParameter("key-file");
+ tls_ = true;
+ key_file = skey.c_str();
+ } catch (...) {
+ // No private key file
+ }
+
+ const char* cipher_list(0);
+ string scipher;
+ try {
+ scipher = getParameter("cipher-list");
+ tls_ = true;
+ cipher_list = scipher.c_str();
+ } catch (...) {
+ // No cipher list
+ }
+
// Set options for the connection:
//
// Set options for the connection:
mysql_error(mysql_));
}
+ // If TLS is enabled set it. If something should go wrong it will be later
+ // at the mysql_real_connect call.
+ if (tls_) {
+ mysql_ssl_set(mysql_, key_file, cert_file, ca_file, ca_dir,
+ cipher_list);
+ }
+
// Open the database.
//
// The option CLIENT_FOUND_ROWS is specified so that in an UPDATE,
DbCallback callback = DbCallback())
: DatabaseConnection(parameters, callback),
io_service_accessor_(io_accessor), io_service_(),
- transaction_ref_count_(0) {
+ transaction_ref_count_(0), tls_(false) {
}
/// @brief Destructor
}
}
+ /// @brief Get the TLS flag.
+ ///
+ /// @return True if TLS was required, false otherwise.
+ bool getTls() const {
+ return (tls_);
+ }
+
+ /// @brief Get the TLS cipher
+ ///
+ /// This method is used to check if required TLS was setup.
+ std::string getTlsCipher() {
+ const char* cipher = mysql_get_ssl_cipher(mysql_);
+ return (cipher ? std::string(cipher) : "");
+ }
+
/// @brief Prepared statements
///
/// This field is public, because it is used heavily from MySqlConnection
/// started. We want to not start new transactions when one is already
/// in progress.
int transaction_ref_count_;
+
+ /// @brief TLS flag (true when TLS was required, false otherwise).
+ bool tls_;
};
} // end of isc::db namespace