SOURCES: qmail-dkeys-shared.patch (NEW), qmail-1.03-dk-0.53.patch ...

glen glen at pld-linux.org
Sat Jun 25 17:37:24 CEST 2005


Author: glen                         Date: Sat Jun 25 15:37:24 2005 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- domainkeys support

---- Files affected:
SOURCES:
   qmail-dkeys-shared.patch (NONE -> 1.1)  (NEW), qmail-1.03-dk-0.53.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/qmail-dkeys-shared.patch
diff -u /dev/null SOURCES/qmail-dkeys-shared.patch:1.1
--- /dev/null	Sat Jun 25 17:37:24 2005
+++ SOURCES/qmail-dkeys-shared.patch	Sat Jun 25 17:37:19 2005
@@ -0,0 +1,29 @@
+--- qmail-1.03/Makefile~	2005-06-25 18:29:31.000000000 +0300
++++ qmail-1.03/Makefile	2005-06-25 18:29:33.000000000 +0300
+@@ -1116,13 +1116,13 @@
+ load qmail-dk.o triggerpull.o fmtqfn.o now.o date822fmt.o \
+ datetime.a seek.a ndelay.a open.a sig.a alloc.a substdio.a error.a \
+ str.a fs.a auto_qmail.o auto_split.o auto_uids.o fd.a wait.a \
+-../libdomainkeys.a env.a getln.a control.o stralloc.a dns.lib
++env.a getln.a control.o stralloc.a dns.lib
+ 	./load qmail-dk triggerpull.o fmtqfn.o now.o \
+ 	date822fmt.o datetime.a seek.a ndelay.a open.a sig.a \
+ 	substdio.a error.a fs.a auto_qmail.o \
+ 	auto_split.o auto_uids.o \
+ 	fd.a wait.a \
+-        ../libdomainkeys.a -lcrypto env.a control.o open.a getln.a \
++        -ldomainkeys -lcrypto env.a control.o open.a getln.a \
+ 	stralloc.a alloc.a  scan_ulong.o str.a `cat dns.lib`
+ 
+ qmail-dk.0: \
+--- qmail-1.03/qmail-dk.c~	2005-06-25 18:20:14.000000000 +0300
++++ qmail-1.03/qmail-dk.c	2005-06-25 18:30:45.000000000 +0300
+@@ -20,7 +20,7 @@
+ #include "fmtqfn.h"
+ #include "env.h"
+ #include "control.h"
+-#include "../domainkeys.h"
++#include <domainkeys.h>
+ 
+ #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */
+ #define ADDR 1003

