Skip to content

Commit

Permalink
updated indimail-mta
Browse files Browse the repository at this point in the history
1. qmail-spamfilter.c: added HAMEXITCODE, UNSUREEXITCODE
2. qmail-spamfilter.c: Fixed working of globalspamredirect + REJECTSPAM
3. updated man pages
4. updated test-indimail script
  • Loading branch information
mbhangui committed Oct 26, 2023
1 parent 4459bd5 commit 4827b2e
Show file tree
Hide file tree
Showing 9 changed files with 635 additions and 137 deletions.
3 changes: 3 additions & 0 deletions indimail-mta-x/doc/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Release 3.0.6-1.1 Start 25/10/2023 End XX/XX/XXXX
08. create_services.in: added --setuser-priv option for slowq service
09. autoresponder.c, indimail-spamfilter.c: rewind descriptor 0 regardless of
MAKE_SEEKABLE setting
- 25/10/2023
10. qmail-spamfilter.c: added HAMEXITCODE, UNSUREEXITCODE
11. qmail-spamfilter.c: Fixed working of globalspamredirect + REJECTSPAM

* Tue Oct 17 2023 18:34:04 +0000 Manvendra Bhangui <indimail-mta@indimail.org> 3.0.5-1.1%{?dist}
Release 3.0.5-1.1 Start 11/09/2023 End 17/10/2023
Expand Down
11 changes: 6 additions & 5 deletions indimail-mta-x/qmail-dkim.9
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ message. To invoke \fBqmail-dkim\fR, set QMAILQUEUE to full path of
qmail-dkim in the environment, when you send or receive email.

After inserting the DKIM header, \fBqmail-dkim\fR will call
\fBqmail-multi\fR as a default, to deposit message in the queue. If you
\fBqmail-queue\fR as a default, to deposit message in the queue. If you
want to call something pass it as in the command line arguments to
\fBqmail-dkim\fR or set the \fBDKIMQUEUE\fR environment variable. Command
line arguments takes precedence over environment variable.
\fBqmail-dkim\fR or set the \fBDKIMQUEUE\fR or \fBQUEUEPROG\fR environment
variable. Command line arguments takes precedence over environment
variable.

.EX
DKIMQUEUE=PREFIX/sbin/qmail-queue
DKIMQUEUE=PREFIX/sbin/qmail-spamfilter
.EE

Will make qmail-dkim call qmail-queue instead of qmail-multi.
Will make qmail-dkim call qmail-spamfilter instead of qmail-queue.

\fBqmail-dkim\fR supports RSA-SHA1, RSA-SHA256 and ED25519-SHA256 (rfc8463)
encryption methods for signing and verification. By default RSA-SHA256 is
Expand Down
14 changes: 7 additions & 7 deletions indimail-mta-x/qmail-qfilter.1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.\" vim: tw=75
.TH qmail-qfilter 1
.SH NAME
qmail-qfilter \- front end for qmail-multi that does filtering
qmail-qfilter \- front end for qmail-queue that does filtering
.SH SYNOPSIS
.B qmail-qfilter
.I filter
Expand All @@ -13,17 +13,17 @@ qmail-qfilter \- front end for qmail-multi that does filtering
commands named on the command line. Each filter is run separately, with
standard input opened to the input email, and standard output opened to a
new temporary file that will become the input to either the next filter, or
\fBqmail-multi\fR. If the filter does not modify the message it passes
\fBqmail-queue\fR. If the filter does not modify the message it passes
unchanged to the next step. It also makes the envelope available to each
filter as file descriptor 3. File descriptor 4 is opened to a new temporary
file for the modified envelope, allowing the filter to modify the envelope
or the message. If the filter does not modify the envelope, the envelope
remains unchanged for either the next filter or \fBqmail-multi\fR. This
remains unchanged for either the next filter or \fBqmail-queue\fR. This
provides compatibility for existing filters that do not know about the
envelope. \fBqmail-qfilter\fR also opens up file descriptor 5 to a
temporary file. If this file is empty after all the filters have executed,
its contents are read and used to specify a program to execute in place of
\fBqmail-multi\fR. Each filter on the command line is separated by
\fBqmail-queue\fR. Each filter on the command line is separated by
\fB--\fR.

