On 10/4/19 10:03 AM, [email protected] wrote:
> October 4, 2019 9:55 AM, "Martijn van Duren" 
> <[email protected]> wrote:
>>
>> This is similar to the diff I send a few months ago, but still doesn't
>> fix the case when someone sends a standalone '\n' as line-ending.
>>
> 
> Unsure I understand that, can you elaborate ?

I send the diff below to you and Eric back in April, but it was dropped
in favour of forbidding the <CR> totally (the thing being discussed
now).
> 
> 
>> I'd prefer if we go with reverting (=my previous diff) until we have
>> something that definitively fixes things. If people send broken mails
>> they get broken signatures until that time.
> 
> Fine by me
> 


Index: bounce.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/bounce.c,v
retrieving revision 1.80
diff -u -p -r1.80 bounce.c
--- bounce.c    8 Dec 2018 08:01:15 -0000       1.80
+++ bounce.c    24 Apr 2019 09:33:35 -0000
@@ -718,7 +718,7 @@ bounce_io(struct io *io, int evt, void *
        switch (evt) {
        case IO_DATAIN:
            nextline:
-               line = io_getline(s->io, &len);
+               line = io_getline_rn(s->io, &len);
                if (line == NULL && io_datalen(s->io) >= LINE_MAX) {
                        bounce_status(s, "Input too long");
                        bounce_free(s);
Index: iobuf.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/iobuf.c,v
retrieving revision 1.10
diff -u -p -r1.10 iobuf.c
--- iobuf.c     17 Mar 2017 20:56:04 -0000      1.10
+++ iobuf.c     24 Apr 2019 09:33:35 -0000
@@ -156,7 +156,35 @@ iobuf_drop(struct iobuf *io, size_t n)
 }
 
 char *
-iobuf_getline(struct iobuf *iobuf, size_t *rlen)
+iobuf_getline_n(struct iobuf *iobuf, size_t *rlen)
+{
+       char    *buf;
+       size_t   len, i;
+
+       buf = iobuf_data(iobuf);
+       len = iobuf_len(iobuf);
+
+       for (i = 0; i + 1 <= len; i++)
+               if (buf[i] == '\n') {
+                       /* Note: the returned address points into the iobuf
+                        * buffer.  We NUL-end it for convenience, and discard
+                        * the data from the iobuf, so that the caller doesn't
+                        * have to do it.  The data remains "valid" as long
+                        * as the iobuf does not overwrite it, that is until
+                        * the next call to iobuf_normalize() or iobuf_extend().
+                        */
+                       iobuf_drop(iobuf, i + 1);
+                       buf[i] = '\0';
+                       if (rlen)
+                               *rlen = i;
+                       return (buf);
+               }
+
+       return (NULL);
+}
+
+char *
+iobuf_getline_rn(struct iobuf *iobuf, size_t *rlen)
 {
        char    *buf;
        size_t   len, i;
Index: iobuf.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/iobuf.h,v
retrieving revision 1.4
diff -u -p -r1.4 iobuf.h
--- iobuf.h     20 Jan 2015 17:37:54 -0000      1.4
+++ iobuf.h     24 Apr 2019 09:33:35 -0000
@@ -51,7 +51,8 @@ size_t        iobuf_space(struct iobuf *);
 size_t iobuf_len(struct iobuf *);
 size_t iobuf_left(struct iobuf *);
 char   *iobuf_data(struct iobuf *);
-char   *iobuf_getline(struct iobuf *, size_t *);
+char   *iobuf_getline_n(struct iobuf *, size_t *);
+char   *iobuf_getline_rn(struct iobuf *, size_t *);
 ssize_t        iobuf_read(struct iobuf *, int);
 ssize_t        iobuf_read_ssl(struct iobuf *, void *);
 
Index: ioev.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/ioev.c,v
retrieving revision 1.41
diff -u -p -r1.41 ioev.c
--- ioev.c      17 May 2017 14:00:06 -0000      1.41
+++ ioev.c      24 Apr 2019 09:33:35 -0000
@@ -501,9 +501,15 @@ io_datalen(struct io *io)
 }
 
 char *
-io_getline(struct io *io, size_t *sz)
+io_getline_n(struct io *io, size_t *sz)
 {
-       return iobuf_getline(&io->iobuf, sz);
+       return iobuf_getline_n(&io->iobuf, sz);
+}
+
+char *
+io_getline_rn(struct io *io, size_t *sz)
+{
+       return iobuf_getline_rn(&io->iobuf, sz);
 }
 
 void
Index: ioev.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/ioev.h,v
retrieving revision 1.16
diff -u -p -r1.16 ioev.h
--- ioev.h      30 Nov 2016 17:43:32 -0000      1.16
+++ ioev.h      24 Apr 2019 09:33:35 -0000
@@ -65,5 +65,6 @@ size_t io_queued(struct io *);
 /* Buffered input functions */
 void* io_data(struct io *);
 size_t io_datalen(struct io *);
-char* io_getline(struct io *, size_t *);
+char* io_getline_n(struct io *, size_t *);
+char* io_getline_rn(struct io *, size_t *);
 void io_drop(struct io *, size_t);
Index: lka_filter.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/lka_filter.c,v
retrieving revision 1.35
diff -u -p -r1.35 lka_filter.c
--- lka_filter.c        8 Apr 2019 07:44:45 -0000       1.35
+++ lka_filter.c        24 Apr 2019 09:33:35 -0000
@@ -393,7 +393,7 @@ filter_session_io(struct io *io, int evt
        switch (evt) {
        case IO_DATAIN:
        nextline:
-               line = io_getline(fs->io, &len);
+               line = io_getline_rn(fs->io, &len);
                /* No complete line received */
                if (line == NULL)
                        return;
Index: lka_proc.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/lka_proc.c,v
retrieving revision 1.6
diff -u -p -r1.6 lka_proc.c
--- lka_proc.c  21 Dec 2018 19:07:47 -0000      1.6
+++ lka_proc.c  24 Apr 2019 09:33:35 -0000
@@ -124,7 +124,7 @@ processor_io(struct io *io, int evt, voi
        switch (evt) {
        case IO_DATAIN:
            nextline:
-               line = io_getline(io, &len);
+               line = io_getline_n(io, &len);
                /* No complete line received */
                if (line == NULL)
                        return;
Index: mta_session.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/mta_session.c,v
retrieving revision 1.115
diff -u -p -r1.115 mta_session.c
--- mta_session.c       23 Dec 2018 16:37:53 -0000      1.115
+++ mta_session.c       24 Apr 2019 09:33:35 -0000
@@ -1111,7 +1111,7 @@ mta_io(struct io *io, int evt, void *arg
 
        case IO_DATAIN:
            nextline:
-               line = io_getline(s->io, &len);
+               line = io_getline_rn(s->io, &len);
                if (line == NULL) {
                        if (io_datalen(s->io) >= LINE_MAX) {
                                mta_error(s, "Input too long");
Index: smtp_client.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtp_client.c,v
retrieving revision 1.8
diff -u -p -r1.8 smtp_client.c
--- smtp_client.c       20 Sep 2018 11:42:28 -0000      1.8
+++ smtp_client.c       24 Apr 2019 09:33:35 -0000
@@ -667,7 +667,7 @@ smtp_client_readline(struct smtp_client 
        char *line, *msg, *p;
        int cont;
 
-       line = io_getline(proto->io, &len);
+       line = io_getline_rn(proto->io, &len);
        if (line == NULL) {
                if (io_datalen(proto->io) >= proto->params.linemax)
                        smtp_client_abort(proto, FAIL_PROTO, "Line too long");
Index: smtp_session.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtp_session.c,v
retrieving revision 1.389
diff -u -p -r1.389 smtp_session.c
--- smtp_session.c      20 Feb 2019 11:56:27 -0000      1.389
+++ smtp_session.c      24 Apr 2019 09:33:35 -0000
@@ -1078,7 +1078,7 @@ smtp_io(struct io *io, int evt, void *ar
 
        case IO_DATAIN:
            nextline:
-               line = io_getline(s->io, &len);
+               line = io_getline_rn(s->io, &len);
                if ((line == NULL && io_datalen(s->io) >= SMTP_LINE_MAX) ||
                    (line && len >= SMTP_LINE_MAX)) {
                        s->flags |= SF_BADINPUT;
@@ -2727,7 +2727,7 @@ filter_session_io(struct io *io, int evt
        switch (evt) {
        case IO_DATAIN:
        nextline:
-               line = io_getline(tx->filter, &len);
+               line = io_getline_rn(tx->filter, &len);
                /* No complete line received */
                if (line == NULL)
                        return;

Reply via email to