commit 58a6bc69bbda6ff4b5c1ec0b918afb31d42b4e10 from: Martijn van Duren date: Mon Dec 05 12:38:12 2022 UTC add osmtpd_register_report_auth() and friends. Initial diff from Martin Kjaer Jorgensen (me lagy org) commit - 681d8d4923321c8caf195fd32a7682c98b61ec07 commit + 58a6bc69bbda6ff4b5c1ec0b918afb31d42b4e10 blob - a73487daca0c4c739ebea7f7c7267d404b7fcdd1 blob + 648038bd9c9ec155da670cfb9e07c6b8c3565c09 --- 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_auth osmtpd_register_report_begin osmtpd_register_report_mail osmtpd_register_report_rcpt blob - 71b0691f55d1ae2f533b94e0f027e22cf510c52e blob + 4d551f0f161ea841d896117f7a9a8521263adc7e --- opensmtpd.c +++ opensmtpd.c @@ -81,6 +81,8 @@ static void osmtpd_link_greeting(struct osmtpd_callbac static void osmtpd_link_identify(struct osmtpd_callback *, struct osmtpd_ctx *, char *, char *); static void osmtpd_link_tls(struct osmtpd_callback *, struct osmtpd_ctx *, + char *, char *); +static void osmtpd_link_auth(struct osmtpd_callback *, struct osmtpd_ctx *, char *, char *); static void osmtpd_tx_begin(struct osmtpd_callback *, struct osmtpd_ctx *, char *, char *); @@ -288,6 +290,15 @@ static struct osmtpd_callback osmtpd_callbacks[] = { }, { OSMTPD_TYPE_REPORT, + OSMTPD_PHASE_LINK_AUTH, + 1, + osmtpd_link_auth, + NULL, + 0, + 0 + }, + { + OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_BEGIN, 1, osmtpd_tx_begin, @@ -432,6 +443,15 @@ static struct osmtpd_callback osmtpd_callbacks[] = { }, { OSMTPD_TYPE_REPORT, + OSMTPD_PHASE_LINK_AUTH, + 0, + osmtpd_link_auth, + NULL, + 0, + 0 + }, + { + OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_BEGIN, 0, osmtpd_tx_begin, @@ -721,6 +741,16 @@ osmtpd_register_report_tls(int incoming, void (*cb)(st } void +osmtpd_register_report_auth(int incoming, void (*cb)(struct osmtpd_ctx *, + const char *, enum osmtpd_auth_status)) +{ + osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_LINK_AUTH, 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)) { @@ -866,6 +896,9 @@ osmtpd_register_need(int incoming) incoming, 1, NULL); if (needs & OSMTPD_NEED_CIPHERS) osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_LINK_TLS, + incoming, 1, NULL); + if (needs & OSMTPD_NEED_USERNAME) + osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_LINK_AUTH, incoming, 1, NULL); if (needs & OSMTPD_NEED_MSGID) { osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_TX_BEGIN, @@ -1147,6 +1180,7 @@ osmtpd_newline(struct io *io, int ev, __unused void *a ctx->ctx.greeting.identity = NULL; ctx->ctx.ciphers = NULL; ctx->ctx.msgid = 0; + ctx->ctx.username = NULL; ctx->ctx.mailfrom = NULL; ctx->ctx.rcptto = malloc(sizeof(*(ctx->ctx.rcptto))); if (ctx->ctx.rcptto == NULL) @@ -1336,6 +1370,7 @@ osmtpd_link_disconnect(struct osmtpd_callback *cb, str free(session->ctx.identity); free(session->ctx.greeting.identity); free(session->ctx.ciphers); + free(session->ctx.username); free(session->ctx.mailfrom); for (i = 0; session->ctx.rcptto[i] != NULL; i++) free(session->ctx.rcptto[i]); @@ -1392,6 +1427,36 @@ osmtpd_link_tls(struct osmtpd_callback *cb, struct osm } static void +osmtpd_link_auth(struct osmtpd_callback *cb, struct osmtpd_ctx *ctx, + char *username, char *linedup) +{ + void (*f)(struct osmtpd_ctx *, const char *, enum osmtpd_auth_status); + char *status; + enum osmtpd_auth_status s; + + if ((status = strrchr(username, '|')) == NULL) + osmtpd_errx(1, "Invalid auth received: %s", linedup); + status[0] = '\0'; + status++; + if (strcmp(status, "pass") == 0) + s = OSMTPD_AUTH_PASS; + else if (strcmp(status, "fail") == 0) + s = OSMTPD_AUTH_FAIL; + else if (strcmp(status, "error") == 0) + s = OSMTPD_AUTH_ERROR; + else + osmtpd_errx(1, "Invalid auth status received: %s", linedup); + + if (cb->storereport && s == OSMTPD_AUTH_PASS) { + if ((ctx->username = strdup(username)) == NULL) + osmtpd_err(1, NULL); + } + + if ((f = cb->cb) != NULL) + f(ctx, username, s); +} + +static void osmtpd_tx_begin(struct osmtpd_callback *cb, struct osmtpd_ctx *ctx, char *msgid, char *linedup) { @@ -1880,6 +1945,8 @@ osmtpd_strtophase(const char *phase, const char *lined return OSMTPD_PHASE_LINK_IDENTIFY; if (strcmp(phase, "link-tls") == 0) return OSMTPD_PHASE_LINK_TLS; + if (strcmp(phase, "link-auth") == 0) + return OSMTPD_PHASE_LINK_AUTH; if (strcmp(phase, "tx-begin") == 0) return OSMTPD_PHASE_TX_BEGIN; if (strcmp(phase, "tx-mail") == 0) @@ -1961,6 +2028,8 @@ osmtpd_phasetostr(enum osmtpd_phase phase) return "link-identify"; case OSMTPD_PHASE_LINK_TLS: return "link-tls"; + case OSMTPD_PHASE_LINK_AUTH: + return "link-auth"; case OSMTPD_PHASE_TX_BEGIN: return "tx-begin"; case OSMTPD_PHASE_TX_MAIL: blob - eef32374977851e19c0518f7be2c250d9ff3fa10 blob + dc06d018816c18df0c231914fd9c582c9db0c7cd --- opensmtpd.h +++ opensmtpd.h @@ -28,6 +28,12 @@ enum osmtpd_status { OSMTPD_STATUS_PERMFAIL }; +enum osmtpd_auth_status { + OSMTPD_AUTH_PASS, + OSMTPD_AUTH_FAIL, + OSMTPD_AUTH_ERROR, +}; + enum osmtpd_type { OSMTPD_TYPE_FILTER, OSMTPD_TYPE_REPORT @@ -54,6 +60,7 @@ enum osmtpd_phase { OSMTPD_PHASE_LINK_GREETING, OSMTPD_PHASE_LINK_IDENTIFY, OSMTPD_PHASE_LINK_TLS, + OSMTPD_PHASE_LINK_AUTH, OSMTPD_PHASE_TX_BEGIN, OSMTPD_PHASE_TX_MAIL, OSMTPD_PHASE_TX_RCPT, @@ -75,9 +82,10 @@ enum osmtpd_phase { #define OSMTPD_NEED_GREETING 1 << 5 #define OSMTPD_NEED_CIPHERS 1 << 6 #define OSMTPD_NEED_MSGID 1 << 7 -#define OSMTPD_NEED_MAILFROM 1 << 8 -#define OSMTPD_NEED_RCPTTO 1 << 9 -#define OSMTPD_NEED_EVPID 1 << 10 +#define OSMTPD_NEED_USERNAME 1 << 8 +#define OSMTPD_NEED_MAILFROM 1 << 9 +#define OSMTPD_NEED_RCPTTO 1 << 10 +#define OSMTPD_NEED_EVPID 1 << 11 struct osmtpd_ctx { enum osmtpd_type type; @@ -100,6 +108,7 @@ struct osmtpd_ctx { } greeting; char *ciphers; uint32_t msgid; + char *username; char *mailfrom; char **rcptto; uint64_t evpid; @@ -136,6 +145,8 @@ void osmtpd_register_report_identify(int, void (*)(str const char *)); void osmtpd_register_report_tls(int, void (*)(struct osmtpd_ctx *, const char *)); +void osmtpd_register_report_auth(int, void (*)(struct osmtpd_ctx *, + const char *, enum osmtpd_auth_status)); 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 - 8c9fbbbcbf4b5d16e859dea3b4825d86372684fe blob + 5e9e8ca23ddbceca7c1a2c5a9600bd3475c324c6 --- osmtpd_run.3 +++ osmtpd_run.3 @@ -37,6 +37,7 @@ .Nm osmtpd_register_report_disconnect , .Nm osmtpd_register_report_identify , .Nm osmtpd_register_report_tls , +.Nm osmtpd_register_report_auth , .Nm osmtpd_register_report_begin , .Nm osmtpd_register_report_mail , .Nm osmtpd_register_report_rcpt , @@ -142,6 +143,11 @@ .Fo osmtpd_register_report_tls .Fa "int incoming" .Fa "void (*cb)(struct osmtpd_ctx *ctx, const char *ciphers)" +.Fc +.Ft void +.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_begin @@ -300,6 +306,8 @@ function: .Nm osmtpd_register_report_identify .It Dv OSMTPD_PHASE_LINK_TLS .Nm osmtpd_register_report_tls +.It Dv OSMTPD_PHASE_LINK_AUTH +.Nm osmtpd_register_report_auth .It Dv OSMTPD_PHASE_TX_BEGIN .Nm osmtpd_register_report_begin .It Dv OSMTPD_PHASE_TX_MAIL @@ -425,6 +433,13 @@ Filters in need of filter specific data can use .Nm osmtpd_local_message and .Va local_message . +.It Vt char Va *username +The username with which the session was successfully authenticated. +.Nm osmtpd_need +needs to be initialized with +.DV OSMTPD_NEED_USERNAME . +If not available or authentication failed is set to +.Dv NULL . .It Vt char Va *mailfrom The envelope MAIL FROM address in the SMTP transaction. .Nm osmtpd_need blob - 3d7c908e43d641cb0dcddbee5df35d0ac5910b46 blob + 1edea46de912aea697c8369a973244bc7866c3e8 --- shlib_version +++ shlib_version @@ -1,2 +1,2 @@ -major=0 -minor=1 +major=1 +minor=0