diff options
author | Martijn van Duren <martijn@cvs.openbsd.org> | 2019-07-01 07:40:44 +0000 |
---|---|---|
committer | Martijn van Duren <martijn@cvs.openbsd.org> | 2019-07-01 07:40:44 +0000 |
commit | df26446210b7d451d5591ed94b8aa0d0022462cc (patch) | |
tree | 30e743b1166661e5d6379a3c3e3a9bd361ae70e5 /usr.sbin/smtpd | |
parent | b13a5b2fc92e7c8c66ffce1cb6de4641883f9bff (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.c | 26 |
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 |