Index | Thread | Search

From:
Philipp <philipp+openbsd@bureaucracy.de>
Subject:
Re: smtpd vs upper-case pki labels
To:
tech@openbsd.org
Cc:
"Omar Polo" <op@omarpolo.com>
Date:
Thu, 19 Jun 2025 14:45:10 +0200

Download raw body.

Thread
Hello

[2025-06-15 08:21] "Omar Polo" <op@omarpolo.com>
> Hello tech, Gilles,
>
> This was reported on the -portable repository:
>
> https://github.com/OpenSMTPD/OpenSMTPD/issues/1286
>
> The problem is that upper-case pki labels are currently wrong.  Take
> this configuration example:
>
> 	pki FOO key "/tmp/x.key"	# notice FOO uppercase
> 	pki FOO cert "/tmp/x.pem"
> 	action "local_mail" maildir
> 	match for local action "local_mail"
> 	listen on localhost port smtp tls pki FOO
>
> the `listen' lines yields "pki name not found: FOO".
>
> The issue stems from the fact that in the top-level `pki' handling
> we lowercase the argument, while later we don't.
>
> Instead of doing xlowercase() when looking it up, simply avoid to do it
> in the first place.  IMHO labels should be case-sensitive (even if this
> is an host name and so I might be convinced to always lowercase-ify it)

As far as I understand the code, the hostname check was there to support
the SNI implementation. But with the change to libtls, it's not necesary
anymore. So I would just remove the complete hostname check.

Philipp

diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index 795e9527..430b056d 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -403,22 +403,13 @@ pki:
 PKI STRING {
 	char buf[HOST_NAME_MAX+1];
 
-	/* if not catchall, check that it is a valid domain */
-	if (strcmp($2, "*") != 0) {
-		if (!res_hnok($2)) {
-			yyerror("not a valid domain name: %s", $2);
-			free($2);
-			YYERROR;
-		}
-	}
-	xlowercase(buf, $2, sizeof(buf));
-	free($2);
-	pki = dict_get(conf->sc_pki_dict, buf);
+	pki = dict_get(conf->sc_pki_dict, $2);
 	if (pki == NULL) {
 		pki = xcalloc(1, sizeof *pki);
-		(void)strlcpy(pki->pki_name, buf, sizeof(pki->pki_name));
+		(void)strlcpy(pki->pki_name, $2, sizeof(pki->pki_name));
 		dict_set(conf->sc_pki_dict, pki->pki_name, pki);
 	}
+	free($2);
 } pki_params
 ;