diff options
author | Stef Walter <stef@thewalter.net> | 2010-11-17 15:17:18 +0000 |
---|---|---|
committer | Stef Walter <stef@thewalter.net> | 2011-01-23 15:47:45 -0600 |
commit | 78658c88caf7e6374efbbb451159da261e3b0695 (patch) | |
tree | 47bb5b664ea9bc226df3583b9f707ac68c0961a8 | |
parent | ee9d43a08eab4c21c038b502215429143b12b13f (diff) |
Reject early before recipient server gets the envelope.
-rw-r--r-- | common/smtppass.c | 33 | ||||
-rw-r--r-- | common/smtppass.h | 12 | ||||
-rw-r--r-- | 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); @@ -1863,6 +1878,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; int len, x; @@ -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 @@ -239,6 +239,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 * soon after to prevent the strings from going out of scope. @@ -275,6 +280,13 @@ 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 * sp_read_data, sp_write_data. 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; |