Skip to content

Commit

Permalink
fix imap, pop3 STARTTLS issue, poppass privileges
Browse files Browse the repository at this point in the history
1. svctool: fixed uid/gid for qmail-poppass to run under qmaild:indimail
2. svctool: fix STARTTLS issue for imap port 143, pop3 port 110 permission
   reading servercert.pem. Run with qcerts gid
3. qmail-poppass.c: ensure qmail-poppass runs with qmaild:indimail privileges
  • Loading branch information
mbhangui committed Sep 2, 2024
1 parent e2499f8 commit 7d19fc6
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 115 deletions.
4 changes: 2 additions & 2 deletions indimail-mta-x/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3068,8 +3068,8 @@ variables.h set_environment.h
./compile rrt.c

qmail-poppass: \
load qmail-poppass.o auto_uids.o
./load qmail-poppass auto_uids.o $(QMAILLIB)
load qmail-poppass.o auto_uids.o get_uid.o
./load qmail-poppass auto_uids.o get_uid.o $(QMAILLIB)

qmail-poppass.o: \
compile qmail-poppass.c auto_uids.h buffer_defs.h
Expand Down
5 changes: 5 additions & 0 deletions indimail-mta-x/doc/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Release @version@-@release@ Start 08/08/2024 End XX/XX/XXXX
1. svctool: fixed mariadb db creation for mariadb 11.x on archlinux
- 01/09/2024
2. queue-fix.c: bug - tcpto buffer size was unitialized
- 02/09/2024
3. svctool: fixed uid/gid for qmail-poppass to run under qmaild:indimail
4. svctool: fix STARTTLS issue for imap port 143, pop3 port 110 permission
reading servercert.pem. Run with qcerts gid
5. qmail-poppass.c: ensure qmail-poppass runs with qmaild:indimail privileges

* Tue Aug 06 2024 12:51:02 +0000 Manvendra Bhangui <indimail-mta@indimail.org> 3.0.8-1.1%{?dist}
Release @version@-@release@ Start 05/02/2024 End XX/XX/XXXX
Expand Down
65 changes: 30 additions & 35 deletions indimail-mta-x/qmail-poppass.9
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.\" vim: tw=75
.TH qmail-poppass 8 "03 Aug 2009" IndiMail "Authentication"
.SH "NAME"
qmail-poppass \- change passwords from across the network using
Expand Down Expand Up @@ -28,10 +29,10 @@ interface for authencation and uses the
interface for setting the password.
.B checkpassword
interface provides a simple, uniform password-checking interface to all root
applications. It is suitable for use by applications such as login, ftpd, and pop3d.
applications. It is suitable for use by applications such as login, ftpd.
.B setpassword
interface provides a simple, uniform password-setting interface to all root applications. It is suitable for use by
applications such as pop3d, imapd.
interface provides a simple, uniform password-setting interface to all root
applications. It is suitable for use by applications such as pop3d, imapd.

.PP
.IR checkprogram ,
Expand All @@ -47,8 +48,9 @@ another 0 byte, and a final two 0 bytes.
.I checkprogram
invokes
.I subprogram
upon unsuccessful authentication, passing the same data (read earlier on descriptor 3) on a pipe with file descriptor 4
as the write end and file descriptor 3 as the read end.
upon unsuccessful authentication, passing the same data (read earlier on
descriptor 3) on a pipe with file descriptor 4 as the write end and file
descriptor 3 as the read end.
.I subprogram
should read file descriptor 3 and should in turn return 0 to
.BR qmail-poppass
Expand All @@ -63,7 +65,8 @@ There can be multiple
.I subprograms
for a particular type of authentication. The last
.I subprogram
should typically be /bin/false or /usr/bin/false depending on your Operating System.
should typically be /bin/false or /usr/bin/false depending on your
Operating System.

.PP
.B qmail-poppass
Expand Down Expand Up @@ -91,48 +94,40 @@ logs all password change attempts whether they are successful or not.

.SH "EXAMPLE CLIENT-SERVER CONVERSATION"
All messages passed between server and client are text based allowing
a client session to be easily mimicked with telnet. Using telnet,
changing a user's password would look like this:
a client session to be easily mimicked with telnet on an unencrypted
channel. On an encrypted channel you can use \fBtcpclient\fR(1), using
which changing a user's password would look like this:

Connected to localhost.localdomain (127.0.0.1).
.br
Escape character is '^]'.
.br
200 indimail.org hello, who are you?\\r\\n
.br
user <username>\\r\\n
.br
200 Your password please.\\r\\n
.br
pass <current password>
.br
200 Your new password please.\\r\\n
.br
newpass <new password>\\r\\n
.br
200 Password changed, thank-you.\\r\\n
.br
quit\\r\\n
.br
200 Bye.\\r\\n
.br
Connection closed by foreign host.
.EX
$ tcpclient -n /etc/indimail/certs/clientcert.pem 0 106
200 indimail.org hello, who are you?\\r\\n
user <username>\\r\\n
200 Your password please.\\r\\n
pass <current password>
200 Your new password please.\\r\\n
newpass <new password>\\r\\n
200 Password changed, thank-you.\\r\\n
quit\\r\\n
200 Bye.\\r\\n
Connection closed by foreign host.
.EE

