On Fri, Oct 04, 2019 at 10:09:06AM +0200, Martijn van Duren wrote:
> 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).
>
Yes, I recall.
> >> 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
> >
>
ok lets revert and find the proper fix post release.
> 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;
--
Gilles Chehade @poolpOrg
https://www.poolp.org patreon: https://www.patreon.com/gilles