On Sun, 15 Mar 2020 13:29:46 +0100, Eric Faurot wrote:

> This diff makes the local enqueuer use CRLF line ending during the
> SMTP dialog, as required by the protocol.

Looks good, one comment inline.

 - todd

> Index: enqueue.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/smtpd/enqueue.c,v
> retrieving revision 1.117
> diff -u -p -r1.117 enqueue.c
> --- enqueue.c 8 Mar 2020 21:47:05 -0000       1.117
> +++ enqueue.c 9 Mar 2020 13:15:59 -0000
> @@ -136,7 +136,7 @@ struct {
>  
>  #define QP_TEST_WRAP(fp, buf, linelen, size) do {                    \
>       if (((linelen) += (size)) + 1 > 76) {                           \
> -             fprintf((fp), "=\n");                                   \
> +             fprintf((fp), "=\r\n");                                 \
>               if (buf[0] == '.')                                      \
>                       fprintf((fp), ".");                             \
>               (linelen) = (size);                                     \
> @@ -178,7 +178,7 @@ qp_encoded_write(FILE *fp, char *buf)
>                       fprintf(fp, "%c", *buf);
>               }
>       }
> -     fprintf(fp, "\n");
> +     fprintf(fp, "\r\n");
>  }
>  
>  int
> @@ -325,7 +325,7 @@ enqueue(int argc, char *argv[], FILE *of
>       if (!get_responses(fout, 1))
>               goto fail;
>  
> -     if (!send_line(fout, verbose, "EHLO localhost\n"))
> +     if (!send_line(fout, verbose, "EHLO localhost\r\n"))
>               goto fail;
>       if (!get_responses(fout, 1))
>               goto fail;
> @@ -333,7 +333,7 @@ enqueue(int argc, char *argv[], FILE *of
>       if (msg.dsn_envid != NULL)
>               envid_sz = strlen(msg.dsn_envid);
>  
> -     if (!send_line(fout, verbose, "MAIL FROM:<%s> %s%s %s%s\n",
> +     if (!send_line(fout, verbose, "MAIL FROM:<%s> %s%s %s%s\r\n",
>           msg.from,
>           msg.dsn_ret ? "RET=" : "",
>           msg.dsn_ret ? msg.dsn_ret : "",
> @@ -344,7 +344,7 @@ enqueue(int argc, char *argv[], FILE *of
>               goto fail;
>  
>       for (i = 0; i < msg.rcpt_cnt; i++) {
> -             if (!send_line(fout, verbose, "RCPT TO:<%s> %s%s\n",
> +             if (!send_line(fout, verbose, "RCPT TO:<%s> %s%s\r\n",
>                   msg.rcpts[i],
>                   msg.dsn_notify ? "NOTIFY=" : "",
>                   msg.dsn_notify ? msg.dsn_notify : ""))
> @@ -353,41 +353,41 @@ enqueue(int argc, char *argv[], FILE *of
>                       goto fail;
>       }
>  
> -     if (!send_line(fout, verbose, "DATA\n"))
> +     if (!send_line(fout, verbose, "DATA\r\n"))
>               goto fail;
>       if (!get_responses(fout, 1))
>               goto fail;
>  
>       /* add From */
> -     if (!msg.saw_from && !send_line(fout, 0, "From: %s%s<%s>\n",
> +     if (!msg.saw_from && !send_line(fout, 0, "From: %s%s<%s>\r\n",
>           msg.fromname ? msg.fromname : "", msg.fromname ? " " : "",
>           msg.from))
>               goto fail;
>  
>       /* add Date */
> -     if (!msg.saw_date && !send_line(fout, 0, "Date: %s\n",
> +     if (!msg.saw_date && !send_line(fout, 0, "Date: %s\r\n",
>           time_to_text(timestamp)))
>               goto fail;
>  
>       if (msg.need_linesplit) {
>               /* we will always need to mime encode for long lines */
>               if (!msg.saw_mime_version && !send_line(fout, 0,
> -                 "MIME-Version: 1.0\n"))
> +                 "MIME-Version: 1.0\r\n"))
>                       goto fail;
>               if (!msg.saw_content_type && !send_line(fout, 0,
> -                 "Content-Type: text/plain; charset=unknown-8bit\n"))
> +                 "Content-Type: text/plain; charset=unknown-8bit\r\n"))
>                       goto fail;
>               if (!msg.saw_content_disposition && !send_line(fout, 0,
> -                 "Content-Disposition: inline\n"))
> +                 "Content-Disposition: inline\r\n"))
>                       goto fail;
>               if (!msg.saw_content_transfer_encoding && !send_line(fout, 0,
> -                 "Content-Transfer-Encoding: quoted-printable\n"))
> +                 "Content-Transfer-Encoding: quoted-printable\r\n"))
>                       goto fail;
>       }
>  
>       /* add separating newline */
>       if (msg.noheader) {
> -             if (!send_line(fout, 0, "\n"))
> +             if (!send_line(fout, 0, "\r\n"))
>                       goto fail;
>               inheaders = 0;
>       }
> @@ -420,7 +420,7 @@ enqueue(int argc, char *argv[], FILE *of
>  
>               if (msg.saw_content_transfer_encoding || msg.noheader ||
>                   inheaders || !msg.need_linesplit) {
> -                     if (!send_line(fout, 0, "%.*s", (int)len, line))
> +                     if (!send_line(fout, 0, "%.*s\r\n", (int)len - 1, line)

Using len-1 here looks a bit fragile to me.  Maybe just decrement len
after the newline check?  E.g.

        if (buf[len-1] != '\n')
                errx(EX_SOFTWARE, "expect EOL");
        len--;

> )
>                               goto fail;
>                       if (inheaders && buf[0] == '\n')
>                               inheaders = 0;
> @@ -431,12 +431,12 @@ enqueue(int argc, char *argv[], FILE *of
>               qp_encoded_write(fout, line);
>       }
>       free(buf);
> -     if (!send_line(fout, verbose, ".\n"))
> +     if (!send_line(fout, verbose, ".\r\n"))
>               goto fail;
>       if (!get_responses(fout, 1))
>               goto fail;
>  
> -     if (!send_line(fout, verbose, "QUIT\n"))
> +     if (!send_line(fout, verbose, "QUIT\r\n"))
>               goto fail;
>       if (!get_responses(fout, 1))
>               goto fail;

Reply via email to