.SH "BUGS"
.PP
If you've found a bug in
.BR qmail-poppass ,
please report it to
mbhangui@gmail\&.com
manvendra@indimail\&.org

.SH "SEE ALSO"
qmail-smtpd(8), vsetpass(8)

.SH "AUTHOR"
.PP
.B qmail-poppass
was written by Manvendra Bhangui <mbhangui@gmail\&.com>
is based on poppassd and was written by Manvendra Bhangui
<mbhangui@gmail\&.com>
.PP
.B poppassd
was written by Pawel Krawczyk based on an ealier
version written by John Norstad, Roy Smith and Daniel L. Leavitt
was written by Pawel Krawczyk based on an ealier version written by John
Norstad, Roy Smith and Daniel L. Leavitt
120 changes: 50 additions & 70 deletions indimail-mta-x/qmail-poppass.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/*
* $Log: qmail-poppass.c,v $
* Revision 1.10 2024-09-02 19:32:26+05:30 Cprogrammer
* ensure qmail-poppass runs with qmaild:indimail privileges
*
* Revision 1.9 2024-05-09 22:03:17+05:30 mbhangui
* fix discarded-qualifier compiler warnings
*
Expand Down Expand Up @@ -111,15 +114,11 @@ flush()
no_return void
my_error(const char *s1, int exit_val)
{
if (substdio_puts(&sserr, s1))
_exit(111);
if (substdio_puts(&sserr, ": "))
_exit(111);
if (substdio_puts(&sserr, error_str(errno)))
_exit(111);
if (substdio_puts(&sserr, "\n"))
_exit(111);
if (substdio_flush(&sserr) == -1)
if (substdio_puts(&sserr, s1) == -1 ||
substdio_puts(&sserr, ": ") == -1 ||
substdio_puts(&sserr, error_str(errno)) == -1 ||
substdio_puts(&sserr, "\n") ||
substdio_flush(&sserr) == -1)
_exit(111);
out(exit_val ? "500 " : " 400");
out(s1);
Expand All @@ -144,8 +143,7 @@ authenticate()
my_error("Requested action aborted: child won't start and I can't auth (#4.3.0)", 0);
case 0:
close(pi[1]);
if (pi[0] != 3)
{
if (pi[0] != 3) {
dup2(pi[0], 3);
close(pi[0]);
}
Expand All @@ -155,20 +153,16 @@ authenticate()
}
close(pi[0]);
substdio_fdbuf(&ssup, write, pi[1], upbuf, sizeof upbuf);
if (substdio_put(&ssup, user.s, user.len) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
if (substdio_put(&ssup, old_pass.s, old_pass.len) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
if (substdio_put(&ssup, "\0\0", 2) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
if (substdio_flush(&ssup) == -1)
if (substdio_put(&ssup, user.s, user.len) == -1 ||
substdio_put(&ssup, old_pass.s, old_pass.len) == -1 ||
substdio_put(&ssup, "\0\0", 2) == -1 ||
substdio_flush(&ssup) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
/* byte_zero(old_pass.s, old_pass.len); */
byte_zero(upbuf, sizeof upbuf);
close(pi[1]);
if (wait_pid(&wstat, child) == -1)
my_error("Requested action aborted: problem with child and I can't auth (#4.3.0)", 0);
if (wait_crashed(wstat))
if (wait_pid(&wstat, child) == -1 ||
wait_crashed(wstat))
my_error("Requested action aborted: problem with child and I can't auth (#4.3.0)", 0);
return (wait_exitcode(wstat));
}
Expand Down Expand Up @@ -199,23 +193,18 @@ change_pass()
}
close(pi[0]);
substdio_fdbuf(&ssup, write, pi[1], upbuf, sizeof upbuf);
if (substdio_put(&ssup, user.s, user.len) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
if (substdio_put(&ssup, old_pass.s, old_pass.len) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
if (substdio_put(&ssup, "\0", 1) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
if (substdio_put(&ssup, new_pass.s, new_pass.len) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
if (substdio_flush(&ssup) == -1)
if (substdio_put(&ssup, user.s, user.len) == -1 ||
substdio_put(&ssup, old_pass.s, old_pass.len) == -1 ||
substdio_put(&ssup, "\0", 1) == -1 ||
substdio_put(&ssup, new_pass.s, new_pass.len) == -1 ||
substdio_flush(&ssup) == -1)
my_error("Requested action aborted: unable to write pipe and I can't auth (#4.3.0)", 0);
byte_zero(old_pass.s, old_pass.len);
byte_zero(new_pass.s, new_pass.len);
byte_zero(upbuf, sizeof upbuf);
close(pi[1]);
if (wait_pid(&wstat, child) == -1)
my_error("Requested action aborted: problem with child and I can't auth (#4.3.0)", 0);
if (wait_crashed(wstat))
if (wait_pid(&wstat, child) == -1 ||
wait_crashed(wstat))
my_error("Requested action aborted: problem with child and I can't auth (#4.3.0)", 0);
return (wait_exitcode(wstat));
}
Expand All @@ -227,19 +216,18 @@ main(int argc, char **argv)
int match, item;
char *host, *ptr;
uid_t uid;
gid_t gid;
char strnum[FMT_ULONG];

if (argc < 2)
{
if (argc < 2) {
out("500 usage: ");
out(argv[0]);
out(" hostname checkprogram [subprogram subprogram]\r\n");
flush();
sleep(1);
return (1);
}
if (!(ptr = env_get("PASSWORD_COMMAND")))
{
if (!(ptr = env_get("PASSWORD_COMMAND"))) {
out("500 PASSWORD_COMMAND not set\r\n");
flush();
sleep(1);
Expand All @@ -250,26 +238,28 @@ main(int argc, char **argv)
host = argv[1];
authargs = argv + 2;
uid = getuid();
if (uid != auto_uidi && uid != 0)
{
gid = getgid();
if (uidinit(1, 1) == -1)
my_error("unable to get uid/gid: ", 0);
if (uid != auto_uidi && uid != 0 && gid != auto_gidi) {
out("500 you should run this program with uid 0 or uid ");
strnum[fmt_ulong(strnum, auto_uidi)] = 0;
out(strnum);
out(" or gid ");
strnum[fmt_ulong(strnum, auto_gidi)] = 0;
out(strnum);
out("\r\n");
flush();
sleep(1);
return (1);
}
for (item = 1;;)
{
for (item = 1;;) {
switch (item)
{
case 1:
if (!stralloc_copys(&user, ""))
my_error("out of memory", 0);
if (!stralloc_copys(&old_pass, ""))
my_error("out of memory", 0);
if (!stralloc_copys(&new_pass, ""))
if (!stralloc_copys(&user, "") ||
!stralloc_copys(&old_pass, "") ||
!stralloc_copys(&new_pass, ""))
my_error("out of memory", 0);

out("200 ");
Expand All @@ -291,65 +281,55 @@ main(int argc, char **argv)
--line.len;
if (line.len && (line.s[line.len - 1] == '\r'))
--line.len;
if (!str_diffn(line.s, "quit", 4))
{
if (!str_diffn(line.s, "quit", 4)) {
out("200 Bye-bye\r\n");
flush();
_exit (0);
}
switch (item)
{
case 1:
if (str_diffn(line.s, "user ", 5))
{
if (str_diffn(line.s, "user ", 5)) {
out("500 Username required.\r\n");
continue;
}
if (!stralloc_catb(&user, line.s + 5, line.len - 5))
my_error("out of memory", 0);
if (!stralloc_0(&user))
if (!stralloc_catb(&user, line.s + 5, line.len - 5) ||
!stralloc_0(&user))
my_error("out of memory", 0);
break;
case 2:
if (str_diffn(line.s, "pass ", 5))
{
if (str_diffn(line.s, "pass ", 5)) {
out("500 Password required.\r\n");
item = 1;
continue;
}
if (!stralloc_catb(&old_pass, line.s + 5, line.len - 5))
my_error("out of memory", 0);
if (!stralloc_0(&old_pass))
if (!stralloc_catb(&old_pass, line.s + 5, line.len - 5) ||
!stralloc_0(&old_pass))
my_error("out of memory", 0);
if (authenticate())
{
if (authenticate()) {
out("500 Old password is incorrect or user not found.\r\n");
item = 1;
sleep (5);
continue;
}
break;
case 3:
if (str_diffn(line.s, "newpass ", 8))
{
if (str_diffn(line.s, "newpass ", 8)) {
out("500 New Password required.\r\n");
item = 1;
continue;
}
if (!stralloc_catb(&new_pass, line.s + 8, line.len - 8))
my_error("out of memory", 0);
if (!stralloc_0(&new_pass))
if (!stralloc_catb(&new_pass, line.s + 8, line.len - 8) ||
!stralloc_0(&new_pass))
my_error("out of memory", 0);
if (change_pass())
{
if (change_pass()) {
errlog("Password change for ");
errlog(user.s);
errlogf(" failed\n");
out("500 Password change failed.\r\n");
item = 1;
continue;
} else
{
} else {
errlog("Password change for ");
errlog(user.s);
errlogf(" succeeded\n");
Expand All @@ -369,7 +349,7 @@ main(int argc, char **argv)
void
getversion_qmail_poppass_c()
{
const char *x = "$Id: qmail-poppass.c,v 1.9 2024-05-09 22:03:17+05:30 mbhangui Exp mbhangui $";
const char *x = "$Id: qmail-poppass.c,v 1.10 2024-09-02 19:32:26+05:30 Cprogrammer Exp mbhangui $";

x = sccsidmakeargsh;
x++;
Expand Down
Loading

0 comments on commit 7d19fc6

Please sign in to comment.