summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@cvs.openbsd.org>2024-05-02 18:14:34 +0000
committerOmar Polo <op@cvs.openbsd.org>2024-05-02 18:14:34 +0000
commit1b5ebf891dd17486aa2b59970f169ab479db9509 (patch)
tree7b4ecda67b61b5fc92ff79d23a2ddcaa362b3618
parent32fd6c8adb068f09728a26d9b39556009b651774 (diff)
unbreak parsing of IPv6 addresses in file-backed table(5)s
The file parser splits the line on the ':' character too for key-value tables, and so mis-parses IPv6 addresses. The "::1 localhost" example in table(5) is actually parsed as key "" and value ":1 localhost". For list tables, the "# @list" marker can be used as a workaround, but for key-valued the parser has to be fixed. There are also some weird edge cases when splitting the lines. Now the parser always splits on the first whitespace or colon, and then strips the spaces. For lines starting with '[' the parser will jump to the matching ']' before attempting to split. So, for example: [::1]:localhost becomes "[::1]" -> "localhost" [::1] example.org becomes "[::1]" -> "example.org" foo: bar becomes "foo" -> "bar" foo::bar becomes "foo" -> ":bar" foo : bar becomes "foo" -> ": bar" etc... This only affects the parser for file table(5)s and makemap(8). Inline tables or "proc" tables are unaffected. ok gilles@
-rw-r--r--usr.sbin/smtpd/table.521
-rw-r--r--usr.sbin/smtpd/util.c40
2 files changed, 28 insertions, 33 deletions
diff --git a/usr.sbin/smtpd/table.5 b/usr.sbin/smtpd/table.5
index 65dca359f38..3f4d40938db 100644
--- a/usr.sbin/smtpd/table.5
+++ b/usr.sbin/smtpd/table.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: table.5,v 1.13 2023/12/27 11:29:56 op Exp $
+.\" $OpenBSD: table.5,v 1.14 2024/05/02 18:14:33 op Exp $
.\"
.\" Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
.\" Copyright (c) 2013 Gilles Chehade <gilles@poolp.org>
@@ -16,7 +16,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\"
-.Dd $Mdocdate: December 27 2023 $
+.Dd $Mdocdate: May 2 2024 $
.Dt TABLE 5
.Os
.Sh NAME
@@ -173,10 +173,11 @@ of addresses in the table until a match is found.
A netaddr table can contain exact addresses or netmasks, and looks as follow:
.Bd -literal -offset indent
192.168.1.1
-::1
-ipv6:::1
+[::1]
192.168.1.0/24
.Ed
+.Pp
+IPv6 addresses must be enclosed in square brackets.
.Ss Userinfo tables
Userinfo tables are used in rule context to specify an alternate userbase,
mapping virtual users to local system users by UID, GID and home directory.
@@ -214,11 +215,11 @@ A source table looks as follow:
.Bd -literal -offset indent
192.168.1.2
192.168.1.3
-::1
-::2
-ipv6:::3
-ipv6:::4
+[::1]
+[::2]
.Ed
+.Pp
+IPv6 address must be enclosed in square brackets.
.Ss Mailaddr tables
Mailaddr tables are lists of email addresses.
They can be used in the following contexts:
@@ -254,10 +255,12 @@ outgoing connection.
.Pp
The format is a mapping from inet4 or inet6 addresses to hostnames:
.Bd -literal -offset indent
-::1 localhost
+[::1] localhost
127.0.0.1 localhost
88.190.23.165 www.opensmtpd.org
.Ed
+.Pp
+IPv6 addresses must be enclosed in square brackets.
.Sh SEE ALSO
.Xr smtpd.conf 5 ,
.Xr makemap 8 ,
diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c
index d481162c897..e2e03222ab3 100644
--- a/usr.sbin/smtpd/util.c
+++ b/usr.sbin/smtpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.156 2024/02/11 09:24:26 op Exp $ */
+/* $OpenBSD: util.c,v 1.157 2024/05/02 18:14:33 op Exp $ */
/*
* Copyright (c) 2000,2001 Markus Friedl. All rights reserved.
@@ -855,7 +855,7 @@ int
parse_table_line(FILE *fp, char **line, size_t *linesize,
int *type, char **key, char **val, int *malformed)
{
- char *keyp, *valp, *p;
+ char *keyp, *valp;
ssize_t linelen;
*key = NULL;
@@ -885,16 +885,17 @@ parse_table_line(FILE *fp, char **line, size_t *linesize,
return 0;
}
- if (*type == T_NONE) {
- for (p = keyp; *p; p++) {
- if (*p == ' ' || *p == '\t' || *p == ':') {
- *type = T_HASH;
- break;
- }
+ if (*keyp == '[') {
+ if ((valp = strchr(keyp, ']')) == NULL) {
+ *malformed = 1;
+ return (0);
}
- if (*type == T_NONE)
- *type = T_LIST;
- }
+ valp++;
+ } else
+ valp = keyp + strcspn(keyp, " \t:");
+
+ if (*type == T_NONE)
+ *type = (*valp == '\0') ? T_LIST : T_HASH;
if (*type == T_LIST) {
*key = keyp;
@@ -902,20 +903,11 @@ parse_table_line(FILE *fp, char **line, size_t *linesize,
}
/* T_HASH */
- valp = keyp;
- strsep(&valp, " \t:");
- if (valp) {
- while (*valp) {
- if (!isspace((unsigned char)*valp) &&
- !(*valp == ':' &&
- isspace((unsigned char)*(valp + 1))))
- break;
- ++valp;
- }
- if (*valp == '\0')
- valp = NULL;
+ if (*valp != '\0') {
+ *valp++ = '\0';
+ valp += strspn(valp, " \t");
}
- if (valp == NULL)
+ if (*valp == '\0')
*malformed = 1;
*key = keyp;