From 784f972a6f085c9ba61256673330cc824fc3c9c1 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Wed, 10 Jun 2026 15:12:51 +0200 Subject: [PATCH] MINOR: acme/lua: implement ACME.challenge_ready() Lua function 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 in certificate 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 | 22 ++++++++++++++++++++ src/acme.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst index 8c2ecfb8f..08568bcc3 100644 --- a/doc/lua-api/index.rst +++ b/doc/lua-api/index.rst @@ -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 in certificate 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 ====================== diff --git a/src/acme.c b/src/acme.c index f9beba643..b9b022947 100644 --- a/src/acme.c +++ b/src/acme.c @@ -37,6 +37,12 @@ #include #include #include +#ifdef USE_LUA +#include +#include +#include +#include +#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 in certificate 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 */ /* -- 2.47.3