From b555c4ed5c837d66a6dd65e4570c33b1a52513f7 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Tue, 30 Sep 2025 10:53:43 -0700 Subject: [PATCH] Conf: allow unversioned challenge names. Simplify "challenge" directive parsing. --- README.md | 7 +++++-- src/acme/types.rs | 11 ----------- src/conf.rs | 16 ++++++++-------- t/acme_conf_issuer.t | 17 ++++++++++++++++- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 0267ecb..9c93162 100644 --- a/README.md +++ b/README.md @@ -201,8 +201,11 @@ restart unless [state_path](#state_path) is configured. Sets challenge type used for this issuer. Allowed values: -- `http-01` -- `tls-alpn-01` +- `http-01` (`http`) +- `tls-alpn-01` (`tls-alpn`) + +ACME challenges are versioned, but if you specify an unversioned name, +the module will select the latest implemented version automatically. ### contact diff --git a/src/acme/types.rs b/src/acme/types.rs index 7889e59..693e2f6 100644 --- a/src/acme/types.rs +++ b/src/acme/types.rs @@ -157,17 +157,6 @@ pub enum ChallengeKind { Other(String), } -impl From<&str> for ChallengeKind { - fn from(s: &str) -> Self { - match s { - "http-01" => ChallengeKind::Http01, - "dns-01" => ChallengeKind::Dns01, - "tls-alpn-01" => ChallengeKind::TlsAlpn01, - _ => ChallengeKind::Other(s.to_string()), - } - } -} - #[derive(Clone, Debug, Deserialize, Eq, PartialEq)] #[serde(rename_all = "camelCase")] pub enum ChallengeStatus { diff --git a/src/conf.rs b/src/conf.rs index a13580f..c4f92f1 100644 --- a/src/conf.rs +++ b/src/conf.rs @@ -338,15 +338,15 @@ extern "C" fn cmd_issuer_set_challenge( } // NGX_CONF_TAKE1 ensures that args contains 2 elements - let args = cf.args(); + let val = cf.args()[1]; - let Ok(val) = core::str::from_utf8(args[1].as_bytes()) else { - return NGX_CONF_ERROR; - }; - let val = ChallengeKind::from(val); - if !matches!(val, ChallengeKind::Http01 | ChallengeKind::TlsAlpn01) { - ngx_conf_log_error!(NGX_LOG_EMERG, cf, "unsupported challenge type: {val:?}"); - return NGX_CONF_ERROR; + let val = match val.as_bytes() { + b"http" | b"http-01" => ChallengeKind::Http01, + b"tls-alpn" | b"tls-alpn-01" => ChallengeKind::TlsAlpn01, + _ => { + ngx_conf_log_error!(NGX_LOG_EMERG, cf, "unsupported challenge: {val}"); + return NGX_CONF_ERROR; + } }; issuer.challenge = Some(val); diff --git a/t/acme_conf_issuer.t b/t/acme_conf_issuer.t index 64951f2..bba0678 100644 --- a/t/acme_conf_issuer.t +++ b/t/acme_conf_issuer.t @@ -24,7 +24,7 @@ use Test::Nginx; select STDERR; $| = 1; select STDOUT; $| = 1; -my $t = Test::Nginx->new()->has(qw/http http_ssl/)->plan(7); +my $t = Test::Nginx->new()->has(qw/http http_ssl/)->plan(8); use constant TEMPLATE_CONF => <<'EOF'; @@ -67,6 +67,7 @@ acme_shared_zone zone=ngx_acme_shared:1M; acme_issuer example { uri https://localhost:%%PORT_9000%%/dir; account_key ecdsa:256; + challenge http; contact admin@example.test; ssl_verify off; state_path %%TESTDIR%%; @@ -161,6 +162,20 @@ resolver 127.0.0.1:%%PORT_8980_UDP%%; EOF + +like(check($t, <<'EOF' ), qr/\[emerg].*unsupported challenge/, 'bad challenge'); + +acme_issuer example { + uri https://localhost:%%PORT_9000%%/dir; + challenge bad-value; + ssl_verify off; + state_path %%TESTDIR%%; +} + +resolver 127.0.0.1:%%PORT_8980_UDP%%; + +EOF + # stop and clear the log to avoid triggering sanitizer checks $t->stop()->write_file('error.log', '');