summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorMartijn van Duren <martijn@cvs.openbsd.org>2019-07-01 07:40:44 +0000
committerMartijn van Duren <martijn@cvs.openbsd.org>2019-07-01 07:40:44 +0000
commitdf26446210b7d451d5591ed94b8aa0d0022462cc (patch)
tree30e743b1166661e5d6379a3c3e3a9bd361ae70e5 /usr.sbin/smtpd
parentb13a5b2fc92e7c8c66ffce1cb6de4641883f9bff (diff)
The proceed reply doesn't have a parameter, resulting in subsequent filters
in a chain to receive a "(null)" parameter. Fix this by storing the current parameter in the session. Found the hard way and fix tested by Mischa Peters. OK gilles@
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/lka_filter.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/usr.sbin/smtpd/lka_filter.c b/usr.sbin/smtpd/lka_filter.c
index 04f2d8a43d9..85fa0d8e25e 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.37 2019/06/28 06:05:07 gilles Exp $ */
+/* $OpenBSD: lka_filter.c,v 1.38 2019/07/01 07:40:43 martijn Exp $ */
/*
* Copyright (c) 2018 Gilles Chehade <gilles@poolp.org>
@@ -41,7 +41,7 @@ struct filter;
struct filter_session;
static void filter_protocol_internal(struct filter_session *, uint64_t *, uint64_t, enum filter_phase, const char *);
static void filter_protocol(uint64_t, enum filter_phase, const char *);
-static void filter_protocol_next(uint64_t, uint64_t, enum filter_phase, const char *);
+static void filter_protocol_next(uint64_t, uint64_t, enum filter_phase);
static void filter_protocol_query(struct filter *, uint64_t, uint64_t, const char *, const char *);
static void filter_data_internal(struct filter_session *, uint64_t, uint64_t, const char *);
@@ -68,6 +68,8 @@ struct filter_session {
uint64_t id;
struct io *io;
+ char *lastparam;
+
char *filter_name;
struct sockaddr_storage ss_src;
struct sockaddr_storage ss_dest;
@@ -337,6 +339,9 @@ lka_filter_end(uint64_t reqid)
fs = tree_xpop(&sessions, reqid);
free(fs->rdns);
+ free(fs->helo);
+ free(fs->mail_from);
+ free(fs->lastparam);
free(fs);
log_trace(TRACE_FILTERS, "%016"PRIx64" filters session-end", reqid);
}
@@ -504,7 +509,7 @@ lka_filter_process_response(const char *name, const char *line)
return 1;
}
- filter_protocol_next(token, reqid, 0, parameter);
+ filter_protocol_next(token, reqid, 0);
return 1;
}
@@ -658,14 +663,11 @@ filter_protocol(uint64_t reqid, enum filter_phase phase, const char *param)
switch (phase) {
case FILTER_HELO:
case FILTER_EHLO:
- if (fs->helo)
- free(fs->helo);
+ free(fs->helo);
fs->helo = xstrdup(param);
break;
case FILTER_MAIL_FROM:
- if (fs->mail_from)
- free(fs->mail_from);
-
+ free(fs->mail_from);
fs->mail_from = xstrdup(param + 1);
*strchr(fs->mail_from, '>') = '\0';
param = fs->mail_from;
@@ -683,13 +685,17 @@ filter_protocol(uint64_t reqid, enum filter_phase phase, const char *param)
default:
break;
}
+
+ free(fs->lastparam);
+ fs->lastparam = xstrdup(param);
+
filter_protocol_internal(fs, &token, reqid, phase, param);
if (nparam)
free(nparam);
}
static void
-filter_protocol_next(uint64_t token, uint64_t reqid, enum filter_phase phase, const char *param)
+filter_protocol_next(uint64_t token, uint64_t reqid, enum filter_phase phase)
{
struct filter_session *fs;
@@ -697,7 +703,7 @@ filter_protocol_next(uint64_t token, uint64_t reqid, enum filter_phase phase, co
if ((fs = tree_get(&sessions, reqid)) == NULL)
return;
- filter_protocol_internal(fs, &token, reqid, phase, param);
+ filter_protocol_internal(fs, &token, reqid, phase, fs->lastparam);
}
static void