Commit Diff


commit - 0a1c0aa333ea4415f00eea875bc6dfe967e2cfda
commit + f8c5e10bf875054fa615d67c60f84ae2986fdfd5
blob - 87884c2751b47f99d2b50af444e1b2246d4f3ff7
blob + b61f0fc3b925c722a173438383a24d4585711ff8
--- opensmtpd.c
+++ opensmtpd.c
@@ -91,6 +91,8 @@ static void osmtpd_link_tls(struct osmtpd_callback *, 
     char *, char *);
 static void osmtpd_link_auth(struct osmtpd_callback *, struct osmtpd_session *,
     char *, char *);
+static void osmtpd_tx_reset(struct osmtpd_callback *, struct osmtpd_session *,
+    char *, char *);
 static void osmtpd_tx_begin(struct osmtpd_callback *, struct osmtpd_session *,
     char *, char *);
 static void osmtpd_tx_mail(struct osmtpd_callback *, struct osmtpd_session *,
@@ -306,6 +308,15 @@ static struct osmtpd_callback osmtpd_callbacks[] = {
 	},
 	{
 	    OSMTPD_TYPE_REPORT,
+	    OSMTPD_PHASE_TX_RESET,
+	    1,
+	    osmtpd_tx_reset,
+	    NULL,
+	    0,
+	    0
+	},
+	{
+	    OSMTPD_TYPE_REPORT,
 	    OSMTPD_PHASE_TX_BEGIN,
 	    1,
 	    osmtpd_tx_begin,
@@ -459,6 +470,15 @@ static struct osmtpd_callback osmtpd_callbacks[] = {
 	},
 	{
 	    OSMTPD_TYPE_REPORT,
+	    OSMTPD_PHASE_TX_RESET,
+	    0,
+	    osmtpd_tx_reset,
+	    NULL,
+	    0,
+	    0
+	},
+	{
+	    OSMTPD_TYPE_REPORT,
 	    OSMTPD_PHASE_TX_BEGIN,
 	    0,
 	    osmtpd_tx_begin,
@@ -758,6 +778,16 @@ osmtpd_register_report_auth(int incoming, void (*cb)(s
 }
 
 void
+osmtpd_register_report_reset(int incoming, void (*cb)(struct osmtpd_ctx *,
+    uint32_t))
+{
+	osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_RESET, incoming, 0,
+	    (void *)cb);
+	osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_LINK_DISCONNECT,
+	    incoming, 0, NULL);
+}
+
+void
 osmtpd_register_report_begin(int incoming, void (*cb)(struct osmtpd_ctx *,
     uint32_t))
 {
@@ -910,34 +940,26 @@ osmtpd_register_need(int incoming)
 	if (needs & OSMTPD_NEED_MSGID) {
 		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_BEGIN,
 		    incoming, 1, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_ROLLBACK,
-		    incoming, 0, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_COMMIT,
+		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_RESET,
 		    incoming, 0, NULL);
 	}
 	if (needs & OSMTPD_NEED_MAILFROM) {
 		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_MAIL,
 		    incoming, 1, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_ROLLBACK,
+		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_RESET,
 		    incoming, 0, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_COMMIT,
-		    incoming, 0, NULL);
 	}
 	if (needs & OSMTPD_NEED_RCPTTO) {
 		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_RCPT,
 		    incoming, 1, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_ROLLBACK,
+		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_RESET,
 		    incoming, 0, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_COMMIT,
-		    incoming, 0, NULL);
 	}
 	if (needs & OSMTPD_NEED_EVPID) {
 		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_ENVELOPE,
 		    incoming, 1, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_ROLLBACK,
+		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_RESET,
 		    incoming, 0, NULL);
-		osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_COMMIT,
-		    incoming, 0, NULL);
 	}
 
 	osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_LINK_DISCONNECT,
