aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmime/smtp_proto.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-07-23 12:53:08 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-07-23 12:53:08 +0100
commitfe79d8c5a39f2b717f78cc3f3ef21b3cfc46500b (patch)
treec84e6a5d4c5cd78a7a2cc3c7adbc7af5d0541682 /src/libmime/smtp_proto.c
parente0483657ff6cf1adc828ccce457814d61fe90a0d (diff)
downloadrspamd-fe79d8c5a39f2b717f78cc3f3ef21b3cfc46500b.tar.gz
rspamd-fe79d8c5a39f2b717f78cc3f3ef21b3cfc46500b.zip
Revert "Unify code style."
This reverts commit e0483657ff6cf1adc828ccce457814d61fe90a0d.
Diffstat (limited to 'src/libmime/smtp_proto.c')
-rw-r--r--src/libmime/smtp_proto.c799
1 files changed, 361 insertions, 438 deletions
diff --git a/src/libmime/smtp_proto.c b/src/libmime/smtp_proto.c
index 3c8395784..3af1c3910 100644
--- a/src/libmime/smtp_proto.c
+++ b/src/libmime/smtp_proto.c
@@ -22,24 +22,21 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "cfg_file.h"
#include "config.h"
#include "main.h"
+#include "cfg_file.h"
+#include "util.h"
#include "smtp.h"
#include "smtp_proto.h"
#include "smtp_utils.h"
-#include "util.h"
-gchar *
-make_smtp_error (rspamd_mempool_t *pool,
- gint error_code,
- const gchar *format,
- ...)
+gchar *
+make_smtp_error (rspamd_mempool_t *pool, gint error_code, const gchar *format, ...)
{
- va_list vp;
- gchar *result = NULL, *p;
- size_t len;
-
+ va_list vp;
+ gchar *result = NULL, *p;
+ size_t len;
+
va_start (vp, format);
len = g_printf_string_upper_bound (format, vp);
va_end (vp);
@@ -56,9 +53,7 @@ make_smtp_error (rspamd_mempool_t *pool,
gboolean
-parse_smtp_command (struct smtp_session *session,
- f_str_t *line,
- struct smtp_command **cmd)
+parse_smtp_command (struct smtp_session *session, f_str_t *line, struct smtp_command **cmd)
{
enum {
SMTP_PARSE_START = 0,
@@ -66,11 +61,11 @@ parse_smtp_command (struct smtp_session *session,
SMTP_PARSE_ARGUMENT,
SMTP_PARSE_DONE
} state;
- gchar *p, *c, ch, cmd_buf[4];
- guint i;
- f_str_t *arg = NULL;
- struct smtp_command *pcmd;
-
+ gchar *p, *c, ch, cmd_buf[4];
+ guint i;
+ f_str_t *arg = NULL;
+ struct smtp_command *pcmd;
+
if (line->len == 0) {
return FALSE;
}
@@ -81,129 +76,125 @@ parse_smtp_command (struct smtp_session *session,
*cmd = rspamd_mempool_alloc0 (session->pool, sizeof (struct smtp_command));
pcmd = *cmd;
- for (i = 0; i < line->len; i++, p++) {
+ for (i = 0; i < line->len; i ++, p ++) {
ch = *p;
switch (state) {
- case SMTP_PARSE_START:
- if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i ==
- line->len - 1) {
- if (i == line->len - 1) {
- p++;
- }
- if (p - c == 4) {
- cmd_buf[0] = g_ascii_toupper (c[0]);
- cmd_buf[1] = g_ascii_toupper (c[1]);
- cmd_buf[2] = g_ascii_toupper (c[2]);
- cmd_buf[3] = g_ascii_toupper (c[3]);
-
- if (memcmp (cmd_buf, "HELO", 4) == 0) {
- pcmd->command = SMTP_COMMAND_HELO;
- }
- else if (memcmp (cmd_buf, "EHLO", 4) == 0) {
- pcmd->command = SMTP_COMMAND_EHLO;
- }
- else if (memcmp (cmd_buf, "MAIL", 4) == 0) {
- pcmd->command = SMTP_COMMAND_MAIL;
+ case SMTP_PARSE_START:
+ if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == line->len - 1) {
+ if (i == line->len - 1) {
+ p ++;
}
- else if (memcmp (cmd_buf, "RCPT", 4) == 0) {
- pcmd->command = SMTP_COMMAND_RCPT;
+ if (p - c == 4) {
+ cmd_buf[0] = g_ascii_toupper (c[0]);
+ cmd_buf[1] = g_ascii_toupper (c[1]);
+ cmd_buf[2] = g_ascii_toupper (c[2]);
+ cmd_buf[3] = g_ascii_toupper (c[3]);
+
+ if (memcmp (cmd_buf, "HELO", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_HELO;
+ }
+ else if (memcmp (cmd_buf, "EHLO", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_EHLO;
+ }
+ else if (memcmp (cmd_buf, "MAIL", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_MAIL;
+ }
+ else if (memcmp (cmd_buf, "RCPT", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_RCPT;
+ }
+ else if (memcmp (cmd_buf, "DATA", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_DATA;
+ }
+ else if (memcmp (cmd_buf, "QUIT", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_QUIT;
+ }
+ else if (memcmp (cmd_buf, "NOOP", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_NOOP;
+ }
+ else if (memcmp (cmd_buf, "EXPN", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_EXPN;
+ }
+ else if (memcmp (cmd_buf, "RSET", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_RSET;
+ }
+ else if (memcmp (cmd_buf, "HELP", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_HELP;
+ }
+ else if (memcmp (cmd_buf, "VRFY", 4) == 0) {
+ pcmd->command = SMTP_COMMAND_VRFY;
+ }
+ else {
+ msg_info ("invalid command: %*s", 4, cmd_buf);
+ return FALSE;
+ }
}
- else if (memcmp (cmd_buf, "DATA", 4) == 0) {
- pcmd->command = SMTP_COMMAND_DATA;
- }
- else if (memcmp (cmd_buf, "QUIT", 4) == 0) {
- pcmd->command = SMTP_COMMAND_QUIT;
- }
- else if (memcmp (cmd_buf, "NOOP", 4) == 0) {
- pcmd->command = SMTP_COMMAND_NOOP;
- }
- else if (memcmp (cmd_buf, "EXPN", 4) == 0) {
- pcmd->command = SMTP_COMMAND_EXPN;
+ else {
+ /* Invalid command */
+ msg_info ("invalid command: %*s", 4, c);
+ return FALSE;
}
- else if (memcmp (cmd_buf, "RSET", 4) == 0) {
- pcmd->command = SMTP_COMMAND_RSET;
+ /* Now check what we have */
+ if (ch == ' ' || ch == ':') {
+ state = SMTP_PARSE_SPACES;
}
- else if (memcmp (cmd_buf, "HELP", 4) == 0) {
- pcmd->command = SMTP_COMMAND_HELP;
+ else if (ch == CR) {
+ state = SMTP_PARSE_DONE;
}
- else if (memcmp (cmd_buf, "VRFY", 4) == 0) {
- pcmd->command = SMTP_COMMAND_VRFY;
- }
- else {
- msg_info ("invalid command: %*s", 4, cmd_buf);
- return FALSE;
+ else if (ch == LF) {
+ return TRUE;
}
}
- else {
- /* Invalid command */
- msg_info ("invalid command: %*s", 4, c);
+ else if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
+ msg_info ("invalid letter code in SMTP command: %d", (gint)ch);
return FALSE;
}
- /* Now check what we have */
- if (ch == ' ' || ch == ':') {
- state = SMTP_PARSE_SPACES;
- }
- else if (ch == CR) {
+ break;
+ case SMTP_PARSE_SPACES:
+ if (ch == CR) {
state = SMTP_PARSE_DONE;
}
else if (ch == LF) {
- return TRUE;
+ goto end;
}
- }
- else if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
- msg_info ("invalid letter code in SMTP command: %d", (gint)ch);
- return FALSE;
- }
- break;
- case SMTP_PARSE_SPACES:
- if (ch == CR) {
- state = SMTP_PARSE_DONE;
- }
- else if (ch == LF) {
- goto end;
- }
- else if (ch != ' ' && ch != ':') {
- state = SMTP_PARSE_ARGUMENT;
- arg = rspamd_mempool_alloc (session->pool, sizeof (f_str_t));
- c = p;
- }
- break;
- case SMTP_PARSE_ARGUMENT:
- if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i ==
- line->len - 1) {
- if (i == line->len - 1 && (ch != ' ' && ch != CR && ch != LF)) {
- p++;
- }
- arg->len = p - c;
- arg->begin = rspamd_mempool_alloc (session->pool, arg->len);
- memcpy (arg->begin, c, arg->len);
- pcmd->args = g_list_prepend (pcmd->args, arg);
- if (ch == ' ' || ch == ':') {
- state = SMTP_PARSE_SPACES;
- }
- else if (ch == CR) {
- state = SMTP_PARSE_DONE;
+ else if (ch != ' ' && ch != ':') {
+ state = SMTP_PARSE_ARGUMENT;
+ arg = rspamd_mempool_alloc (session->pool, sizeof (f_str_t));
+ c = p;
}
- else {
+ break;
+ case SMTP_PARSE_ARGUMENT:
+ if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == line->len - 1) {
+ if (i == line->len - 1 && (ch != ' ' && ch != CR && ch != LF)) {
+ p ++;
+ }
+ arg->len = p - c;
+ arg->begin = rspamd_mempool_alloc (session->pool, arg->len);
+ memcpy (arg->begin, c, arg->len);
+ pcmd->args = g_list_prepend (pcmd->args, arg);
+ if (ch == ' ' || ch == ':') {
+ state = SMTP_PARSE_SPACES;
+ }
+ else if (ch == CR) {
+ state = SMTP_PARSE_DONE;
+ }
+ else {
+ goto end;
+ }
+ }
+ break;
+ case SMTP_PARSE_DONE:
+ if (ch == LF) {
goto end;
}
- }
- break;
- case SMTP_PARSE_DONE:
- if (ch == LF) {
- goto end;
- }
- msg_info ("CR without LF in SMTP command");
- return FALSE;
+ msg_info ("CR without LF in SMTP command");
+ return FALSE;
}
}
end:
if (pcmd->args) {
pcmd->args = g_list_reverse (pcmd->args);
- rspamd_mempool_add_destructor (session->pool,
- (rspamd_mempool_destruct_t)g_list_free,
- pcmd->args);
+ rspamd_mempool_add_destructor (session->pool, (rspamd_mempool_destruct_t)g_list_free, pcmd->args);
}
return TRUE;
}
@@ -211,14 +202,14 @@ end:
static gboolean
check_smtp_path (f_str_t *path)
{
- guint i;
- gchar *p;
+ guint i;
+ gchar *p;
p = path->begin;
if (*p != '<' || path->len < 2) {
return FALSE;
}
- for (i = 0; i < path->len; i++, p++) {
+ for (i = 0; i < path->len; i++, p ++) {
if (*p == '>' && i != path->len - 1) {
return FALSE;
}
@@ -230,7 +221,7 @@ check_smtp_path (f_str_t *path)
gboolean
parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd)
{
- f_str_t *arg;
+ f_str_t *arg;
if (cmd->args == NULL) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
@@ -265,8 +256,8 @@ parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd)
gboolean
parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd)
{
- f_str_t *arg;
- GList *cur = cmd->args;
+ f_str_t *arg;
+ GList *cur = cmd->args;
if (cmd->args == NULL) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
@@ -275,10 +266,10 @@ parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd)
arg = cur->data;
/* First argument MUST be FROM */
if (arg->len != 4 || (
- g_ascii_toupper (arg->begin[0]) != 'F' ||
- g_ascii_toupper (arg->begin[1]) != 'R' ||
- g_ascii_toupper (arg->begin[2]) != 'O' ||
- g_ascii_toupper (arg->begin[3]) != 'M')) {
+ g_ascii_toupper (arg->begin[0]) != 'F' ||
+ g_ascii_toupper (arg->begin[1]) != 'R' ||
+ g_ascii_toupper (arg->begin[2]) != 'O' ||
+ g_ascii_toupper (arg->begin[3]) != 'M')) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
return FALSE;
}
@@ -303,8 +294,8 @@ parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd)
gboolean
parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd)
{
- f_str_t *arg;
- GList *cur = cmd->args;
+ f_str_t *arg;
+ GList *cur = cmd->args;
if (cmd->args == NULL) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
@@ -313,8 +304,8 @@ parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd)
arg = cur->data;
/* First argument MUST be FROM */
if (arg->len != 2 || (
- g_ascii_toupper (arg->begin[0]) != 'T' ||
- g_ascii_toupper (arg->begin[1]) != 'O')) {
+ g_ascii_toupper (arg->begin[0]) != 'T' ||
+ g_ascii_toupper (arg->begin[1]) != 'O')) {
session->error = SMTP_ERROR_BAD_ARGUMENTS;
return FALSE;
}
@@ -341,7 +332,7 @@ parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd)
static gint
check_smtp_ustream_reply (f_str_t *in, gchar success_code)
{
- gchar *p;
+ gchar *p;
/* Check for 250 at the begin of line */
if (in->len >= sizeof ("220 ") - 1) {
@@ -366,13 +357,13 @@ check_smtp_ustream_reply (f_str_t *in, gchar success_code)
size_t
smtp_upstream_write_list (GList *args, gchar *buf, size_t buflen)
{
- GList *cur = args;
- size_t r = 0;
- f_str_t *arg;
+ GList *cur = args;
+ size_t r = 0;
+ f_str_t *arg;
while (cur && r < buflen - 3) {
arg = cur->data;
- r += rspamd_snprintf (buf + r, buflen - r, " %V", arg);
+ r += rspamd_snprintf (buf + r, buflen - r, " %V", arg);
cur = g_list_next (cur);
}
@@ -383,351 +374,288 @@ smtp_upstream_write_list (GList *args, gchar *buf, size_t buflen)
return r;
}
-gboolean
+gboolean
smtp_upstream_write_socket (void *arg)
{
- struct smtp_session *session = arg;
-
+ struct smtp_session *session = arg;
+
if (session->upstream_state == SMTP_STATE_IN_SENDFILE) {
session->upstream_state = SMTP_STATE_AFTER_DATA;
- return rspamd_dispatcher_write (session->upstream_dispatcher,
- CRLF DATA_END_TRAILER,
- sizeof (CRLF DATA_END_TRAILER) - 1,
- FALSE,
- TRUE);
+ return rspamd_dispatcher_write (session->upstream_dispatcher, CRLF DATA_END_TRAILER, sizeof (CRLF DATA_END_TRAILER) - 1, FALSE, TRUE);
}
return TRUE;
}
-gboolean
+gboolean
smtp_upstream_read_socket (f_str_t * in, void *arg)
{
- struct smtp_session *session = arg;
- gchar outbuf[BUFSIZ];
- gint r;
-
+ struct smtp_session *session = arg;
+ gchar outbuf[BUFSIZ];
+ gint r;
+
msg_debug ("in: %V, state: %d", in, session->upstream_state);
switch (session->upstream_state) {
- case SMTP_STATE_GREETING:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- in->len, FALSE, TRUE)) {
- goto err;
+ case SMTP_STATE_GREETING:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+ goto err;
+ }
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
}
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
+ else if (r == 1) {
+ if (session->ctx->use_xclient) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "XCLIENT NAME=%s ADDR=%s" CRLF,
+ session->resolved ? session->hostname : "[UNDEFINED]",
+ inet_ntoa (session->client_addr));
+ session->upstream_state = SMTP_STATE_HELO;
+ return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
+ }
+ else {
+ session->upstream_state = SMTP_STATE_FROM;
+ if (session->helo) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
+ session->esmtp ? "EHLO" : "HELO",
+ session->helo);
+ }
+ else {
+ return smtp_upstream_read_socket (in, arg);
+ }
+ return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
+ }
}
- destroy_session (session->s);
- return FALSE;
- }
- else if (r == 1) {
- if (session->ctx->use_xclient) {
- r = rspamd_snprintf (outbuf,
- sizeof (outbuf),
- "XCLIENT NAME=%s ADDR=%s" CRLF,
- session->resolved ? session->hostname : "[UNDEFINED]",
- inet_ntoa (session->client_addr));
- session->upstream_state = SMTP_STATE_HELO;
- return rspamd_dispatcher_write (session->upstream_dispatcher,
- outbuf,
- r,
- FALSE,
- FALSE);
+ break;
+ case SMTP_STATE_HELO:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+ goto err;
+ }
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
}
- else {
+ else if (r == 1) {
session->upstream_state = SMTP_STATE_FROM;
if (session->helo) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
- session->esmtp ? "EHLO" : "HELO",
- session->helo);
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
+ session->esmtp ? "EHLO" : "HELO",
+ session->helo);
}
else {
return smtp_upstream_read_socket (in, arg);
}
- return rspamd_dispatcher_write (session->upstream_dispatcher,
- outbuf,
- r,
- FALSE,
- FALSE);
+ return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
}
- }
- break;
- case SMTP_STATE_HELO:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- in->len, FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
- }
- else if (r == 1) {
- session->upstream_state = SMTP_STATE_FROM;
- if (session->helo) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF,
- session->esmtp ? "EHLO" : "HELO",
- session->helo);
- }
- else {
- return smtp_upstream_read_socket (in, arg);
- }
- return rspamd_dispatcher_write (session->upstream_dispatcher,
- outbuf,
- r,
- FALSE,
- FALSE);
- }
- break;
- case SMTP_STATE_FROM:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- in->len, FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
- }
- else if (r == 1) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "MAIL FROM: ");
- r +=
- smtp_upstream_write_list (session->from,
- outbuf + r,
- sizeof (outbuf) - r);
- session->upstream_state = SMTP_STATE_RCPT;
- return rspamd_dispatcher_write (session->upstream_dispatcher,
- outbuf,
- r,
- FALSE,
- FALSE);
- }
- break;
- case SMTP_STATE_RCPT:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- in->len, FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
- }
- else if (r == 1) {
- r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
- session->cur_rcpt = g_list_first (session->rcpt);
- r += smtp_upstream_write_list (session->cur_rcpt->data,
- outbuf + r,
- sizeof (outbuf) - r);
- session->cur_rcpt = g_list_next (session->cur_rcpt);
- session->upstream_state = SMTP_STATE_BEFORE_DATA;
- return rspamd_dispatcher_write (session->upstream_dispatcher,
- outbuf,
- r,
- FALSE,
- FALSE);
- }
- break;
- case SMTP_STATE_BEFORE_DATA:
- r = check_smtp_ustream_reply (in, '2');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- in->len, FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
+ break;
+ case SMTP_STATE_FROM:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+ goto err;
+ }
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
}
- if (session->cur_rcpt) {
- session->rcpt = g_list_delete_link (session->rcpt,
- session->cur_rcpt);
+ else if (r == 1) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "MAIL FROM: ");
+ r += smtp_upstream_write_list (session->from, outbuf + r, sizeof (outbuf) - r);
+ session->upstream_state = SMTP_STATE_RCPT;
+ return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
}
- else {
- session->rcpt =
- g_list_delete_link (session->rcpt, session->rcpt);
+ break;
+ case SMTP_STATE_RCPT:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+ goto err;
+ }
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
}
- session->errors++;
- session->state = SMTP_STATE_RCPT;
- return TRUE;
- }
- else if (r == 1) {
- if (session->cur_rcpt != NULL) {
+ else if (r == 1) {
r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
- r += smtp_upstream_write_list (session->cur_rcpt,
- outbuf + r,
- sizeof (outbuf) - r);
+ session->cur_rcpt = g_list_first (session->rcpt);
+ r += smtp_upstream_write_list (session->cur_rcpt->data, outbuf + r, sizeof (outbuf) - r);
session->cur_rcpt = g_list_next (session->cur_rcpt);
- if (!rspamd_dispatcher_write (session->upstream_dispatcher,
- outbuf, r, FALSE, FALSE)) {
+ session->upstream_state = SMTP_STATE_BEFORE_DATA;
+ return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
+ }
+ break;
+ case SMTP_STATE_BEFORE_DATA:
+ r = check_smtp_ustream_reply (in, '2');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
goto err;
}
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ if (session->cur_rcpt) {
+ session->rcpt = g_list_delete_link (session->rcpt, session->cur_rcpt);
+ }
+ else {
+ session->rcpt = g_list_delete_link (session->rcpt, session->rcpt);
+ }
+ session->errors ++;
+ session->state = SMTP_STATE_RCPT;
+ return TRUE;
+ }
+ else if (r == 1) {
+ if (session->cur_rcpt != NULL) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
+ r += smtp_upstream_write_list (session->cur_rcpt, outbuf + r, sizeof (outbuf) - r);
+ session->cur_rcpt = g_list_next (session->cur_rcpt);
+ if (! rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE)) {
+ goto err;
+ }
+ }
+ else {
+ session->upstream_state = SMTP_STATE_DATA;
+ rspamd_dispatcher_pause (session->upstream_dispatcher);
+ }
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* Write to client */
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+ goto err;
+ }
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ if (session->state == SMTP_STATE_WAIT_UPSTREAM) {
+ rspamd_dispatcher_restore (session->dispatcher);
+ session->state = SMTP_STATE_RCPT;
+ }
}
- else {
- session->upstream_state = SMTP_STATE_DATA;
- rspamd_dispatcher_pause (session->upstream_dispatcher);
- }
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* Write to client */
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- in->len, FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
- goto err;
+ break;
+ case SMTP_STATE_DATA:
+ r = check_smtp_ustream_reply (in, '3');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ goto err;
+ }
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
}
- if (session->state == SMTP_STATE_WAIT_UPSTREAM) {
+ else if (r == 1) {
+ if (! make_smtp_tempfile (session)) {
+ session->error = SMTP_ERROR_FILE;
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_restore (session->dispatcher);
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ goto err;
+ }
+ destroy_session (session->s);
+ return FALSE;
+ }
+ session->state = SMTP_STATE_AFTER_DATA;
+ session->error = SMTP_ERROR_DATA_OK;
rspamd_dispatcher_restore (session->dispatcher);
- session->state = SMTP_STATE_RCPT;
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ goto err;
+ }
+ rspamd_dispatcher_pause (session->upstream_dispatcher);
+ rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, 0);
+ session->dispatcher->strip_eol = FALSE;
+ return TRUE;
}
- }
- break;
- case SMTP_STATE_DATA:
- r = check_smtp_ustream_reply (in, '3');
- if (r == -1) {
+ break;
+ case SMTP_STATE_AFTER_DATA:
session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
- session->state = SMTP_STATE_CRITICAL_ERROR;
+ session->state = SMTP_STATE_DATA;
rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- 0, FALSE, TRUE)) {
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
goto err;
}
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
goto err;
}
- destroy_session (session->s);
- return FALSE;
- }
- else if (r == 1) {
- if (!make_smtp_tempfile (session)) {
- session->error = SMTP_ERROR_FILE;
+ if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, sizeof ("QUIT" CRLF) - 1, FALSE, TRUE)) {
+ goto err;
+ }
+ session->upstream_state = SMTP_STATE_END;
+ return TRUE;
+ break;
+ case SMTP_STATE_END:
+ r = check_smtp_ustream_reply (in, '5');
+ if (r == -1) {
+ session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
+ rspamd_strlcpy (session->error, in->begin, in->len + 1);
+ /* XXX: assume upstream errors as critical errors */
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher,
- session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ goto err;
+ }
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
return FALSE;
}
- session->state = SMTP_STATE_AFTER_DATA;
- session->error = SMTP_ERROR_DATA_OK;
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- 0, FALSE, TRUE)) {
- goto err;
+ else {
+ remove_normal_event (session->s, (event_finalizer_t)smtp_upstream_finalize_connection, session);
}
- rspamd_dispatcher_pause (session->upstream_dispatcher);
- rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, 0);
- session->dispatcher->strip_eol = FALSE;
- return TRUE;
- }
- break;
- case SMTP_STATE_AFTER_DATA:
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- session->state = SMTP_STATE_DATA;
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0,
- FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) -
- 1, FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF,
- sizeof ("QUIT" CRLF) - 1, FALSE, TRUE)) {
- goto err;
- }
- session->upstream_state = SMTP_STATE_END;
- return TRUE;
- break;
- case SMTP_STATE_END:
- r = check_smtp_ustream_reply (in, '5');
- if (r == -1) {
- session->error = rspamd_mempool_alloc (session->pool, in->len + 1);
- rspamd_strlcpy (session->error, in->begin, in->len + 1);
- /* XXX: assume upstream errors as critical errors */
+ return FALSE;
+ break;
+ default:
+ msg_err ("got upstream reply at unexpected state: %d, reply: %V", session->upstream_state, in);
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error,
- 0, FALSE, TRUE)) {
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
goto err;
}
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF,
- sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
return FALSE;
- }
- else {
- remove_normal_event (session->s,
- (event_finalizer_t)smtp_upstream_finalize_connection,
- session);
- }
- return FALSE;
- break;
- default:
- msg_err ("got upstream reply at unexpected state: %d, reply: %V",
- session->upstream_state,
- in);
- session->state = SMTP_STATE_CRITICAL_ERROR;
- rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0,
- FALSE, TRUE)) {
- goto err;
- }
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) -
- 1, FALSE, TRUE)) {
- goto err;
- }
- destroy_session (session->s);
- return FALSE;
}
return TRUE;
@@ -736,24 +664,20 @@ err:
return FALSE;
}
-void
+void
smtp_upstream_err_socket (GError *err, void *arg)
{
- struct smtp_session *session = arg;
+ struct smtp_session *session = arg;
- msg_info ("abnormally closing connection with upstream %s, error: %s",
- session->upstream->name,
- err->message);
+ msg_info ("abnormally closing connection with upstream %s, error: %s", session->upstream->name, err->message);
session->error = SMTP_ERROR_UPSTREAM;
session->state = SMTP_STATE_CRITICAL_ERROR;
/* XXX: assume upstream errors as critical errors */
rspamd_dispatcher_restore (session->dispatcher);
- if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE,
- TRUE)) {
+ if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
return;
}
- if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1,
- FALSE, TRUE)) {
+ if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
return;
}
upstream_fail (&session->upstream->up, session->session_time);
@@ -763,11 +687,10 @@ smtp_upstream_err_socket (GError *err, void *arg)
void
smtp_upstream_finalize_connection (gpointer data)
{
- struct smtp_session *session = data;
-
+ struct smtp_session *session = data;
+
if (session->state != SMTP_STATE_CRITICAL_ERROR) {
- if (!rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF,
- 0, FALSE, TRUE)) {
+ if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, 0, FALSE, TRUE)) {
msg_warn ("cannot send correctly closing message to upstream");
}
}