[pkg-nagios-changes] [Git][nagios-team/pkg-icinga2][upstream] New upstream version 2.12.3
Bas Couwenberg
gitlab at salsa.debian.org
Wed Dec 16 05:03:36 GMT 2020
Bas Couwenberg pushed to branch upstream at Debian Nagios Maintainer Group / pkg-icinga2
Commits:
1684f2b5 by Bas Couwenberg at 2020-12-16T05:31:29+01:00
New upstream version 2.12.3
- - - - -
18 changed files:
- .github/workflows/packages.yml
- CHANGELOG.md
- VERSION
- lib/base/CMakeLists.txt
- lib/base/process.cpp
- lib/base/process.hpp
- − lib/base/spinlock.cpp
- − lib/base/spinlock.hpp
- lib/base/tlsutility.cpp
- lib/base/tlsutility.hpp
- lib/cli/pkiverifycommand.cpp
- lib/icinga/checkable-check.cpp
- lib/icinga/checkable-notification.cpp
- lib/remote/apilistener-configsync.cpp
- lib/remote/apilistener-filesync.cpp
- lib/remote/apilistener.hpp
- lib/remote/jsonrpcconnection-pki.cpp
- lib/remote/pkiutility.cpp
Changes:
=====================================
.github/workflows/packages.yml
=====================================
@@ -132,28 +132,16 @@ jobs:
release: 8
- name: centos
release: 7
- - name: centos
- release: 6
- name: fedora
release: 32
- name: fedora
release: 31
- - name: fedora
- release: 30
- - name: fedora
- release: 29
- name: sles
release: '15.1'
- - name: sles
- release: '15.0'
- name: sles
release: '12.5'
- - name: sles
- release: '12.4'
- name: opensuse
release: '15.1'
- - name: opensuse
- release: '15.0'
runs-on: ubuntu-latest
=====================================
CHANGELOG.md
=====================================
@@ -7,6 +7,37 @@ documentation before upgrading to a new release.
Released closed milestones can be found on [GitHub](https://github.com/Icinga/icinga2/milestones?state=closed).
+## 2.12.3 (2020-12-15)
+
+Version 2.12.3 resolves a security vulnerability with revoked certificates being
+renewed automatically ignoring the CRL.
+
+This version also resolves issues with high load on Windows regarding the config sync
+and not being able to disable/enable Icinga 2 features over the API.
+
+### Security
+
+* Fix that revoked certificates due for renewal will automatically be renewed ignoring the CRL (CVE-2020-29663)
+
+When a CRL is specified in the ApiListener configuration, Icinga 2 only used it
+when connections were established so far, but not when a certificate is requested.
+This allows a node to automatically renew a revoked certificate if it meets the
+other conditions for auto renewal (issued before 2017 or expires in less than 30 days).
+
+Because Icinga 2 currently (v2.12.3 and earlier) uses a validity duration of 15 years,
+this only affects setups with external certificate signing and revoked certificates
+that expire in less then 30 days.
+
+### Bugfixes
+
+* Improve config sync locking - resolves high load issues on Windows #8511
+* Fix runtime config updates being ignored for objects without zone #8549
+* Use proper buffer size for OpenSSL error messages #8542
+
+### Enhancements
+
+* On checkable recovery: re-check children that have a problem #8506
+
## 2.12.2 (2020-12-01)
Version 2.12.2 fixes several issues to improve the reliability of the cluster functionality.
=====================================
VERSION
=====================================
@@ -1,2 +1,2 @@
-Version: 2.12.2
+Version: 2.12.3
Revision: 1
=====================================
lib/base/CMakeLists.txt
=====================================
@@ -64,7 +64,6 @@ set(base_SOURCES
shared-object.hpp
singleton.hpp
socket.cpp socket.hpp
- spinlock.cpp spinlock.hpp
stacktrace.cpp stacktrace.hpp
statsfunction.hpp
stdiostream.cpp stdiostream.hpp
=====================================
lib/base/process.cpp
=====================================
@@ -49,7 +49,8 @@ static boost::once_flag l_ProcessOnceFlag = BOOST_ONCE_INIT;
static boost::once_flag l_SpawnHelperOnceFlag = BOOST_ONCE_INIT;
Process::Process(Process::Arguments arguments, Dictionary::Ptr extraEnvironment)
- : m_Arguments(std::move(arguments)), m_ExtraEnvironment(std::move(extraEnvironment)), m_Timeout(600), m_AdjustPriority(false)
+ : m_Arguments(std::move(arguments)), m_ExtraEnvironment(std::move(extraEnvironment)),
+ m_Timeout(600), m_AdjustPriority(false), m_ResultAvailable(false)
#ifdef _WIN32
, m_ReadPending(false), m_ReadFailed(false), m_Overlapped()
#endif /* _WIN32 */
@@ -1007,6 +1008,12 @@ void Process::Run(const std::function<void(const ProcessResult&)>& callback)
#endif /* _WIN32 */
}
+const ProcessResult& Process::WaitForResult() {
+ std::unique_lock<std::mutex> lock(m_ResultMutex);
+ m_ResultCondition.wait(lock, [this]{ return m_ResultAvailable; });
+ return m_Result;
+}
+
bool Process::DoEvents()
{
bool is_timeout = false;
@@ -1114,10 +1121,15 @@ bool Process::DoEvents()
}
#endif /* _WIN32 */
- m_Result.PID = m_PID;
- m_Result.ExecutionEnd = Utility::GetTime();
- m_Result.ExitStatus = exitcode;
- m_Result.Output = output;
+ {
+ std::lock_guard<std::mutex> lock(m_ResultMutex);
+ m_Result.PID = m_PID;
+ m_Result.ExecutionEnd = Utility::GetTime();
+ m_Result.ExitStatus = exitcode;
+ m_Result.Output = output;
+ m_ResultAvailable = true;
+ }
+ m_ResultCondition.notify_all();
if (m_Callback)
Utility::QueueAsyncCallback(std::bind(m_Callback, m_Result));
=====================================
lib/base/process.hpp
=====================================
@@ -9,6 +9,8 @@
#include <deque>
#include <vector>
#include <sstream>
+#include <mutex>
+#include <condition_variable>
namespace icinga
{
@@ -61,6 +63,8 @@ public:
void Run(const std::function<void (const ProcessResult&)>& callback = std::function<void (const ProcessResult&)>());
+ const ProcessResult& WaitForResult();
+
pid_t GetPID() const;
static Arguments PrepareCommand(const Value& command);
@@ -94,6 +98,9 @@ private:
std::ostringstream m_OutputStream;
std::function<void (const ProcessResult&)> m_Callback;
ProcessResult m_Result;
+ bool m_ResultAvailable;
+ std::mutex m_ResultMutex;
+ std::condition_variable m_ResultCondition;
static void IOThreadProc(int tid);
bool DoEvents();
=====================================
lib/base/spinlock.cpp deleted
=====================================
@@ -1,22 +0,0 @@
-/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
-
-#include "base/spinlock.hpp"
-#include <atomic>
-
-using namespace icinga;
-
-void SpinLock::lock()
-{
- while (m_Locked.test_and_set(std::memory_order_acquire)) {
- }
-}
-
-bool SpinLock::try_lock()
-{
- return !m_Locked.test_and_set(std::memory_order_acquire);
-}
-
-void SpinLock::unlock()
-{
- m_Locked.clear(std::memory_order_release);
-}
=====================================
lib/base/spinlock.hpp deleted
=====================================
@@ -1,35 +0,0 @@
-/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
-
-#ifndef SPINLOCK_H
-#define SPINLOCK_H
-
-#include <atomic>
-
-namespace icinga
-{
-
-/**
- * A spin lock.
- *
- * @ingroup base
- */
-class SpinLock
-{
-public:
- SpinLock() = default;
- SpinLock(const SpinLock&) = delete;
- SpinLock& operator=(const SpinLock&) = delete;
- SpinLock(SpinLock&&) = delete;
- SpinLock& operator=(SpinLock&&) = delete;
-
- void lock();
- bool try_lock();
- void unlock();
-
-private:
- std::atomic_flag m_Locked = ATOMIC_FLAG_INIT;
-};
-
-}
-
-#endif /* SPINLOCK_H */
=====================================
lib/base/tlsutility.cpp
=====================================
@@ -106,8 +106,9 @@ static void SetupSslContext(const Shared<boost::asio::ssl::context>::Ptr& contex
if (!pubkey.IsEmpty()) {
if (!SSL_CTX_use_certificate_chain_file(sslContext, pubkey.CStr())) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error with public key file '" << pubkey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error with public key file '" << pubkey << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SSL_CTX_use_certificate_chain_file")
<< errinfo_openssl_error(ERR_peek_error())
@@ -117,8 +118,9 @@ static void SetupSslContext(const Shared<boost::asio::ssl::context>::Ptr& contex
if (!privkey.IsEmpty()) {
if (!SSL_CTX_use_PrivateKey_file(sslContext, privkey.CStr(), SSL_FILETYPE_PEM)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error with private key file '" << privkey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error with private key file '" << privkey << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SSL_CTX_use_PrivateKey_file")
<< errinfo_openssl_error(ERR_peek_error())
@@ -126,8 +128,9 @@ static void SetupSslContext(const Shared<boost::asio::ssl::context>::Ptr& contex
}
if (!SSL_CTX_check_private_key(sslContext)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error checking private key '" << privkey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error checking private key '" << privkey << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SSL_CTX_check_private_key")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -136,8 +139,9 @@ static void SetupSslContext(const Shared<boost::asio::ssl::context>::Ptr& contex
if (!cakey.IsEmpty()) {
if (!SSL_CTX_load_verify_locations(sslContext, cakey.CStr(), nullptr)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error loading and verifying locations in ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error loading and verifying locations in ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SSL_CTX_load_verify_locations")
<< errinfo_openssl_error(ERR_peek_error())
@@ -148,8 +152,9 @@ static void SetupSslContext(const Shared<boost::asio::ssl::context>::Ptr& contex
cert_names = SSL_load_client_CA_file(cakey.CStr());
if (!cert_names) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error loading client ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error loading client ca key file '" << cakey << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SSL_load_client_CA_file")
<< errinfo_openssl_error(ERR_peek_error())
@@ -191,12 +196,13 @@ void SetCipherListToSSLContext(const Shared<boost::asio::ssl::context>::Ptr& con
char errbuf[256];
if (SSL_CTX_set_cipher_list(context->native_handle(), cipherList.CStr()) == 0) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
<< "Cipher list '"
<< cipherList
<< "' does not specify any usable ciphers: "
<< ERR_peek_error() << ", \""
- << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SSL_CTX_set_cipher_list")
@@ -242,30 +248,43 @@ void SetTlsProtocolminToSSLContext(const Shared<boost::asio::ssl::context>::Ptr&
}
/**
- * Loads a CRL and appends its certificates to the specified SSL context..
+ * Loads a CRL and appends its certificates to the specified Boost SSL context.
*
* @param context The SSL context.
* @param crlPath The path to the CRL file.
*/
void AddCRLToSSLContext(const Shared<boost::asio::ssl::context>::Ptr& context, const String& crlPath)
{
- char errbuf[256];
X509_STORE *x509_store = SSL_CTX_get_cert_store(context->native_handle());
+ AddCRLToSSLContext(x509_store, crlPath);
+}
+
+/**
+ * Loads a CRL and appends its certificates to the specified OpenSSL X509 store.
+ *
+ * @param context The SSL context.
+ * @param crlPath The path to the CRL file.
+ */
+void AddCRLToSSLContext(X509_STORE *x509_store, const String& crlPath)
+{
+ char errbuf[256];
X509_LOOKUP *lookup;
lookup = X509_STORE_add_lookup(x509_store, X509_LOOKUP_file());
if (!lookup) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error adding X509 store lookup: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error adding X509 store lookup: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("X509_STORE_add_lookup")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (X509_LOOKUP_load_file(lookup, crlPath.CStr(), X509_FILETYPE_PEM) != 1) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error loading crl file '" << crlPath << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error loading crl file '" << crlPath << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("X509_LOOKUP_load_file")
<< errinfo_openssl_error(ERR_peek_error())
@@ -286,8 +305,9 @@ static String GetX509NameCN(X509_NAME *name)
int rc = X509_NAME_get_text_by_NID(name, NID_commonName, buffer, sizeof(buffer));
if (rc == -1) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error with x509 NAME getting text by NID: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error with x509 NAME getting text by NID: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("X509_NAME_get_text_by_NID")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -320,16 +340,18 @@ std::shared_ptr<X509> GetX509Certificate(const String& pemfile)
BIO *fpcert = BIO_new(BIO_s_file());
if (!fpcert) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error creating new BIO: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error creating new BIO: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("BIO_new")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (BIO_read_filename(fpcert, pemfile.CStr()) < 0) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error reading pem file '" << pemfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error reading pem file '" << pemfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("BIO_read_filename")
<< errinfo_openssl_error(ERR_peek_error())
@@ -338,8 +360,9 @@ std::shared_ptr<X509> GetX509Certificate(const String& pemfile)
cert = PEM_read_bio_X509_AUX(fpcert, nullptr, nullptr, nullptr);
if (!cert) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on bio X509 AUX reading pem file '" << pemfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on bio X509 AUX reading pem file '" << pemfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("PEM_read_bio_X509_AUX")
<< errinfo_openssl_error(ERR_peek_error())
@@ -361,8 +384,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
BIGNUM *e = BN_new();
if (!rsa || !e) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while creating RSA key: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while creating RSA key: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("RSA_generate_key")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -371,8 +395,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
BN_set_word(e, RSA_F4);
if (!RSA_generate_key_ex(rsa, 4096, e, nullptr)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while creating RSA key: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while creating RSA key: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("RSA_generate_key")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -386,8 +411,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
BIO *bio = BIO_new_file(const_cast<char *>(keyfile.CStr()), "w");
if (!bio) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while opening private RSA key file '" << keyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while opening private RSA key file '" << keyfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("BIO_new_file")
<< errinfo_openssl_error(ERR_peek_error())
@@ -395,8 +421,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
}
if (!PEM_write_bio_RSAPrivateKey(bio, rsa, nullptr, nullptr, 0, nullptr, nullptr)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while writing private RSA key to file '" << keyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while writing private RSA key to file '" << keyfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("PEM_write_bio_RSAPrivateKey")
<< errinfo_openssl_error(ERR_peek_error())
@@ -426,8 +453,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
bio = BIO_new_file(const_cast<char *>(certfile.CStr()), "w");
if (!bio) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while opening certificate file '" << certfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while opening certificate file '" << certfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("BIO_new_file")
<< errinfo_openssl_error(ERR_peek_error())
@@ -435,8 +463,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
}
if (!PEM_write_bio_X509(bio, cert.get())) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while writing certificate to file '" << certfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while writing certificate to file '" << certfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("PEM_write_bio_X509")
<< errinfo_openssl_error(ERR_peek_error())
@@ -478,8 +507,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
bio = BIO_new_file(const_cast<char *>(csrfile.CStr()), "w");
if (!bio) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while opening CSR file '" << csrfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while opening CSR file '" << csrfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("BIO_new_file")
<< errinfo_openssl_error(ERR_peek_error())
@@ -487,8 +517,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
}
if (!PEM_write_bio_X509_REQ(bio, req)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error while writing CSR to file '" << csrfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error while writing CSR to file '" << csrfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("PEM_write_bio_X509")
<< errinfo_openssl_error(ERR_peek_error())
@@ -518,29 +549,32 @@ std::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME
String id = Utility::NewUniqueID();
- char errbuf[120];
+ char errbuf[256];
SHA_CTX context;
unsigned char digest[SHA_DIGEST_LENGTH];
if (!SHA1_Init(&context)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA1 Init: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA1 Init: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA1_Init")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (!SHA1_Update(&context, (unsigned char*)id.CStr(), id.GetLength())) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA1 Update: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA1 Update: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA1_Update")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (!SHA1_Final(digest, &context)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA1 Final: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA1 Final: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA1_Final")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -592,7 +626,7 @@ String GetIcingaCADir()
std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject)
{
- char errbuf[120];
+ char errbuf[256];
String cadir = GetIcingaCADir();
@@ -603,16 +637,18 @@ std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject)
BIO *cakeybio = BIO_new_file(const_cast<char *>(cakeyfile.CStr()), "r");
if (!cakeybio) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Could not open CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Could not open CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
return std::shared_ptr<X509>();
}
rsa = PEM_read_bio_RSAPrivateKey(cakeybio, nullptr, nullptr, nullptr);
if (!rsa) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Could not read RSA key from CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Could not read RSA key from CA key file '" << cakeyfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
return std::shared_ptr<X509>();
}
@@ -692,29 +728,32 @@ String PBKDF2_SHA256(const String& password, const String& salt, int iterations)
String SHA1(const String& s, bool binary)
{
- char errbuf[120];
+ char errbuf[256];
SHA_CTX context;
unsigned char digest[SHA_DIGEST_LENGTH];
if (!SHA1_Init(&context)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA Init: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA Init: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA1_Init")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (!SHA1_Update(&context, (unsigned char*)s.CStr(), s.GetLength())) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA Update: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA Update: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA1_Update")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (!SHA1_Final(digest, &context)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA Final: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA Final: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA1_Final")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -732,29 +771,32 @@ String SHA1(const String& s, bool binary)
String SHA256(const String& s)
{
- char errbuf[120];
+ char errbuf[256];
SHA256_CTX context;
unsigned char digest[SHA256_DIGEST_LENGTH];
if (!SHA256_Init(&context)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA256 Init: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA256 Init: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA256_Init")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (!SHA256_Update(&context, (unsigned char*)s.CStr(), s.GetLength())) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA256 Update: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA256 Update: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA256_Update")
<< errinfo_openssl_error(ERR_peek_error()));
}
if (!SHA256_Final(digest, &context)) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error on SHA256 Final: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error on SHA256 Final: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("SHA256_Final")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -779,10 +821,11 @@ String RandomString(int length)
if (!RAND_bytes(bytes, length)) {
delete [] bytes;
- char errbuf[120];
+ char errbuf[256];
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Error for RAND_bytes: " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Error for RAND_bytes: " << ERR_peek_error() << ", \"" << errbuf << "\"";
BOOST_THROW_EXCEPTION(openssl_error()
<< boost::errinfo_api_function("RAND_bytes")
<< errinfo_openssl_error(ERR_peek_error()));
@@ -801,7 +844,7 @@ String RandomString(int length)
return result;
}
-bool VerifyCertificate(const std::shared_ptr<X509>& caCertificate, const std::shared_ptr<X509>& certificate)
+bool VerifyCertificate(const std::shared_ptr<X509> &caCertificate, const std::shared_ptr<X509> &certificate, const String& crlFile)
{
X509_STORE *store = X509_STORE_new();
@@ -810,6 +853,10 @@ bool VerifyCertificate(const std::shared_ptr<X509>& caCertificate, const std::sh
X509_STORE_add_cert(store, caCertificate.get());
+ if (!crlFile.IsEmpty()) {
+ AddCRLToSSLContext(store, crlFile);
+ }
+
X509_STORE_CTX *csc = X509_STORE_CTX_new();
X509_STORE_CTX_init(csc, store, certificate.get(), nullptr);
@@ -899,19 +946,4 @@ Array::Ptr GetSubjectAltNames(const std::shared_ptr<X509>& cert)
return sans;
}
-std::string to_string(const errinfo_openssl_error& e)
-{
- std::ostringstream tmp;
- int code = e.value();
- char errbuf[120];
-
- const char *message = ERR_error_string(code, errbuf);
-
- if (!message)
- message = "Unknown error.";
-
- tmp << code << ", \"" << message << "\"";
- return "[errinfo_openssl_error]" + tmp.str() + "\n";
-}
-
}
=====================================
lib/base/tlsutility.hpp
=====================================
@@ -30,6 +30,7 @@ String GetOpenSSLVersion();
Shared<boost::asio::ssl::context>::Ptr MakeAsioSslContext(const String& pubkey = String(), const String& privkey = String(), const String& cakey = String());
void AddCRLToSSLContext(const Shared<boost::asio::ssl::context>::Ptr& context, const String& crlPath);
+void AddCRLToSSLContext(X509_STORE *x509_store, const String& crlPath);
void SetCipherListToSSLContext(const Shared<boost::asio::ssl::context>::Ptr& context, const String& cipherList);
void SetTlsProtocolminToSSLContext(const Shared<boost::asio::ssl::context>::Ptr& context, const String& tlsProtocolmin);
@@ -51,7 +52,7 @@ String SHA1(const String& s, bool binary = false);
String SHA256(const String& s);
String RandomString(int length);
-bool VerifyCertificate(const std::shared_ptr<X509>& caCertificate, const std::shared_ptr<X509>& certificate);
+bool VerifyCertificate(const std::shared_ptr<X509>& caCertificate, const std::shared_ptr<X509>& certificate, const String& crlFile);
bool IsCa(const std::shared_ptr<X509>& cacert);
int GetCertificateVersion(const std::shared_ptr<X509>& cert);
String GetSignatureAlgorithm(const std::shared_ptr<X509>& cert);
@@ -62,8 +63,6 @@ class openssl_error : virtual public std::exception, virtual public boost::excep
struct errinfo_openssl_error_;
typedef boost::error_info<struct errinfo_openssl_error_, unsigned long> errinfo_openssl_error;
-std::string to_string(const errinfo_openssl_error& e);
-
}
#endif /* TLSUTILITY_H */
=====================================
lib/cli/pkiverifycommand.cpp
=====================================
@@ -28,12 +28,13 @@ void PKIVerifyCommand::InitParameters(boost::program_options::options_descriptio
visibleDesc.add_options()
("cn", po::value<std::string>(), "Common Name (optional). Use with '--cert' to check the CN in the certificate.")
("cert", po::value<std::string>(), "Certificate file path (optional). Standalone: print certificate. With '--cacert': Verify against CA.")
- ("cacert", po::value<std::string>(), "CA certificate file path (optional). If passed standalone, verifies whether this is a CA certificate");
+ ("cacert", po::value<std::string>(), "CA certificate file path (optional). If passed standalone, verifies whether this is a CA certificate")
+ ("crl", po::value<std::string>(), "CRL file path (optional). Check the certificate against this revocation list when verifying against CA.");
}
std::vector<String> PKIVerifyCommand::GetArgumentSuggestions(const String& argument, const String& word) const
{
- if (argument == "cert" || argument == "cacert")
+ if (argument == "cert" || argument == "cacert" || argument == "crl")
return GetBashCompletionSuggestions("file", word);
else
return CLICommand::GetArgumentSuggestions(argument, word);
@@ -46,7 +47,7 @@ std::vector<String> PKIVerifyCommand::GetArgumentSuggestions(const String& argum
*/
int PKIVerifyCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
{
- String cn, certFile, caCertFile;
+ String cn, certFile, caCertFile, crlFile;
if (vm.count("cn"))
cn = vm["cn"].as<std::string>();
@@ -57,6 +58,9 @@ int PKIVerifyCommand::Run(const boost::program_options::variables_map& vm, const
if (vm.count("cacert"))
caCertFile = vm["cacert"].as<std::string>();
+ if (vm.count("crl"))
+ crlFile = vm["crl"].as<std::string>();
+
/* Verify CN in certificate. */
if (!cn.IsEmpty() && !certFile.IsEmpty()) {
std::shared_ptr<X509> cert;
@@ -126,10 +130,15 @@ int PKIVerifyCommand::Run(const boost::program_options::variables_map& vm, const
bool signedByCA;
try {
- signedByCA = VerifyCertificate(cacert, cert);
+ signedByCA = VerifyCertificate(cacert, cert, crlFile);
} catch (const std::exception& ex) {
- Log(LogCritical, "cli")
- << "CRITICAL: Certificate with CN '" << certCN << "' is NOT signed by CA: " << DiagnosticInformation(ex, false);
+ Log logmsg (LogCritical, "cli");
+ logmsg << "CRITICAL: Certificate with CN '" << certCN << "' is NOT signed by CA: ";
+ if (const unsigned long *openssl_code = boost::get_error_info<errinfo_openssl_error>(ex)) {
+ logmsg << X509_verify_cert_error_string(*openssl_code) << " (code " << *openssl_code << ")";
+ } else {
+ logmsg << DiagnosticInformation(ex, false);
+ }
return ServiceCritical;
}
=====================================
lib/icinga/checkable-check.cpp
=====================================
@@ -242,6 +242,20 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
OnReachabilityChanged(this, cr, children, origin);
}
+ if (recovery) {
+ for (auto& child : children) {
+ if (child->GetProblem() && child->GetEnableActiveChecks()) {
+ auto nextCheck (now + Utility::Random() % 60);
+
+ ObjectLock oLock (child);
+
+ if (nextCheck < child->GetNextCheck()) {
+ child->SetNextCheck(nextCheck);
+ }
+ }
+ }
+ }
+
if (!reachable)
SetLastStateUnreachable(Utility::GetTime());
=====================================
lib/icinga/checkable-notification.cpp
=====================================
@@ -10,6 +10,7 @@
#include "base/exception.hpp"
#include "base/context.hpp"
#include "base/convert.hpp"
+#include "base/lazy-init.hpp"
#include "remote/apilistener.hpp"
using namespace icinga;
@@ -145,35 +146,58 @@ static void FireSuppressedNotifications(Checkable* checkable)
int subtract = 0;
- for (auto type : {NotificationProblem, NotificationRecovery, NotificationFlappingStart, NotificationFlappingEnd}) {
- if (suppressed_types & type) {
- bool still_applies = checkable->NotificationReasonApplies(type);
-
- if (still_applies) {
- bool still_suppressed;
-
- switch (type) {
- case NotificationProblem:
- /* Fall through. */
- case NotificationRecovery:
- still_suppressed = !checkable->IsReachable(DependencyNotification) || checkable->IsInDowntime() || checkable->IsAcknowledged();
- break;
- case NotificationFlappingStart:
- /* Fall through. */
- case NotificationFlappingEnd:
- still_suppressed = checkable->IsInDowntime();
- break;
- default:
- break;
+ {
+ LazyInit<bool> wasLastParentRecoveryRecent ([&checkable]() {
+ auto cr (checkable->GetLastCheckResult());
+
+ if (!cr) {
+ return true;
+ }
+
+ auto threshold (cr->GetExecutionStart());
+
+ for (auto& dep : checkable->GetDependencies()) {
+ auto parent (dep->GetParent());
+ ObjectLock oLock (parent);
+
+ if (!parent->GetProblem() && parent->GetLastStateChange() >= threshold) {
+ return true;
}
+ }
- if (!still_suppressed && !checkable->IsLikelyToBeCheckedSoon()) {
- Checkable::OnNotificationsRequested(checkable, type, checkable->GetLastCheckResult(), "", "", nullptr);
+ return false;
+ });
+
+ for (auto type : {NotificationProblem, NotificationRecovery, NotificationFlappingStart, NotificationFlappingEnd}) {
+ if (suppressed_types & type) {
+ bool still_applies = checkable->NotificationReasonApplies(type);
+
+ if (still_applies) {
+ bool still_suppressed;
+
+ switch (type) {
+ case NotificationProblem:
+ /* Fall through. */
+ case NotificationRecovery:
+ still_suppressed = !checkable->IsReachable(DependencyNotification) || checkable->IsInDowntime() || checkable->IsAcknowledged();
+ break;
+ case NotificationFlappingStart:
+ /* Fall through. */
+ case NotificationFlappingEnd:
+ still_suppressed = checkable->IsInDowntime();
+ break;
+ default:
+ break;
+ }
+
+ if (!still_suppressed && !checkable->IsLikelyToBeCheckedSoon() && !wasLastParentRecoveryRecent.Get()) {
+ Checkable::OnNotificationsRequested(checkable, type, checkable->GetLastCheckResult(), "", "", nullptr);
+ subtract |= type;
+ }
+ } else {
subtract |= type;
}
- } else {
- subtract |= type;
}
}
}
=====================================
lib/remote/apilistener-configsync.cpp
=====================================
@@ -74,7 +74,7 @@ Value ApiListener::ConfigUpdateObjectAPIHandler(const MessageOrigin::Ptr& origin
String objZone = params->Get("zone");
- if (!Zone::GetByName(objZone)) {
+ if (!objZone.IsEmpty() && !Zone::GetByName(objZone)) {
Log(LogNotice, "ApiListener")
<< "Discarding 'config update object' message"
<< " from '" << identity << "' (endpoint: '" << endpoint->GetName() << "', zone: '" << endpointZone->GetName() << "')"
@@ -325,7 +325,11 @@ void ApiListener::UpdateConfigObject(const ConfigObject::Ptr& object, const Mess
params->Set("name", object->GetName());
params->Set("type", object->GetReflectionType()->GetName());
params->Set("version", object->GetVersion());
- params->Set("zone", object->GetZoneName());
+
+ String zoneName = object->GetZoneName();
+
+ if (!zoneName.IsEmpty())
+ params->Set("zone", zoneName);
if (object->GetPackage() == "_api") {
String file;
=====================================
lib/remote/apilistener-filesync.cpp
=====================================
@@ -20,7 +20,7 @@ using namespace icinga;
REGISTER_APIFUNCTION(Update, config, &ApiListener::ConfigUpdateHandler);
-SpinLock ApiListener::m_ConfigSyncStageLock;
+std::mutex ApiListener::m_ConfigSyncStageLock;
/**
* Entrypoint for updating all authoritative configs from /etc/zones.d, packages, etc.
@@ -330,7 +330,7 @@ void ApiListener::HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dic
/* Only one transaction is allowed, concurrent message handlers need to wait.
* This affects two parent endpoints sending the config in the same moment.
*/
- auto lock (Shared<std::unique_lock<SpinLock>>::Make(m_ConfigSyncStageLock));
+ std::lock_guard<std::mutex> lock(m_ConfigSyncStageLock);
String apiZonesStageDir = GetApiZonesStageDir();
String fromEndpointName = origin->FromClient->GetEndpoint()->GetName();
@@ -544,7 +544,7 @@ void ApiListener::HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dic
Log(LogInformation, "ApiListener")
<< "Received configuration updates (" << count << ") from endpoint '" << fromEndpointName
<< "' are different to production, triggering validation and reload.";
- AsyncTryActivateZonesStage(relativePaths, lock);
+ TryActivateZonesStage(relativePaths);
} else {
Log(LogInformation, "ApiListener")
<< "Received configuration updates (" << count << ") from endpoint '" << fromEndpointName
@@ -554,17 +554,44 @@ void ApiListener::HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dic
}
/**
- * Callback for stage config validation.
- * When validation was successful, the configuration is copied from
- * stage to production and a restart is triggered.
- * On failure, there's no restart and this is logged.
+ * Spawns a new validation process with 'System.ZonesStageVarDir' set to override the config validation zone dirs with
+ * our current stage. Then waits for the validation result and if it was successful, the configuration is copied from
+ * stage to production and a restart is triggered. On validation failure, there is no restart and this is logged.
+ *
+ * The caller of this function must hold m_ConfigSyncStageLock.
*
- * @param pr Result of the validation process.
* @param relativePaths Collected paths including the zone name, which are copied from stage to current directories.
*/
-void ApiListener::TryActivateZonesStageCallback(const ProcessResult& pr,
- const std::vector<String>& relativePaths)
+void ApiListener::TryActivateZonesStage(const std::vector<String>& relativePaths)
{
+ VERIFY(Application::GetArgC() >= 1);
+
+ /* Inherit parent process args. */
+ Array::Ptr args = new Array({
+ Application::GetExePath(Application::GetArgV()[0]),
+ });
+
+ for (int i = 1; i < Application::GetArgC(); i++) {
+ String argV = Application::GetArgV()[i];
+
+ if (argV == "-d" || argV == "--daemonize")
+ continue;
+
+ args->Add(argV);
+ }
+
+ args->Add("--validate");
+
+ // Set the ZonesStageDir. This creates our own local chroot without any additional automated zone includes.
+ args->Add("--define");
+ args->Add("System.ZonesStageVarDir=" + GetApiZonesStageDir());
+
+ Process::Ptr process = new Process(Process::PrepareCommand(args));
+ process->SetTimeout(Application::GetReloadTimeout());
+
+ process->Run();
+ const ProcessResult& pr = process->WaitForResult();
+
String apiZonesDir = GetApiZonesDir();
String apiZonesStageDir = GetApiZonesStageDir();
@@ -628,44 +655,6 @@ void ApiListener::TryActivateZonesStageCallback(const ProcessResult& pr,
listener->UpdateLastFailedZonesStageValidation(pr.Output);
}
-/**
- * Spawns a new validation process and waits for its output.
- * Sets 'System.ZonesStageVarDir' to override the config validation zone dirs with our current stage.
- *
- * @param relativePaths Required for later file operations in the callback. Provides the zone name plus path in a list.
- */
-void ApiListener::AsyncTryActivateZonesStage(const std::vector<String>& relativePaths, const Shared<std::unique_lock<SpinLock>>::Ptr& lock)
-{
- VERIFY(Application::GetArgC() >= 1);
-
- /* Inherit parent process args. */
- Array::Ptr args = new Array({
- Application::GetExePath(Application::GetArgV()[0]),
- });
-
- for (int i = 1; i < Application::GetArgC(); i++) {
- String argV = Application::GetArgV()[i];
-
- if (argV == "-d" || argV == "--daemonize")
- continue;
-
- args->Add(argV);
- }
-
- args->Add("--validate");
-
- // Set the ZonesStageDir. This creates our own local chroot without any additional automated zone includes.
- args->Add("--define");
- args->Add("System.ZonesStageVarDir=" + GetApiZonesStageDir());
-
- Process::Ptr process = new Process(Process::PrepareCommand(args));
- process->SetTimeout(Application::GetReloadTimeout());
-
- process->Run([relativePaths, lock](const ProcessResult& pr) {
- TryActivateZonesStageCallback(pr, relativePaths);
- });
-}
-
/**
* Update the structure from the last failed validation output.
* Uses the current timestamp.
=====================================
lib/remote/apilistener.hpp
=====================================
@@ -11,7 +11,6 @@
#include "base/configobject.hpp"
#include "base/process.hpp"
#include "base/shared.hpp"
-#include "base/spinlock.hpp"
#include "base/timer.hpp"
#include "base/workqueue.hpp"
#include "base/tcpsocket.hpp"
@@ -188,7 +187,7 @@ private:
void RemoveStatusFile();
/* filesync */
- static SpinLock m_ConfigSyncStageLock;
+ static std::mutex m_ConfigSyncStageLock;
void SyncLocalZoneDirs() const;
void SyncLocalZoneDir(const Zone::Ptr& zone) const;
@@ -200,9 +199,7 @@ private:
static ConfigDirInformation LoadConfigDir(const String& dir);
static void ConfigGlobHandler(ConfigDirInformation& config, const String& path, const String& file);
- static void TryActivateZonesStageCallback(const ProcessResult& pr,
- const std::vector<String>& relativePaths);
- static void AsyncTryActivateZonesStage(const std::vector<String>& relativePaths, const Shared<std::unique_lock<SpinLock>>::Ptr& lock);
+ static void TryActivateZonesStage(const std::vector<String>& relativePaths);
static String GetChecksum(const String& content);
static bool CheckConfigChange(const ConfigDirInformation& oldConfig, const ConfigDirInformation& newConfig);
=====================================
lib/remote/jsonrpcconnection-pki.cpp
=====================================
@@ -55,13 +55,25 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
bool signedByCA = false;
- try {
- signedByCA = VerifyCertificate(cacert, cert);
- } catch (const std::exception&) { } /* Swallow the exception on purpose, cacert will never be a non-CA certificate. */
-
- Log(LogInformation, "JsonRpcConnection")
- << "Received certificate request for CN '" << cn << "'"
- << (signedByCA ? "" : " not") << " signed by our CA.";
+ {
+ Log logmsg(LogInformation, "JsonRpcConnection");
+ logmsg << "Received certificate request for CN '" << cn << "'";
+
+ try {
+ signedByCA = VerifyCertificate(cacert, cert, listener->GetCrlPath());
+ if (!signedByCA) {
+ logmsg << " not";
+ }
+ logmsg << " signed by our CA.";
+ } catch (const std::exception &ex) {
+ logmsg << " not signed by our CA";
+ if (const unsigned long *openssl_code = boost::get_error_info<errinfo_openssl_error>(ex)) {
+ logmsg << ": " << X509_verify_cert_error_string(long(*openssl_code)) << " (code " << *openssl_code << ")";
+ } else {
+ logmsg << ".";
+ }
+ }
+ }
if (signedByCA) {
time_t now;
@@ -204,7 +216,7 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
* we're using for cluster connections (there's no point in sending a client
* a certificate it wouldn't be able to use to connect to us anyway) */
try {
- if (!VerifyCertificate(cacert, newcert)) {
+ if (!VerifyCertificate(cacert, newcert, listener->GetCrlPath())) {
Log(LogWarning, "JsonRpcConnection")
<< "The CA in '" << listener->GetDefaultCaPath() << "' does not match the CA which Icinga uses "
<< "for its own cluster connections. This is most likely a configuration problem.";
=====================================
lib/remote/pkiutility.cpp
=====================================
@@ -63,8 +63,9 @@ int PkiUtility::SignCsr(const String& csrfile, const String& certfile)
X509_REQ *req = PEM_read_bio_X509_REQ(csrbio, nullptr, nullptr, nullptr);
if (!req) {
+ ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf);
Log(LogCritical, "SSL")
- << "Could not read X509 certificate request from '" << csrfile << "': " << ERR_peek_error() << ", \"" << ERR_error_string(ERR_peek_error(), errbuf) << "\"";
+ << "Could not read X509 certificate request from '" << csrfile << "': " << ERR_peek_error() << ", \"" << errbuf << "\"";
return 1;
}
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icinga2/-/commit/1684f2b546f66edcc5652e0f79bcc3e5d63f34eb
--
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icinga2/-/commit/1684f2b546f66edcc5652e0f79bcc3e5d63f34eb
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20201216/29c1703f/attachment-0001.html>
More information about the pkg-nagios-changes
mailing list