================================================================
Index: SOURCES/qmail-1.03-dk-0.53.patch
diff -u /dev/null SOURCES/qmail-1.03-dk-0.53.patch:1.1
--- /dev/null	Sat Jun 25 17:37:24 2005
+++ SOURCES/qmail-1.03-dk-0.53.patch	Sat Jun 25 17:37:19 2005
@@ -0,0 +1,492 @@
+This patch can be used to create qmail-dk.
+
+
+#fetch libdomainkeys from http://sourceforge.net/projects/domainkeys/
+tar xfz libdomainkeys-0.62.tar.gz
+cd libdomainkeys-0.62
+make
+tar xfz /path/to/qmail-1.03.tar.gz
+cd qmail-1.03
+patch <this-patch-file
+make qmail-dk
+cp qmail-dk /var/qmail/bin/
+
+Then to use it you have to set some environment variables in the
+programs that (ultimately) invoke qmail-queue.  If you are running
+netqmail-1.05, or otherwise have the qmailqueue patch installed, you
+can invoke it like this:
+
+65.172.240.33-62:allow,RELAYCLIENT="",DKSIGN="/etc/domainkeys/dog",QMAILQUEUE="b
+in/qmail-dk"
+192.203.178.:allow,DKVERIFY="DEGIJKfh",QMAILQUEUE="bin/qmail-dk"
+
+Or, if you don't, then you have a little bit of extra work to do:
+  ln /var/qmail/bin/qmail-queue /var/qmail/bin/qmail-queue.orig
+  ln /var/qmail/bin/qmail-dk /var/qmail/bin/qmail-queue.new
+  mv /var/qmail/bin/qmail-queue.new /var/qmail/bin/qmail-queue
+
+Then, when you invoke the qmail-dk program as qmail-queue, it invokes
+qmail-queue.orig instead.
+
+diff -u orig/Makefile ./Makefile
+--- orig/Makefile	1998-06-15 06:53:16.000000000 -0400
++++ ./Makefile	2004-08-22 23:40:19.000000000 -0400
+@@ -808,6 +808,7 @@
+ forward preline condredirect bouncesaying except maildirmake \
+ maildir2mbox maildirwatch qail elq pinq idedit install-big install \
+ instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \
++qmail-dk \
+ binm3 binm3+df
+ 
+ load: \
+@@ -1107,6 +1108,30 @@
+ 	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+ 	> qmail-control.5
+ 
++qmail-dk: \
++load qmail-dk.o triggerpull.o fmtqfn.o now.o date822fmt.o \
++datetime.a seek.a ndelay.a open.a sig.a alloc.a substdio.a error.a \
++str.a fs.a auto_qmail.o auto_split.o auto_uids.o fd.a wait.a \
++../libdomainkeys.a env.a getln.a control.o stralloc.a dns.lib
++	./load qmail-dk triggerpull.o fmtqfn.o now.o \
++	date822fmt.o datetime.a seek.a ndelay.a open.a sig.a \
++	substdio.a error.a fs.a auto_qmail.o \
++	auto_split.o auto_uids.o \
++	fd.a wait.a \
++        ../libdomainkeys.a -lcrypto env.a control.o open.a getln.a \
++	stralloc.a alloc.a  scan_ulong.o str.a `cat dns.lib`
++
++qmail-dk.0: \
++qmail-dk.8
++	nroff -man qmail-dk.8 > qmail-dk.0
++
++qmail-dk.o: \
++compile qmail-dk.c readwrite.h sig.h exit.h open.h seek.h fmt.h \
++alloc.h substdio.h datetime.h now.h datetime.h triggerpull.h extra.h \
++env.h wait.h fd.h fork.h str.h \
++auto_qmail.h auto_uids.h date822fmt.h fmtqfn.h
++	./compile qmail-dk.c
++
+ qmail-getpw: \
+ load qmail-getpw.o case.a substdio.a error.a str.a fs.a auto_break.o \
+ auto_usera.o
+diff -u orig/qmail-dk.8 ./qmail-dk.8
+--- orig/qmail-dk.8	2004-08-22 21:15:13.000000000 -0400
++++ ./qmail-dk.8	2004-10-05 20:25:01.000000000 -0400
+@@ -0,0 +1,115 @@
++.TH qmail-dk 8
++.SH NAME
++qmail-dk \- sign/verify and queue a mail message for delivery
++.SH SYNOPSIS
++.B qmail-dk
++.SH DESCRIPTION
++.B qmail-dk
++has the same interface as
++.B qmail-queue
++except that it inserts an appropriate DomainKeys header before it
++queues the message.  There are two separate ways to invoke
++.BR qmail-dk .
++For one way, you can patch qmail with the http://qmail.org/qmailqueue
++patch and set QMAILQUEUE to point to qmail-dk in the environment when
++you send or receive email.
++For another way, you can rename qmail-queue to qmail-queue.orig, and set DKQUEUE=bin/qmail-queue.orig.
++
++.B qmail-dk
++supports DomainKey signing and verification.  It uses the libdomainkey
++and OpenSSL libraries.  To sign a message, set the
++.B DKSIGN
++environment variable to the pathname to the private key that will be
++used to sign the message.  If there is a % character in the environment
++variable, it is removed and replaced by the domain name in the From: header.
++If, after substituting the %, that file does not exist, the message will not be signed.
++If there is no % and the file does not exist, the message will be rejected with error 32.
++The selector will be taken from the
++basename of the file.  The private key should be created by 
++.BR dknewkey ,
++which comes with libdomainkey.
++
++To verify a message, set the
++.B DKVERIFY
++environment variable to a desired set of letters.  Precisely, if you
++want a libdomainkey return status to generate an error, include that
++letter, where A is the first return status (DK_STAT_OK), B is the
++second (DK_STAT_BADSIG), etc.  The letter should be uppercase if you
++want a permanent error to be returned (exit code 13), and lowercase if
++you want a temporary error to be returned (exit code 82).
++
++For example, if you want to permanently reject messages that have a
++signature that has been revoked, include the letter 'K' in the
++.B DKVERIFY
++environment variable.  A conservative set of letters is
++.BR DEGIJKfh .
++Reject permanently BADSIG, NOKEY, BADKEY, SYNTAX, ARGS, REVOKED, and
++INTERNAL errors, and temporarily CANTVRFY and NORESOURCE.  Add in
++.B B
++if you want to reject messages that have a signature that doesn't
++verify (presumably because the message is a forgery or has been
++damaged in transit.  Note that
++.B qmail-dk
++always inserts the 
++.B DomainKey-Status
++header, so that messages can be
++rejected at delivery time, or in the mail reader.
++
++Typically, you would sign messages generated on-host by setting
++.B DKSIGN
++in the environment before running an email program.  DKSIGN will be carried
++through qmail's sendmail emulation through 
++.B qmail-inject
++to
++.BR qmail-dk .
++You would also set it for
++.B qmail-smtpd
++at the same time
++.B RELAYCLIENT
++is set, most often in the tcpserver cdb file.  If a host is authorized
++to relay, you probably want to sign messages sent by that host.
++.B DKVERIFY
++should be set for all other hosts.
++
++If neither
++.B DKSIGN
++nor
++.B DKVERIFY
++are set, then
++.B DKSIGN
++will be set to /etc/domainkeys/%/default.  If such a private key exists, it will be used to sign the domain.
++
++.B qmail-dk
++will ordinarily spawn qmail-queue, but if DKQUEUE is set in the environment,
++the program that it points to will be executed instead.  If DKQUEUE is not set, and
++.B qmail-dk
++has been invoked as
++.B qmail-queue
++then
++.B qmail-queue.orig
++is spawned instead.
++
++.SH "EXIT CODES"
++.B qmail-dk
++returns the same exit codes as qmail-queue with these additions:
++.TP 5
++.B 32
++The private key file does not exist.
++.TP 5
++.B 57
++Trouble waiting for qmail-queue to exit.
++.TP 5
++.B 58
++Unable to vfork.
++.TP 5
++.B 59
++Unable to create a pipe to qmail-queue.
++.SH "SEE ALSO"
++addresses(5),
++envelopes(5),
++qmail-header(5),
++qmail-inject(8),
++qmail-qmqpc(8),
++qmail-queue(8),
++qmail-send(8),
++qmail-smtpd(8)
+diff -u orig/qmail-dk.c ./qmail-dk.c
+--- orig/qmail-dk.c	2004-08-22 21:15:17.000000000 -0400
++++ ./qmail-dk.c	2004-10-19 18:08:49.000000000 -0400
+@@ -0,0 +1,297 @@
++#include <sys/types.h>
++#include "readwrite.h"
++#include "sig.h"
++#include "exit.h"
++#include "open.h"
++#include "seek.h"
++#include "fmt.h"
++#include "alloc.h"
++#include "str.h"
++#include "stralloc.h"
++#include "substdio.h"
++#include "datetime.h"
++#include "now.h"
++#include "fork.h"
++#include "wait.h"
++#include "extra.h"
++#include "auto_qmail.h"
++#include "auto_uids.h"
++#include "date822fmt.h"
++#include "fmtqfn.h"
++#include "env.h"
++#include "control.h"
++#include "../domainkeys.h"
++
++#define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */
++#define ADDR 1003
++
++char inbuf[2048];
++struct substdio ssin;
++char outbuf[256];
++struct substdio ssout;
++
++datetime_sec starttime;
++struct datetime dt;
++unsigned long mypid;
++unsigned long uid;
++char *pidfn;
++int messfd;
++int readfd;
++
++void die(e) int e; { _exit(e); }
++void die_write() { die(53); }
++void die_read() { die(54); }
++void sigalrm() { /* thou shalt not clean up here */ die(52); }
++void sigbug() { die(81); }
++void maybe_die_dk(e) DK_STAT e; {
++  switch(e) {
++  case DK_STAT_BADKEY: _exit(55);
++  case DK_STAT_CANTVRFY: _exit(74);
++  case DK_STAT_NORESOURCE: _exit(51);
++  case DK_STAT_ARGS: _exit(12);
++  case DK_STAT_INTERNAL: _exit(81);
++  }
++}
++
++unsigned int pidfmt(s,seq)
++char *s;
++unsigned long seq;
++{
++ unsigned int i;
++ unsigned int len;
++
++ len = 0;
++ i = fmt_str(s,"/tmp/qmail-dk."); len += i; if (s) s += i;
++ i = fmt_ulong(s,mypid); len += i; if (s) s += i;
++ i = fmt_str(s,"."); len += i; if (s) s += i;
++ i = fmt_ulong(s,starttime); len += i; if (s) s += i;
++ i = fmt_str(s,"."); len += i; if (s) s += i;
++ i = fmt_ulong(s,seq); len += i; if (s) s += i;
++ ++len; if (s) *s++ = 0;
++
++ return len;
++}
++
++void pidopen()
++{
++ unsigned int len;
++ unsigned long seq;
++
++ seq = 1;
++ len = pidfmt((char *) 0,seq);
++ pidfn = alloc(len);
++ if (!pidfn) die(51);
++
++ for (seq = 1;seq < 10;++seq)
++  {
++   if (pidfmt((char *) 0,seq) > len) die(81); /* paranoia */
++   pidfmt(pidfn,seq);
++   messfd = open_excl(pidfn);
++   if (messfd != -1) return;
++  }
++
++ die(63);
++}
++
++char tmp[FMT_ULONG];
++
++char *dksign = 0;
++stralloc dksignature = {0};
++stralloc dkoutput = {0};
++char *dkverify = 0;
++char *dkqueue = 0;
++DK_LIB *dklib;
++DK *dk;
++DK_STAT st;
++
++static void write_signature(DK *dk, char *keyfn)
++{
++ char advice[2048];
++ char *selector;
++ char *from;
++ static stralloc keyfnfrom = {0};
++ int i;
++
++ from = dk_from(dk);
++ i = str_chr(keyfn, '%');
++ if (keyfn[i]) {
++   if (!stralloc_copyb(&keyfnfrom,keyfn,i)) die(51);
++   if (!stralloc_cats(&keyfnfrom,from)) die(51);
++   if (!stralloc_cats(&keyfnfrom,keyfn + i + 1)) die(51);
++ } else {
++   if (!stralloc_copys(&keyfnfrom,keyfn)) die(51);
++ }
++ if (!stralloc_0(&keyfnfrom)) die(51);
++
++ switch(control_readfile(&dksignature,keyfnfrom.s,0)) {
++ case 0:
++   if (keyfn[i]) return;
++   die(32);
++ case 1: break;
++ default: die(31);
++ }
++ for(i=0; i < dksignature.len; i++)
++   if (dksignature.s[i] == '\0') dksignature.s[i] = '\n';
++ if (!stralloc_0(&dksignature)) die(51);
++
++ st = dk_getsig(dk, dksignature.s, advice, sizeof(advice));
++ maybe_die_dk(st);
++
++ if (!stralloc_cats(&dkoutput,
++   "Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys\n"
++	   "DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;\n"
++	   "  s=")) die(51);
++ selector = keyfn;
++ while (*keyfn) {
++   if (*keyfn == '/') selector = keyfn+1;
++    keyfn++;
++ }
++ if (!stralloc_cats(&dkoutput,selector)) die(51);
++ if (!stralloc_cats(&dkoutput,"; d=")) die(51);
++ if (from) {
++   if (!stralloc_cats(&dkoutput,from)) die(51);
++ } else if (!stralloc_cats(&dkoutput,"unknown")) die(51);
++ if (!stralloc_cats(&dkoutput,";\n  b=")) die(51);
++ if (!stralloc_cats(&dkoutput,advice)) die(51);
++ if (!stralloc_cats(&dkoutput,"  ;\n")) die(51);
++}
++
++static char *binqqargs[2] = { "bin/qmail-queue", 0 } ;
++
++void main(int argc, char *argv[])
++{
++ unsigned int len;
++ char ch;
++ int pim[2];
++ int wstat;
++ unsigned long pid;
++
++ sig_blocknone();
++ umask(033);
++
++ dksign = env_get("DKSIGN");
++ dkverify = env_get("DKVERIFY");
++ if (!dksign && !dkverify)
++   dksign = "/etc/domainkeys/%/default";
++
++ dkqueue = env_get("DKQUEUE");
++ if (dkqueue && *dkqueue) binqqargs[0] = dkqueue;
++ else if (str_equal(argv[0]+str_rchr(argv[0], '/'), "/qmail-queue"))
++   binqqargs[0] = "bin/qmail-queue.orig";
++
++ if (dksign || dkverify) {
++   dklib = dk_init(0);
++   if (!dklib) die(51);
++ }
++ if (dksign) {
++    dk = dk_sign(dklib, &st, DK_CANON_NOFWS);
++    if (!dk) die(31);
++ } else if (dkverify) {
++    dk = dk_verify(dklib, &st);
++    if (!dk) die(31);
++ }
++
++ mypid = getpid();
++ uid = getuid();
++ starttime = now();
++ datetime_tai(&dt,starttime);
++
++ sig_pipeignore();
++ sig_miscignore();
++ sig_alarmcatch(sigalrm);
++ sig_bugcatch(sigbug);
++
++ alarm(DEATH);
++
++ pidopen();
++ readfd = open_read(pidfn);
++ if (unlink(pidfn) == -1) die(63);
++
++ substdio_fdbuf(&ssout,write,messfd,outbuf,sizeof(outbuf));
++ substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
++
++ for (;;) {
++   register int n;
++   register char *x;
++   int i;
++
++   n = substdio_feed(&ssin);
++   if (n < 0) die_read();
++   if (!n) break;
++   x = substdio_PEEK(&ssin);
++   if (dksign || dkverify)
++     for(i=0; i < n; i++) {
++       if (x[i] == '\n') st = dk_message(dk, "\r\n", 2);
++       else st = dk_message(dk, x+i, 1);
++       maybe_die_dk(st);
++      }
++   if (substdio_put(&ssout,x,n) == -1) die_write();
++   substdio_SEEK(&ssin,n);
++ }
++
++ if (substdio_flush(&ssout) == -1) die_write();
++
++ if (dksign || dkverify) {
++   st = dk_eom(dk, (void *)0);
++   maybe_die_dk(st);
++   if (dksign) {
++     write_signature(dk, dksign);
++   } else if (dkverify) {
++     char *status;
++     if (!stralloc_copys(&dkoutput,"DomainKey-Status: ")) die(51);
++     switch(st) {
++     case DK_STAT_OK:         status = "good        "; break;
++     case DK_STAT_BADSIG:     status = "bad         "; break;
++     case DK_STAT_NOSIG:      status = "no signature"; break;
++     case DK_STAT_NOKEY:
++     case DK_STAT_CANTVRFY:   status = "no key      "; break;
++     case DK_STAT_BADKEY:     status = "bad key     "; break;
++     case DK_STAT_INTERNAL:
++     case DK_STAT_ARGS:
++     case DK_STAT_SYNTAX:     status = "bad format  "; break;
++     case DK_STAT_NORESOURCE: status = "no resources"; break;
++     case DK_STAT_REVOKED:    status = "revoked     "; break;
++     }
++     if (!stralloc_cats(&dkoutput,status)) die(51);
++     if (!stralloc_cats(&dkoutput,"\n")) die(51);
++     if (dkverify[str_chr(dkverify, 'A'+st)]) die(13);
++     if (dkverify[str_chr(dkverify, 'a'+st)]) die(82);
++   }
++ }
++
++ if (pipe(pim) == -1) die(59);
++ 
++ switch(pid = vfork()) {
++ case -1:
++   close(pim[0]); close(pim[1]);
++   die(58);
++ case 0:
++   close(pim[1]);
++   if (fd_move(0,pim[0]) == -1) die(120);
++   if (chdir(auto_qmail) == -1) die(61);
++   execv(*binqqargs,binqqargs);
++   die(120);
++ }
++
++ close(pim[0]);
++
++ substdio_fdbuf(&ssin,read,readfd,inbuf,sizeof(inbuf));
++ substdio_fdbuf(&ssout,write,pim[1],outbuf,sizeof(outbuf));
++
++ if (substdio_bput(&ssout,dkoutput.s,dkoutput.len) == -1) die_write();
++ switch(substdio_copy(&ssout,&ssin))
++  {
++   case -2: die_read();
++   case -3: die_write();
++  }
++
++ if (substdio_flush(&ssout) == -1) die_write();
++ close(pim[1]);
++
++ if (wait_pid(&wstat,pid) != pid)
++   die(57);
++ if (wait_crashed(wstat))
++   die(57);
++ die(wait_exitcode(wstat));
++
++}
================================================================



More information about the pld-cvs-commit mailing list