From 0aa6dedf7253b3153e290088779e7244b7433a14 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Wed, 9 Apr 2025 17:45:39 +0200 Subject: [PATCH] MINOR: acme: handle the nonce ACME requests are supposed to be sent with a Nonce, the first Nonce should be retrieved using the newNonce URI provided by the directory. This nonce is stored and must be replaced by the new one received in the each response. --- include/haproxy/acme-t.h | 2 ++ src/acme.c | 54 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/haproxy/acme-t.h b/include/haproxy/acme-t.h index db378ff0a..4a0940086 100644 --- a/include/haproxy/acme-t.h +++ b/include/haproxy/acme-t.h @@ -31,6 +31,7 @@ struct acme_cfg { enum acme_st { ACME_RESSOURCES = 0, + ACME_NEWNONCE, ACME_END }; @@ -52,5 +53,6 @@ struct acme_ctx { struct ist newAccount; struct ist newOrder; } ressources; + struct ist nonce; }; #endif diff --git a/src/acme.c b/src/acme.c index cc3ba42de..639932ef2 100644 --- a/src/acme.c +++ b/src/acme.c @@ -529,6 +529,43 @@ error: } +int acme_nonce(struct task *task, struct acme_ctx *ctx, char **errmsg) +{ + struct httpclient *hc; + struct http_hdr *hdrs, *hdr; + + hc = ctx->hc; + if (!hc) + goto error; + + if (hc->res.status < 200 || hc->res.status >= 300) { + memprintf(errmsg, "invalid HTTP status code %d when getting Nonce URL", hc->res.status); + goto error; + } + + hdrs = hc->res.hdrs; + + for (hdr = hdrs; isttest(hdr->v); hdr++) { + if (isteqi(hdr->n, ist("Replay-Nonce"))) { + istfree(&ctx->nonce); + ctx->nonce = istdup(hdr->v); +// fprintf(stderr, "Replay-Nonce: %.*s\n", (int)hdr->v.len, hdr->v.ptr); + + } + } + + httpclient_destroy(hc); + ctx->hc = NULL; + + return 0; + +error: + httpclient_destroy(hc); + ctx->hc = NULL; + + return 1; +} + int acme_directory(struct task *task, struct acme_ctx *ctx, char **errmsg) { struct httpclient *hc; @@ -617,10 +654,25 @@ struct task *acme_process(struct task *task, void *context, unsigned int state) http_st = ACME_HTTP_REQ; goto retry; } - st = ACME_END; + st = ACME_NEWNONCE; + http_st = ACME_HTTP_REQ; + task_wakeup(task, TASK_WOKEN_MSG); } break; + case ACME_NEWNONCE: + if (http_st == ACME_HTTP_REQ) { + if (acme_http_req(task, ctx, ctx->ressources.newNonce, HTTP_METH_HEAD) != 0) + goto retry; + } + if (http_st == ACME_HTTP_RES) { + if (acme_nonce(task, ctx, &errmsg) != 0) { + http_st = ACME_HTTP_REQ; + goto retry; + } + st = ACME_END; + } + break; case ACME_END: goto end; break;