summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@thewalter.net>2010-11-17 15:17:18 +0000
committerStef Walter <stef@thewalter.net>2011-01-23 15:47:45 -0600
commit78658c88caf7e6374efbbb451159da261e3b0695 (patch)
tree47bb5b664ea9bc226df3583b9f707ac68c0961a8
parentee9d43a08eab4c21c038b502215429143b12b13f (diff)
Reject early before recipient server gets the envelope.
-rw-r--r--common/smtppass.c33
-rw-r--r--common/smtppass.h12
-rw-r--r--src/proxsmtpd.c13
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;