return string(buf);
}
-void DNSCryptContext::addNewCertificate(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, bool active)
+void DNSCryptContext::addNewCertificate(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, bool active, bool reload)
{
WriteLock w(&d_lock);
for (auto pair : certs) {
if (pair->cert.getSerial() == newCert.getSerial()) {
- throw std::runtime_error("Error adding a new certificate: we already have a certificate with the same serial");
+ if (reload) {
+ /* on reload we just assume that this is the same certificate */
+ return;
+ }
+ else {
+ throw std::runtime_error("Error adding a new certificate: we already have a certificate with the same serial");
+ }
}
}
certs.push_back(pair);
}
-void DNSCryptContext::loadNewCertificate(const std::string& certFile, const std::string& keyFile, bool active)
+void DNSCryptContext::loadNewCertificate(const std::string& certFile, const std::string& keyFile, bool active, bool reload)
{
DNSCryptCert newCert;
DNSCryptPrivateKey newPrivateKey;
loadCertFromFile(certFile, newCert);
newPrivateKey.loadFromFile(keyFile);
- addNewCertificate(newCert, newPrivateKey, active);
+ addNewCertificate(newCert, newPrivateKey, active, reload);
+ certificatePath = certFile;
+ keyPath = keyFile;
+}
+
+void DNSCryptContext::reloadCertificate()
+{
+ loadNewCertificate(certificatePath, keyPath, true, true);
}
void DNSCryptContext::markActive(uint32_t serial)
DNSCryptContext(const std::string& pName, const std::string& certFile, const std::string& keyFile);
DNSCryptContext(const std::string& pName, const DNSCryptCert& certificate, const DNSCryptPrivateKey& pKey);
- void loadNewCertificate(const std::string& certFile, const std::string& keyFile, bool active=true);
- void addNewCertificate(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, bool active=true);
+ void reloadCertificate();
+ void loadNewCertificate(const std::string& certFile, const std::string& keyFile, bool active=true, bool reload=false);
+ void addNewCertificate(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, bool active=true, bool reload=false);
void markActive(uint32_t serial);
void markInactive(uint32_t serial);
void removeInactiveCertificate(uint32_t serial);
pthread_rwlock_t d_lock;
std::vector<std::shared_ptr<DNSCryptCertificatePair>> certs;
DNSName providerName;
+ std::string certificatePath;
+ std::string keyPath;
};
bool generateDNSCryptCertificate(const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, DNSCryptExchangeVersion version, DNSCryptCert& certOut, DNSCryptPrivateKey& keyOut);
{ "RCodeRule", true, "rcode", "matches responses with the specified rcode" },
{ "RegexRule", true, "regex", "matches the query name against the supplied regex" },
{ "registerDynBPFFilter", true, "DynBPFFilter", "register this dynamic BPF filter into the web interface so that its counters are displayed" },
+ { "reloadAllCertificates", true, "", "reload all DNSCrypt and TLS certificates, along with their associated keys" },
{ "RemoteLogAction", true, "RemoteLogger [, alterFunction [, serverID]]", "send the content of this query to a remote logger via Protocol Buffer. `alterFunction` is a callback, receiving a DNSQuestion and a DNSDistProtoBufMessage, that can be used to modify the Protocol Buffer content, for example for anonymization purposes. `serverID` is the server identifier." },
{ "RemoteLogResponseAction", true, "RemoteLogger [,alterFunction [,includeCNAME [, serverID]]]", "send the content of this response to a remote logger via Protocol Buffer. `alterFunction` is the same callback than the one in `RemoteLogAction` and `includeCNAME` indicates whether CNAME records inside the response should be parsed and exported. The default is to only exports A and AAAA records. `serverID` is the server identifier." },
{ "rmCacheHitResponseRule", true, "id", "remove cache hit response rule in position 'id', or whose uuid matches if 'id' is an UUID string" },
#endif
});
- g_lua.writeFunction("setAllowEmptyResponse", [](bool allow) { g_allowEmptyResponse=allow; });
+ g_lua.writeFunction("reloadAllCertificates", []() {
+ for (auto& frontend : g_frontends) {
+ if (!frontend) {
+ continue;
+ }
+ try {
+#ifdef HAVE_DNSCRYPT
+ if (frontend->dnscryptCtx) {
+ frontend->dnscryptCtx->reloadCertificate();
+ }
+#endif /* HAVE_DNSCRYPT */
+#ifdef HAVE_DNS_OVER_TLS
+ if (frontend->tlsFrontend) {
+ frontend->tlsFrontend->setupTLS();
+ }
+#endif /* HAVE_DNS_OVER_TLS */
+ }
+ catch(const std::exception& e) {
+ errlog("Error reloading certificates for frontend %s: %s", frontend->local.toStringWithPort(), e.what());
+ }
+ }
+ });
+
+ g_lua.writeFunction("setAllowEmptyResponse", [](bool allow) { g_allowEmptyResponse=allow; });
}
vector<std::function<void(void)>> setupLua(bool client, const std::string& config)
:param str path: The directory to load configuration files from. Each file must end in ``.conf``.
+.. function:: reloadAllCertificates()
+
+ .. versionadded:: 1.4.0
+
+ Reload all DNSCrypt and TLS certificates, along with their associated keys.
+
Listen Sockets
~~~~~~~~~~~~~~