Apache HTTPD
md_status.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <assert.h>
18#include <stdlib.h>
19
20#include <apr_lib.h>
21#include <apr_strings.h>
22#include <apr_tables.h>
23#include <apr_time.h>
24#include <apr_date.h>
25
26#include "md_json.h"
27#include "md.h"
28#include "md_acme.h"
29#include "md_crypt.h"
30#include "md_event.h"
31#include "md_log.h"
32#include "md_ocsp.h"
33#include "md_store.h"
34#include "md_result.h"
35#include "md_reg.h"
36#include "md_util.h"
37#include "md_status.h"
38
39#define MD_STATUS_WITH_SCTS 0
40
41/**************************************************************************************************/
42/* certificate status information */
43
45{
46 const char *finger;
48 md_timeperiod_t valid;
49 md_json_t *json;
50
51 json = md_json_create(p);
58
59#if MD_STATUS_WITH_SCTS
60 do {
62 const char *hex;
63 const md_sct *sct;
65 int i;
66
67 scts = apr_array_make(p, 5, sizeof(const md_sct*));
69 for (i = 0; i < scts->nelts; ++i) {
70 sct = APR_ARRAY_IDX(scts, i, const md_sct*);
72
73 apr_rfc822_date(ts, sct->timestamp);
74 md_json_sets(ts, sctj, "signed", NULL);
76 md_data_to_hex(&hex, 0, p, sct->logid);
77 md_json_sets(hex, sctj, "logid", NULL);
78 md_data_to_hex(&hex, 0, p, sct->signature);
79 md_json_sets(hex, sctj, "signature", NULL);
80 md_json_sets(md_nid_get_sname(sct->signature_type_nid), sctj, "signature-type", NULL);
81 md_json_addj(sctj, json, "scts", NULL);
82 }
83 }
84 while (0);
85#endif
86leave:
87 *pjson = (APR_SUCCESS == rv)? json : NULL;
88 return rv;
89}
90
92 struct md_reg_t *reg, int with_log, apr_pool_t *p)
93{
94 apr_status_t rv;
95
96 md_store_t *store = md_reg_store_get(reg);
97 rv = md_store_load_json(store, group, name, MD_FN_JOB, pjson, p);
99 return rv;
100}
101
104 const md_cert_t *cert,
105 const md_t *md,
106 md_reg_t *reg,
107 md_ocsp_reg_t *ocsp,
108 int with_logs,
109 apr_pool_t *p)
110{
114 apr_status_t rv;
115
116 if (APR_SUCCESS != (rv = status_get_cert_json(&certj, cert, p))) goto leave;
117 if (md->stapling && ocsp) {
118 rv = md_ocsp_get_meta(&cert_stat, &ocsp_valid, ocsp, cert, p, md);
119 if (APR_SUCCESS == rv) {
122 }
123 else if (!APR_STATUS_IS_ENOENT(rv)) goto leave;
124 rv = APR_SUCCESS;
125 if (APR_SUCCESS == job_loadj(&jobj, MD_SG_OCSP, md->name, reg, with_logs, p)) {
127 }
128 }
129leave:
130 *pjson = (APR_SUCCESS == rv)? certj : NULL;
131 return rv;
132}
133
134static int get_cert_count(const md_t *md, int from_staging)
135{
136 if (!from_staging && md->cert_files && md->cert_files->nelts) {
137 return md->cert_files->nelts;
138 }
139 return md_pkeys_spec_count(md->pks);
140}
141
142static const char *get_cert_name(const md_t *md, int i, int from_staging, apr_pool_t *p)
143{
144 if (!from_staging && md->cert_files && md->cert_files->nelts) {
145 /* static files configured, not from staging, used index names */
146 return apr_psprintf(p, "%d", i);
147 }
149}
150
152 int from_staging,
153 const md_t *md, md_reg_t *reg,
154 md_ocsp_reg_t *ocsp, int with_logs,
155 apr_pool_t *p)
156{
157 md_json_t *json, *certj;
158 md_timeperiod_t certs_valid = {0, 0}, valid;
160 int i;
162
163 json = md_json_create(p);
164 for (i = 0; i < get_cert_count(md, from_staging); ++i) {
165 cert = APR_ARRAY_IDX(certs, i, md_cert_t*);
166 if (!cert) continue;
167
168 rv = status_get_cert_json_ex(&certj, cert, md, reg, ocsp, with_logs, p);
169 if (APR_SUCCESS != rv) goto leave;
170 valid = md_cert_get_valid(cert);
171 certs_valid = i? md_timeperiod_common(&certs_valid, &valid) : valid;
173 }
174
175 if (certs_valid.start) {
177 }
178leave:
179 *pjson = (APR_SUCCESS == rv)? json : NULL;
180 return rv;
181}
182
184 md_reg_t *reg, apr_pool_t *p)
185{
186 md_pkey_spec_t *spec;
187 int i;
188 apr_array_header_t *chain, *certs;
189 const md_cert_t *cert;
190 apr_status_t rv;
191
192 certs = apr_array_make(p, 5, sizeof(md_cert_t*));
193 for (i = 0; i < get_cert_count(md, 1); ++i) {
194 spec = md_pkeys_spec_get(md->pks, i);
195 cert = NULL;
196 rv = md_pubcert_load(md_reg_store_get(reg), MD_SG_STAGING, md->name, spec, &chain, p);
197 if (APR_SUCCESS == rv) {
198 cert = APR_ARRAY_IDX(chain, 0, const md_cert_t*);
199 }
200 APR_ARRAY_PUSH(certs, const md_cert_t*) = cert;
201 }
202 return status_get_certs_json(pjson, certs, 1, md, reg, NULL, 0, p);
203}
204
206 md_reg_t *reg, md_ocsp_reg_t *ocsp,
207 int with_logs, apr_pool_t *p)
208{
210 int renew;
211 const md_pubcert_t *pubcert;
212 const md_cert_t *cert = NULL;
213 apr_array_header_t *certs;
216 int i;
217
218 mdj = md_to_public_json(md, p);
219 certs = apr_array_make(p, 5, sizeof(md_cert_t*));
220 for (i = 0; i < get_cert_count(md, 0); ++i) {
221 cert = NULL;
222 if (APR_SUCCESS == md_reg_get_pubcert(&pubcert, reg, md, i, p)) {
223 cert = APR_ARRAY_IDX(pubcert->certs, 0, const md_cert_t*);
224 }
225 APR_ARRAY_PUSH(certs, const md_cert_t*) = cert;
226 }
227
228 rv = status_get_certs_json(&certsj, certs, 0, md, reg, ocsp, with_logs, p);
229 if (APR_SUCCESS != rv) goto leave;
231
232 renew_at = md_reg_renew_at(reg, md, p);
233 if (renew_at > 0) {
235 }
236
239 renew = md_reg_should_renew(reg, md, p);
240 if (renew) {
242 rv = job_loadj(&jobj, MD_SG_STAGING, md->name, reg, with_logs, p);
243 if (APR_SUCCESS == rv) {
244 if (APR_SUCCESS == get_staging_certs_json(&certsj, md, reg, p)) {
246 }
248 }
249 else if (APR_STATUS_IS_ENOENT(rv)) rv = APR_SUCCESS;
250 else goto leave;
251 }
252
253leave:
254 if (APR_SUCCESS != rv) {
256 }
257 *pjson = mdj;
258 return rv;
259}
260
262 md_reg_t *reg, md_ocsp_reg_t *ocsp, apr_pool_t *p)
263{
264 return status_get_md_json(pjson, md, reg, ocsp, 1, p);
265}
266
268 md_reg_t *reg, md_ocsp_reg_t *ocsp, apr_pool_t *p)
269{
270 md_json_t *json, *mdj;
271 const md_t *md;
272 int i;
273
274 json = md_json_create(p);
276 for (i = 0; i < mds->nelts; ++i) {
277 md = APR_ARRAY_IDX(mds, i, const md_t *);
278 status_get_md_json(&mdj, md, reg, ocsp, 0, p);
280 }
281 *pjson = json;
282 return APR_SUCCESS;
283}
284
285/**************************************************************************************************/
286/* drive job persistence */
287
289 md_store_group_t group, const char *name,
290 apr_time_t min_delay)
291{
292 md_job_t *job = apr_pcalloc(p, sizeof(*job));
293 job->group = group;
294 job->mdomain = apr_pstrdup(p, name);
295 job->store = store;
296 job->p = p;
297 job->max_log = 128;
298 job->min_delay = min_delay;
299 return job;
300}
301
303{
304 job->group = group;
305}
306
308{
309 const char *s;
310
311 /* not good, this is malloced from a temp pool */
312 /*job->mdomain = md_json_gets(json, MD_KEY_NAME, NULL);*/
317 if (s && *s) job->next_run = apr_date_parse_rfc(s);
319 if (s && *s) job->last_run = apr_date_parse_rfc(s);
321 if (s && *s) job->valid_from = apr_date_parse_rfc(s);
323 if (md_json_has_key(json, MD_KEY_LAST, NULL)) {
325 }
326 job->log = md_json_getj(json, MD_KEY_LOG, NULL);
327}
328
329static void job_to_json(md_json_t *json, const md_job_t *job,
331{
332 char ts[APR_RFC822_DATE_LEN];
333
334 md_json_sets(job->mdomain, json, MD_KEY_NAME, NULL);
338 if (job->next_run > 0) {
339 apr_rfc822_date(ts, job->next_run);
341 }
342 if (job->last_run > 0) {
343 apr_rfc822_date(ts, job->last_run);
345 }
346 if (job->valid_from > 0) {
347 apr_rfc822_date(ts, job->valid_from);
349 }
351 if (!result) result = job->last_result;
352 if (result) {
354 }
355 if (job->log) md_json_setj(job->log, json, MD_KEY_LOG, NULL);
356}
357
359{
361 apr_status_t rv;
362
363 rv = md_store_load_json(job->store, job->group, job->mdomain, MD_FN_JOB, &jprops, job->p);
364 if (APR_SUCCESS == rv) {
365 md_job_from_json(job, jprops, job->p);
366 }
367 return rv;
368}
369
371{
373 apr_status_t rv;
374
376 job_to_json(jprops, job, result, p);
377 rv = md_store_save_json(job->store, p, job->group, job->mdomain, MD_FN_JOB, jprops, 0);
378 if (APR_SUCCESS == rv) job->dirty = 0;
379 return rv;
380}
381
382void md_job_log_append(md_job_t *job, const char *type,
383 const char *status, const char *detail)
384{
385 md_json_t *entry;
386 char ts[APR_RFC822_DATE_LEN];
387
388 entry = md_json_create(job->p);
390 md_json_sets(ts, entry, MD_KEY_WHEN, NULL);
393 if (detail) md_json_sets(detail, entry, MD_KEY_DETAIL, NULL);
394 if (!job->log) job->log = md_json_create(job->p);
395 md_json_insertj(entry, 0, job->log, MD_KEY_ENTRIES, NULL);
397 job->dirty = 1;
398}
399
400typedef struct {
402 const char *type;
404 size_t index;
406
407static int find_first_log_entry(void *baton, size_t index, md_json_t *entry)
408{
410 const char *etype;
411
413 if (etype == ctx->type || (etype && ctx->type && !strcmp(etype, ctx->type))) {
414 ctx->entry = entry;
415 ctx->index = index;
416 return 0;
417 }
418 return 1;
419}
420
422
423{
425
426 memset(&ctx, 0, sizeof(ctx));
427 ctx.job = job;
428 ctx.type = type;
430 return ctx.entry;
431}
432
434{
435 md_json_t *entry;
436 const char *s;
437
438 entry = md_job_log_get_latest(job, type);
439 if (entry) {
440 s = md_json_gets(entry, MD_KEY_WHEN, NULL);
441 if (s) return apr_date_parse_rfc(s);
442 }
443 return 0;
444}
445
447 md_reg_t *reg, apr_pool_t *p)
448{
449 const md_t *md;
450 md_job_t *job;
451 int i, complete, renewing, errored, ready, total;
452 md_json_t *json;
453
454 json = md_json_create(p);
455 complete = renewing = errored = ready = total = 0;
456 for (i = 0; i < mds->nelts; ++i) {
457 md = APR_ARRAY_IDX(mds, i, const md_t *);
458 ++total;
459 switch (md->state) {
460 case MD_S_COMPLETE: ++complete; /* fall through */
461 case MD_S_INCOMPLETE:
462 if (md_reg_should_renew(reg, md, p)) {
463 ++renewing;
464 job = md_reg_job_make(reg, md->name, p);
465 if (APR_SUCCESS == md_job_load(job)) {
466 if (job->error_runs > 0
467 || (job->last_result && job->last_result->status != APR_SUCCESS)) {
468 ++errored;
469 }
470 else if (job->finished) {
471 ++ready;
472 }
473 }
474 }
475 break;
476 default: ++errored; break;
477 }
478 }
479 md_json_setl(total, json, MD_KEY_TOTAL, NULL);
480 md_json_setl(complete, json, MD_KEY_COMPLETE, NULL);
483 md_json_setl(ready, json, MD_KEY_READY, NULL);
484 *pjson = json;
485}
486
494
496{
499 const char *msg, *sep;
500
501 if (md_result_cmp(ctx->last, result)) {
502 now = apr_time_now();
504 if (result->activity || result->problem || result->detail) {
505 msg = sep = "";
506 if (result->activity) {
507 msg = apr_psprintf(result->p, "%s", result->activity);
508 sep = ": ";
509 }
510 if (result->detail) {
511 msg = apr_psprintf(result->p, "%s%s%s", msg, sep, result->detail);
512 sep = ", ";
513 }
514 if (result->problem) {
515 msg = apr_psprintf(result->p, "%s%sproblem: %s", msg, sep, result->problem);
516 sep = " ";
517 }
518 md_job_log_append(ctx->job, "progress", NULL, msg);
519
520 if (ctx->store && apr_time_as_msec(now - ctx->last_save) > 500) {
521 md_job_save(ctx->job, result, ctx->p);
522 ctx->last_save = now;
523 }
524 }
525 }
526}
527
529{
531 (void)p;
532 if (result == ctx->job->observing) {
533 return md_job_notify(ctx->job, event, result);
534 }
535 return APR_SUCCESS;
536}
537
538static void job_result_holler(md_result_t *result, void *data, const char *event, apr_pool_t *p)
539{
541 if (result == ctx->job->observing) {
542 md_event_holler(event, ctx->job->mdomain, ctx->job, result, p);
543 }
544}
545
563
565{
567 job->observing = NULL;
568}
569
571{
572 job->fatal_error = 0;
573 job->last_run = apr_time_now();
574 job_observation_start(job, result, store);
575 md_job_log_append(job, "starting", NULL, NULL);
576}
577
579{
580 apr_time_t delay = 0, max_delay = apr_time_from_sec(24*60*60); /* daily */
581 unsigned char c;
582
584 /* If ACME server reported a problem and that problem indicates that our
585 * input values, e.g. our configuration, has something wrong, we always
586 * go to max delay as frequent retries are unlikely to resolve the situation.
587 * However, we should nevertheless retry daily, bc. it might be that there
588 * is a bug in the server. Unlikely, but... */
590 }
591 else if (err_count > 0) {
592 /* back off duration, depending on the errors we encounter in a row */
593 delay = job->min_delay << (err_count - 1);
594 if (delay > max_delay) {
596 }
597 }
598 if (delay > 0) {
599 /* jitter the delay by +/- 0-50%.
600 * Background: we see retries of jobs being too regular (e.g. all at midnight),
601 * possibly cumulating from many installations that restart their Apache at a
602 * fixed hour. This can contribute to an overload at the CA and a continuation
603 * of failure.
604 */
605 md_rand_bytes(&c, sizeof(c), job->p);
606 delay += apr_time_from_sec((apr_time_sec(delay) * (c - 128)) / 256);
607 }
608 return delay;
609}
610
612{
613 if (APR_SUCCESS == result->status) {
614 job->finished = 1;
615 job->valid_from = result->ready_at;
616 job->error_runs = 0;
617 job->dirty = 1;
618 md_job_log_append(job, "finished", NULL, NULL);
619 }
620 else {
621 ++job->error_runs;
622 job->dirty = 1;
623 job->next_run = apr_time_now() + md_job_delay_on_errors(job, job->error_runs, result->problem);
624 }
626}
627
629{
630 job->next_run = later;
631 job->dirty = 1;
632}
633
635{
636 apr_status_t rv;
637
639 rv = md_event_raise(reason, job->mdomain, job, result, job->p);
640 job->dirty = 1;
641 if (APR_SUCCESS == rv && APR_SUCCESS == result->status) {
642 job->notified = 1;
643 if (!strcmp("renewed", reason)) {
644 job->notified_renewed = 1;
645 }
646 }
647 else {
648 ++job->error_runs;
649 job->next_run = apr_time_now() + md_job_delay_on_errors(job, job->error_runs, result->problem);
650 }
651 return result->status;
652}
653
APR-UTIL date routines.
APR general purpose library routines.
APR Strings library.
APR Table library.
APR Time Library.
ap_vhost_iterate_conn_cb void * baton
Definition http_vhost.h:87
#define APR_STATUS_IS_ENOENT(s)
Definition apr_errno.h:1246
apr_brigade_flush void * ctx
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
int type
apr_array_header_t ** result
apr_vformatter_buff_t * c
Definition apr_lib.h:175
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * sep
const char * s
Definition apr_strings.h:95
#define APR_ARRAY_PUSH(ary, type)
Definition apr_tables.h:150
#define APR_ARRAY_IDX(ary, i, type)
Definition apr_tables.h:141
int reason
int int status
#define apr_time_as_msec(time)
Definition apr_time.h:72
#define APR_RFC822_DATE_LEN
Definition apr_time.h:186
apr_int64_t apr_time_t
Definition apr_time.h:45
#define apr_time_sec(time)
Definition apr_time.h:63
#define apr_time_from_sec(sec)
Definition apr_time.h:78
#define MD_KEY_VALID_FROM
Definition md.h:211
#define MD_KEY_RENEWAL
Definition md.h:184
#define MD_KEY_RENEW
Definition md.h:181
#define MD_KEY_WATCHED
Definition md.h:214
#define MD_KEY_ENTRIES
Definition md.h:143
@ MD_S_INCOMPLETE
Definition md.h:54
@ MD_S_COMPLETE
Definition md.h:55
#define MD_KEY_RENEW_AT
Definition md.h:182
#define MD_KEY_TOTAL
Definition md.h:202
#define MD_KEY_ERROR
Definition md.h:145
#define MD_KEY_NAME
Definition md.h:167
#define MD_KEY_LAST_RUN
Definition md.h:161
#define MD_KEY_COMPLETE
Definition md.h:131
#define MD_KEY_SERIAL
Definition md.h:191
#define MD_KEY_ERRORED
Definition md.h:144
#define MD_KEY_LOG
Definition md.h:163
#define MD_KEY_STAPLING
Definition md.h:193
#define MD_KEY_TYPE
Definition md.h:204
#define MD_KEY_READY
Definition md.h:179
#define MD_KEY_ERRORS
Definition md.h:146
#define MD_KEY_STATUS
Definition md.h:196
#define MD_KEY_SHA256_FINGERPRINT
Definition md.h:192
#define MD_KEY_FINISHED
Definition md.h:149
#define MD_KEY_RENEWING
Definition md.h:185
#define MD_KEY_LAST
Definition md.h:160
#define MD_KEY_NOTIFIED
Definition md.h:169
#define MD_KEY_VERSION
Definition md.h:213
#define MD_KEY_NEXT_RUN
Definition md.h:168
#define MD_KEY_VALID
Definition md.h:210
#define MD_KEY_CERT
Definition md.h:124
#define MD_KEY_MDS
Definition md.h:164
#define MD_KEY_OCSP
Definition md.h:171
#define MD_KEY_DETAIL
Definition md.h:136
struct md_json_t * md_to_public_json(const md_t *md, apr_pool_t *p)
Definition md_core.c:391
#define MD_KEY_WHEN
Definition md.h:215
#define MD_KEY_NOTIFIED_RENEWED
Definition md.h:170
int md_acme_problem_is_input_related(const char *problem)
Definition md_acme.c:91
apr_status_t md_rand_bytes(unsigned char *buf, apr_size_t len, apr_pool_t *p)
Definition md_crypt.c:162
apr_status_t md_cert_to_sha256_fingerprint(const char **pfinger, const md_cert_t *cert, apr_pool_t *p)
Definition md_crypt.c:1443
const char * md_cert_get_serial_number(const md_cert_t *cert, apr_pool_t *p)
Definition md_crypt.c:1180
md_pkey_spec_t * md_pkeys_spec_get(const md_pkeys_spec_t *pks, int index)
Definition md_crypt.c:562
const char * md_pkey_spec_name(const md_pkey_spec_t *spec)
Definition md_crypt.c:520
apr_time_t md_cert_get_not_before(const md_cert_t *cert)
Definition md_crypt.c:1217
md_timeperiod_t md_cert_get_valid(const md_cert_t *cert)
Definition md_crypt.c:1222
const char * md_nid_get_sname(int nid)
Definition md_crypt.c:2056
int md_pkeys_spec_count(const md_pkeys_spec_t *pks)
Definition md_crypt.c:555
apr_status_t md_cert_get_ct_scts(apr_array_header_t *scts, apr_pool_t *p, const md_cert_t *cert)
Definition md_crypt.c:2066
apr_time_t md_cert_get_not_after(const md_cert_t *cert)
Definition md_crypt.c:1212
apr_pool_t * p
Definition md_event.c:32
apr_status_t md_event_raise(const char *event, const char *mdomain, struct md_job_t *job, struct md_result_t *result, apr_pool_t *p)
Definition md_event.c:61
void md_event_holler(const char *event, const char *mdomain, struct md_job_t *job, struct md_result_t *result, apr_pool_t *p)
Definition md_event.c:78
md_json_t * md_json_create(apr_pool_t *pool)
Definition md_json.c:92
apr_status_t md_json_set_timeperiod(const md_timeperiod_t *tp, md_json_t *json,...)
Definition md_json.c:1259
int md_json_getb(const md_json_t *json,...)
Definition md_json.c:330
apr_status_t md_json_sets(const char *value, md_json_t *json,...)
Definition md_json.c:430
const char * md_json_gets(const md_json_t *json,...)
Definition md_json.c:406
long md_json_getl(const md_json_t *json,...)
Definition md_json.c:381
md_json_t * md_json_getj(md_json_t *json,...)
Definition md_json.c:473
const md_json_t * md_json_getcj(const md_json_t *json,...)
Definition md_json.c:508
apr_status_t md_json_addj(const md_json_t *value, md_json_t *json,...)
Definition md_json.c:555
apr_size_t md_json_limita(size_t max_elements, md_json_t *json,...)
Definition md_json.c:577
apr_status_t md_json_set_time(apr_time_t value, md_json_t *json,...)
Definition md_json.c:457
apr_status_t md_json_insertj(md_json_t *value, size_t index, md_json_t *json,...)
Definition md_json.c:566
apr_status_t md_json_del(md_json_t *json,...)
Definition md_json.c:618
apr_status_t md_json_setj(const md_json_t *value, md_json_t *json,...)
Definition md_json.c:527
int md_json_has_key(const md_json_t *json,...)
Definition md_json.c:279
int md_json_itera(md_json_itera_cb *cb, void *baton, md_json_t *json,...)
Definition md_json.c:809
apr_status_t md_json_setb(int value, md_json_t *json,...)
Definition md_json.c:342
const char * md_json_dups(apr_pool_t *p, const md_json_t *json,...)
Definition md_json.c:418
apr_status_t md_json_setl(long value, md_json_t *json,...)
Definition md_json.c:392
const char * md_ocsp_cert_stat_name(md_ocsp_cert_stat_t stat)
Definition md_ocsp.c:101
apr_status_t md_ocsp_get_meta(md_ocsp_cert_stat_t *pstat, md_timeperiod_t *pvalid, md_ocsp_reg_t *reg, const md_cert_t *cert, apr_pool_t *p, const md_t *md)
Definition md_ocsp.c:457
md_ocsp_cert_stat_t
Definition md_ocsp.h:27
apr_status_t md_reg_get_pubcert(const md_pubcert_t **ppubcert, md_reg_t *reg, const md_t *md, int i, apr_pool_t *p)
Definition md_reg.c:608
int md_reg_should_renew(md_reg_t *reg, const md_t *md, apr_pool_t *p)
Definition md_reg.c:706
md_job_t * md_reg_job_make(md_reg_t *reg, const char *mdomain, apr_pool_t *p)
Definition md_reg.c:1321
struct md_store_t * md_reg_store_get(md_reg_t *reg)
Definition md_reg.c:122
apr_time_t md_reg_renew_at(md_reg_t *reg, const md_t *md, apr_pool_t *p)
Definition md_reg.c:671
md_result_t * md_result_from_json(const struct md_json_t *json, apr_pool_t *p)
Definition md_result.c:144
struct md_json_t * md_result_to_json(const md_result_t *result, apr_pool_t *p)
Definition md_result.c:160
void md_result_on_holler(md_result_t *result, md_result_holler_cb *cb, void *data)
Definition md_result.c:281
void md_result_on_change(md_result_t *result, md_result_change_cb *cb, void *data)
Definition md_result.c:258
void md_result_assign(md_result_t *dest, const md_result_t *src)
Definition md_result.c:206
int md_result_cmp(const md_result_t *r1, const md_result_t *r2)
Definition md_result.c:193
void md_result_set(md_result_t *result, apr_status_t status, const char *detail)
Definition md_result.c:91
md_result_t * md_result_md_make(apr_pool_t *p, const char *md_name)
Definition md_result.c:50
void md_result_on_raise(md_result_t *result, md_result_raise_cb *cb, void *data)
Definition md_result.c:275
static apr_status_t job_loadj(md_json_t **pjson, md_store_group_t group, const char *name, struct md_reg_t *reg, int with_log, apr_pool_t *p)
Definition md_status.c:91
static apr_status_t status_get_md_json(md_json_t **pjson, const md_t *md, md_reg_t *reg, md_ocsp_reg_t *ocsp, int with_logs, apr_pool_t *p)
Definition md_status.c:205
static void job_observation_start(md_job_t *job, md_result_t *result, md_store_t *store)
Definition md_status.c:546
md_job_t * md_job_make(apr_pool_t *p, md_store_t *store, md_store_group_t group, const char *name, apr_time_t min_delay)
Definition md_status.c:288
void md_job_start_run(md_job_t *job, md_result_t *result, md_store_t *store)
Definition md_status.c:570
void md_job_set_group(md_job_t *job, md_store_group_t group)
Definition md_status.c:302
static const char * get_cert_name(const md_t *md, int i, int from_staging, apr_pool_t *p)
Definition md_status.c:142
static int find_first_log_entry(void *baton, size_t index, md_json_t *entry)
Definition md_status.c:407
static void job_result_holler(md_result_t *result, void *data, const char *event, apr_pool_t *p)
Definition md_status.c:538
apr_status_t md_job_load(md_job_t *job)
Definition md_status.c:358
static void job_observation_end(md_job_t *job)
Definition md_status.c:564
void md_job_end_run(md_job_t *job, md_result_t *result)
Definition md_status.c:611
static apr_status_t status_get_cert_json(md_json_t **pjson, const md_cert_t *cert, apr_pool_t *p)
Definition md_status.c:44
static int get_cert_count(const md_t *md, int from_staging)
Definition md_status.c:134
static void job_to_json(md_json_t *json, const md_job_t *job, md_result_t *result, apr_pool_t *p)
Definition md_status.c:329
static apr_status_t job_result_raise(md_result_t *result, void *data, const char *event, apr_pool_t *p)
Definition md_status.c:528
md_json_t * md_job_log_get_latest(md_job_t *job, const char *type)
Definition md_status.c:421
apr_status_t md_job_save(md_job_t *job, md_result_t *result, apr_pool_t *p)
Definition md_status.c:370
static apr_status_t status_get_cert_json_ex(md_json_t **pjson, const md_cert_t *cert, const md_t *md, md_reg_t *reg, md_ocsp_reg_t *ocsp, int with_logs, apr_pool_t *p)
Definition md_status.c:102
apr_status_t md_status_get_json(md_json_t **pjson, apr_array_header_t *mds, md_reg_t *reg, md_ocsp_reg_t *ocsp, apr_pool_t *p)
Definition md_status.c:267
static void md_job_from_json(md_job_t *job, md_json_t *json, apr_pool_t *p)
Definition md_status.c:307
apr_time_t md_job_delay_on_errors(md_job_t *job, int err_count, const char *last_problem)
Definition md_status.c:578
static void job_result_update(md_result_t *result, void *data)
Definition md_status.c:495
void md_job_retry_at(md_job_t *job, apr_time_t later)
Definition md_status.c:628
apr_time_t md_job_log_get_time_of_latest(md_job_t *job, const char *type)
Definition md_status.c:433
static apr_status_t status_get_certs_json(md_json_t **pjson, apr_array_header_t *certs, int from_staging, const md_t *md, md_reg_t *reg, md_ocsp_reg_t *ocsp, int with_logs, apr_pool_t *p)
Definition md_status.c:151
apr_status_t md_status_get_md_json(md_json_t **pjson, const md_t *md, md_reg_t *reg, md_ocsp_reg_t *ocsp, apr_pool_t *p)
Definition md_status.c:261
void md_job_log_append(md_job_t *job, const char *type, const char *status, const char *detail)
Definition md_status.c:382
void md_status_take_stock(md_json_t **pjson, apr_array_header_t *mds, md_reg_t *reg, apr_pool_t *p)
Definition md_status.c:446
apr_status_t md_job_notify(md_job_t *job, const char *reason, md_result_t *result)
Definition md_status.c:634
static apr_status_t get_staging_certs_json(md_json_t **pjson, const md_t *md, md_reg_t *reg, apr_pool_t *p)
Definition md_status.c:183
apr_status_t md_store_save_json(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, const char *aspect, struct md_json_t *data, int create)
Definition md_store.c:113
apr_status_t md_pubcert_load(md_store_t *store, md_store_group_t group, const char *name, md_pkey_spec_t *spec, struct apr_array_header_t **ppubcert, apr_pool_t *p)
Definition md_store.c:295
apr_status_t md_store_load_json(md_store_t *store, md_store_group_t group, const char *name, const char *aspect, struct md_json_t **pdata, apr_pool_t *p)
Definition md_store.c:106
md_store_group_t
Definition md_store.h:62
@ MD_SG_STAGING
Definition md_store.h:67
@ MD_SG_OCSP
Definition md_store.h:70
#define MD_FN_JOB
Definition md_store.h:75
md_timeperiod_t md_timeperiod_common(const md_timeperiod_t *a, const md_timeperiod_t *b)
Definition md_time.c:315
apr_status_t md_data_to_hex(const char **phex, char separator, apr_pool_t *p, const md_data_t *data)
Definition md_util.c:169
#define MOD_MD_VERSION
Definition md_version.h:30
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
char * name
const char * type
Definition md_status.c:402
size_t index
Definition md_status.c:404
md_job_t * job
Definition md_status.c:401
md_json_t * entry
Definition md_status.c:403
apr_pool_t * p
Definition md_status.c:488
apr_time_t last_save
Definition md_status.c:492
md_job_t * job
Definition md_status.c:489
md_result_t * last
Definition md_status.c:491
md_store_t * store
Definition md_status.c:490
struct md_result_t * observing
Definition md_status.h:70
apr_time_t min_delay
Definition md_status.h:71
int fatal_error
Definition md_status.h:65
int notified
Definition md_status.h:61
int error_runs
Definition md_status.h:64
int dirty
Definition md_status.h:69
apr_time_t last_run
Definition md_status.h:58
md_store_t * store
Definition md_status.h:55
const char * mdomain
Definition md_status.h:54
apr_time_t valid_from
Definition md_status.h:63
apr_time_t next_run
Definition md_status.h:57
int finished
Definition md_status.h:60
int notified_renewed
Definition md_status.h:62
struct md_result_t * last_result
Definition md_status.h:59
md_json_t * log
Definition md_status.h:66
apr_size_t max_log
Definition md_status.h:68
md_store_group_t group
Definition md_status.h:53
apr_pool_t * p
Definition md_status.h:56
apr_status_t status
Definition md_result.h:32
Definition md.h:76
const char * name
Definition md.h:77
md_state_t state
Definition md.h:108
int watched
Definition md.h:112
struct md_pkeys_spec_t * pks
Definition md.h:81
int stapling
Definition md.h:111
struct apr_array_header_t * cert_files
Definition md.h:91
apr_time_t end
Definition md_time.h:29
apr_time_t start
Definition md_time.h:28
static apr_time_t now
Definition testtime.c:33
apr_status_t apr_rfc822_date(char *date_str, apr_time_t t)
Definition timestr.c:42
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray