commit 30a44402454eca17beb8339a8b661cc8683be5b3
parent 2a469cc632ac74bc2cb915e6f8cd0ccc330d88f6
Author: Amitai Schleier <schmonz-web-git@schmonz.com>
Date: Mon, 2 Sep 2019 11:47:45 -0400
qmail-pop3d: exit 1, pronto, if running as root.
At least checkpassword-pam and DJB's original checkpassword are willing
to authenticate the root user and run a child program with UID 0. For
POP3 service -- the canonical checkpassword use case! -- this produces
runtime behavior that is inconsistent with...
- qmail's design, because qmail-local will never run as root to populate
a Maildir that qmail-pop3d could serve, and
- qmail's security focus, because it lets abusers dictionary-attack the
root password over the network.
Instead, in qmail-pop3d, if getuid() returns 0, we write to the logs and
exit 1. If someone manages to guess the root password, they won't know
they did: it looks exactly like any other failed checkpassword login.
And the sysadmin could potentially be alerted.
Diffstat:
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/CHANGES b/CHANGES
@@ -1,3 +1,6 @@
+20200514 bug: qmail-pop3d runs as root if root authenticates.
+ impact: vector for dictionary attack on root password.
+ fix: exit 1, same as a failed checkpassword login.
20200514 code: changed qmail-popup interface (leave kid's fd 2 alone).
20200511 code: remove tryshsgr.c and use uid_t, gid_t types.
20200511 add first unittest, run with "make test"
diff --git a/qmail-pop3d.8 b/qmail-pop3d.8
@@ -22,9 +22,26 @@ under
.BR qmail-popup ,
which reads a username and password,
and
-.BR /bin/checkpassword ,
+.BR checkpassword ,
which checks the password and sets up environment variables.
+Since root will never have a
+.B maildir
+(because
+.B qmail-lspawn
+refuses to run
+.B qmail-local
+as root),
+.B qmail-pop3d
+also refuses to run as root.
+The event will be logged and
+.B qmail-pop3d
+will exit 1, looking to
+.B qmail-popup
+like any other failed
+.B checkpassword
+login.
+
.B qmail-pop3d
has a 20-minute idle timeout.
diff --git a/qmail-pop3d.c b/qmail-pop3d.c
@@ -1,5 +1,6 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include "commands.h"
#include "sig.h"
#include "getln.h"
@@ -35,6 +36,9 @@ int safewrite(fd,buf,len) int fd; char *buf; int len;
return r;
}
+char sserrbuf[128];
+substdio sserr = SUBSTDIO_FDBUF(safewrite,2,sserrbuf,sizeof sserrbuf);
+
char ssoutbuf[1024];
substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf);
@@ -63,6 +67,10 @@ void err(s) char *s;
void die_nomem() { err("out of memory"); die(); }
void die_nomaildir() { err("this user has no $HOME/Maildir"); die(); }
+void die_root() {
+ substdio_putsflush(&sserr,"qmail-pop3d invoked as uid 0, terminating\n");
+ _exit(1);
+}
void die_scan() { err("unable to scan $HOME/Maildir"); die(); }
void err_syntax() { err("syntax error"); }
@@ -294,6 +302,7 @@ char **argv;
sig_alarmcatch(die);
sig_pipeignore();
+ if (!getuid()) die_root();
if (!argv[1]) die_nomaildir();
if (chdir(argv[1]) == -1) die_nomaildir();