Mailing List Archive

QMAILREMOTE patch
A friend wants to DKIM-sign outgoing mail, probably using Kyle Wheeler's
DKIM wrapper around qmail-remote
(http://www.memoryhole.net/qmail/#dkim). But he doesn't want to confuse
his package manager by moving aside the real qmail-remote binary and
putting something else in its place.

Inspired by the QMAILQUEUE patch, we patched qmail-rspawn to look for
QMAILREMOTE in its environment. The 0th arg to execvp() is either the
value of the env var (if set), or "qmail-remote" as usual. We tested
with various arguments to qmail-start.

When QMAILREMOTE is not set:

May 21 08:13:29 magnetic-babysitter-netbsd7 nbqmailsend: delivery
1: success:
166.84.7.144_accepted_message./Remote_host_said:_250_ok_1495368789_qp_3818/


When QMAILREMOTE is set to an empty string, or a non-empty path (full or
unqualified) of a program that does not exist:

May 21 08:16:34 magnetic-babysitter-netbsd7 nbqmailsend: delivery
1: failure: Unable_to_run_qmail-remote./


When QMAILREMOTE is set to /var/tmp/schmonz (a shell script that runs
'exec qmail-remote "$@"'):

May 21 08:22:19 magnetic-babysitter-netbsd7 nbqmailsend: delivery
1: success:
166.84.7.144_accepted_message./Remote_host_said:_250_ok_1495369319_qp_19267/


Does this patch look reasonable?


--- Makefile.orig 2007-11-30 20:22:54.000000000 +0000
+++ Makefile
@@ -1462,19 +1462,19 @@ tcpto.h readwrite.h timeoutconn.h timeou

qmail-rspawn: \
load qmail-rspawn.o spawn.o tcpto_clean.o now.o coe.o sig.a open.a \
-seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a str.a \
+seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a env.a
str.a \
auto_qmail.o auto_uids.o auto_spawn.o
./load qmail-rspawn spawn.o tcpto_clean.o now.o coe.o \
sig.a open.a seek.a lock.a wait.a fd.a stralloc.a alloc.a \
- substdio.a error.a str.a auto_qmail.o auto_uids.o \
- auto_spawn.o
+ substdio.a error.a env.a str.a auto_qmail.o auto_uids.o \
+ auto_spawn.o

qmail-rspawn.0: \
qmail-rspawn.8
nroff -man qmail-rspawn.8 > qmail-rspawn.0

qmail-rspawn.o: \
-compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h \
+compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h
env.h \
tcpto.h
./compile qmail-rspawn.c

--- qmail-rspawn.c.orig 1998-06-15 10:53:16.000000000 +0000
+++ qmail-rspawn.c
@@ -5,6 +5,17 @@
#include "fork.h"
#include "error.h"
#include "tcpto.h"
+#include "env.h"
+
+static char *qrargs[1] = { 0 };
+
+static void setup_qrargs()
+{
+ if (!qrargs[0])
+ qrargs[0] = env_get("QMAILREMOTE");
+ if(!qrargs[0])
+ qrargs[0] = "qmail-remote";
+}

void initialize(argc,argv)
int argc;
@@ -84,7 +95,9 @@ char *s; char *r; int at;
int f;
char *(args[5]);

- args[0] = "qmail-remote";
+ setup_qrargs();
+
+ args[0] = qrargs[0];
args[1] = r + at + 1;
args[2] = s;
args[3] = r;
Re: QMAILREMOTE patch [ In reply to ]
On 2017-05-21 14:27, Amitai Schleier wrote:
> A friend wants to DKIM-sign outgoing mail, probably using Kyle
> Wheeler's DKIM wrapper around qmail-remote
> (http://www.memoryhole.net/qmail/#dkim). But he doesn't want to
> confuse his package manager by moving aside the real qmail-remote
> binary and putting something else in its place.
Renaming qmail-remote shouldn't be a recommended way.
>
> Inspired by the QMAILQUEUE patch, we patched qmail-rspawn to look for
> QMAILREMOTE in its environment. The 0th arg to execvp() is either the
> value of the env var (if set), or "qmail-remote" as usual. We tested
> with various arguments to qmail-start.
>
> When QMAILREMOTE is not set:
>
> May 21 08:13:29 magnetic-babysitter-netbsd7 nbqmailsend: delivery
> 1: success:
> 166.84.7.144_accepted_message./Remote_host_said:_250_ok_1495368789_qp_3818/
>
>
> When QMAILREMOTE is set to an empty string, or a non-empty path (full
> or unqualified) of a program that does not exist:
>
> May 21 08:16:34 magnetic-babysitter-netbsd7 nbqmailsend: delivery
> 1: failure: Unable_to_run_qmail-remote./
>
>
> When QMAILREMOTE is set to /var/tmp/schmonz (a shell script that runs
> 'exec qmail-remote "$@"'):
>
> May 21 08:22:19 magnetic-babysitter-netbsd7 nbqmailsend: delivery
> 1: success:
> 166.84.7.144_accepted_message./Remote_host_said:_250_ok_1495369319_qp_19267/
>
>
> Does this patch look reasonable?

My first question: where do you set the env var?

However, I announced some time ago my netqmail-1.06-before-remote.patch.
See https://blog.dyndn.es/doku.php/blog/2016/02/01_netqmail-bfrmt.
Meanwhile the code changed a bit, I no longer use <string.h> (as I
initially made it, I have had more less glue of djb's libs ;-) ):

#include "auto_qmail.h"
char *np = "qmail-bfrmt"; /* next program to call */
...
struct stat st;
stralloc sa = {0};

if(!stralloc_copys(&sa,auto_qmail)) err_sys(errno);
if(!stralloc_catb(&sa,"/bin/qmail-bfrmt",16)) err_sys(errno); /* len:
16 + \0 */
if(!stralloc_0(&sa)) err_sys(errno);
char *x = sa.s;
if (stat(x,&st) != 0) { np = "qmail-remote"; }

int f;
char *(args[5]);
args[0] = np;

'err_sys' comes from a new lib in djb style replacing strerr/error* -
use something like the 'die_nomem()' function instead.

The functionality is the same as describe in the link, including:

- qmail-remote will be executed directly if an error occurs
- a log message will be written if there is an error
- changes can be done on the fly (no restart required)

This is part of eQmail too. In preparation of **a**Qmail I there will be
additional improvements, like to use multiple plugins (e.g. srs) more
flexible. There are no plans to make a new version of the patch above.

regards
Kai

PS: As a preview: there will be coming soon a full featured DKIM package
as installable plugin - it will be part of aQmail too. Beware that the
latest libdkim-1.0.21 has a security bug which is not solved officially
- AFAIK.

>
>
> --- Makefile.orig 2007-11-30 20:22:54.000000000 +0000
> +++ Makefile
> @@ -1462,19 +1462,19 @@ tcpto.h readwrite.h timeoutconn.h timeou
>
> qmail-rspawn: \
> load qmail-rspawn.o spawn.o tcpto_clean.o now.o coe.o sig.a open.a \
> -seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a str.a
> \
> +seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a env.a
> str.a \
> auto_qmail.o auto_uids.o auto_spawn.o
> ./load qmail-rspawn spawn.o tcpto_clean.o now.o coe.o \
> sig.a open.a seek.a lock.a wait.a fd.a stralloc.a alloc.a \
> - substdio.a error.a str.a auto_qmail.o auto_uids.o \
> - auto_spawn.o
> + substdio.a error.a env.a str.a auto_qmail.o auto_uids.o \
> + auto_spawn.o
>
> qmail-rspawn.0: \
> qmail-rspawn.8
> nroff -man qmail-rspawn.8 > qmail-rspawn.0
>
> qmail-rspawn.o: \
> -compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h \
> +compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h
> env.h \
> tcpto.h
> ./compile qmail-rspawn.c
>
> --- qmail-rspawn.c.orig 1998-06-15 10:53:16.000000000 +0000
> +++ qmail-rspawn.c
> @@ -5,6 +5,17 @@
> #include "fork.h"
> #include "error.h"
> #include "tcpto.h"
> +#include "env.h"
> +
> +static char *qrargs[1] = { 0 };
> +
> +static void setup_qrargs()
> +{
> + if (!qrargs[0])
> + qrargs[0] = env_get("QMAILREMOTE");
> + if(!qrargs[0])
> + qrargs[0] = "qmail-remote";
> +}
>
> void initialize(argc,argv)
> int argc;
> @@ -84,7 +95,9 @@ char *s; char *r; int at;
> int f;
> char *(args[5]);
>
> - args[0] = "qmail-remote";
> + setup_qrargs();
> +
> + args[0] = qrargs[0];
> args[1] = r + at + 1;
> args[2] = s;
> args[3] = r;

--
Sent with eQmail-1.10
Re: QMAILREMOTE patch [ In reply to ]
On 21 May 2017, at 11:05, Kai Peter wrote:

> My first question: where do you set the env var?

Same place PATH gets set for qmail-start(8), in /var/qmail/rc or
similar, as an additional argument to the env(1) invocation.

> - qmail-remote will be executed directly if an error occurs
> - a log message will be written if there is an error
> - changes can be done on the fly (no restart required)

I couldn't find another patch that modifies how qmail-remote is invoked,
but I assumed I couldn't be the first! Given that I'm running netqmail
with a few small patches, I think your approach is more featureful than
I need right now. But if and when I can switch to aQmail, I bet I'll be
happy dropping my patch and using what you've provided.

Thanks,

- Amitai
Re: QMAILREMOTE patch [ In reply to ]
On 21 May 2017, at 8:27, Amitai Schleier wrote:

> Inspired by the QMAILQUEUE patch, we patched qmail-rspawn to look for
> QMAILREMOTE in its environment.

I've posted the patch to my site, along with a brief explanation:
https://schmonz.com/2017/05/22/qmail-outbound-dkim/
Re: QMAILREMOTE patch [ In reply to ]
On 21 May 2017 at 17:57, Amitai Schleier <
schmonz-lists-djb-qmail@schmonz.com> wrote:

> A friend wants to DKIM-sign outgoing mail, probably using Kyle Wheeler's
> DKIM wrapper around qmail-remote (http://www.memoryhole.net/qmail/#dkim).
> But he doesn't want to confuse his package manager by moving aside the real
> qmail-remote binary and putting something else in its place.
>
> Inspired by the QMAILQUEUE patch, we patched qmail-rspawn to look for
> QMAILREMOTE in its environment. The 0th arg to execvp() is either the value
> of the env var (if set), or "qmail-remote" as usual. We tested with various
> arguments to qmail-start.
>
> Nice and quite useful. Have done exactly the same. I use the same variable
QMAILREMOTE. Additionally, I have modified qmail-lspawn.c to use QMAILLOCAL
and call a binary other than qmail-local. Use it for doing DKIM
verification.

I use the variables QMAILLOCAL and QMAILREMOTE to run some filters before
the actual delivery attempt.


>
> Does this patch look reasonable?
>
>
Yes, it does. Rather than moving the original binary, it helps preserve the
binary checksum. rpm -V does not complain. If the path defined by
QMAILREMOTE does not exist, the qmail-send logs will contain the standard
error message "Unable to run qmail-remote"


> --- Makefile.orig 2007-11-30 20:22:54.000000000 +0000
> +++ Makefile
> @@ -1462,19 +1462,19 @@ tcpto.h readwrite.h timeoutconn.h timeou
>
> qmail-rspawn: \
> load qmail-rspawn.o spawn.o tcpto_clean.o now.o coe.o sig.a open.a \
> -seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a str.a \
> +seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a env.a
> str.a \
> auto_qmail.o auto_uids.o auto_spawn.o
> ./load qmail-rspawn spawn.o tcpto_clean.o now.o coe.o \
> sig.a open.a seek.a lock.a wait.a fd.a stralloc.a alloc.a \
> - substdio.a error.a str.a auto_qmail.o auto_uids.o \
> - auto_spawn.o
> + substdio.a error.a env.a str.a auto_qmail.o auto_uids.o \
> + auto_spawn.o
>
> qmail-rspawn.0: \
> qmail-rspawn.8
> nroff -man qmail-rspawn.8 > qmail-rspawn.0
>
> qmail-rspawn.o: \
> -compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h \
> +compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h env.h
> \
> tcpto.h
> ./compile qmail-rspawn.c
>
> --- qmail-rspawn.c.orig 1998-06-15 10:53:16.000000000 +0000
> +++ qmail-rspawn.c
> @@ -5,6 +5,17 @@
> #include "fork.h"
> #include "error.h"
> #include "tcpto.h"
> +#include "env.h"
> +
> +static char *qrargs[1] = { 0 };
> +
> +static void setup_qrargs()
> +{
> + if (!qrargs[0])
> + qrargs[0] = env_get("QMAILREMOTE");
> + if(!qrargs[0])
> + qrargs[0] = "qmail-remote";
> +}
>
> void initialize(argc,argv)
> int argc;
> @@ -84,7 +95,9 @@ char *s; char *r; int at;
> int f;
> char *(args[5]);
>
> - args[0] = "qmail-remote";
> + setup_qrargs();
> +
> + args[0] = qrargs[0];
> args[1] = r + at + 1;
> args[2] = s;
> args[3] = r;
>



--
Regards Manvendra - http://www.indimail.org
GPG Pub Key
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC7CBC760014D250C
Re: QMAILREMOTE patch [ In reply to ]
On 23 May 2017, at 0:21, Manvendra Bhangui wrote:

> Nice and quite useful. Have done exactly the same. I use the same
> variable
> QMAILREMOTE. Additionally, I have modified qmail-lspawn.c to use
> QMAILLOCAL
> and call a binary other than qmail-local. Use it for doing DKIM
> verification.

Makes sense. If my friend gets around to wanting to verify DKIM on
incoming messages, we'll want that. Have you posted these patches
somewhere stable?

> I use the variables QMAILLOCAL and QMAILREMOTE to run some filters
> before
> the actual delivery attempt.

Would you be willing to share some of your filters? I'm curious to see
examples (besides DKIM) of what qmail-{remote,local} wrappers can be
used for.
Re: QMAILREMOTE patch [ In reply to ]
On 24 May 2017 at 11:19, Amitai Schleier <
schmonz-lists-djb-qmail@schmonz.com> wrote:

> On 23 May 2017, at 0:21, Manvendra Bhangui wrote:
>
> Nice and quite useful. Have done exactly the same. I use the same variable
>> QMAILREMOTE. Additionally, I have modified qmail-lspawn.c to use
>> QMAILLOCAL
>> and call a binary other than qmail-local. Use it for doing DKIM
>> verification.
>>
>
> Makes sense. If my friend gets around to wanting to verify DKIM on
> incoming messages, we'll want that. Have you posted these patches somewhere
> stable?
>
> I use the variables QMAILLOCAL and QMAILREMOTE to run some filters before
>> the actual delivery attempt.
>>
>
> Would you be willing to share some of your filters? I'm curious to see
> examples (besides DKIM) of what qmail-{remote,local} wrappers can be used
> for.
>

It is posted here.
dkim-netqmail-1.06.patch-1.18.gz
<https://sourceforge.net/projects/indimail/files/netqmail-addons/qmail-dkim-1.0/dkim-netqmail-1.06.patch-1.18.gz/download>

<https://sourceforge.net/projects/indimail/files/netqmail-addons/qmail-dkim-1.0/dkim-netqmail-1.06.patch-1.18.gz/download>Full
instructions to use it is available here.

https://notes.sagredo.eu/node/92

The change I have made, uses QMAILLOCAL and QMAILREMOTE to call a program
called spawn-filter. You can define it to anything else. For remote
deliveries spawn-filter calls qmail-remote. For local deliveries,
spawn-filter calls qmail-local. It uses a control file
/var/qmail/control/filterargs. filterargs control file is like this

example.com:remote:grep -v ^DKIM-SIGNATURE
*:remote:dk-filter
mydomain.com:local:grep -v ^X-Forwarded

NOTE: spawn-filter uses sh -c to call the commands, hence filterargs can
contain any shell code snippet.

The first line causes spawn-filter to strip out DKIM-Signature before
sending any email to example.com
The second line causes spawn-filter to call dk-filter and feed the output
of dk-filter to qmail-remote for all remote deliveries. dk-filter is a
small shell script which adds DKIM-Signature to the email
The 3rd line simply strips out X-Forwarded line for local deliveries to
mydomain.com

If there is no match, the email passes unchanged to qmail-local or
qmail-remote
spawn-filter can also be used to ratelimit emails to certain domains. I
used it for yahoo.com. There is a man page too. But off course, you need
not use spawn-filter at all and are free to set QMAILLOCAL or QMAILREMOTE
as per your requirement.

The latest code can be obtained from (git) can be browsed here. You can
look at qmail-lspawn.c, qmail-rspawn.c, spawn-filter.c at

https://sourceforge.net/p/indimail/code/ci/master/tree/qmail-1.03/

--
Regards Manvendra - http://www.indimail.org
GPG Pub Key
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC7CBC760014D250C