.SH "RETURN VALUES"
Expand All @@ -39,7 +39,7 @@ anything other than 0 or 99. If your filter exits 88, you can put your
custom error string on standard error. This enables client like
\fBqmail-smtpd\fR to report the error. If a filter returns 99,
\fBqmail-qfilter\fR returns 0 immediately without running any other
filters. Otherwise returns the exit code of \fBqmail-multi\fR.
filters. Otherwise returns the exit code of \fBqmail-queue\fR.

.SH ENVIRONMENT
For compatibility with previous versions, \fBqmail-qfilter\fR sets
Expand All @@ -52,8 +52,8 @@ It also sets \fBENVSIZE\fR to the size of the envelope, \fBMSGSIZE\fR to
the length of the message, and \fBNUMRCPTS\fR to the number of recipients.
These values are updated before each filter is run.
.P
If \fBQQF_QMAILQUEUE\fR is set, its value is used in place of
\fBqmail-multi\fR.
If \fBQQF_QMAILQUEUE\fR or \fBQUEUEPROG\fR is set, that value is used in
place of \fBqmail-queue\fR.

.SH "SEE ALSO"
qfrontend(1),
Expand Down
28 changes: 14 additions & 14 deletions indimail-mta-x/qmail-queue.9
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ qmail-queue \- queue a mail message for delivery
.SH DESCRIPTION
\fBqmail-queue\fR reads a mail message from descriptor 0. It then reads
envelope information from descriptor 1. It places the message into the
outgoing queue for future delivery by \fBqmail-send\fR. The default
outgoing queue for future delivery by \fBqmail-send\fR. The default
outgoing queue is @qmaildir@/queue. This can be changed by setting
environment variable QUEUEDIR to point to a path having a valid
queue created by the program \fBqueue-fix\fR(8). \fBqmail-queue\fR
Expand Down Expand Up @@ -205,7 +205,7 @@ the form
type:regexp:dest_mailbox
.EE

