summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2010-04-19 10:12:49 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2010-04-19 10:12:49 +0000
commit9f070ef69cab532420e05ecd8825e51aa48bd578 (patch)
treeb9ec6b2a97ab09d2b8182a8bc07c1476e06dc193
parent787f10a3deccb19b7f172aba71e305126945d4ab (diff)
basic support for SIZE extension, has been sitting in my tree for a month
or so ... okayd by jacekm@ a while ago
-rw-r--r--usr.sbin/smtpd/parse.y37
-rw-r--r--usr.sbin/smtpd/smtp_session.c17
-rw-r--r--usr.sbin/smtpd/smtpd.h3
3 files changed, 52 insertions, 5 deletions
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index 4793086720e..8d3d6c45393 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.51 2010/02/26 15:06:39 gilles Exp $ */
+/* $OpenBSD: parse.y,v 1.52 2010/04/19 10:12:48 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -114,7 +114,7 @@ typedef struct {
%}
-%token QUEUE INTERVAL LISTEN ON ALL PORT
+%token QUEUE INTERVAL SIZE LISTEN ON ALL PORT
%token MAP TYPE HASH LIST SINGLE SSL SMTPS CERTIFICATE
%token DNS DB TFILE EXTERNAL DOMAIN CONFIG SOURCE
%token RELAY VIA DELIVER TO MAILDIR MBOX HOSTNAME
@@ -123,7 +123,7 @@ typedef struct {
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.map> map
-%type <v.number> quantifier decision port from auth ssl
+%type <v.number> quantifier decision port from auth ssl size
%type <v.cond> condition
%type <v.tv> interval
%type <v.object> mapref
@@ -191,6 +191,33 @@ interval : NUMBER quantifier {
$$.tv_sec = $1 * $2;
}
+size : NUMBER {
+ if ($1 < 0) {
+ yyerror("invalid size: %lld", $1);
+ YYERROR;
+ }
+ $$ = $1;
+ }
+ | NUMBER STRING {
+ if ($1 < 0) {
+ yyerror("invalid size: %lld", $1);
+ YYERROR;
+ }
+
+ if (strcmp("KB", $2) == 0)
+ $$ = 1024;
+ else if (strcmp("MB", $2) == 0)
+ $$ = 1048576;
+ else if (strcmp("GB", $2) == 0)
+ $$ = 1073741824;
+ else {
+ yyerror("invalid quantifier: %s", $2);
+ YYERROR;
+ }
+ $$ *= $1;
+ }
+ ;
+
port : PORT STRING {
struct servent *servent;
@@ -1016,6 +1043,7 @@ lookup(char *s)
{ "reject", REJECT },
{ "relay", RELAY },
{ "single", SINGLE },
+ { "size", SIZE },
{ "smtps", SMTPS },
{ "source", SOURCE },
{ "ssl", SSL },
@@ -1357,6 +1385,9 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts)
conf = x_conf;
bzero(conf, sizeof(*conf));
+
+ conf->sc_maxsize = SIZE_MAX;
+
if ((conf->sc_maps = calloc(1, sizeof(*conf->sc_maps))) == NULL) {
log_warn("cannot allocate memory");
return (-1);
diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c
index be708f162a2..d18c7e34122 100644
--- a/usr.sbin/smtpd/smtp_session.c
+++ b/usr.sbin/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.128 2009/12/31 15:37:55 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.129 2010/04/19 10:12:48 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -366,6 +366,10 @@ session_rfc5321_ehlo_handler(struct session *s, char *args)
s->s_env->sc_hostname, args, ss_to_text(&s->s_ss));
session_respond(s, "250-8BITMIME");
+ /* XXX - we also want to support reading SIZE from MAIL parameters */
+ if (s->s_env->sc_maxsize < SIZE_MAX)
+ session_respond(s, "250-SIZE %lu", s->s_env->sc_maxsize);
+
if (ADVERTISE_TLS(s))
session_respond(s, "250-STARTTLS");
@@ -816,6 +820,7 @@ tempfail:
void
session_read_data(struct session *s, char *line)
{
+ size_t datalen;
size_t len;
size_t i;
@@ -853,6 +858,16 @@ session_read_data(struct session *s, char *line)
len = strlen(line);
+ /* If size of data overflows a size_t or exceeds max size allowed
+ * for a message, set permanent failure.
+ */
+ datalen = ftell(s->datafp);
+ if (SIZE_MAX - datalen < len + 1 ||
+ datalen + len + 1 > s->s_env->sc_maxsize) {
+ s->s_msg.status |= S_MESSAGE_PERMFAILURE;
+ return;
+ }
+
if (fprintf(s->datafp, "%s\n", line) != (int)len + 1) {
s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
return;
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 1ad585d78ac..f1f66d07f9a 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.172 2010/04/19 08:14:07 jacekm Exp $ */
+/* $OpenBSD: smtpd.h,v 1.173 2010/04/19 10:12:48 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -587,6 +587,7 @@ struct session {
struct smtpd {
char sc_conffile[MAXPATHLEN];
+ size_t sc_maxsize;
#define SMTPD_OPT_VERBOSE 0x00000001
#define SMTPD_OPT_NOACTION 0x00000002