From 78658c88caf7e6374efbbb451159da261e3b0695 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 17 Nov 2010 15:17:18 +0000 Subject: Reject early before recipient server gets the envelope. --- common/smtppass.c | 33 ++++++++++++++++++++++++++++----- common/smtppass.h | 12 ++++++++++++ src/proxsmtpd.c | 13 +++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/common/smtppass.c b/common/smtppass.c index 73600fd..8cc0522 100644 --- a/common/smtppass.c +++ b/common/smtppass.c @@ -1075,6 +1075,21 @@ static int smtp_passthru(spctx_t* ctx) auth_started = 1; } + else if(is_first_word(C_LINE, FROM_CMD, KL(FROM_CMD)) || + is_first_word(C_LINE, TO_CMD, KL(TO_CMD))) + { + r = cb_check_pre(ctx); + if(r < 0) + { + RETURN(-1); + } + else if(r == 0) + { + cleanup_context(ctx); + continue; + } + } + /* All other commands just get passed through to server */ if(spio_write_data(ctx, &(ctx->server), C_LINE) == -1) RETURN(-1); @@ -1862,6 +1877,19 @@ int sp_pass_data(spctx_t* ctx) } int sp_fail_data(spctx_t* ctx, const char* smtp_status) +{ + if(sp_fail_msg(ctx, smtp_status) < 0) + return -1; + + /* Tell the server to forget about the current message */ + if(spio_write_data(ctx, &(ctx->server), SMTP_RSET) == -1 || + read_server_response(ctx) == -1) + return -1; + + return 0; +} + +int sp_fail_msg(spctx_t* ctx, const char* smtp_status) { char buf[256 + KL(SMTP_REJPREFIX) + KL(CRLF) + 1]; char* t = NULL; @@ -1895,11 +1923,6 @@ int sp_fail_data(spctx_t* ctx, const char* smtp_status) if(spio_write_data(ctx, &(ctx->client), smtp_status) == -1) return -1; - /* Tell the server to forget about the current message */ - if(spio_write_data(ctx, &(ctx->server), SMTP_RSET) == -1 || - read_server_response(ctx) == -1) - return -1; - return 0; } diff --git a/common/smtppass.h b/common/smtppass.h index a54c9b0..5930eb9 100644 --- a/common/smtppass.h +++ b/common/smtppass.h @@ -238,6 +238,11 @@ int sp_fail_data(spctx_t* ctx, const char* smtp_status); */ int sp_pass_data(spctx_t* ctx); +/* + * Just sends a failure message to the client. + */ +int sp_fail_msg(spctx_t* ctx, const char* smtp_status); + /* * Setup the environment with context info. This is useful * if you're going to fork another process. Be sure to exec @@ -274,6 +279,13 @@ void sp_unlock(); extern spctx_t* cb_new_context(); extern void cb_del_context(spctx_t* ctx); +/* + * Called when an email envelope is staring to be sent. + * If this function returns a string, it is used as a failure + * message. + */ +extern int cb_check_pre(spctx_t* ctx); + /* * Called when the data section of an email is being transferred. * Once inside this function you can transfer files using diff --git a/src/proxsmtpd.c b/src/proxsmtpd.c index 6be962f..278ecee 100644 --- a/src/proxsmtpd.c +++ b/src/proxsmtpd.c @@ -225,6 +225,19 @@ static void usage() * SP CALLBACKS */ +int cb_check_pre(spctx_t* ctx) +{ + if(g_pxstate.filter_type == FILTER_REJECT) + { + sp_add_log(ctx, "status=", "REJECTED"); + if(sp_fail_msg(ctx, g_pxstate.reject) < 0) + return -1; /* Message already printed */ + return 0; + } + + return 1; +} + int cb_check_data(spctx_t* ctx) { int r = 0; -- cgit v1.2.3