summaryrefslogtreecommitdiffstats
path: root/network/opensmtpd
diff options
context:
space:
mode:
Diffstat (limited to 'network/opensmtpd')
-rw-r--r--network/opensmtpd/README12
-rw-r--r--network/opensmtpd/fix-crash-on-authentication.patch43
-rw-r--r--network/opensmtpd/openbsd64-020-smtpd.patch4
-rw-r--r--network/opensmtpd/openbsd65-029-smptd-tls.patch52
-rw-r--r--network/opensmtpd/openbsd65-031-smtpd-envelope.patch199
-rw-r--r--network/opensmtpd/openbsd66-019-smtpd-exec.patch46
-rw-r--r--network/opensmtpd/opensmtpd.SlackBuild18
7 files changed, 367 insertions, 7 deletions
diff --git a/network/opensmtpd/README b/network/opensmtpd/README
index bbd1b2606f..39e7203c20 100644
--- a/network/opensmtpd/README
+++ b/network/opensmtpd/README
@@ -19,8 +19,12 @@ This package conflicts with the stock sendmail package included in
Slackware and overwrites some of its files, so remove the sendmail
package before installing opensmtpd.
-In the change from version 5.7.3p2 to 5.9.2p1 the ownership and permissions
-changed for the /var/spool/offline directory
+Alpine hangs when sending mail using the opensmtp sendmail command and the
+opensmtpd server is down.
+
+To prevent this, modify the /etc/pine.conf or the user .pinerc to
+send the mail directly to the server instead of using the
+opensmtpd sendmail command:
+
+ smtp-server=localhost
- chown -R root:smtpq /var/spool/offline
- chmod 770 /var/spool/offline
diff --git a/network/opensmtpd/fix-crash-on-authentication.patch b/network/opensmtpd/fix-crash-on-authentication.patch
new file mode 100644
index 0000000000..c20b5e0a0e
--- /dev/null
+++ b/network/opensmtpd/fix-crash-on-authentication.patch
@@ -0,0 +1,43 @@
+From 9b5f70b93e038df5446bd37a4adac5a0380748e7 Mon Sep 17 00:00:00 2001
+From: johannes <johannes.brechtmann@gmail.com>
+Date: Wed, 21 Feb 2018 23:57:11 +0100
+Subject: [PATCH] crypt_checkpass: include HAVE_CRYPT_H definition, add NULL
+ check
+
+---
+ openbsd-compat/crypt_checkpass.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/openbsd-compat/crypt_checkpass.c b/openbsd-compat/crypt_checkpass.c
+index dafd2dae..d10b3a57 100644
+--- a/openbsd-compat/crypt_checkpass.c
++++ b/openbsd-compat/crypt_checkpass.c
+@@ -1,5 +1,6 @@
+ /* OPENBSD ORIGINAL: lib/libc/crypt/cryptutil.c */
+
++#include "includes.h"
+ #include <errno.h>
+ #ifdef HAVE_CRYPT_H
+ #include <crypt.h>
+@@ -10,6 +11,8 @@
+ int
+ crypt_checkpass(const char *pass, const char *goodhash)
+ {
++ char *c;
++
+ if (goodhash == NULL)
+ goto fail;
+
+@@ -17,7 +20,11 @@ crypt_checkpass(const char *pass, const char *goodhash)
+ if (strlen(goodhash) == 0 && strlen(pass) == 0)
+ return 0;
+
+- if (strcmp(crypt(pass, goodhash), goodhash) == 0)
++ c = crypt(pass, goodhash);
++ if (c == NULL)
++ goto fail;
++
++ if (strcmp(c, goodhash) == 0)
+ return 0;
+
+ fail:
diff --git a/network/opensmtpd/openbsd64-020-smtpd.patch b/network/opensmtpd/openbsd64-020-smtpd.patch
index a1aa51607a..8ce7178da8 100644
--- a/network/opensmtpd/openbsd64-020-smtpd.patch
+++ b/network/opensmtpd/openbsd64-020-smtpd.patch
@@ -1,3 +1,7 @@
+OpenBSD 6.4 errata 020, August 2, 2019
+
+smtpd can crash on excessively large input, causing a denial of service.
+
--- a/smtpd/smtp_session.c 3 Sep 2018 19:01:29 -0000 1.337
+++ b/smtpd/smtp_session.c 1 Aug 2019 21:18:53 -0000
@@ -1904,15 +1904,21 @@ smtp_reply(struct smtp_session *s, char
diff --git a/network/opensmtpd/openbsd65-029-smptd-tls.patch b/network/opensmtpd/openbsd65-029-smptd-tls.patch
new file mode 100644
index 0000000000..a2727decf8
--- /dev/null
+++ b/network/opensmtpd/openbsd65-029-smptd-tls.patch
@@ -0,0 +1,52 @@
+OpenBSD 6.5 errata 029, January 30, 2020:
+
+smtpd can crash on opportunistic TLS downgrade, causing a denial of service.
+
+--- usr.sbin/smtpd/mta_session.c 23 Dec 2018 16:37:53 -0000 1.115
++++ usr.sbin/smtpd/mta_session.c 20 Jan 2020 10:36:58 -0000
+@@ -1292,40 +1292,20 @@ mta_io(struct io *io, int evt, void *arg
+ break;
+
+ case IO_ERROR:
++ case IO_TLSERROR:
+ log_debug("debug: mta: %p: IO error: %s", s, io_error(io));
+- if (!s->ready) {
+- mta_error(s, "IO Error: %s", io_error(io));
+- mta_connect(s);
+- break;
+- }
+- else if (!(s->flags & (MTA_FORCE_TLS|MTA_FORCE_SMTPS|MTA_FORCE_ANYSSL))) {
+- /* error in non-strict SSL negotiation, downgrade to plain */
+- if (s->flags & MTA_TLS) {
+- log_info("smtp-out: Error on session %016"PRIx64
+- ": opportunistic TLS failed, "
+- "downgrading to plain", s->id);
+- s->flags &= ~MTA_TLS;
+- s->flags |= MTA_DOWNGRADE_PLAIN;
+- mta_connect(s);
+- break;
+- }
+- }
+- mta_error(s, "IO Error: %s", io_error(io));
+- mta_free(s);
+- break;
+
+- case IO_TLSERROR:
+- log_debug("debug: mta: %p: TLS IO error: %s", s, io_error(io));
+- if (!(s->flags & (MTA_FORCE_TLS|MTA_FORCE_SMTPS|MTA_FORCE_ANYSSL))) {
++ if (s->state == MTA_STARTTLS && s->use_smtp_tls) {
+ /* error in non-strict SSL negotiation, downgrade to plain */
+- log_info("smtp-out: TLS Error on session %016"PRIx64
+- ": TLS failed, "
++ log_info("smtp-out: Error on session %016"PRIx64
++ ": opportunistic TLS failed, "
+ "downgrading to plain", s->id);
+ s->flags &= ~MTA_TLS;
+ s->flags |= MTA_DOWNGRADE_PLAIN;
+ mta_connect(s);
+ break;
+ }
++
+ mta_error(s, "IO Error: %s", io_error(io));
+ mta_free(s);
+ break;
diff --git a/network/opensmtpd/openbsd65-031-smtpd-envelope.patch b/network/opensmtpd/openbsd65-031-smtpd-envelope.patch
new file mode 100644
index 0000000000..cd59f1d6fa
--- /dev/null
+++ b/network/opensmtpd/openbsd65-031-smtpd-envelope.patch
@@ -0,0 +1,199 @@
+OpenBSD 6.5 errata 031, February 24, 2020:
+
+An out of bounds read in smtpd allows an attacker to inject arbitrary
+commands into the envelope file which are then executed as root.
+Separately, missing privilege revocation in smtpctl allows arbitrary
+commands to be run with the _smtpq group.
+
+--- a/smtpd/makemap.c.orig 2018-01-10 05:06:40.000000000 -0800
++++ b/smtpd/makemap.c 2020-02-24 15:41:18.278340410 -0800
+@@ -105,8 +105,13 @@ makemap(int prog_mode, int argc, char *a
+ int ch, dbputs = 0, Uflag = 0;
+ DBTYPE dbtype = DB_HASH;
+ char *p;
++ gid_t gid;
+ int fd = -1;
+
++ gid = getgid();
++ if (setresgid(gid, gid, gid) == -1)
++ err(1, "setresgid");
++
+ log_init(1, LOG_MAIL);
+
+ mode = prog_mode;
+@@ -180,9 +185,9 @@ makemap(int prog_mode, int argc, char *a
+ errx(1, "database name too long");
+ }
+
+- execlp("makemap", "makemap", "-d", argv[0], "-o", dbname, "-",
+- (char *)NULL);
+- err(1, "execlp");
++ execl(PATH_MAKEMAP, "makemap", "-d", argv[0], "-o", dbname,
++ "-", (char *)NULL);
++ err(1, "execl");
+ }
+
+ if (mode == P_NEWALIASES) {
+--- a/smtpd/mta_session.c.orig 2020-02-08 10:24:17.692029666 -0800
++++ b/smtpd/mta_session.c 2020-02-24 15:46:46.121342818 -0800
+@@ -1214,7 +1214,7 @@ mta_io(struct io *io, int evt, void *arg
+ if (cont) {
+ if (s->replybuf[0] == '\0')
+ (void)strlcat(s->replybuf, line, sizeof s->replybuf);
+- else {
++ else if (len > 4) {
+ line = line + 4;
+ if (isdigit((int)*line) && *(line + 1) == '.' &&
+ isdigit((int)*line+2) && *(line + 3) == '.' &&
+@@ -1229,7 +1229,9 @@ mta_io(struct io *io, int evt, void *arg
+ /* last line of a reply, check if we're on a continuation to parse out status and ESC.
+ * if we overflow reply buffer or are not on continuation, log entire last line.
+ */
+- if (s->replybuf[0] != '\0') {
++ if (s->replybuf[0] == '\0')
++ (void)strlcat(s->replybuf, line, sizeof s->replybuf);
++ else if (len > 4) {
+ p = line + 4;
+ if (isdigit((int)*p) && *(p + 1) == '.' &&
+ isdigit((int)*p+2) && *(p + 3) == '.' &&
+@@ -1238,8 +1240,6 @@ mta_io(struct io *io, int evt, void *arg
+ if (strlcat(s->replybuf, p, sizeof s->replybuf) >= sizeof s->replybuf)
+ (void)strlcpy(s->replybuf, line, sizeof s->replybuf);
+ }
+- else
+- (void)strlcpy(s->replybuf, line, sizeof s->replybuf);
+
+ if (s->state == MTA_QUIT) {
+ log_info("%016"PRIx64" mta event=closed reason=quit messages=%zu",
+--- a/smtpd/smtpctl.c.orig 2018-01-10 05:06:40.000000000 -0800
++++ b/smtpd/smtpctl.c 2020-02-24 14:57:04.687320914 -0800
+@@ -1116,7 +1116,7 @@ sendmail_compat(int argc, char **argv)
+ */
+ for (i = 1; i < argc; i++)
+ if (strncmp(argv[i], "-bi", 3) == 0)
+- exit(makemap(P_NEWALIASES, argc, argv));
++ exit(makemap(P_SENDMAIL, argc, argv));
+
+ if (!srv_connect())
+ offlinefp = offline_file();
+--- a/smtpd/smtpd-defines.h.orig 2018-01-10 05:06:40.000000000 -0800
++++ b/smtpd/smtpd-defines.h 2020-02-24 15:00:29.616322420 -0800
+@@ -46,6 +46,9 @@
+ #ifndef PATH_SPOOL
+ #define PATH_SPOOL "/var/spool/smtpd"
+ #endif
++#ifndef PATH_MAKEUP
++#define PATH_MAKEMAP "/usr/sbin/makemap"
++#endif
+
+ #define SUBADDRESSING_DELIMITER "+"
+
+--- a/smtpd/smtpd.c.orig 2018-01-10 05:06:40.000000000 -0800
++++ b/smtpd/smtpd.c 2020-02-24 15:55:55.503346854 -0800
+@@ -109,9 +109,10 @@ static struct mproc *setup_peer(enum smt
+ static int imsg_wait(struct imsgbuf *, struct imsg *, int);
+
+ static void offline_scan(int, short, void *);
+-static int offline_add(char *);
++static int offline_add(char *, uid_t, gid_t);
+ static void offline_done(void);
+-static int offline_enqueue(char *);
++static int offline_enqueue(char *, uid_t, gid_t);
++
+
+ static void purge_task(void);
+ static int parent_auth_user(const char *, const char *);
+@@ -136,6 +137,8 @@ struct child {
+
+ struct offline {
+ TAILQ_ENTRY(offline) entry;
++ uid_t uid;
++ gid_t gid;
+ char *path;
+ };
+
+@@ -1409,7 +1412,8 @@ offline_scan(int fd, short ev, void *arg
+ continue;
+ }
+
+- if (offline_add(e->fts_name)) {
++ if (offline_add(e->fts_name, e->fts_statp->st_uid,
++ e->fts_statp->st_gid)) {
+ log_warnx("warn: smtpd: "
+ "could not add offline message %s", e->fts_name);
+ continue;
+@@ -1429,7 +1433,7 @@ offline_scan(int fd, short ev, void *arg
+ }
+
+ static int
+-offline_enqueue(char *name)
++offline_enqueue(char *name, uid_t uid, gid_t gid)
+ {
+ char *path;
+ struct stat sb;
+@@ -1491,6 +1495,18 @@ offline_enqueue(char *name)
+ _exit(1);
+ }
+
++ if (sb.st_uid != uid) {
++ log_warnx("warn: smtpd: file %s has bad uid %d",
++ path, sb.st_uid);
++ _exit(1);
++ }
++
++ if (sb.st_gid != gid) {
++ log_warnx("warn: smtpd: file %s has bad gid %d",
++ path, sb.st_gid);
++ _exit(1);
++ }
++
+ pw = getpwuid(sb.st_uid);
+ if (pw == NULL) {
+ log_warnx("warn: smtpd: getpwuid for uid %d failed",
+@@ -1547,17 +1563,19 @@ offline_enqueue(char *name)
+ }
+
+ static int
+-offline_add(char *path)
++offline_add(char *path, uid_t uid, gid_t gid)
+ {
+ struct offline *q;
+
+ if (offline_running < OFFLINE_QUEUEMAX)
+ /* skip queue */
+- return offline_enqueue(path);
++ return offline_enqueue(path, uid, gid);
+
+ q = malloc(sizeof(*q) + strlen(path) + 1);
+ if (q == NULL)
+ return (-1);
++ q->uid = uid;
++ q->gid = gid;
+ q->path = (char *)q + sizeof(*q);
+ memmove(q->path, path, strlen(path) + 1);
+ TAILQ_INSERT_TAIL(&offline_q, q, entry);
+@@ -1576,7 +1594,8 @@ offline_done(void)
+ if ((q = TAILQ_FIRST(&offline_q)) == NULL)
+ break; /* all done */
+ TAILQ_REMOVE(&offline_q, q, entry);
+- offline_enqueue(q->path);
++ offline_enqueue(q->path, q->uid, q->gid);
++
+ free(q);
+ }
+ }
+--- a/smtpd/smtpd.h.orig 2018-01-10 05:06:40.000000000 -0800
++++ b/smtpd/smtpd.h 2020-02-24 15:20:09.043331085 -0800
+@@ -128,8 +128,10 @@
+ #define MTA_EXT_DSN 0x400
+
+
+-#define P_NEWALIASES 0
+-#define P_MAKEMAP 1
++#define P_SENDMAIL 0
++#define P_NEWALIASES 1
++#define P_MAKEMAP 2
++
+
+ struct userinfo {
+ char username[SMTPD_VUSERNAME_SIZE];
diff --git a/network/opensmtpd/openbsd66-019-smtpd-exec.patch b/network/opensmtpd/openbsd66-019-smtpd-exec.patch
new file mode 100644
index 0000000000..93ce19dcb1
--- /dev/null
+++ b/network/opensmtpd/openbsd66-019-smtpd-exec.patch
@@ -0,0 +1,46 @@
+OpenBSD 6.6 errata 019, January 30, 2020:
+
+An incorrect check allows an attacker to trick mbox delivery into executing
+arbitrary commands as root and lmtp delivery into executing arbitrary commands
+as an unprivileged user.
+
+--- usr.sbin/smtpd/smtp_session.c 4 Oct 2019 08:34:29 -0000 1.415
++++ usr.sbin/smtpd/smtp_session.c 26 Jan 2020 05:56:37 -0000
+@@ -2012,24 +2012,22 @@ smtp_mailaddr(struct mailaddr *maddr, ch
+ memmove(maddr->user, p, strlen(p) + 1);
+ }
+
+- if (!valid_localpart(maddr->user) ||
+- !valid_domainpart(maddr->domain)) {
+- /* accept empty return-path in MAIL FROM, required for bounces */
+- if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0')
+- return (1);
++ /* accept empty return-path in MAIL FROM, required for bounces */
++ if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0')
++ return (1);
+
+- /* no user-part, reject */
+- if (maddr->user[0] == '\0')
+- return (0);
+-
+- /* no domain, local user */
+- if (maddr->domain[0] == '\0') {
+- (void)strlcpy(maddr->domain, domain,
+- sizeof(maddr->domain));
+- return (1);
+- }
++ /* no or invalid user-part, reject */
++ if (maddr->user[0] == '\0' || !valid_localpart(maddr->user))
+ return (0);
++
++ /* no domain part, local user */
++ if (maddr->domain[0] == '\0') {
++ (void)strlcpy(maddr->domain, domain,
++ sizeof(maddr->domain));
+ }
++
++ if (!valid_domainpart(maddr->domain))
++ return (0);
+
+ return (1);
+ }
diff --git a/network/opensmtpd/opensmtpd.SlackBuild b/network/opensmtpd/opensmtpd.SlackBuild
index b429cf360a..54a4f8e4cf 100644
--- a/network/opensmtpd/opensmtpd.SlackBuild
+++ b/network/opensmtpd/opensmtpd.SlackBuild
@@ -3,7 +3,7 @@
# Slackware build script for opensmtpd
# Copyright 2013-2014 Robby Workman, Northport, Alabama, USA
-# Copyright 2015-2018 Richard Narron, California, USA
+# Copyright 2015-2020 Richard Narron, California, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -25,7 +25,7 @@
PRGNAM=opensmtpd
VERSION=${VERSION:-6.0.3p1}
-BUILD=${BUILD:-3}
+BUILD=${BUILD:-6}
TAG=${TAG:-_SBo}
if [ -z "$ARCH" ]; then
@@ -95,6 +95,18 @@ find -L . \
# fix reply buffer overflow
cat $CWD/openbsd64-020-smtpd.patch | patch -p1
+# fix tls downgrade
+cat $CWD/openbsd65-029-smptd-tls.patch | patch -p1
+
+# fix exec
+cat $CWD/openbsd66-019-smtpd-exec.patch | patch -p1
+
+# check null from crypt function
+cat $CWD/fix-crash-on-authentication.patch | patch -p1
+
+# fix smtpctl envelop
+cat $CWD/openbsd65-031-smtpd-envelope.patch | patch -p1
+
CFLAGS="$SLKCFLAGS -D_DEFAULT_SOURCE" \
CXXFLAGS="$SLKCFLAGS" \
./configure \
@@ -165,7 +177,7 @@ for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; r
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
cp -a INSTALL LICENSE README.md THANKS $PKG/usr/doc/$PRGNAM-$VERSION
-cat $CWD/README > $PKG/usr/doc/$PRGNAM-$VERSION/README
+cat $CWD/README > $PKG/usr/doc/$PRGNAM-$VERSION/README.slackware
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
mkdir -p $PKG/install