| 190 | } |
| 191 | |
| 192 | void Client::refreshCertificatesTask(const Poco::Util::AbstractConfiguration & config) |
| 193 | { |
| 194 | chassert(keys_initialized); |
| 195 | chassert(api && api->isReady()); |
| 196 | |
| 197 | auto component_guard = Coordination::setCurrentComponent("ACME::Client::refreshCertificatesTask"); |
| 198 | try |
| 199 | { |
| 200 | auto context = Context::getGlobalContextInstance(); |
| 201 | auto zk = context->getZooKeeper(); |
| 202 | |
| 203 | bool need_refresh = false; |
| 204 | for (const auto & domain : domains) |
| 205 | { |
| 206 | std::string private_key; |
| 207 | std::string pem_certificate; |
| 208 | |
| 209 | zk->tryGet(fs::path(zookeeper_path) / acme_hostname / "domains" / domain / "private_key", private_key); |
| 210 | zk->tryGet(fs::path(zookeeper_path) / acme_hostname / "domains" / domain / "certificate", pem_certificate); |
| 211 | |
| 212 | if (private_key.empty() || pem_certificate.empty()) |
| 213 | { |
| 214 | need_refresh = true; |
| 215 | break; |
| 216 | } |
| 217 | |
| 218 | auto x509_certificate_list = X509Certificate::fromBuffer(pem_certificate); |
| 219 | auto & x509_certificate = x509_certificate_list.front(); |
| 220 | |
| 221 | LOG_TRACE(log, "Certificate for domain {} expires on {}", domain, x509_certificate.expiresOn()); |
| 222 | |
| 223 | int tzd = 0; |
| 224 | auto expiration_date = Poco::DateTimeParser::parse("%y%m%d%H%M%S", x509_certificate.expiresOn(), tzd); |
| 225 | auto best_before = Poco::Timestamp() + Poco::Timespan(refresh_certificates_before_seconds * Poco::Timespan::SECONDS); |
| 226 | |
| 227 | if (expiration_date < best_before) |
| 228 | { |
| 229 | LOG_INFO(log, "Certificate for domain {} expires soon, initiating refresh", domain); |
| 230 | need_refresh = true; |
| 231 | break; |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | if (!need_refresh) |
| 236 | { |
| 237 | LOG_DEBUG(log, "All certificates are up to date"); |
| 238 | |
| 239 | CertificateReloader::instance().tryLoad(config); |
| 240 | |
| 241 | refresh_certificates_task->scheduleAfter(refresh_certificates_task_interval_ms); |
| 242 | return; |
| 243 | } |
| 244 | |
| 245 | auto active_order_path = fs::path(zookeeper_path) / acme_hostname / "active_order"; |
| 246 | if ((!lock || !lock->isLocked()) && zk->exists(active_order_path)) |
| 247 | { |
| 248 | LOG_DEBUG( |
| 249 | log, |
nothing calls this directly
no test coverage detected