where \fItype\fR is \fBF\fR or \fBT\fR. If \fItype\fR is \fBF\fR, rule
where \fItype\fR is \fBF\fR or \fBT\fR. If \fItype\fR is \fBF\fR, rule
is appled on the sender. If \fItype\fR is \fBT\fR, the rule is applied on
the recipient. \fItype\fR can be omitted to match all recipients (but not
senders). \fIregexp\fR is an expression to match the address (sender or
Expand Down Expand Up @@ -302,15 +302,15 @@ necessity to call additional programs (like reformime or ripmime) except
for the virus scanner itself.

The QHPSI extension for qmail-queue allows to call an arbitary virus scanner
directly, scanning the incoming data-stream on STDIN or it allows plugins to
be loaded from the @prefix@/lib/indimail/plugins directory. This directory
can be changed by defining \fBPLUGINDIR\fR environment variable. QHPSI can
be advised to pass multiple arguments to the virus scanner for customization.
To run external scanner or load scanner plugins, \fBqmail-queue\fR calls
\fBqhpsi\fR, a program setuid to \fIqscand\fR. By default, \fBqhpsi\fR looks
for the symbol \fIvirusscan\fR to invoke the scanner. The symbol can be
changed by setting the environment variable \fBQUEUE_PLUGIN_SYMB\fR to the
desired symbol.
directly to scan the message file in \fImess\fR subdirectory or it allows
plugins to be loaded from the @prefix@/lib/indimail/plugins directory. This
directory can be changed by defining \fBPLUGINDIR\fR environment variable.
QHPSI can be advised to pass multiple arguments to the virus scanner for
customization. To run external scanner or load scanner plugins,
\fBqmail-queue\fR calls \fBqhpsi\fR, a program setuid to \fIqscand\fR. By
default, \fBqhpsi\fR looks for the symbol \fIvirusscan\fR to invoke the
scanner. The symbol can be changed by setting the environment variable
\fBQUEUE_PLUGIN_SYMB\fR to the desired symbol.

In order to use the QHPSI, the virus scanner has to have the following
qualifications:
Expand Down Expand Up @@ -342,7 +342,7 @@ can be set either to the full path of a scanner or to a list of plugins.
.IP \n[step] 2
is set to full path of the virus scanner, i.e. QHPSI=@prefix@/bin/clamdscan.
If full path is not specified, \fBqmail-queue\fR will use execvp(2) to run
the scanner. Else it uses execv(2). Setting QHPSI environment variable
the scanner. Else it uses execv(2). Setting QHPSI environment variable
turns on the QHPSI interface. The Qmail High Performance Scanner interface
QHPSI also allows \fBqmail-queue\fR to read command line arguments taken
from the \fBQHPSI\fR environment to be used as a call-interface for an
Expand Down Expand Up @@ -399,8 +399,8 @@ to a value > 2 will bounce infected mails to sender
\fBVIRUSFORWARD\fR
Infected mails will be quarantined to the email defined by VIRUSFORWARD.
This will work only if \fBREJECTVIRUS\fR is not equal to 1. Setting
VIRUSFORWARD sets the \fBX-Quarantine-ID\fR containing the list of original
recipient list is added.
VIRUSFORWARD sets the \fBX-Quarantine-ID\fR containing the list of all
recipients.

.TP
\fBQHPSIMINSIZE\fR
Expand Down
2 changes: 1 addition & 1 deletion indimail-mta-x/qmail-queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ main()
for (len = 0; len < ADDR; ++len) {
if (substdio_get(&ssin, &ch, 1) < 1)
die(QQ_READ_ERR, 1, "trouble reading envelope");
if (flagquarantine) {
if (flagquarantine) { /*- append all recipients to quarantine */
if (ch && !stralloc_append(&qqehextra, &ch))
die(QQ_OUT_OF_MEMORY, 1, "out of memory");
} else
Expand Down
46 changes: 26 additions & 20 deletions indimail-mta-x/qmail-spamfilter.9
Original file line number Diff line number Diff line change
Expand Up @@ -45,40 +45,46 @@ the environment variable \fBMAKE_SEEKABLE\fR is defined. This may be
necessary for certain filter programs like bogofilter which allocate memory
for the mail message when lseek(2) fails.

In this case following interpretations on the exit status will be made
\fBqmail-spamfilter\fR by default, interprets the exit status of spam
filter program as below

Exit Status Interpretation
----------- --------------
0,1,2 Program ran successfully. Interpretation depends
on filter implementation. Mail will be accepted
unless REJECTSPAM is set. See description below.
100 Mail will be bounced
anything else Mail will be rejected with a temporary error

A typical application of this would be to run spam filtering software like
spamassasin, bogofilter, etc

When the exit code of the filter program matches SPAMEXITCODE, the mail is
considered to be spam.
When the exit code of the filter program matches the value of
\fBSPAMEXITCODE\fR, the mail is considered to be spam. When the exit code of
the filter program matches the value of \fBHAMEXITCODE\fR, the mail is not
consided to be spam. If the exit code of the filter program matches the
value of \fBUNSUREEXITCODE\fR, the classication of mail as spam or ham
couldn't be determined accurately. All other errors should be consided as
temporary errors except for 100, which should be interpreted as a permanent
error.

If \fBREJECTSPAM\fR is set to 1, the mail will be bounced back to the
sender. If \fBNOTIFYSPAM\fR is set, mails will be redirected to the
recipient specified by the \fBNOTIFYSPAM\fR environment variable. If
\fBNOTIFYSPAM\fR is not set, the recipient can be specified by the
\fIglobalspamredirect\fR control file. The email id in
sender. mail can be redirected to the recipient specified in the
\fIglobalspamredirect\fR control file. The email id in
\fIglobalspamdirect\fR can be overriden by the environment variable
\fBGLOBALSPAMREDIRECT\fR. If both \fBREJECTSPAM\fR and \fBNOTIFYSPAM\fR are
set, spam mails will be bounced back to the sender with a copy redirected
to the recipient specified in by the NOTIFYSPAM environment variable as
well (or the \fBglobalspamredirect\fR control file). you may decide not to
generate a bounce to the sender by setting the environment variable
\fBREJECTSPAM\fR to a value greater than 1 (i.e. black hole SPAM mails).

\fBqmail-spamfilter\fR invokes \fBqmail-multi\fR to deposit the mail. This
can be changed by setting environment variable \fBSPAMQUEUE\fR to the path
of any qmail-queue frontend. It can also be changed by passing the path of
any qmail-queue frontend (along with arguments to the qmail-queue frontend)
on the command line. Passing command line arguments takes precedence
over environment variable.
\fBGLOBALSPAMREDIRECT\fR. If \fBREJECTSPAM\fR is set and
\fIglobalspamdirect\fR control file exists, spam mails will be bounced back
to the sender as wll a copy redirected to the recipient specified in by
\fIglobalspamredirect\fR control file. You may decide not to generate a
bounce to the sender by setting the environment variable \fBREJECTSPAM\fR
to a value greater than 1 (i.e. black hole SPAM mails).

\fBqmail-spamfilter\fR invokes \fBqmail-queue\fR to deposit the mail. This
can be changed by setting environment variable \fBSPAMQUEUE\fR or
\fBQUEUEPROG\fR to the path of any qmail-queue frontend. It can also be
changed by passing the path of any qmail-queue frontend (along with
arguments to the qmail-queue frontend) on the command line. Passing command
line arguments takes precedence over environment variable.

.SH "EXIT CODES"
\fBqmail-spamfilter\fR does not print diagnostics.
Expand Down
126 changes: 70 additions & 56 deletions indimail-mta-x/qmail-spamfilter.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
/*
* $Log: qmail-spamfilter.c,v $
* Revision 1.7 2023-10-25 13:26:09+05:30 Cprogrammer
* rewind descriptor 0 regardless of MAKE_SEEKABLE setting
*
* Revision 1.6 2022-10-17 19:44:59+05:30 Cprogrammer
* use exit codes defines from qmail.h
*
* Revision 1.5 2022-04-03 18:44:36+05:30 Cprogrammer
* refactored qmail_open() error codes
*
* Revision 1.4 2022-03-05 13:35:30+05:30 Cprogrammer
* use auto_prefix/sbin for qscanq path
*
* Revision 1.3 2022-01-30 09:14:32+05:30 Cprogrammer
* removed chdir auto_qmail
*
* Revision 1.2 2021-08-29 23:27:08+05:30 Cprogrammer
* define functions as noreturn
*
* Revision 1.1 2021-06-15 12:16:52+05:30 Cprogrammer
* Initial revision
*
* $Id: qmail-spamfilter.c,v 1.8 2023-10-26 23:14:32+05:30 Cprogrammer Exp mbhangui $
*/
#include <unistd.h>
#include <fcntl.h>
Expand Down Expand Up @@ -57,7 +36,8 @@ sigbug()
int
main(int argc, char **argv)
{
int wstat, filt_exitcode, queueexitcode, n;
int wstat, filt_exitcode, queueexitcode, n, ham_code = 1,
spam_code = 0, unsure_code = 2;
int pipefd[2], recpfd[2];
pid_t filt_pid, queuepid;
struct substdio ssin, ssout;
Expand Down Expand Up @@ -175,45 +155,51 @@ main(int argc, char **argv)
/*
* Process message if exit code is 0, 1, 2
*/
switch (filt_exitcode = wait_exitcode(wstat))
{
case 0: /*- SPAM */
case 1: /*- HAM */
case 2: /*- Unsure */
if ((ptr = env_get("SPAMEXITCODE"))) {
scan_int(ptr, &n);
if (n == filt_exitcode) { /*- Message is SPAM */
if ((n = rewrite_envelope(recpfd[1])) > 1) { /*- Some error */
close(1);
close(recpfd[1]);
wait_pid(&wstat, queuepid);
_exit(n);
}
if (n == 1 || (ptr = env_get("REJECTSPAM"))) {
/*- REJECTSPAM takes precedence over spam notifications */
if (ptr && *ptr > '0') {
(void) discard_envelope();
close(1);
close(recpfd[1]);
wait_pid(&wstat, queuepid);
if (*ptr == '1')
_exit(QQ_SPAM_THRESHOLD); /*- bounce */
else
_exit(0); /*- blackhole */
} else /*- spam notification - envelope has been rewritten */ if (n == 1) {
(void) discard_envelope();
goto finish;
}
}
filt_exitcode = wait_exitcode(wstat);
if (!(ptr = env_get("SPAMEXITCODE")))
spam_code = 0; /*- default for bogofilter */
else
scan_int(ptr, &spam_code);
if (!(ptr = env_get("HAMEXITCODE")))
ham_code = 1; /*- default for bogofilter */
else
scan_int(ptr, &ham_code);
if (!(ptr = env_get("UNSUREEXITCODE")))
unsure_code = 2; /*- default for bogofilter */
else
scan_int(ptr, &unsure_code);
if (spam_code == filt_exitcode) { /* Message is SPAM */
if ((n = rewrite_envelope(recpfd[1])) > 1) { /*- Some error */
close(1);
close(recpfd[1]);
wait_pid(&wstat, queuepid);
_exit(n);
}
ptr = env_get("REJECTSPAM");
if (n == 1 || ptr) {
/*- REJECTSPAM takes precedence over spam notifications */
if (ptr && *ptr > '0') {
(void) discard_envelope();
close(1);
close(recpfd[1]);
wait_pid(&wstat, queuepid);
if (*ptr == '1')
_exit(QQ_SPAM_THRESHOLD); /*- bounce */
else
_exit(0); /*- blackhole */
} else /*- spam notification - envelope has been rewritten */ if (n == 1) {
(void) discard_envelope();
goto finish;
}
}
break;
default: /*- should not happen normally */
} else
if (filt_exitcode != ham_code && filt_exitcode != unsure_code) {
close(1);
close(recpfd[1]);
wait_pid(&wstat, queuepid);
_exit(QQ_TEMP_SPAM_FILTER); /*- treat this as temp problem with spam filter */
}

/*- Write envelope to qmail-queue */
substdio_fdbuf(&ssout, write, recpfd[1], outbuf, sizeof (outbuf));
/*- Read envelope from qmail-smtpd */
Expand Down Expand Up @@ -247,11 +233,39 @@ main(int argc, char **argv)
void
getversion_qmail_spamfilter_c()
{
static char *x = "$Id: qmail-spamfilter.c,v 1.7 2023-10-25 13:26:09+05:30 Cprogrammer Exp mbhangui $";
static char *x = "$Id: qmail-spamfilter.c,v 1.8 2023-10-26 23:14:32+05:30 Cprogrammer Exp mbhangui $";

x = sccsidqmultih;
x = sccsidmakeargsh;
x = sccsidmktempfileh;
x++;
}
#endif

/*
* $Log: qmail-spamfilter.c,v $
* Revision 1.8 2023-10-26 23:14:32+05:30 Cprogrammer
* added HAMEXITCODE, UNSUREEXITCODE
*
* Revision 1.7 2023-10-25 13:26:09+05:30 Cprogrammer
* rewind descriptor 0 regardless of MAKE_SEEKABLE setting
*
* Revision 1.6 2022-10-17 19:44:59+05:30 Cprogrammer
* use exit codes defines from qmail.h
*
* Revision 1.5 2022-04-03 18:44:36+05:30 Cprogrammer
* refactored qmail_open() error codes
*
* Revision 1.4 2022-03-05 13:35:30+05:30 Cprogrammer
* use auto_prefix/sbin for qscanq path
*
* Revision 1.3 2022-01-30 09:14:32+05:30 Cprogrammer
* removed chdir auto_qmail
*
* Revision 1.2 2021-08-29 23:27:08+05:30 Cprogrammer
* define functions as noreturn
*
* Revision 1.1 2021-06-15 12:16:52+05:30 Cprogrammer
* Initial revision
*
*/
Loading

0 comments on commit 4827b2e

Please sign in to comment.