commit d308c5316d2dd25d9253d8a24cde1359412ee466 from: Martijn van Duren date: Mon Feb 03 17:45:32 2025 UTC Add support for tx-reset report and use that to clean up local_message. manpage bits by kirill@ 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