~singpolyma/biboumi

5ce9d3f1429228746fcee724a44860f16ad166f5 — Florent Le Coz 8 years ago e8386bd
Make the CA file configurable
2 files changed, 40 insertions(+), 5 deletions(-)

M doc/biboumi.1.md
M louloulibs/network/credentials_manager.cpp
M doc/biboumi.1.md => doc/biboumi.1.md +6 -0
@@ 114,6 114,12 @@ The configuration file uses a simple format of the form
  from 0 to 3.  0 is debug, 1 is info, 2 is warning, 3 is error.  The
  default is 0, but a more practical value for production use is 1.

`ca_file`

  Specifies which file should be use as the list of trusted CA when
  negociating a TLS session. By default this value is unset and biboumi
  tries a list of well-known paths.

The configuration can be re-read at runtime (you can for example change the
log level without having to restart biboumi) by sending SIGUSR1 or SIGUSR2
(see kill(1)) to the process.

M louloulibs/network/credentials_manager.cpp => louloulibs/network/credentials_manager.cpp +34 -5
@@ 5,11 5,22 @@
#include <network/credentials_manager.hpp>
#include <logger/logger.hpp>
#include <botan/tls_exceptn.h>
#include <config/config.hpp>

#ifdef USE_DATABASE
# include <database/database.hpp>
#endif

/**
 * TODO find a standard way to find that out.
 */
static const std::vector<std::string> default_cert_files = {
    "/etc/ssl/certs/ca-bundle.crt",
    "/etc/pki/tls/certs/ca-bundle.crt",
    "/etc/ssl/certs/ca-certificates.crt",
    "/etc/ca-certificates/extracted/tls-ca-bundle.pem"
};

Botan::Certificate_Store_In_Memory Basic_Credentials_Manager::certificate_store;
bool Basic_Credentials_Manager::certs_loaded = false;



@@ 43,16 54,34 @@ void Basic_Credentials_Manager::load_certs()
  //  Only load the certificates the first time
  if (Basic_Credentials_Manager::certs_loaded)
    return;
  const std::vector<std::string> paths = {"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"};
  const std::string conf_path = Config::get("ca_file", "");
  std::vector<std::string> paths;
  if (conf_path.empty())
    paths = default_cert_files;
  else
    paths.push_back(conf_path);
  for (const auto& path: paths)
    {
      Botan::DataSource_Stream bundle(path);
      while (!bundle.end_of_data() && bundle.check_available(27))
      try
        {
          Botan::DataSource_Stream bundle(path);
          log_debug("Using ca bundle: " << path);
          while (!bundle.end_of_data() && bundle.check_available(27))
            {
              const Botan::X509_Certificate cert(bundle);
              Basic_Credentials_Manager::certificate_store.add_certificate(cert);
            }
          // Only use the first file that can successfully be read.
          goto success;
        }
      catch (Botan::Stream_IO_Error& e)
        {
          const Botan::X509_Certificate cert(bundle);
          Basic_Credentials_Manager::certificate_store.add_certificate(cert);
          log_debug(e.what());
        }
    }
  //  If we could not open one of the files, print a warning
  log_warning("The CA could not be loaded, TLS negociation will probably fail.");
  success:
  Basic_Credentials_Manager::certs_loaded = true;
}