]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: acme/lua: implement ACME.challenge_ready() Lua function
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 10 Jun 2026 13:12:51 +0000 (15:12 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 11 Jun 2026 13:01:38 +0000 (15:01 +0200)
Add a new ACME global Lua table with a challenge_ready(crt, dns) method
that wraps acme_challenge_ready(). It marks the ACME challenge for domain
<dns> in certificate <crt> as ready and returns the number of remaining
challenges, or 0 when all challenges are ready and validation has been
triggered. A Lua error is raised if the certificate or domain is not found.

The ACME table is registered for each lua_State via the new
REGISTER_HLUA_STATE_INIT() mechanism.

doc/lua-api/index.rst
src/acme.c

index 8c2ecfb8f825e5fef8ab07888508b14bc2fecb70..08568bcc3eda10fcb2dcb52480a05859448a611c 100644 (file)
@@ -4739,6 +4739,28 @@ CertCache class
     CertCache.set{filename="certs/localhost9994.pem.rsa", crt=crt}
 
 
+ACME class
+==========
+
+.. js:class:: ACME
+
+   This class provides access to the ACME (Automatic Certificate Management
+   Environment) subsystem. It allows Lua scripts to interact with ongoing ACME
+   certificate challenges.
+
+.. js:function:: ACME.challenge_ready(crt, dns)
+
+  Marks the ACME challenge for domain <dns> in certificate <crt> as ready.
+  Returns the number of remaining challenges, or 0 if all challenges are ready
+  and validation has been triggered. Raises a Lua error if the certificate or
+  domain is not found.
+
+  :param string crt: The filename of the certificate.
+  :param string dns: The domain name for which the challenge is ready.
+  :returns: The number of remaining challenges (integer), or 0 when all
+   challenges are done and validation has been triggered.
+
+
 External Lua libraries
 ======================
 
index f9beba6432a4cda61df94651d99b5e3a8dee9a6d..b9b022947cac0ee6d0f629ac5f587af541d61ff5 100644 (file)
 #include <haproxy/ssl_utils.h>
 #include <haproxy/tools.h>
 #include <haproxy/trace.h>
+#ifdef USE_LUA
+#include <lua.h>
+#include <lauxlib.h>
+#include <haproxy/hlua.h>
+#include <haproxy/hlua_fcn.h>
+#endif
 
 #define TRACE_SOURCE &trace_acme
 
@@ -3692,6 +3698,48 @@ static void __acme_init(void)
 }
 INITCALL0(STG_REGISTER, __acme_init);
 
+#ifdef USE_LUA
+/*
+ * ACME.challenge_ready(crt, dns)
+ *
+ * Marks the ACME challenge for domain <dns> in certificate <crt> as ready.
+ * Returns the number of remaining challenges, or 0 if all challenges are
+ * ready and validation has been triggered.
+ * Raises a Lua error if the certificate or domain is not found.
+ */
+__LJMP static int hlua_acme_challenge_ready(lua_State *L)
+{
+       const char *crt;
+       const char *dns;
+       int ret;
+
+       if (lua_gettop(L) != 2)
+               WILL_LJMP(luaL_error(L, "'ACME.challenge_ready' needs 2 arguments."));
+
+       crt = MAY_LJMP(luaL_checkstring(L, 1));
+       dns = MAY_LJMP(luaL_checkstring(L, 2));
+
+       ret = acme_challenge_ready(crt, dns);
+       if (ret == -2)
+               WILL_LJMP(luaL_error(L, "ACME.challenge_ready: certificate '%s' not found", crt));
+       if (ret == -1)
+               WILL_LJMP(luaL_error(L, "ACME.challenge_ready: domain '%s' not found for certificate '%s'", dns, crt));
+
+       lua_pushinteger(L, ret);
+       return 1;
+}
+
+static int acme_hlua_init_state(lua_State *L, char **errmsg)
+{
+       lua_newtable(L);
+       hlua_class_function(L, "challenge_ready", hlua_acme_challenge_ready);
+       lua_setglobal(L, "ACME");
+       return ERR_NONE;
+}
+
+REGISTER_HLUA_STATE_INIT(acme_hlua_init_state);
+#endif /* USE_LUA */
+
 #endif /* ! HAVE_ACME */
 
 /*