summaryrefslogtreecommitdiffstats
path: root/src/ssl_ocsp.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:11:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:11:10 +0000
commitcff6d757e3ba609c08ef2aaa00f07e53551e5bf6 (patch)
tree08c4fc3255483ad397d712edb4214ded49149fd9 /src/ssl_ocsp.c
parentAdding upstream version 2.9.7. (diff)
downloadhaproxy-cff6d757e3ba609c08ef2aaa00f07e53551e5bf6.tar.xz
haproxy-cff6d757e3ba609c08ef2aaa00f07e53551e5bf6.zip
Adding upstream version 3.0.0.upstream/3.0.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/ssl_ocsp.c')
-rw-r--r--src/ssl_ocsp.c411
1 files changed, 246 insertions, 165 deletions
diff --git a/src/ssl_ocsp.c b/src/ssl_ocsp.c
index 5b103af..7d3a485 100644
--- a/src/ssl_ocsp.c
+++ b/src/ssl_ocsp.c
@@ -33,13 +33,6 @@
#include <string.h>
#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <netinet/tcp.h>
-
-#include <import/ebpttree.h>
#include <import/ebsttree.h>
#include <import/lru.h>
@@ -47,44 +40,27 @@
#include <haproxy/applet.h>
#include <haproxy/arg.h>
#include <haproxy/base64.h>
-#include <haproxy/channel.h>
+#include <haproxy/cfgparse.h>
#include <haproxy/chunk.h>
#include <haproxy/cli.h>
#include <haproxy/connection.h>
-#include <haproxy/dynbuf.h>
#include <haproxy/errors.h>
-#include <haproxy/fd.h>
#include <haproxy/freq_ctr.h>
#include <haproxy/frontend.h>
#include <haproxy/global.h>
-#include <haproxy/http_rules.h>
+#include <haproxy/http_client.h>
+#include <haproxy/istbuf.h>
#include <haproxy/log.h>
#include <haproxy/openssl-compat.h>
-#include <haproxy/pattern-t.h>
-#include <haproxy/proto_tcp.h>
#include <haproxy/proxy.h>
-#include <haproxy/sample.h>
-#include <haproxy/sc_strm.h>
-#include <haproxy/quic_conn.h>
-#include <haproxy/quic_tp.h>
-#include <haproxy/server.h>
#include <haproxy/shctx.h>
#include <haproxy/ssl_ckch.h>
-#include <haproxy/ssl_crtlist.h>
+#include <haproxy/ssl_ocsp-t.h>
#include <haproxy/ssl_sock.h>
#include <haproxy/ssl_utils.h>
-#include <haproxy/stats.h>
-#include <haproxy/stconn.h>
-#include <haproxy/stream-t.h>
#include <haproxy/task.h>
#include <haproxy/ticks.h>
#include <haproxy/time.h>
-#include <haproxy/tools.h>
-#include <haproxy/vars.h>
-#include <haproxy/xxhash.h>
-#include <haproxy/istbuf.h>
-#include <haproxy/ssl_ocsp-t.h>
-#include <haproxy/http_client.h>
/* ***** READ THIS before adding code here! *****
@@ -98,6 +74,8 @@
* to conditionally define it in openssl-compat.h than using lots of ifdefs.
*/
+static struct sockaddr_storage *ocsp_update_dst;
+
#ifndef OPENSSL_NO_OCSP
int ocsp_ex_index = -1;
@@ -383,6 +361,25 @@ int ssl_sock_update_ocsp_response(struct buffer *ocsp_response, char **err)
#if !defined OPENSSL_IS_BORINGSSL
/*
+ * Must be called under ocsp_tree_lock lock.
+ */
+static void ssl_sock_free_ocsp_data(struct certificate_ocsp *ocsp)
+{
+ ebmb_delete(&ocsp->key);
+ eb64_delete(&ocsp->next_update);
+ X509_free(ocsp->issuer);
+ ocsp->issuer = NULL;
+ sk_X509_pop_free(ocsp->chain, X509_free);
+ ocsp->chain = NULL;
+ chunk_destroy(&ocsp->response);
+ if (ocsp->uri) {
+ ha_free(&ocsp->uri->area);
+ ha_free(&ocsp->uri);
+ }
+ free(ocsp);
+}
+
+/*
* Decrease the refcount of the struct ocsp_response and frees it if it's not
* used anymore. Also removes it from the tree if free'd.
*/
@@ -392,21 +389,37 @@ void ssl_sock_free_ocsp(struct certificate_ocsp *ocsp)
return;
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
+ ocsp->refcount_store--;
+ if (ocsp->refcount_store <= 0) {
+ eb64_delete(&ocsp->next_update);
+ /* Might happen if some ongoing requests kept using an SSL_CTX
+ * that referenced this OCSP response after the corresponding
+ * ckch_store was deleted or changed (via cli commands for
+ * instance).
+ */
+ if (ocsp->refcount <= 0)
+ ssl_sock_free_ocsp_data(ocsp);
+ }
+ HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
+}
+
+void ssl_sock_free_ocsp_instance(struct certificate_ocsp *ocsp)
+{
+ if (!ocsp)
+ return;
+
+ HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
ocsp->refcount--;
if (ocsp->refcount <= 0) {
- ebmb_delete(&ocsp->key);
eb64_delete(&ocsp->next_update);
- X509_free(ocsp->issuer);
- ocsp->issuer = NULL;
- sk_X509_pop_free(ocsp->chain, X509_free);
- ocsp->chain = NULL;
- chunk_destroy(&ocsp->response);
- if (ocsp->uri) {
- ha_free(&ocsp->uri->area);
- ha_free(&ocsp->uri);
- }
+ /* Might happen if some ongoing requests kept using an SSL_CTX
+ * that referenced this OCSP response after the corresponding
+ * ckch_store was deleted or changed (via cli commands for
+ * instance).
+ */
+ if (ocsp->refcount_store <= 0)
+ ssl_sock_free_ocsp_data(ocsp);
- free(ocsp);
}
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
}
@@ -626,13 +639,13 @@ void ssl_sock_ocsp_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int id
ocsp_arg = ptr;
if (ocsp_arg->is_single) {
- ssl_sock_free_ocsp(ocsp_arg->s_ocsp);
+ ssl_sock_free_ocsp_instance(ocsp_arg->s_ocsp);
ocsp_arg->s_ocsp = NULL;
} else {
int i;
for (i = 0; i < SSL_SOCK_NUM_KEYTYPES; i++) {
- ssl_sock_free_ocsp(ocsp_arg->m_ocsp[i]);
+ ssl_sock_free_ocsp_instance(ocsp_arg->m_ocsp[i]);
ocsp_arg->m_ocsp[i] = NULL;
}
}
@@ -907,7 +920,7 @@ static int ssl_ocsp_task_schedule()
}
REGISTER_POST_CHECK(ssl_ocsp_task_schedule);
-void ssl_sock_free_ocsp(struct certificate_ocsp *ocsp);
+void ssl_sock_free_ocsp_instance(struct certificate_ocsp *ocsp);
void ssl_destroy_ocsp_update_task(void)
{
@@ -929,7 +942,7 @@ void ssl_destroy_ocsp_update_task(void)
task_destroy(ocsp_update_task);
ocsp_update_task = NULL;
- ssl_sock_free_ocsp(ssl_ocsp_task_ctx.cur_ocsp);
+ ssl_sock_free_ocsp_instance(ssl_ocsp_task_ctx.cur_ocsp);
ssl_ocsp_task_ctx.cur_ocsp = NULL;
if (ssl_ocsp_task_ctx.hc) {
@@ -966,12 +979,6 @@ static inline void ssl_ocsp_set_next_update(struct certificate_ocsp *ocsp)
*/
int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp)
{
- /* This entry was only supposed to be updated once, it does not need to
- * be reinserted into the update tree.
- */
- if (ocsp->update_once)
- return 0;
-
/* Set next_update based on current time and the various OCSP
* minimum/maximum update times.
*/
@@ -980,7 +987,12 @@ int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp)
ocsp->fail_count = 0;
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
- eb64_insert(&ocsp_update_tree, &ocsp->next_update);
+ ocsp->updating = 0;
+ /* An entry with update_once set to 1 was only supposed to be updated
+ * once, it does not need to be reinserted into the update tree.
+ */
+ if (!ocsp->update_once)
+ eb64_insert(&ocsp_update_tree, &ocsp->next_update);
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
return 0;
@@ -997,12 +1009,6 @@ int ssl_ocsp_update_insert_after_error(struct certificate_ocsp *ocsp)
{
int replay_delay = 0;
- /* This entry was only supposed to be updated once, it does not need to
- * be reinserted into the update tree.
- */
- if (ocsp->update_once)
- return 0;
-
/*
* Set next_update based on current time and the various OCSP
* minimum/maximum update times.
@@ -1025,7 +1031,12 @@ int ssl_ocsp_update_insert_after_error(struct certificate_ocsp *ocsp)
ocsp->next_update.key = date.tv_sec + replay_delay;
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
- eb64_insert(&ocsp_update_tree, &ocsp->next_update);
+ ocsp->updating = 0;
+ /* An entry with update_once set to 1 was only supposed to be updated
+ * once, it does not need to be reinserted into the update tree.
+ */
+ if (!ocsp->update_once)
+ eb64_insert(&ocsp_update_tree, &ocsp->next_update);
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
return 0;
@@ -1077,10 +1088,8 @@ void ocsp_update_response_end_cb(struct httpclient *hc)
/*
- * Send a log line that will mimic this previously used logformat :
- * char ocspupdate_log_format[] = "%ci:%cp [%tr] %ft %[ssl_ocsp_certname] \
- * %[ssl_ocsp_status] %{+Q}[ssl_ocsp_status_str] %[ssl_ocsp_fail_cnt] \
- * %[ssl_ocsp_success_cnt]";
+ * Send a log line that will contain only OCSP update related information:
+ * "<proxy_name> <ssl_ocsp_certname> <ocsp_status> \"<ocsp_status_str>\" <ocsp_fail_cnt> <ocsp_success_cnt>"
* We can't use the regular sess_log function because we don't have any control
* over the stream and session used by the httpclient which might not exist
* anymore by the time we call this function.
@@ -1090,8 +1099,6 @@ static void ssl_ocsp_send_log()
int status_str_len = 0;
char *status_str = NULL;
struct certificate_ocsp *ocsp = ssl_ocsp_task_ctx.cur_ocsp;
- struct tm tm;
- char timebuf[25];
if (!httpclient_ocsp_update_px)
return;
@@ -1101,11 +1108,7 @@ static void ssl_ocsp_send_log()
status_str = istptr(ocsp_update_errors[ssl_ocsp_task_ctx.update_status]);
}
- get_localtime(date.tv_sec, &tm);
- date2str_log(timebuf, &tm, &date, 25);
-
- send_log(httpclient_ocsp_update_px, LOG_INFO, "-:- [%s] %s %s %u \"%.*s\" %u %u",
- timebuf,
+ send_log(httpclient_ocsp_update_px, LOG_NOTICE, "%s %s %u \"%.*s\" %u %u",
httpclient_ocsp_update_px->id,
ocsp->path,
ssl_ocsp_task_ctx.update_status,
@@ -1211,7 +1214,7 @@ static struct task *ssl_ocsp_update_responses(struct task *task, void *context,
/* Reinsert the entry into the update list so that it can be updated later */
ssl_ocsp_update_insert(ocsp);
/* Release the reference kept on the updated ocsp response. */
- ssl_sock_free_ocsp(ctx->cur_ocsp);
+ ssl_sock_free_ocsp_instance(ctx->cur_ocsp);
ctx->cur_ocsp = NULL;
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
@@ -1255,6 +1258,7 @@ static struct task *ssl_ocsp_update_responses(struct task *task, void *context,
eb64_delete(&ocsp->next_update);
++ocsp->refcount;
+ ocsp->updating = 1;
ctx->cur_ocsp = ocsp;
ocsp->last_update_status = OCSP_UPDT_UNKNOWN;
@@ -1293,6 +1297,15 @@ static struct task *ssl_ocsp_update_responses(struct task *task, void *context,
goto leave;
}
+ /* if the ocsp_update.http_proxy option was set */
+ if (ocsp_update_dst) {
+ hc->flags |= HC_F_HTTPPROXY;
+ if (!sockaddr_alloc(&hc->dst, ocsp_update_dst, sizeof(*ocsp_update_dst))) {
+ ha_alert("ocsp-update: Failed to allocate sockaddr in %s:%d.\n", __FUNCTION__, __LINE__);
+ goto leave;
+ }
+ }
+
if (httpclient_req_gen(hc, hc->req.url, hc->req.meth,
b_data(req_body) ? ocsp_request_hdrs : NULL,
b_data(req_body) ? ist2(b_orig(req_body), b_data(req_body)) : IST_NULL) != ERR_NONE) {
@@ -1321,7 +1334,7 @@ leave:
++ctx->cur_ocsp->num_failure;
ssl_ocsp_update_insert_after_error(ctx->cur_ocsp);
/* Release the reference kept on the updated ocsp response. */
- ssl_sock_free_ocsp(ctx->cur_ocsp);
+ ssl_sock_free_ocsp_instance(ctx->cur_ocsp);
ctx->cur_ocsp = NULL;
}
if (hc)
@@ -1350,7 +1363,7 @@ http_error:
if (hc)
httpclient_stop_and_destroy(hc);
/* Release the reference kept on the updated ocsp response. */
- ssl_sock_free_ocsp(ctx->cur_ocsp);
+ ssl_sock_free_ocsp_instance(ctx->cur_ocsp);
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
/* Set next_wakeup to the new first entry of the tree */
eb = eb64_first(&ocsp_update_tree);
@@ -1378,11 +1391,11 @@ static int ssl_ocsp_update_precheck()
/* initialize the OCSP update dedicated httpclient */
httpclient_ocsp_update_px = httpclient_create_proxy("<OCSP-UPDATE>");
if (!httpclient_ocsp_update_px)
- return 1;
- httpclient_ocsp_update_px->conf.logformat_string = httpclient_log_format;
+ return ERR_RETRYABLE;
+ httpclient_ocsp_update_px->logformat.str = httpclient_log_format;
httpclient_ocsp_update_px->options2 |= PR_O2_NOLOGNORM;
- return 0;
+ return ERR_NONE;
}
/* initialize the proxy and servers for the HTTP client */
@@ -1433,13 +1446,24 @@ static int cli_parse_update_ocsp_response(char **args, char *payload, struct app
goto end;
}
- update_once = (ocsp->next_update.node.leaf_p == NULL);
- eb64_delete(&ocsp->next_update);
+ /* No need to try to update this response, it is already being updated. */
+ if (!ocsp->updating) {
+ update_once = (ocsp->next_update.node.leaf_p == NULL);
+ eb64_delete(&ocsp->next_update);
- /* Insert the entry at the beginning of the update tree. */
- ocsp->next_update.key = 0;
- eb64_insert(&ocsp_update_tree, &ocsp->next_update);
- ocsp->update_once = update_once;
+ /* Insert the entry at the beginning of the update tree.
+ * We don't need to increase the reference counter on the
+ * certificate_ocsp structure because we would not have a way to
+ * decrease it afterwards since this update operation is asynchronous.
+ * If the corresponding entry were to be destroyed before the update can
+ * be performed, which is pretty unlikely, it would not be such a
+ * problem because that would mean that the OCSP response is not
+ * actually used.
+ */
+ ocsp->next_update.key = 0;
+ eb64_insert(&ocsp_update_tree, &ocsp->next_update);
+ ocsp->update_once = update_once;
+ }
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
@@ -1675,20 +1699,12 @@ yield:
#endif
}
-/* Check if the ckch_store and the entry does have the same configuration */
-int ocsp_update_check_cfg_consistency(struct ckch_store *store, struct crtlist_entry *entry, char *crt_path, char **err)
+static void cli_release_show_ocspresponse(struct appctx *appctx)
{
- int err_code = ERR_NONE;
-
- if (store->data->ocsp_update_mode != SSL_SOCK_OCSP_UPDATE_DFLT || entry->ssl_conf) {
- if ((!entry->ssl_conf && store->data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON)
- || (entry->ssl_conf && entry->ssl_conf->ocsp_update != SSL_SOCK_OCSP_UPDATE_OFF &&
- store->data->ocsp_update_mode != entry->ssl_conf->ocsp_update)) {
- memprintf(err, "%sIncompatibilities found in OCSP update mode for certificate %s\n", err && *err ? *err : "", crt_path);
- err_code |= ERR_ALERT | ERR_FATAL;
- }
- }
- return err_code;
+ struct show_ocspresp_cli_ctx *ctx = appctx->svcctx;
+
+ if (ctx)
+ ssl_sock_free_ocsp_instance(ctx->ocsp);
}
struct show_ocsp_updates_ctx {
@@ -1845,98 +1861,168 @@ static void cli_release_show_ocsp_updates(struct appctx *appctx)
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
}
+static int ssl_parse_global_ocsp_maxdelay(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
+{
+ int value = 0;
+
+ if (*(args[1]) == 0) {
+ memprintf(err, "'%s' expects an integer argument.", args[0]);
+ return -1;
+ }
+
+ value = atoi(args[1]);
+ if (value < 0) {
+ memprintf(err, "'%s' expects a positive numeric value.", args[0]);
+ return -1;
+ }
+
+ if (global_ssl.ocsp_update.delay_min > value) {
+ memprintf(err, "'%s' can not be lower than tune.ssl.ocsp-update.mindelay.", args[0]);
+ return -1;
+ }
+
+ global_ssl.ocsp_update.delay_max = value;
+
+ return 0;
+}
-static int
-smp_fetch_ssl_ocsp_certid(const struct arg *args, struct sample *smp, const char *kw, void *private)
+static int ssl_parse_global_ocsp_mindelay(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
{
- struct buffer *data = get_trash_chunk();
- struct certificate_ocsp *ocsp = ssl_ocsp_task_ctx.cur_ocsp;
+ int value = 0;
- if (!ocsp)
- return 0;
+ if (*(args[1]) == 0) {
+ memprintf(err, "'%s' expects an integer argument.", args[0]);
+ return -1;
+ }
+
+ value = atoi(args[1]);
+ if (value < 0) {
+ memprintf(err, "'%s' expects a positive numeric value.", args[0]);
+ return -1;
+ }
- dump_binary(data, (char *)ocsp->key_data, ocsp->key_length);
+ if (value > global_ssl.ocsp_update.delay_max) {
+ memprintf(err, "'%s' can not be higher than tune.ssl.ocsp-update.maxdelay.", args[0]);
+ return -1;
+ }
- smp->data.type = SMP_T_STR;
- smp->data.u.str = *data;
- return 1;
+ global_ssl.ocsp_update.delay_min = value;
+
+ return 0;
}
-static int
-smp_fetch_ssl_ocsp_certname(const struct arg *args, struct sample *smp, const char *kw, void *private)
+static int ssl_parse_global_ocsp_update_mode(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
{
- struct certificate_ocsp *ocsp = ssl_ocsp_task_ctx.cur_ocsp;
+ if (!*args[1]) {
+ memprintf(err, "'%s' : expecting <on|off>", args[0]);
+ return ERR_ALERT | ERR_FATAL;
+ }
- if (!ocsp)
- return 0;
+ if (strcmp(args[1], "on") == 0)
+ global_ssl.ocsp_update.mode = SSL_SOCK_OCSP_UPDATE_ON;
+ else if (strcmp(args[1], "off") == 0)
+ global_ssl.ocsp_update.mode = SSL_SOCK_OCSP_UPDATE_OFF;
+ else {
+ memprintf(err, "'%s' : expecting <on|off>", args[0]);
+ return ERR_ALERT | ERR_FATAL;
+ }
- smp->data.type = SMP_T_STR;
- smp->data.u.str.area = ocsp->path;
- smp->data.u.str.data = strlen(ocsp->path);
- return 1;
+ return 0;
}
-static int
-smp_fetch_ssl_ocsp_status(const struct arg *args, struct sample *smp, const char *kw, void *private)
+static int ssl_parse_global_ocsp_update_disable(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
{
- struct certificate_ocsp *ocsp = ssl_ocsp_task_ctx.cur_ocsp;
+ if (!*args[1]) {
+ memprintf(err, "'%s' : expecting <on|off>", args[0]);
+ return ERR_ALERT | ERR_FATAL;
+ }
- if (!ocsp)
- return 0;
+ if (strcmp(args[1], "on") == 0)
+ global_ssl.ocsp_update.disable = 1;
+ else if (strcmp(args[1], "off") == 0)
+ global_ssl.ocsp_update.disable = 0;
+ else {
+ memprintf(err, "'%s' : expecting <on|off>", args[0]);
+ return ERR_ALERT | ERR_FATAL;
+ }
- smp->data.type = SMP_T_SINT;
- smp->data.u.sint = ssl_ocsp_task_ctx.update_status;
- return 1;
+ return 0;
}
-static int
-smp_fetch_ssl_ocsp_status_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
+static int ocsp_update_parse_global_http_proxy(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
{
- struct certificate_ocsp *ocsp = ssl_ocsp_task_ctx.cur_ocsp;
+ struct sockaddr_storage *sk;
+ char *errmsg = NULL;
- if (!ocsp)
- return 0;
+ if (too_many_args(1, args, err, NULL))
+ return -1;
- if (ssl_ocsp_task_ctx.update_status >= OCSP_UPDT_ERR_LAST)
- return 0;
+ sockaddr_free(&ocsp_update_dst);
+ /* 'sk' is statically allocated (no need to be freed). */
+ sk = str2sa_range(args[1], NULL, NULL, NULL, NULL, NULL, NULL,
+ &errmsg, NULL, NULL,
+ PA_O_PORT_OK | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
+ if (!sk) {
+ ha_alert("ocsp-update: Failed to parse destination address in %s\n", errmsg);
+ free(errmsg);
+ return -1;
+ }
- smp->data.type = SMP_T_STR;
- smp->data.u.str = ist2buf(ocsp_update_errors[ssl_ocsp_task_ctx.update_status]);
+ if (!sockaddr_alloc(&ocsp_update_dst, sk, sizeof(*sk))) {
+ ha_alert("ocsp-update: Failed to allocate sockaddr in %s:%d.\n", __FUNCTION__, __LINE__);
+ return -1;
+ }
- return 1;
+ return 0;
}
-static int
-smp_fetch_ssl_ocsp_fail_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+int ocsp_update_init(void *value, char *buf, struct ckch_data *d, int cli, char **err)
{
- struct certificate_ocsp *ocsp = ssl_ocsp_task_ctx.cur_ocsp;
+ int ocsp_update_mode = *(int *)value;
+ int ret = 0;
- if (!ocsp)
- return 0;
+ /* inherit from global section */
+ ocsp_update_mode = (ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_DFLT) ? global_ssl.ocsp_update.mode : ocsp_update_mode;
- smp->data.type = SMP_T_SINT;
- smp->data.u.sint = ocsp->num_failure;
- return 1;
+ if (!global_ssl.ocsp_update.disable && ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON) {
+ /* We might need to create the main ocsp update task */
+ ret = ssl_create_ocsp_update_task(err);
+ }
+
+ return ret;
}
-static int
-smp_fetch_ssl_ocsp_success_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+int ocsp_update_postparser_init()
{
- struct certificate_ocsp *ocsp = ssl_ocsp_task_ctx.cur_ocsp;
+ int ret = 0;
+ char *err = NULL;
- if (!ocsp)
- return 0;
+ /* if the global ocsp-update.mode option is not set to "on", there is
+ * no need to start the task, it would have been started when parsing a
+ * crt-store or a crt-list */
+ if (!global_ssl.ocsp_update.disable && (global_ssl.ocsp_update.mode == SSL_SOCK_OCSP_UPDATE_ON)) {
+ /* We might need to create the main ocsp update task */
+ ret = ssl_create_ocsp_update_task(&err);
+ }
- smp->data.type = SMP_T_SINT;
- smp->data.u.sint = ocsp->num_success;
- return 1;
+ return ret;
}
static struct cli_kw_list cli_kws = {{ },{
{ { "set", "ssl", "ocsp-response", NULL }, "set ssl ocsp-response <resp|payload> : update a certificate's OCSP Response from a base64-encode DER", cli_parse_set_ocspresponse, NULL },
- { { "show", "ssl", "ocsp-response", NULL },"show ssl ocsp-response [[text|base64] id] : display the IDs of the OCSP responses used in memory, or the details of a single OCSP response (in text or base64 format)", cli_parse_show_ocspresponse, cli_io_handler_show_ocspresponse, NULL },
+ { { "show", "ssl", "ocsp-response", NULL },"show ssl ocsp-response [[text|base64] id] : display the IDs of the OCSP responses used in memory, or the details of a single OCSP response (in text or base64 format)", cli_parse_show_ocspresponse, cli_io_handler_show_ocspresponse, cli_release_show_ocspresponse },
{ { "show", "ssl", "ocsp-updates", NULL }, "show ssl ocsp-updates : display information about the next 'nb' ocsp responses that will be updated automatically", cli_parse_show_ocsp_updates, cli_io_handler_show_ocsp_updates, cli_release_show_ocsp_updates },
#if ((defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) && !defined OPENSSL_IS_BORINGSSL)
{ { "update", "ssl", "ocsp-response", NULL }, "update ssl ocsp-response <certfile> : send ocsp request and update stored ocsp response", cli_parse_update_ocsp_response, NULL, NULL },
@@ -1946,27 +2032,22 @@ static struct cli_kw_list cli_kws = {{ },{
INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
-
-/* Note: must not be declared <const> as its list will be overwritten.
- * Please take care of keeping this list alphabetically sorted.
- *
- * Those fetches only have a valid value during an OCSP update process so they
- * can only be used in a log format of a log line built by the update process
- * task itself.
- */
-static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
- { "ssl_ocsp_certid", smp_fetch_ssl_ocsp_certid, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
- { "ssl_ocsp_certname", smp_fetch_ssl_ocsp_certname, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
- { "ssl_ocsp_status", smp_fetch_ssl_ocsp_status, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
- { "ssl_ocsp_status_str", smp_fetch_ssl_ocsp_status_str, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
- { "ssl_ocsp_fail_cnt", smp_fetch_ssl_ocsp_fail_cnt, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
- { "ssl_ocsp_success_cnt", smp_fetch_ssl_ocsp_success_cnt, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
- { NULL, NULL, 0, 0, 0 },
+static struct cfg_kw_list cfg_kws = {ILH, {
+#ifndef OPENSSL_NO_OCSP
+ { CFG_GLOBAL, "ocsp-update.disable", ssl_parse_global_ocsp_update_disable },
+ { CFG_GLOBAL, "tune.ssl.ocsp-update.maxdelay", ssl_parse_global_ocsp_maxdelay },
+ { CFG_GLOBAL, "ocsp-update.maxdelay", ssl_parse_global_ocsp_maxdelay },
+ { CFG_GLOBAL, "tune.ssl.ocsp-update.mindelay", ssl_parse_global_ocsp_mindelay },
+ { CFG_GLOBAL, "ocsp-update.mindelay", ssl_parse_global_ocsp_mindelay },
+ { CFG_GLOBAL, "ocsp-update.mode", ssl_parse_global_ocsp_update_mode },
+ { CFG_GLOBAL, "ocsp-update.httpproxy", ocsp_update_parse_global_http_proxy },
+#endif
+ { 0, NULL, NULL },
}};
-INITCALL1(STG_REGISTER, sample_register_fetches, &sample_fetch_keywords);
-
+INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
+REGISTER_CONFIG_POSTPARSER("ocsp-update", ocsp_update_postparser_init);
/*
* Local variables:
* c-indent-level: 8