]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: acme: handle the nonce
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 9 Apr 2025 15:45:39 +0000 (17:45 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Fri, 11 Apr 2025 23:29:27 +0000 (01:29 +0200)
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
src/acme.c

index db378ff0a4079db6c558ed6a058b2e1bdc037553..4a0940086dc2f38c3433239761657bcbc8ad5130 100644 (file)
@@ -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
index cc3ba42debefe093ce65b3523bae8192da165213..639932ef2fe427e596de262ff27e38bad7e68f51 100644 (file)
@@ -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;