diff options
author | Omar Polo <op@cvs.openbsd.org> | 2023-06-21 17:56:27 +0000 |
---|---|---|
committer | Omar Polo <op@cvs.openbsd.org> | 2023-06-21 17:56:27 +0000 |
commit | 7dbfb67e645c1d6ecab97dddfcae883bd8974df8 (patch) | |
tree | a89a793badb07b456fc622e5e0eabc2ae9e5b841 | |
parent | 649999b80368e6a6266edd89d525fc33e62a0c57 (diff) |
avoid truncation of filtered data lines
Don't copy in a buffer the filter' output for parsing as we may truncate
filter-dataline (i.e. the mail body). Instead, parse the string by
advancing the pointer without copying or modifications.
Issue reported by Joachim Schneider on the OpenSMTPD-portable
repository.
ok millert@
-rw-r--r-- | usr.sbin/smtpd/lka_filter.c | 51 |
1 files changed, 16 insertions, 35 deletions
diff --git a/usr.sbin/smtpd/lka_filter.c b/usr.sbin/smtpd/lka_filter.c index 0c63657be21..18ac7c1a3f8 100644 --- a/usr.sbin/smtpd/lka_filter.c +++ b/usr.sbin/smtpd/lka_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka_filter.c,v 1.70 2023/05/15 12:03:04 op Exp $ */ +/* $OpenBSD: lka_filter.c,v 1.71 2023/06/21 17:56:26 op Exp $ */ /* * Copyright (c) 2018 Gilles Chehade <gilles@poolp.org> @@ -593,40 +593,27 @@ lka_filter_process_response(const char *name, const char *line) { uint64_t reqid; uint64_t token; - char buffer[LINE_MAX]; char *ep = NULL; - char *kind = NULL; - char *qid = NULL; - /*char *phase = NULL;*/ - char *response = NULL; - char *parameter = NULL; + const char *kind = NULL; + const char *qid = NULL; + const char *response = NULL; + const char *parameter = NULL; struct filter_session *fs; - (void)strlcpy(buffer, line, sizeof buffer); - if ((ep = strchr(buffer, '|')) == NULL) - fatalx("Missing token: %s", line); - ep[0] = '\0'; - - kind = buffer; + kind = line; + if ((ep = strchr(kind, '|')) == NULL) + fatalx("Missing token: %s", line); qid = ep+1; - if ((ep = strchr(qid, '|')) == NULL) - fatalx("Missing reqid: %s", line); - ep[0] = '\0'; - reqid = strtoull(qid, &ep, 16); - if (qid[0] == '\0' || *ep != '\0') + if (qid[0] == '\0' || *ep != '|') fatalx("Invalid reqid: %s", line); if (errno == ERANGE && reqid == ULLONG_MAX) fatal("Invalid reqid: %s", line); - qid = ep+1; - if ((ep = strchr(qid, '|')) == NULL) - fatal("Missing directive: %s", line); - ep[0] = '\0'; - + qid = ep + 1; token = strtoull(qid, &ep, 16); - if (qid[0] == '\0' || *ep != '\0') + if (qid[0] == '\0' || *ep != '|') fatalx("Invalid token: %s", line); if (errno == ERANGE && token == ULLONG_MAX) fatal("Invalid token: %s", line); @@ -637,7 +624,7 @@ lka_filter_process_response(const char *name, const char *line) if ((fs = tree_get(&sessions, reqid)) == NULL) return; - if (strcmp(kind, "filter-dataline") == 0) { + if (strncmp(kind, "filter-dataline|", 16) == 0) { if (fs->phase != FILTER_DATA_LINE) fatalx("filter-dataline out of dataline phase"); filter_data_next(token, reqid, response); @@ -646,19 +633,13 @@ lka_filter_process_response(const char *name, const char *line) if (fs->phase == FILTER_DATA_LINE) fatalx("filter-result in dataline phase"); - if ((ep = strchr(response, '|'))) { + if ((ep = strchr(response, '|')) != NULL) parameter = ep + 1; - ep[0] = '\0'; - } if (strcmp(response, "proceed") == 0) { - if (parameter != NULL) - fatalx("Unexpected parameter after proceed: %s", line); filter_protocol_next(token, reqid, 0); return; } else if (strcmp(response, "junk") == 0) { - if (parameter != NULL) - fatalx("Unexpected parameter after junk: %s", line); if (fs->phase == FILTER_COMMIT) fatalx("filter-reponse junk after DATA"); filter_result_junk(reqid); @@ -667,11 +648,11 @@ lka_filter_process_response(const char *name, const char *line) if (parameter == NULL) fatalx("Missing parameter: %s", line); - if (strcmp(response, "rewrite") == 0) + if (strncmp(response, "rewrite|", 8) == 0) filter_result_rewrite(reqid, parameter); - else if (strcmp(response, "reject") == 0) + else if (strncmp(response, "reject|", 7) == 0) filter_result_reject(reqid, parameter); - else if (strcmp(response, "disconnect") == 0) + else if (strncmp(response, "disconnect|", 11) == 0) filter_result_disconnect(reqid, parameter); else fatalx("Invalid directive: %s", line); |