]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#34] Checkpoint: code done, tests and hook to do
authorFrancis Dupont <fdupont@isc.org>
Tue, 30 Nov 2021 15:35:10 +0000 (16:35 +0100)
committerFrancis Dupont <fdupont@isc.org>
Thu, 6 Jan 2022 12:12:40 +0000 (13:12 +0100)
src/lib/dhcpsrv/mysql_host_data_source.cc
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/mysql/mysql_connection.cc
src/lib/mysql/mysql_connection.h

index 2834e4170262c908382bac1b37e294d17a992c1c..37acbec98457e7ba0f4ec07172785371c3689c4b 100644 (file)
@@ -2802,6 +2802,18 @@ MySqlHostDataSourceImpl::createContext() const {
     // 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.
index f7668540ea989b89d95447cd06201607a87e570f..c97740bbe349700202cc5e6325753e56c6baf11d 100644 (file)
@@ -1887,6 +1887,18 @@ MySqlLeaseMgr::createContext() const {
     // 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());
index 0ef5f37ec88ffa25f25b4b4ef4d3b4ef7189fd4b..672a3bcc58989e1fd11d5237b435bada97be9aaa 100644 (file)
 #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;
@@ -49,7 +64,6 @@ MySqlTransaction::commit() {
     committed_ = true;
 }
 
-
 // Open the database using the parameters passed to the constructor.
 
 void
@@ -156,6 +170,51 @@ MySqlConnection::openDatabase() {
         }
     }
 
+    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:
@@ -196,6 +255,13 @@ MySqlConnection::openDatabase() {
                   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,
index 767e385e1ea87dc3955c13fc4b473345eb4efbb7..bac72205302c7494b202fa59798a686dee8a0c60 100644 (file)
@@ -250,7 +250,7 @@ public:
                     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
@@ -697,6 +697,21 @@ public:
         }
     }
 
+    /// @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
@@ -734,6 +749,9 @@ public:
     /// 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