Commit Diff


commit - 866e5e0eeeff8df523d89b5070c2575a15a4e62f
commit + d308c5316d2dd25d9253d8a24cde1359412ee466
blob - 9d16a5268ffd4e2b654cd9b21ca6cd590aff7025
blob + eb194087ab831b51d259be96c06fbee8f9c2c8d5
--- Symbols.list
+++ Symbols.list
@@ -18,6 +18,7 @@ osmtpd_register_report_connect
 osmtpd_register_report_disconnect
 osmtpd_register_report_identify
 osmtpd_register_report_tls
+osmtpd_register_report_reset
 osmtpd_register_report_auth
 osmtpd_register_report_begin
 osmtpd_register_report_mail
blob - 005a5e773276f5d23b1d89431c0ca3cb69617d27
blob + cafadc22a92a1f5dd4d21bc646410b61dc7ea04a
--- opensmtpd.c
+++ opensmtpd.c
@@ -90,6 +90,8 @@ static void osmtpd_link_identify(struct osmtpd_callbac
 static void osmtpd_link_tls(struct osmtpd_callback *, struct osmtpd_session *,
     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 *);
@@ -300,6 +302,15 @@ static struct osmtpd_callback osmtpd_callbacks[] = {
 	    OSMTPD_PHASE_LINK_AUTH,
 	    1,
 	    osmtpd_link_auth,
+	    NULL,
+	    0,
+	    0
+	},
+	{
+	    OSMTPD_TYPE_REPORT,
+	    OSMTPD_PHASE_TX_RESET,
+	    1,
+	    osmtpd_tx_reset,
 	    NULL,
 	    0,
 	    0
@@ -453,6 +464,15 @@ static struct osmtpd_callback osmtpd_callbacks[] = {
 	    OSMTPD_PHASE_LINK_AUTH,
 	    0,
 	    osmtpd_link_auth,
+	    NULL,
+	    0,
+	    0
+	},
+	{
+	    OSMTPD_TYPE_REPORT,
+	    OSMTPD_PHASE_TX_RESET,
+	    0,
+	    osmtpd_tx_reset,
 	    NULL,
 	    0,
 	    0
@@ -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 &&
@@ -1206,6 +1225,7 @@ osmtpd_newline(struct io *io, int ev, __unused void *a
 		if (ctx == NULL) {
 			if ((ctx = malloc(sizeof(*ctx))) == NULL)
 				osmtpd_err(1, NULL);
+			ctx->status = SESSION_OK;
 			ctx->ctx.reqid = search.ctx.reqid;
 			ctx->ctx.rdns = NULL;
 			ctx->ctx.fcrdns = OSMTPD_STATUS_TEMPFAIL;
@@ -1487,6 +1507,47 @@ osmtpd_link_auth(struct osmtpd_callback *cb, struct os
 
 	if ((f = cb->cb) != NULL && session->status == SESSION_OK)
 		f(&session->ctx, username, s);
+}
+
+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
@@ -1692,7 +1753,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;
@@ -1716,20 +1777,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
@@ -1739,7 +1786,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;
@@ -1757,20 +1803,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
@@ -2013,6 +2045,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)
@@ -2096,6 +2130,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 - 41f4aa485141d8a8e041197ba07b27bf8dfcb9a6
blob + f10b1b40489a1200391eae13016d8770f1b81ab9
--- 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));
blob - 75877a9b789949faab1755d45524211d65d0d491
blob + 58ce153580d9714e5b5f3df2f1a0d4b39846598f
--- osmtpd_run.3
+++ osmtpd_run.3
@@ -38,6 +38,7 @@
 .Nm osmtpd_register_report_identify ,
 .Nm osmtpd_register_report_tls ,
 .Nm osmtpd_register_report_auth ,
+.Nm osmtpd_register_report_reset ,
 .Nm osmtpd_register_report_begin ,
 .Nm osmtpd_register_report_mail ,
 .Nm osmtpd_register_report_rcpt ,
@@ -150,6 +151,11 @@
 .Fo osmtpd_register_report_auth
 .Fa "int incoming"
 .Fa "void (*cb)(struct osmtpd_ctx *ctx, const char *username, enum osmtpd_auth_status status)"
+.Fc
+.Ft void
+.Fo osmtpd_register_report_reset
+.Fa "int incoming"
+.Fa "void (*cb)(struct osmtpd_ctx *ctx, uint32_t msgid)"
 .Fc
 .Ft void
 .Fo osmtpd_register_report_begin
@@ -314,6 +320,8 @@ function:
 .Nm osmtpd_register_report_tls
 .It Dv OSMTPD_PHASE_LINK_AUTH
 .Nm osmtpd_register_report_auth
+.It Dv OSMTPD_PHASE_TX_RESET
+.Nm osmtpd_register_report_reset
 .It Dv OSMTPD_PHASE_TX_BEGIN
 .Nm osmtpd_register_report_begin
 .It Dv OSMTPD_PHASE_TX_MAIL