Skip to content

Commit

Permalink
Simplify PlatformCertFile::get().
Browse files Browse the repository at this point in the history
  • Loading branch information
teo-tsirpanis committed Nov 20, 2024
1 parent 11e35dc commit 5bf62e8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 126 deletions.
38 changes: 34 additions & 4 deletions tiledb/platform/cert_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,41 @@

#include "tiledb/platform/cert_file.h"

namespace tiledb::platform {
#if defined(__linux__)
#include <array>
#include <filesystem>
#endif

namespace tiledb::platform::PlatformCertFile {

#if defined(__linux__)
std::once_flag CertFileTraits<LinuxOS>::cert_file_initialized_;
std::string CertFileTraits<LinuxOS>::cert_file_;
std::string get() {
// This will execute only once since C++11.
static std::string cert_file = []() -> std::string {
const std::array<std::string, 6> cert_files = {
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
"/etc/ssl/cert.pem" // Alpine Linux
};

for (const std::string& cert : cert_files) {
std::error_code ec;
if (std::filesystem::exists(cert, ec)) {
return cert;
}
}
return "";
}();

return cert_file;
}
#else
std::string get() {
return "";
}
#endif

} // namespace tiledb::platform
} // namespace tiledb::platform::PlatformCertFile
125 changes: 9 additions & 116 deletions tiledb/platform/cert_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,126 +33,19 @@
#ifndef TILEDB_CERT_FILE_H
#define TILEDB_CERT_FILE_H

#include <array>
#include <mutex>
#include <string>
#include <system_error>

#include "tiledb/platform/os.h"

// We can remove this preprocessor block once our minimum
// macOS version is at least 10.15. Until then macOS won't
// compile even though this std::filesystem is only run
// on Linux.
#if defined(__APPLE__) && defined(__MACH__)
static bool file_exists(const std::string&) {
throw std::runtime_error("cert file discovery not supported");
}
#else
#include <filesystem>
static bool file_exists(const std::string& path) {
std::error_code ec;
return std::filesystem::exists(path, ec);
}
#endif

namespace tiledb::platform {

/**
* A base traits class for determining whether the current
* platform might have a CA Cert file on disk in a well
* known location.
*/
template <class T>
class CertFileTraits {
CertFileTraits() = delete;
};

/**
* A platform dependent alias to the appropriate
* certficate file trait.
*/
using PlatformCertFile = CertFileTraits<PlatformOS>;

/**
* A trait specialization for when the current platform does
* not have a certificate file in a well known location.
*/
template <>
class CertFileTraits<BaseOS> {
public:
/**
* A boolean flag indicating that the current platform does
* not have a certificate file in a well known location.
*/
static constexpr bool enabled = false;

/**
* Unconditionally returns an empty string for platforms
* that do not have a certificate file in a well known
* location.
*
* \return An empty string.
*/
static std::string get() {
return {};
}
};
namespace tiledb::platform::PlatformCertFile {

/**
* A trait specialization for when the current platform might
* have a certificate file in a well known location.
* Return the possibly cached certificate file location. Only
* the first call to this function actually performs the search.
* All subsequent calls return the cached location.
*
* \return The path to a well known certificate file path or
* an empty string if no such file is found.
*/
template <>
class CertFileTraits<LinuxOS> {
public:
/**
* A boolean flag indicating that the current platform has
* a certficate file in a well known location.
*/
static constexpr bool enabled = true;

/**
* An instance of `std::once_flag` to search for a
* certificate file at most once per process lifetime.
*/
static std::once_flag cert_file_initialized_;

/**
* The cached certificate file location.
*/
static std::string cert_file_;

/**
* Return the possibly cached certificate file location. Only
* the first call to this function actually performs the search.
* All subsequent calls return the cached location.
*
* \return The path to a well known certificate file path or
* an empty string if no such file is found.
*/
static std::string get() {
std::call_once(cert_file_initialized_, []() {
const std::array<std::string, 6> cert_files = {
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
"/etc/ssl/cert.pem" // Alpine Linux
};

for (const std::string& cert : cert_files) {
if (file_exists(cert)) {
cert_file_ = cert;
return;
}
}
});

return cert_file_;
}
};
std::string get();

} // namespace tiledb::platform
} // namespace tiledb::platform::PlatformCertFile
#endif // TILEDB_CERT_FILE_H
10 changes: 4 additions & 6 deletions tiledb/sm/filesystem/ssl_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ SSLConfig::SSLConfig(const Config& cfg)
ca_path_ = ca_path.value();
}

if constexpr (tiledb::platform::PlatformCertFile::enabled) {
// If neither ca_file or ca_path are set, we look for a system default
// CA file on Linux platforms.
if (ca_file_.empty() && ca_path_.empty()) {
ca_file_ = tiledb::platform::PlatformCertFile::get();
}
// If neither ca_file or ca_path are set, we look for a system default
// CA file if available.
if (ca_file_.empty() && ca_path_.empty()) {
ca_file_ = tiledb::platform::PlatformCertFile::get();
}

auto verify = cfg.get<bool>("ssl.verify");
Expand Down

0 comments on commit 5bf62e8

Please sign in to comment.