@@ -976,10 +998,7 @@ osmtpd_run(void)
 				    OSMTPD_PHASE_TX_BEGIN,
 				    osmtpd_callbacks[i].incoming, 0, NULL);
 				osmtpd_register(OSMTPD_TYPE_REPORT,
-				    OSMTPD_PHASE_TX_ROLLBACK,
-				    osmtpd_callbacks[i].incoming, 0, NULL);
-				osmtpd_register(OSMTPD_TYPE_REPORT,
-				    OSMTPD_PHASE_TX_COMMIT,
+				    OSMTPD_PHASE_TX_RESET,
 				    osmtpd_callbacks[i].incoming, 0, NULL);
 			}
 			if (osmtpd_callbacks[i].type == OSMTPD_TYPE_FILTER &&
@@ -1464,6 +1483,47 @@ osmtpd_link_auth(struct osmtpd_callback *cb, struct os
 }
 
 static void
+osmtpd_tx_reset(struct osmtpd_callback *cb, struct osmtpd_session *session,
+    char *params, char *linedup)
+{
+	char *end;
+	unsigned long imsgid;
+	uint32_t msgid;
+	size_t i;
+	void (*f)(struct osmtpd_ctx *, uint32_t);
+
+	errno = 0;
+	imsgid = strtoul(params, &end, 16);
+	if ((imsgid == ULONG_MAX && errno != 0))
+		osmtpd_errx(1, "Invalid line received: invalid msgid: %s",
+		    linedup);
+	if (end[0] != '\0')
+		osmtpd_errx(1, "Invalid line received: missing address: %s",
+		    linedup);
+	msgid = imsgid;
+	if ((unsigned long) msgid != imsgid)
+		osmtpd_errx(1, "Invalid line received: invalid msgid: %s",
+		    linedup);
+
+	if ((f = cb->cb) != NULL && session->status == SESSION_OK)
+		f(&session->ctx, msgid);
+
+	if (ondeletecb_message != NULL && session->ctx.local_message != NULL) {
+		ondeletecb_message(&session->ctx, session->ctx.local_message);
+		session->ctx.local_message = NULL;
+	}
+
+	free(session->ctx.mailfrom);
+	session->ctx.mailfrom = NULL;
+
+	for (i = 0; session->ctx.rcptto[i] != NULL; i++)
+		free(session->ctx.rcptto[i]);
+	session->ctx.rcptto[0] = NULL;
+	session->ctx.evpid = 0;
+	session->ctx.msgid = 0;
+}
+
+static void
 osmtpd_tx_begin(struct osmtpd_callback *cb, struct osmtpd_session *session,
     char *msgid, char *linedup)
 {
@@ -1666,7 +1726,7 @@ osmtpd_tx_commit(struct osmtpd_callback *cb, struct os
 	const char *errstr = NULL;
 	unsigned long imsgid;
 	uint32_t msgid;
-	size_t i, msgsz;
+	size_t msgsz;
 	void (*f)(struct osmtpd_ctx *, uint32_t, size_t);
 
 	errno = 0;
@@ -1690,20 +1750,6 @@ osmtpd_tx_commit(struct osmtpd_callback *cb, struct os
 
 	if ((f = cb->cb) != NULL && session->status == SESSION_OK)
 		f(&session->ctx, msgid, msgsz);
-
-	if (ondeletecb_message != NULL && session->ctx.local_message != NULL) {
-		ondeletecb_message(&session->ctx, session->ctx.local_message);
-		session->ctx.local_message = NULL;
-	}
-
-	free(session->ctx.mailfrom);
-	session->ctx.mailfrom = NULL;
-
-	for (i = 0; session->ctx.rcptto[i] != NULL; i++)
-		free(session->ctx.rcptto[i]);
-	session->ctx.rcptto[0] = NULL;
-	session->ctx.evpid = 0;
-	session->ctx.msgid = 0;
 }
 
 static void
@@ -1713,7 +1759,6 @@ osmtpd_tx_rollback(struct osmtpd_callback *cb, struct 
 	char *end;
 	unsigned long imsgid;
 	uint32_t msgid;
-	size_t i;
 	void (*f)(struct osmtpd_ctx *, uint32_t);
 
 	errno = 0;
@@ -1731,20 +1776,6 @@ osmtpd_tx_rollback(struct osmtpd_callback *cb, struct 
 
 	if ((f = cb->cb) != NULL && session->status == SESSION_OK)
 		f(&session->ctx, msgid);
-
-	if (ondeletecb_message != NULL && session->ctx.local_message != NULL) {
-		ondeletecb_message(&session->ctx, session->ctx.local_message);
-		session->ctx.local_message = NULL;
-	}
-
-	free(session->ctx.mailfrom);
-	session->ctx.mailfrom = NULL;
-
-	for (i = 0; session->ctx.rcptto[i] != NULL; i++)
-		free(session->ctx.rcptto[i]);
-	session->ctx.rcptto[0] = NULL;
-	session->ctx.evpid = 0;
-	session->ctx.msgid = 0;
 }
 
 void
@@ -1987,6 +2018,8 @@ osmtpd_strtophase(const char *phase, const char *lined
 		return OSMTPD_PHASE_LINK_TLS;
 	if (strcmp(phase, "link-auth") == 0)
 		return OSMTPD_PHASE_LINK_AUTH;
+	if (strcmp(phase, "tx-reset") == 0)
+		return OSMTPD_PHASE_TX_RESET;
 	if (strcmp(phase, "tx-begin") == 0)
 		return OSMTPD_PHASE_TX_BEGIN;
 	if (strcmp(phase, "tx-mail") == 0)
@@ -2070,6 +2103,8 @@ osmtpd_phasetostr(enum osmtpd_phase phase)
 		return "link-tls";
 	case OSMTPD_PHASE_LINK_AUTH:
 		return "link-auth";
+	case OSMTPD_PHASE_TX_RESET:
+		return "tx-reset";
 	case OSMTPD_PHASE_TX_BEGIN:
 		return "tx-begin";
 	case OSMTPD_PHASE_TX_MAIL:
blob - dc06d018816c18df0c231914fd9c582c9db0c7cd
blob + 65d9e6d4cecc4d738b5a4156fe5398affd2fd5ba
--- opensmtpd.h
+++ opensmtpd.h
@@ -61,6 +61,7 @@ enum osmtpd_phase {
 	OSMTPD_PHASE_LINK_IDENTIFY,
 	OSMTPD_PHASE_LINK_TLS,
 	OSMTPD_PHASE_LINK_AUTH,
+	OSMTPD_PHASE_TX_RESET,
 	OSMTPD_PHASE_TX_BEGIN,
 	OSMTPD_PHASE_TX_MAIL,
 	OSMTPD_PHASE_TX_RCPT,
@@ -147,6 +148,7 @@ void osmtpd_register_report_tls(int, void (*)(struct o
     const char *));
 void osmtpd_register_report_auth(int, void (*)(struct osmtpd_ctx *,
     const char *, enum osmtpd_auth_status));
+void osmtpd_register_report_reset(int, void (*)(struct osmtpd_ctx *, uint32_t));
 void osmtpd_register_report_begin(int, void (*)(struct osmtpd_ctx *, uint32_t));
 void osmtpd_register_report_mail(int, void (*)(struct osmtpd_ctx *, uint32_t,
     const char *, enum osmtpd_status));