aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Vadot <elbarto@bocal.org>2014-10-22 09:53:44 +0200
committerEmmanuel Vadot <elbarto@bocal.org>2014-10-22 09:53:44 +0200
commitecee83f41db3c7dc105632f7622d0a621e6afeb2 (patch)
treeffed70912416e4b2e995e5f50446c66d77b42f99
parentMerge branch 'master' into portable (diff)
downloadOpenSMTPD-ecee83f41db3c7dc105632f7622d0a621e6afeb2.tar.xz
OpenSMTPD-ecee83f41db3c7dc105632f7622d0a621e6afeb2.zip
- Add support for mail addresses and name on a multiline.
-rw-r--r--openbsd-compat/entropy.c2
-rw-r--r--smtpd/rfc822.c101
-rw-r--r--smtpd/rfc822.h3
-rw-r--r--smtpd/smtp_session.c2
4 files changed, 73 insertions, 35 deletions
diff --git a/openbsd-compat/entropy.c b/openbsd-compat/entropy.c
index 09ffe145..2005eff0 100644
--- a/openbsd-compat/entropy.c
+++ b/openbsd-compat/entropy.c
@@ -48,7 +48,7 @@
//#include "xmalloc.h"
//#include "atomicio.h"
//#include "pathnames.h"
-#include "log.h"
+#include "smtpd/log.h"
//#include "buffer.h"
void
diff --git a/smtpd/rfc822.c b/smtpd/rfc822.c
index f8e90d23..c9fc8ff7 100644
--- a/smtpd/rfc822.c
+++ b/smtpd/rfc822.c
@@ -31,12 +31,54 @@
#include "rfc822.h"
+#include "log.h"
+
+static int
+parse_addresses_finish(struct rfc822_parser *rp)
+{
+ char *wptr;
+
+ /* some flags still set, malformed header */
+ if (rp->escape || rp->comment || rp->quote || rp->bracket) {
+ free(rp->ra);
+ return 0;
+ }
+
+ /* no value, malformed header */
+ if (rp->ra->name[0] == '\0' && rp->ra->address[0] == '\0') {
+ free(rp->ra);
+ return 0;
+ }
+
+ /* no <>, use name as address */
+ if (rp->ra->address[0] == '\0') {
+ memcpy(rp->ra->address, rp->ra->name, sizeof rp->ra->address);
+ memset(rp->ra->name, 0, sizeof rp->ra->name);
+ }
+
+ /* strip first trailing whitespace from name */
+ wptr = &rp->ra->name[0] + strlen(rp->ra->name);
+ while (wptr != &rp->ra->name[0]) {
+ if (*wptr && ! isspace(*wptr))
+ break;
+ *wptr-- = '\0';
+ }
+
+ log_debug("rfc822: address: %s", rp->ra->address);
+ log_debug("rfc822: name: %s", rp->ra->name);
+
+ TAILQ_INSERT_TAIL(&rp->addresses, rp->ra, next);
+ rp->count++;
+ rp->ra = NULL;
+
+ return 1;
+}
+
static int
parse_addresses(struct rfc822_parser *rp, const char *buffer, size_t len)
{
const char *s;
char *wptr;
- struct rfc822_address *ra;
s = buffer;
@@ -48,11 +90,16 @@ parse_addresses(struct rfc822_parser *rp, const char *buffer, size_t len)
if (*s == '\0')
return 0;
- ra = calloc(1, sizeof *ra);
- if (ra == NULL)
- return -1;
+ if (rp->ra == NULL) {
+ rp->ra = calloc(1, sizeof *(rp->ra));
+ if (rp->ra == NULL)
+ return -1;
+ }
+ else {
+ log_debug("rfc822: reuse: addr = '%s' name = '%s'", rp->ra->address, rp->ra->name);
+ }
- wptr = ra->name;
+ wptr = rp->ra->name;
for (; len; s++, len--) {
if (*s == '(' && !rp->escape && !rp->quote)
rp->comment++;
@@ -60,16 +107,16 @@ parse_addresses(struct rfc822_parser *rp, const char *buffer, size_t len)
rp->quote = !rp->quote;
if (!rp->comment && !rp->quote && !rp->escape) {
if (*s == '<' && rp->bracket) {
- free(ra);
+ free(rp->ra);
return 0;
}
if (*s == '>' && !rp->bracket) {
- free(ra);
+ free(rp->ra);
return 0;
}
if (*s == '<') {
- wptr = ra->address;
+ wptr = rp->ra->address;
rp->bracket++;
continue;
}
@@ -89,34 +136,11 @@ parse_addresses(struct rfc822_parser *rp, const char *buffer, size_t len)
*wptr++ = *s;
}
- /* some flags still set, malformed header */
- if (rp->escape || rp->comment || rp->quote || rp->bracket) {
- free(ra);
- return 0;
- }
+ if (*s == '\0')
+ return 1;
- /* no value, malformed header */
- if (ra->name[0] == '\0' && ra->address[0] == '\0') {
- free(ra);
+ if (!parse_addresses_finish(rp))
return 0;
- }
-
- /* no <>, use name as address */
- if (ra->address[0] == '\0') {
- memcpy(ra->address, ra->name, sizeof ra->address);
- memset(ra->name, 0, sizeof ra->name);
- }
-
- /* strip first trailing whitespace from name */
- wptr = &ra->name[0] + strlen(ra->name);
- while (wptr != &ra->name[0]) {
- if (*wptr && ! isspace(*wptr))
- break;
- *wptr-- = '\0';
- }
-
- TAILQ_INSERT_TAIL(&rp->addresses, ra, next);
- rp->count++;
/* do we have more to process ? */
for (; *s; ++s, --len)
@@ -156,6 +180,15 @@ rfc822_parser_reset(struct rfc822_parser *rp)
memset(rp, 0, sizeof *rp);
}
+void
+rfc822_parser_finish(struct rfc822_parser *rp)
+{
+ if (!rp->ra)
+ return;
+
+ parse_addresses_finish(rp);
+}
+
int
rfc822_parser_feed(struct rfc822_parser *rp, const char *line)
{
diff --git a/smtpd/rfc822.h b/smtpd/rfc822.h
index aafb3770..3102f9be 100644
--- a/smtpd/rfc822.h
+++ b/smtpd/rfc822.h
@@ -32,6 +32,8 @@ struct rfc822_parser {
size_t count;
TAILQ_HEAD(addresses, rfc822_address) addresses;
+ struct rfc822_address *ra;
+
uint8_t quote;
uint8_t comment;
uint8_t escape;
@@ -40,6 +42,7 @@ struct rfc822_parser {
void rfc822_parser_init(struct rfc822_parser *);
void rfc822_parser_reset(struct rfc822_parser *);
+void rfc822_parser_finish(struct rfc822_parser *);
int rfc822_parser_feed(struct rfc822_parser *, const char *);
#endif
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index 14ffd134..43c38b40 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -301,6 +301,8 @@ header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
if (! rfc822_parser_feed(&rp, l->buffer))
goto fail;
+ rfc822_parser_finish(&rp);
+
len = strlen(hdr->name) + 1;
if (iobuf_fqueue(&s->obuf, "%s:", hdr->name) != (int)len) {
s->msgflags |= MF_ERROR_IO;