aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2014-10-13 10:44:48 +0200
committerGilles Chehade <gilles@poolp.org>2014-10-13 10:44:48 +0200
commit1b497785cb0a016eb99bd308b03cee5be53fb89b (patch)
treeb053d6442bc2dd829c035f45c9286fb965bafb96
parentplug rfc2822 parser to smtp_session but do not process lines yet (diff)
downloadOpenSMTPD-1b497785cb0a016eb99bd308b03cee5be53fb89b.tar.xz
OpenSMTPD-1b497785cb0a016eb99bd308b03cee5be53fb89b.zip
feed rfc2822 parser but do not register callbacks yet
-rw-r--r--smtpd/smtp_session.c86
1 files changed, 81 insertions, 5 deletions
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index 9ee73f0d..fa3178de 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -82,12 +82,14 @@ enum session_flags {
};
enum message_flags {
- MF_QUEUE_ENVELOPE_FAIL = 0x0001,
- MF_ERROR_SIZE = 0x1000,
- MF_ERROR_IO = 0x2000,
- MF_ERROR_LOOP = 0x4000,
+ MF_QUEUE_ENVELOPE_FAIL = 0x00001,
+ MF_ERROR_SIZE = 0x01000,
+ MF_ERROR_IO = 0x02000,
+ MF_ERROR_LOOP = 0x04000,
+ MF_ERROR_MALFORMED = 0x08000,
+ MF_ERROR_RESOURCES = 0x10000,
};
-#define MF_ERROR (MF_ERROR_SIZE | MF_ERROR_IO | MF_ERROR_LOOP)
+#define MF_ERROR (MF_ERROR_SIZE | MF_ERROR_IO | MF_ERROR_LOOP | MF_ERROR_MALFORMED | MF_ERROR_RESOURCES)
enum smtp_command {
CMD_HELO = 0,
@@ -230,6 +232,60 @@ static struct tree wait_ssl_init;
static struct tree wait_ssl_verify;
static void
+header_default_callback(const struct rfc2822_header *hdr, void *arg)
+{
+ /*
+ struct smtp_session *s = arg;
+ struct rfc2822_line *l;
+ size_t len;
+
+ len = strlen(hdr->name) + 1;
+ if (fprintf(s->ofile, "%s:", hdr->name) != (int)len) {
+ s->msgflags |= MF_ERROR_IO;
+ return;
+ }
+ s->datalen += len;
+
+ TAILQ_FOREACH(l, &hdr->lines, next) {
+ len = strlen(l->buffer) + 1;
+ if (fprintf(s->ofile, "%s\n", l->buffer) != (int)len) {
+ s->msgflags |= MF_ERROR_IO;
+ return;
+ }
+ s->datalen += len;
+ }
+ */
+}
+
+static void
+dataline_callback(const char *line, void *arg)
+{
+ /*
+ struct smtp_session *s = arg;
+ size_t len;
+
+ len = strlen(line) + 1;
+
+ if (s->datalen + len > env->sc_maxsize) {
+ s->msgflags |= MF_ERROR_SIZE;
+ return;
+ }
+
+ if (fprintf(s->ofile, "%s\n", line) != (int)len) {
+ s->msgflags |= MF_ERROR_IO;
+ return;
+ }
+
+ s->datalen += len;
+ */
+}
+
+static void
+header_bcc_callback(const struct rfc2822_header *hdr, void *arg)
+{
+}
+
+static void
smtp_session_init(void)
{
static int init = 0;
@@ -1061,6 +1117,14 @@ smtp_data_io_done(struct smtp_session *s)
smtp_reply(s, "500 %s %s: Loop detected",
esc_code(ESC_STATUS_PERMFAIL, ESC_ROUTING_LOOP_DETECTED),
esc_description(ESC_ROUTING_LOOP_DETECTED));
+ else if (s->msgflags & MF_ERROR_RESOURCES)
+ smtp_reply(s, "421 %s: Temporary Error",
+ esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
+ else if (s->msgflags & MF_ERROR_MALFORMED)
+ smtp_reply(s, "550 %s %s: Message is not RFC 2822 compliant",
+ esc_code(ESC_STATUS_PERMFAIL,
+ ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED),
+ esc_description(ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED));
else if (s->msgflags)
smtp_reply(s, "421 Internal server error");
smtp_message_reset(s, 0);
@@ -2061,6 +2125,7 @@ static void
smtp_filter_dataline(struct smtp_session *s, const char *line)
{
int n;
+ int ret;
/* ignore data line if an error flag is set */
if (s->msgflags & MF_ERROR)
@@ -2080,6 +2145,17 @@ smtp_filter_dataline(struct smtp_session *s, const char *line)
}
}
+ ret = rfc2822_parser_feed(&s->rfc2822_parser, line);
+ if (ret == -1) {
+ s->msgflags |= MF_ERROR_RESOURCES;
+ return;
+ }
+
+ if (ret == 0) {
+ s->msgflags |= MF_ERROR_MALFORMED;
+ return;
+ }
+
n = iobuf_fqueue(&s->obuf, "%s\n", line);
if (n == -1) {
/* XXX */