[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

Reply via email to