[2025-01-05 12:52] Philipp <phil...@bureaucracy.de> > [2024-12-30 19:00] "Darren S." <phatbuck...@gmail.com> > > I'm wondering the best path forward here. Given the security relevance, it > > seems like we should be able to see link-auth events for successful or > > failed authentication attempts at all points; before and after STARTTLS, > > and in cases whether `auth` is enabled on a listener or not. Is this a case > > where the smtpd-filters(7) event logging should be improved in OpenSMTPD, > > or am I thinking about this wrong? > > As far as I see there are currently two[0] places where auth is rejected > without a auth report. So the best way I see is to add an auth-rejected > event.
I had a bit time to implement this, sadly not enough to test it. A patch is attached so you can test this. Quick overview: auth-rejected is reported when check_auth() fails or when the auth method is not implemented. The reason is a textual explanation. Philipp
From 6f4d036621eea65e99a6c90671218afe203f9ce6 Mon Sep 17 00:00:00 2001 From: Philipp <philipp+open...@bureaucracy.de> Date: Tue, 7 Jan 2025 23:03:38 +0100 Subject: [PATCH] add report auth-rejected --- usr.sbin/smtpd/lka.c | 12 ++++++++++++ usr.sbin/smtpd/lka_filter.c | 9 +++++++++ usr.sbin/smtpd/report_smtp.c | 15 +++++++++++++++ usr.sbin/smtpd/smtp_session.c | 18 ++++++++++++++++-- usr.sbin/smtpd/smtpd.c | 1 + usr.sbin/smtpd/smtpd.h | 3 +++ 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index 8c40f7b1..417cd836 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -83,6 +83,7 @@ lka_imsg(struct mproc *p, struct imsg *imsg) const char *heloname; const char *filter_name; const char *result; + const char *reason; struct sockaddr_storage ss_src, ss_dest; int filter_response; int filter_phase; @@ -448,6 +449,17 @@ lka_imsg(struct mproc *p, struct imsg *imsg) lka_report_smtp_link_auth(direction, &tv, reqid, username, result); return; + case IMSG_REPORT_SMTP_AUTH_REJECTED: + m_msg(&m, imsg); + m_get_string(&m, &direction); + m_get_timeval(&m, &tv); + m_get_id(&m, &reqid); + m_get_string(&m, &reason); + m_end(&m); + + lka_report_smtp_auth_rejected(direction, &tv, reqid, reason); + return; + case IMSG_REPORT_SMTP_TX_RESET: m_msg(&m, imsg); m_get_string(&m, &direction); diff --git a/usr.sbin/smtpd/lka_filter.c b/usr.sbin/smtpd/lka_filter.c index 8d4d38cc..e1da1df9 100644 --- a/usr.sbin/smtpd/lka_filter.c +++ b/usr.sbin/smtpd/lka_filter.c @@ -167,6 +167,7 @@ static struct smtp_events { { "filter-report" }, { "filter-response" }, + { "auth-rejected" }, { "timeout" }, }; @@ -1470,6 +1471,14 @@ lka_report_smtp_link_auth(const char *direction, struct timeval *tv, uint64_t re result, username); } +void +lka_report_smtp_auth_rejected(const char *direction, struct timeval *tv, uint64_t reqid, + const char *reason) +{ + report_smtp_broadcast(reqid, direction, tv, "auth-rejected", "%s\n", + reason); +} + void lka_report_smtp_link_identify(const char *direction, struct timeval *tv, uint64_t reqid, const char *method, const char *heloname) diff --git a/usr.sbin/smtpd/report_smtp.c b/usr.sbin/smtpd/report_smtp.c index ef931799..502a662e 100644 --- a/usr.sbin/smtpd/report_smtp.c +++ b/usr.sbin/smtpd/report_smtp.c @@ -143,6 +143,21 @@ report_smtp_link_auth(const char *direction, uint64_t qid, const char *user, con m_close(p_lka); } +void +report_smtp_auth_rejected(const char *direction, uint64_t qid, const char *reason) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + m_create(p_lka, IMSG_REPORT_SMTP_AUTH_REJECTED, 0, 0, -1); + m_add_string(p_lka, direction); + m_add_timeval(p_lka, &tv); + m_add_id(p_lka, qid); + m_add_string(p_lka, reason); + m_close(p_lka); +} + void report_smtp_tx_reset(const char *direction, uint64_t qid, uint32_t msgid) { diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index 7f17516f..119d938a 100644 --- a/usr.sbin/smtpd/smtp_session.c +++ b/usr.sbin/smtpd/smtp_session.c @@ -272,6 +272,7 @@ static void smtp_report_tx_rollback(struct smtp_session *, uint32_t); static void smtp_report_protocol_client(struct smtp_session *, const char *); static void smtp_report_protocol_server(struct smtp_session *, const char *); static void smtp_report_filter_response(struct smtp_session *, int, int, const char *); +static void smtp_report_auth_rejected(struct smtp_session *, const char *); static void smtp_report_timeout(struct smtp_session *); @@ -1320,8 +1321,10 @@ smtp_command(struct smtp_session *s, char *line) break; case CMD_AUTH: - if (!smtp_check_auth(s, args)) + if (!smtp_check_auth(s, args)) { + smtp_report_auth_rejected(s, "check-auth failed"); break; + } smtp_filter_phase(FILTER_AUTH, s, args); break; @@ -1834,11 +1837,13 @@ smtp_proceed_auth(struct smtp_session *s, const char *args) smtp_rfc4954_auth_plain(s, eom); else if (strcasecmp(method, "LOGIN") == 0) smtp_rfc4954_auth_login(s, eom); - else + else { + smtp_report_auth_rejected(s, "method not supported"); smtp_reply(s, "504 %s %s: AUTH method \"%s\" not supported", esc_code(ESC_STATUS_PERMFAIL, ESC_SECURITY_FEATURES_NOT_SUPPORTED), esc_description(ESC_SECURITY_FEATURES_NOT_SUPPORTED), method); + } } static void @@ -2997,6 +3002,15 @@ smtp_report_link_auth(struct smtp_session *s, const char *user, const char *resu report_smtp_link_auth("smtp-in", s->id, user, result); } +static void +smtp_report_auth_rejected(struct smtp_session *s, const char *reason) +{ + if (! SESSION_FILTERED(s)) + return; + + report_smtp_auth_rejected("smtp-in", s->id, reason); +} + static void smtp_report_tx_reset(struct smtp_session *s, uint32_t msgid) { diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index a9607233..33a9a041 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -2162,6 +2162,7 @@ imsg_to_str(int type) CASE(IMSG_REPORT_SMTP_PROTOCOL_CLIENT); CASE(IMSG_REPORT_SMTP_PROTOCOL_SERVER); CASE(IMSG_REPORT_SMTP_FILTER_RESPONSE); + CASE(IMSG_REPORT_SMTP_AUTH_REJECTED); CASE(IMSG_REPORT_SMTP_TIMEOUT); CASE(IMSG_FILTER_SMTP_BEGIN); diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 413a1c9f..9ac39d84 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -341,6 +341,7 @@ enum imsg_type { IMSG_REPORT_SMTP_PROTOCOL_CLIENT, IMSG_REPORT_SMTP_PROTOCOL_SERVER, IMSG_REPORT_SMTP_FILTER_RESPONSE, + IMSG_REPORT_SMTP_AUTH_REJECTED, IMSG_REPORT_SMTP_TIMEOUT, IMSG_FILTER_SMTP_BEGIN, @@ -1404,6 +1405,7 @@ void lka_report_smtp_protocol_client(const char *, struct timeval *, uint64_t, c void lka_report_smtp_protocol_server(const char *, struct timeval *, uint64_t, const char *); void lka_report_smtp_filter_response(const char *, struct timeval *, uint64_t, int, int, const char *); +void lka_report_smtp_auth_rejected(const char *, struct timeval *, uint64_t, const char *); void lka_report_smtp_timeout(const char *, struct timeval *, uint64_t); void lka_report_filter_report(uint64_t, const char *, int, const char *, struct timeval *, const char *); @@ -1580,6 +1582,7 @@ void report_smtp_tx_rollback(const char *, uint64_t, uint32_t); void report_smtp_protocol_client(const char *, uint64_t, const char *); void report_smtp_protocol_server(const char *, uint64_t, const char *); void report_smtp_filter_response(const char *, uint64_t, int, int, const char *); +void report_smtp_auth_rejected(const char *, uint64_t, const char *); void report_smtp_timeout(const char *, uint64_t); -- 2.39.5