commit f8c5e10bf875054fa615d67c60f84ae2986fdfd5 from: Martijn van Duren date: Tue Jan 28 18:57:57 2025 UTC Add support for tx-reset report and use that to clean up local_message. 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));