notqmail logo

smtpauth

patch - info

This patch was originally for netqmail-1.03 as a tar archive with multiple files mixed with multiple patches. It have been applied on top of diff` file.

diff --git a/FILES.auth b/FILES.auth
new file mode 100644
index 0000000..e9c4b44
--- /dev/null
+++ b/FILES.auth
@@ -0,0 +1,27 @@
+The qmail-smtpd Auth patch modifies the following QMAIL 1.03 files:
+
+= TARGETS
+= Makefile
+= qmail-smtpd.c
+= qmail-smtpd.8
+= qmail-remote.c
+= qmail-remote.8
+= qmail-showctl.c
+= qmail-control.9
+
+Added files:
+
++ base64.c
++ base64.h
++ case_startb.c
++ hmac_md5.h
++ hmac_md5.c
++ global.h
++ md5.h
++ md5c.c
+
+Informational files:
+
+% install_auth.sh  (Installation shell script)
+% LICENSE.authentication (some sort of ...)
+% README.auth
diff --git a/LICENSE.authentication b/LICENSE.authentication
new file mode 100644
index 0000000..ee95da6
--- /dev/null
+++ b/LICENSE.authentication
@@ -0,0 +1,43 @@
+AUTHOR
+======
+
+Author:
+	Dr. Erwin Hoffmann - FEHCom Germany
+Web-Site:
+	http://www.fehcom.de/qmail.html
+E-Mail:
+	feh@fehcom.de
+
+
+LICENSE
+=======
+
+qmail AUTHENTICATION is free software.
+This includes:
+	You can download and use qmail AUTHENTICATION (and parts of it) as you like.
+	You can modify the source code without notification to or permission by the author.
+Please check:
+	http://www.cr.yp.to/softwarelaw.html
+
+
+DEPENDENCIES
+============
+
+qmail AUTHENTICATION patches (modifies) parts of the qmail-1.03 source files.
+It should only be applied against the source as supplied by D.J. Bernstein.
+
+
+FITNESS
+=======
+
+The Author does not guarantee a specific fitness of qmail AUTHENTICATION.
+If you use qmail AUTHENTICATION, it's on your own risk.
+
+
+DISTRIBUTION
+============
+
+qmail AUTHENTICATION may be included in ports and packages under the following conditions:
+	The port/package has to show the current version number of qmail AUTHENTICATION.
+	All files (namely this) have to be included.
+
diff --git a/Makefile b/Makefile
index 0f0e31a..ca58373 100644
--- a/Makefile
+++ b/Makefile
@@ -136,6 +136,18 @@ auto_usera.o: \
 compile auto_usera.c
 	./compile auto_usera.c
 
+base64.o: \
+compile base64.c base64.h stralloc.h substdio.h str.h
+	./compile base64.c
+
+md5c.o : \
+compile md5c.c md5.h
+	./compile md5c.c
+
+hmac_md5.o : \
+compile hmac_md5.c hmac_md5.h global.h
+	./compile hmac_md5.c
+
 binm1: \
 binm1.sh conf-qmail
 	cat binm1.sh \
@@ -1441,12 +1453,15 @@ qmail-remote: \
 load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \
 timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o ipme.o quote.o \
 ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \
-substdio.a error.a str.a fs.a auto_qmail.o dns.lib socket.lib
+substdio.a error.a str.a fs.a auto_qmail.o \
+base64.o md5c.o hmac_md5.o \
+dns.lib socket.lib
 	./load qmail-remote control.o constmap.o timeoutread.o \
 	timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \
 	ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \
 	lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \
-	str.a fs.a auto_qmail.o  `cat dns.lib` `cat socket.lib`
+	base64.o md5c.o hmac_md5.o \
+	str.a fs.a auto_qmail.o `cat dns.lib` `cat socket.lib`
 
 qmail-remote.0: \
 qmail-remote.8
@@ -1536,12 +1551,12 @@ load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \
 timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
 date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
 open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \
-fs.a auto_qmail.o socket.lib
+fs.a auto_qmail.o base64.o socket.lib
 	./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
 	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
 	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
 	datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
-	alloc.a substdio.a error.a str.a fs.a auto_qmail.o  `cat \
+	alloc.a substdio.a error.a str.a fs.a auto_qmail.o base64.o  `cat \
 	socket.lib`
 
 qmail-smtpd.0: \
@@ -1553,7 +1568,7 @@ compile qmail-smtpd.c sig.h readwrite.h stralloc.h gen_alloc.h \
 substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \
 error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \
 substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
-exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h
+exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h base64.h
 	./compile qmail-smtpd.c
 
 qmail-start: \
diff --git a/README.auth b/README.auth
new file mode 100644
index 0000000..0a014b5
--- /dev/null
+++ b/README.auth
@@ -0,0 +1,154 @@
+README qmail SMTP Authentication
+================================
+
+Scope:
+------
+
+This patch supports RFC 2554 "SMTP Service Extension for Authentication" and
+RFC 4409 "Message Submission for Mail" for
+
+* qmail-smtpd and
+* qmail-remote
+
+and supports commonly the AUTH methods
+
+- CRAM-MD5
+- LOGIN (unsecure)
+- PLAIN (unsecure)
+
+Additionally, RFC 1870 is honoured ("SMTP Service Extension for Message Size Declaration").
+For more technical details see: http://www.fehcom.de/qmail/docu/smtpauth.html.
+
+
+Installation:
+-------------
+
+* Untar the source in the qmail-1.03 home direcotry.
+* Run ./install_auth.
+* Re-make qmail.
+
+
+Setup for qmail-smtpd:
+----------------------
+
+1. Prereqs:
+
+In order to use SMTP Authentication you have to use a 'Pluggable Authentication Module'
+PAM to be called by qmail-smtpd; typically
+
+	/var/qmail/bin/qmail-smtpd /bin/checkpassword true 2>&1
+
+Since qmail-smtpd does not run as root, checkpassword has to be made sticky.
+There is no need to include additionally the hostname in the call.
+In order to compute the CRAM-MD5 challenge, qmail-smtpd uses the 'tcplocalhost' information.
+
+2. Invocation:
+
+In order activate SMTP authentication, you need to provide the environment
+variable 'SMTPAUTH' to qmail-smtpd.
+
+Possible choices:
+	
+	a) SMTPAUTH=""; 	qmail-smtpd supports auth of type PLAIN and/or LOGIN.
+	b) SMTPAUTH="+cram";	qmail-smtpd will additionally annonce CRAM-MD5,
+				this requires a CRAM-MD5 supporting PAM.
+	c) SMTPAUTH="cram";	qmail-smtpd will only annonce CRAM-MD5.
+	d) SMTPAUTH="!";	this instructs qmail-smtpd to require (any type) authentication for this connection.
+				This behavior is equivalent to the Submission feaure.
+	e) SMTPAUTH="!cram";	same as d) but now CRAM-MD5 is the only method instead.
+
+
+Setup for qmail-remote:
+-----------------------
+
+SMTP Authentication with qmail-remote is faclitated by two means:
+
+a) SMTP Authentication by sender/sending domain as provided in the 'Mail From:'
+
+The control file 'authsenders' which works similar to 'control/smtproutes'
+but with additional authentication information (username + password):
+
+    @example.com:relay.example.com|user|passwd
+    info@example.com:relay.example.com:26|infouser|infopasswd
+    :mailrelay.example.com:587|e=mc2|testpass
+
+Note: The choice of the AUTH method depends on the capabilities of the server.
+
+b) SMTP Authentication by recipient domain:
+
+The control file 'smtproutes' is enhanced with the authentication information:
+
+    authdomain.com:mx.authdomain.com:125|myuserid|mypassword
+    :mailrelay.example.com:587|e=mc2|testpass
+
+
+Historical Notes:
+-----------------
+
+SMTP authentication for qmail-smtpd was initially provided by Krysztof Dabrowski (version 0.31):
+
+
+Changes wrt. Krysztof Dabrowski's patch:
+
+* Avoid the 'hostname' in the call of the PAM.
+* Confirm to Dan Bernstein's checkpassword interface even for CRAM-MD5.
+* Doesn't close FD 2; thus not inhibiting logging to STDERR.
+* Fixed bugs in base64.c.
+* Modified unconditional close of FD 3 in order to sustain reading of 'control/morecpthosts.cdb'.
+* Evaluation of the (informational) Mail From: < > Auth=username.
+* Additional support for the advertised "Size" via 'Mail From: <return-path> SIZE=123456780' (RFC 1870).
+* RFC 3848 conformance for Received header in case of SMTP Auth (keyword ESMTPA).
+* Added SMTPAUTH environment variable.
+* The particular Submission feature has been removed; obsolete.
+
+
+SMTP authentication for qmail-remote is taken from Bjoern Kalkbrenner.
+
+Changes wrt. Bjoern Kalkbrenner's patch (version 0.0.1 / 20020715):
+
+* Uniform, modular support for LOGIN and PLAIN.
+* Added 'Mail From: < > Auth=username' information in provisionally XTEXT format.
+* Added CRAM-MD5 support.
+* Added authentication by recipient domain.
+
+
+Release Notes:
+--------------
+
+Version:	Notes:					Date:
+-------------------------------------------------------------------
+0.5.9		qmail-smtpd AUTH (only)			25.3.2008
+0.6.9		qmail-authentication			1.2.2010
+0.7.0		Based on qmail-authentication 0.69
+		including now CRAM-MD5 support
+		for qmail-remote			31.7.2010
+0.7.1		cosmetics for qmail-remote		5.8.2010
+0.7.2		authorization-id = authentication-id
+		for qmail-remote;
+		added SMTPAUTH environment variable
+		for qmail-smtpd; backport from SC 2.7	29.4.2012
+0.7.3		Fixed missing AUTH for qmai-smtpd announcement.
+		Improved SUBMISSION port handling.	2.5.2012
+0.7.4		Fixed missing 250 statements for AUTH.
+		Changed SMTPAUTH settings for cram-md5 	18.5.2012
+0.7.5		Fixed bug in qmail-remote not respecting
+		announced AUTH types. Tx. Callum Gibson.
+		Added '432' server code evaluation for
+	 	AUTH password expired in qmail-remote. 	23.10.2012
+0.7.6		Fixed order of SMTP commands (tx roberto).
+							02.02.2013
+0.8.0		Added authentication by recipient domain
+		for qmail-remote.
+		Removed SUBMISSION port feature for
+		qmail-smtpd.				22.03.2013
+0.8.1		Added SMTPAUTH="!+crom" feature.	24.03.2013
+0.8.2		Bug fix: qmail-smtpd ACCEPTS auth commands
+		even if SMTPAUTH="-". (tx chris).	21.01.2015
+0.8.3		Fixed bug in MD5 calculation for AMD64.
+		Fixed 'die_nomem' bug in qmail-smtpd.	23.08.2015
+
+
+
+Erwin Hoffmann - Hoehn 2015-08-23 (www.fehcom.de)
+
+
diff --git a/TARGETS b/TARGETS
index facdad7..4cba994 100644
--- a/TARGETS
+++ b/TARGETS
@@ -10,6 +10,7 @@ qmail-local.o
 qmail.o
 quote.o
 now.o
+base64.o
 gfrom.o
 myctime.o
 slurpclose.o
@@ -182,6 +183,8 @@ dns.lib
 qmail-remote
 qmail-rspawn.o
 tcpto_clean.o
+md5c.o
+hmac_md5.o
 qmail-rspawn
 direntry.h
 qmail-clean.o
diff --git a/base64.c b/base64.c
new file mode 100644
index 0000000..9784755
--- /dev/null
+++ b/base64.c
@@ -0,0 +1,124 @@
+#include "base64.h"
+#include "stralloc.h"
+#include "substdio.h"
+#include "str.h"
+
+static char *b64alpha =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+#define B64PAD '='
+
+/* returns 0 ok, 1 illegal, -1 problem */
+
+int b64decode(in,l,out)
+const unsigned char *in;
+int l;
+stralloc *out; /* not null terminated */
+{
+  int p = 0;
+  int n;
+  unsigned int x;
+  int i, j;
+  char *s;
+  unsigned char b[3];
+
+  if (l == 0)
+  {
+    if (!stralloc_copys(out,"")) return -1;
+    return 0;
+  }
+
+  while(in[l-1] == B64PAD) {
+    p ++;
+    l--;
+  }
+
+  n = (l + p) / 4;
+  i = (n * 3) - p;
+  if (!stralloc_ready(out,i)) return -1;
+  out->len = i;
+  s = out->s;
+
+  for(i = 0; i < n - 1 ; i++) {
+    x = 0;
+    for(j = 0; j < 4; j++) {
+      if(in[j] >= 'A' && in[j] <= 'Z')
+        x = (x << 6) + (unsigned int)(in[j] - 'A' + 0);
+      else if(in[j] >= 'a' && in[j] <= 'z')
+        x = (x << 6) + (unsigned int)(in[j] - 'a' + 26);
+      else if(in[j] >= '0' && in[j] <= '9')
+        x = (x << 6) + (unsigned int)(in[j] - '0' + 52);
+      else if(in[j] == '+')
+        x = (x << 6) + 62;
+      else if(in[j] == '/')
+        x = (x << 6) + 63;
+      else if(in[j] == '=')
+        x = (x << 6);
+    }
+
+    s[2] = (unsigned char)(x & 255); x >>= 8;
+    s[1] = (unsigned char)(x & 255); x >>= 8;
+    s[0] = (unsigned char)(x & 255); x >>= 8;
+    s += 3; in += 4;
+  }
+
+  x = 0;
+  for(j = 0; j < 4; j++) {
+    if(in[j] >= 'A' && in[j] <= 'Z')
+      x = (x << 6) + (unsigned int)(in[j] - 'A' + 0);
+    else if(in[j] >= 'a' && in[j] <= 'z')
+      x = (x << 6) + (unsigned int)(in[j] - 'a' + 26);
+    else if(in[j] >= '0' && in[j] <= '9')
+      x = (x << 6) + (unsigned int)(in[j] - '0' + 52);
+    else if(in[j] == '+')
+      x = (x << 6) + 62;
+    else if(in[j] == '/')
+      x = (x << 6) + 63;
+    else if(in[j] == '=')
+      x = (x << 6);
+  }
+
+  b[2] = (unsigned char)(x & 255); x >>= 8;
+  b[1] = (unsigned char)(x & 255); x >>= 8;
+  b[0] = (unsigned char)(x & 255); x >>= 8;
+
+  for(i = 0; i < 3 - p; i++)
+    s[i] = b[i];
+
+  return 0;
+}
+
+int b64encode(in,out)
+stralloc *in;
+stralloc *out; /* not null terminated */
+{
+  unsigned char a, b, c;
+  int i;
+  char *s;
+
+  if (in->len == 0)
+  {
+    if (!stralloc_copys(out,"")) return -1;
+    return 0;
+  }
+
+  i = in->len / 3 * 4 + 4;
+  if (!stralloc_ready(out,i)) return -1;
+  s = out->s;
+
+  for (i = 0;i < in->len;i += 3) {
+    a = in->s[i];
+    b = i + 1 < in->len ? in->s[i + 1] : 0;
+    c = i + 2 < in->len ? in->s[i + 2] : 0;
+
+    *s++ = b64alpha[a >> 2];
+    *s++ = b64alpha[((a & 3 ) << 4) | (b >> 4)];
+
+    if (i + 1 >= in->len) *s++ = B64PAD;
+    else *s++ = b64alpha[((b & 15) << 2) | (c >> 6)];
+
+    if (i + 2 >= in->len) *s++ = B64PAD;
+    else *s++ = b64alpha[c & 63];
+  }
+  out->len = s - out->s;
+  return 0;
+}
diff --git a/base64.h b/base64.h
new file mode 100644
index 0000000..a9164c0
--- /dev/null
+++ b/base64.h
@@ -0,0 +1,7 @@
+#ifndef BASE64_H
+#define BASE64_H
+
+extern int b64decode();
+extern int b64encode();
+
+#endif
diff --git a/case_startb.c b/case_startb.c
new file mode 100644
index 0000000..ee88efe
--- /dev/null
+++ b/case_startb.c
@@ -0,0 +1,21 @@
+#include "case.h"
+
+int case_startb(s,len,t)
+register char *s;
+unsigned int len;
+register char *t;
+{
+  register unsigned char x;
+  register unsigned char y;
+
+  for (;;) {
+    y = *t++ - 'A';
+    if (y <= 'Z' - 'A') y += 'a'; else y += 'A';
+    if (!y) return 1;
+    if (!len) return 0;
+    --len;
+    x = *s++ - 'A';
+    if (x <= 'Z' - 'A') x += 'a'; else x += 'A';
+    if (x != y) return 0;
+  }
+}
diff --git a/global.h b/global.h
new file mode 100644
index 0000000..e0cf2dc
--- /dev/null
+++ b/global.h
@@ -0,0 +1,51 @@
+/* GLOBAL.H - RSAREF types and constants */
+
+#include <string.h>
+#include "uint32.h"
+
+/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
+     Inc., created 1991. All rights reserved.
+ */
+
+#ifndef _GLOBAL_H_
+#define _GLOBAL_H_ 1
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+     function argument prototyping.
+   The following makes PROTOTYPES default to 1 if it has not already been
+     defined as 0 with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 1
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+#ifdef UINT32_H
+#define UINT4 uint32
+#endif
+
+#ifndef NULL_PTR
+#define NULL_PTR ((POINTER)0)
+#endif
+
+#ifndef UNUSED_ARG
+#define UNUSED_ARG(x) x = *(&x);
+#endif
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+   If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+     returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+
+#endif /* end _GLOBAL_H_ */
diff --git a/hmac_md5.c b/hmac_md5.c
new file mode 100644
index 0000000..606979d
--- /dev/null
+++ b/hmac_md5.c
@@ -0,0 +1,76 @@
+#include "global.h"
+#include "md5.h"
+
+/*
+** Function: hmac_md5
+*/
+
+void hmac_md5(text, text_len, key, key_len, digest)
+unsigned char*  text;                /* pointer to data stream */
+int             text_len;            /* length of data stream */
+unsigned char*  key;                 /* pointer to authentication key */
+int             key_len;             /* length of authentication key */
+unsigned char   *digest;              /* caller digest to be filled in */
+
+{
+        MD5_CTX context;
+        unsigned char k_ipad[65];    /* inner padding -
+                                      * key XORd with ipad
+                                      */
+        unsigned char k_opad[65];    /* outer padding -
+                                      * key XORd with opad
+                                      */
+        unsigned char tk[16];
+        int i;
+        /* if key is longer than 64 bytes reset it to key=MD5(key) */
+        if (key_len > 64) {
+
+                MD5_CTX      tctx;
+
+                MD5Init(&tctx);
+                MD5Update(&tctx, key, key_len);
+                MD5Final(tk, &tctx);
+
+                key = tk;
+                key_len = 16;
+        }
+
+        /*
+         * the HMAC_MD5 transform looks like:
+         *
+         * MD5(K XOR opad, MD5(K XOR ipad, text))
+         *
+         * where K is an n byte key
+         * ipad is the byte 0x36 repeated 64 times
+         * opad is the byte 0x5c repeated 64 times
+         * and text is the data being protected
+         */
+
+        /* start out by storing key in pads */
+        bzero( k_ipad, sizeof k_ipad);
+        bzero( k_opad, sizeof k_opad);
+        bcopy( key, k_ipad, key_len);
+        bcopy( key, k_opad, key_len);
+
+        /* XOR key with ipad and opad values */
+        for (i=0; i<64; i++) {
+                k_ipad[i] ^= 0x36;
+                k_opad[i] ^= 0x5c;
+        }
+        /*
+         * perform inner MD5
+         */
+        MD5Init(&context);                   /* init context for 1st pass */
+        MD5Update(&context, k_ipad, 64);      /* start with inner pad */
+        MD5Update(&context, text, text_len); /* then text of datagram */
+        MD5Final(digest, &context);          /* finish up 1st pass */
+        /*
+         * perform outer MD5
+         */
+        MD5Init(&context);                   /* init context for 2nd
+                                              * pass */
+        MD5Update(&context, k_opad, 64);     /* start with outer pad */
+        MD5Update(&context, digest, 16);     /* then results of 1st
+                                              * hash */
+        MD5Final(digest, &context);          /* finish up 2nd pass */
+}
diff --git a/hmac_md5.h b/hmac_md5.h
new file mode 100644
index 0000000..8c1d835
--- /dev/null
+++ b/hmac_md5.h
@@ -0,0 +1,11 @@
+
+/* prototypes */
+
+void hmac_md5( unsigned char* text, int text_len, unsigned char* key, int key_len, unsigned char* digest);
+
+/* pointer to data stream */
+/* length of data stream */
+/* pointer to authentication key */
+/* length of authentication key */
+/* caller digest to be filled in */
+
diff --git a/md5.h b/md5.h
new file mode 100644
index 0000000..94774ba
--- /dev/null
+++ b/md5.h
@@ -0,0 +1,49 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+#ifndef _MD5_H_
+#define _MD5_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MD5 context. */
+typedef struct {
+  UINT4 state[4];                                   /* state (ABCD) */
+  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];                         /* input buffer */
+} MD5_CTX;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+  ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/md5c.c b/md5c.c
new file mode 100644
index 0000000..8b0c856
--- /dev/null
+++ b/md5c.c
@@ -0,0 +1,334 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+#include "global.h"
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+  ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+  ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+   Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+    (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+    (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+    (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+    (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+    (a) = ROTATE_LEFT ((a), (s)); \
+    (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context;                                        /* context */
+{
+  context->count[0] = context->count[1] = 0;
+
+  /* Load magic initialization constants.
+   */
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+     operation, processing another message block, and updating the
+     context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context;                                        /* context */
+unsigned char *input;                                /* input block */
+unsigned int inputLen;                     /* length of input block */
+{
+  unsigned int i, index, partLen;
+
+  /* Compute number of bytes mod 64 */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3))
+      < ((UINT4)inputLen << 3))
+    context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+
+  partLen = 64 - index;
+
+  /* Transform as many times as possible.
+   */
+  if (inputLen >= partLen) {
+    MD5_memcpy
+      ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+    MD5Transform (context->state, context->buffer);
+
+    for (i = partLen; i + 63 < inputLen; i += 64)
+      MD5Transform (context->state, &input[i]);
+
+    index = 0;
+  }
+  else
+    i = 0;
+
+  /* Buffer remaining input */
+  MD5_memcpy
+    ((POINTER)&context->buffer[index], (POINTER)&input[i],
+     inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+     the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16];                         /* message digest */
+MD5_CTX *context;                                       /* context */
+{
+  unsigned char bits[8];
+  unsigned int index, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64.
+   */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (index < 56) ? (56 - index) : (120 - index);
+  MD5Update (context, PADDING, padLen);
+
+  /* Append length (before padding) */
+  MD5Update (context, bits, 8);
+
+  /* Store state in digest */
+  Encode (digest, context->state, 16);
+
+  /* Zeroize sensitive information.
+   */
+  MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+  /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+
+  /* Zeroize sensitive information.
+   */
+  MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+     a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4) {
+    output[j] = (unsigned char)(input[i] & 0xff);
+    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+     a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4)
+    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+    output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+    ((char *)output)[i] = (char)value;
+}
diff --git a/qmail-control.9 b/qmail-control.9
index 503ce93..2857813 100644
--- a/qmail-control.9
+++ b/qmail-control.9
@@ -40,6 +40,7 @@ See the corresponding man pages for further details.
 .ta 5c 10c
 control	default	used by
 
+.I authsender	\fR(none)	\fRqmail-remote
 .I badmailfrom	\fR(none)	\fRqmail-smtpd
 .I bouncefrom	\fRMAILER-DAEMON	\fRqmail-send
 .I bouncehost	\fIme	\fRqmail-send
diff --git a/qmail-remote.8 b/qmail-remote.8
index 08bae85..8ab9b93 100644
--- a/qmail-remote.8
+++ b/qmail-remote.8
@@ -53,6 +53,7 @@ does not take options
 and does not follow the
 .B getopt
 standard.
+
 .SH TRANSPARENCY
 End-of-file in SMTP is encoded as dot CR LF.
 A dot at the beginning of a line is encoded as dot dot.
@@ -100,6 +101,73 @@ Message report: permanent failure.
 After this letter comes a human-readable description of
 what happened.
 
+.B qmail-remote
+may use SMTP Authenticaton of type CRAM-MD4, PLAIN, or LOGIN
+(in this order) to connect to remote hosts.
+The following reports are provided:
+.TP 5
+K
+no supported AUTH method found, continuing without authentication.
+.TP 5
+Z
+Connected to
+.I host
+but authentication was rejected (AUTH PLAIN).
+.TP 5
+Z
+Connected to
+.I host
+but unable to base64encode (plain).
+.TP 5
+Z
+Connected to
+.I host
+but authentication was rejected (plain)."
+.TP 5
+Z
+Connected to
+.I host
+but authentication was rejected (AUTH LOGIN).
+.TP 5
+Z
+Connected to
+.I host
+but unable to base64encode user.
+.TP 5
+Z
+Connected to
+.I host
+but authentication was rejected (username).
+.TP 5
+Z
+Connected to
+.I host
+but unable to base64encode pass.
+.TP 5
+Z
+Connected to
+.I host
+but authentication was rejected (AUTH CRAM-MD5).
+Z
+Connected to
+.I host
+but unable to base64decode challenge.
+.TP 5
+Z
+Connected to
+.I host
+but unable to base64encode username+digest.
+.TP 5
+Z
+Connected to
+.I host
+but password expired.
+.TP 5
+Z
+Connected to
+.I host
+but authentication was rejected (username+digest).
+.PP
 The recipient reports will always be printed in the same order as
 .BR qmail-remote 's
 .I recip
@@ -114,6 +182,51 @@ arguments.
 always exits zero.
 .SH "CONTROL FILES"
 .TP 5
+.I authsenders
+Authenticated sender.
+For each
+.I sender
+included in
+.IR authsenders :
+.I sender\fB:\fIrelay\fB:\fIport\fB|\fIuser\fB|\fIpassword
+.B qmail-remote
+will try SMTP Authentication
+of type CRAM-MD5, LOGIN, or PLAIN
+with the provided user name
+.I user
+and password
+.I password
+(the authentication information)
+and eventually relay the
+mail through
+.I relay
+on port
+.IR port .
+The use of
+.I relay
+and
+.I port
+follows the same rules as for
+.IR smtproutes
+Note: In case
+.I sender
+is empty,
+.B qmail-remote
+will try to deliver each outgoing mail
+SMTP authenticated. If the authentication
+information is missing, the mail is
+delivered none-authenticated.
+.I authsenders
+can be constructed as follows:
+
+.EX
+   @example.com|generic|passwd
+   .subdomain.example.com|other|otherpw
+   mail@example.com|test|testpass
+   info@example.com:smtp.example.com:26|other|otherpw
+   :mailrelay.example.com:587|e=mc2|testpass
+.EE
+.TP 5
 .I helohost
 Current host name,
 for use solely in saying hello to the remote SMTP server.
@@ -128,7 +241,9 @@ refuses to run.
 Artificial SMTP routes.
 Each route has the form
 .IR domain\fB:\fIrelay ,
-without any extra spaces.
+or
+.IR domain\fB:\fIrelay\fB|\fIuser\fB|\fIpassword
+in case of authenticated routes without any extra spaces.
 If
 .I domain
 matches
@@ -149,6 +264,7 @@ normal SMTP port, 25:
 
 .EX
    inside.af.mil:firewall.af.mil:26
+  :submission.myrelay.com:587|myuserid|mypasswd
 .EE
 
 .I relay
@@ -177,11 +293,15 @@ any other address is artificially routed to
 The
 .B qmail
 system does not protect you if you create an artificial
-mail loop between machines.
+mail loop between machines.
 However,
 you are always safe using
 .I smtproutes
 if you do not accept mail from the network.
+Note:
+.I authsender
+routes have precedence over
+.IR smtproutes .
 .TP 5
 .I timeoutconnect
 Number of seconds
diff --git a/qmail-remote.c b/qmail-remote.c
index 7d65473..ddc7317 100644
--- a/qmail-remote.c
+++ b/qmail-remote.c
@@ -28,6 +28,7 @@
 #include "timeoutconn.h"
 #include "timeoutread.h"
 #include "timeoutwrite.h"
+#include "base64.h"
 
 #define HUGESMTPTEXT 5000
 
@@ -44,6 +45,16 @@ struct constmap maproutes;
 stralloc host = {0};
 stralloc sender = {0};
 
+stralloc authsenders = {0};
+struct constmap mapauthsenders;
+stralloc user = {0};
+stralloc pass = {0};
+stralloc auth = {0};
+stralloc plain = {0};
+stralloc chal  = {0};
+stralloc slop  = {0};
+char *authsender;
+
 saa reciplist = {0};
 
 struct ip_address partner;
@@ -86,6 +97,12 @@ Sorry. Although I'm listed as a best-preference MX or A for that host,\n\
 it isn't in my control/locals file, so I don't treat it as local. (#5.4.6)\n");
 zerodie(); }
 
+void err_authprot() {
+  out("Kno supported AUTH method found, continuing without authentication.\n");
+  zero();
+  substdio_flush(subfdoutsmall);
+}
+
 void outhost()
 {
   char x[IPFMT];
@@ -216,24 +233,192 @@ void blast()
 
 stralloc recip = {0};
 
+void mailfrom()
+{
+  substdio_puts(&smtpto,"MAIL FROM:<");
+  substdio_put(&smtpto,sender.s,sender.len);
+  substdio_puts(&smtpto,">\r\n");
+  substdio_flush(&smtpto);
+}
+
+stralloc xuser = {0};
+
+int xtext(sa,s,len)
+stralloc *sa;
+char *s;
+int len;
+{
+  int i;
+
+  if(!stralloc_copys(sa,"")) temp_nomem();
+
+  for (i = 0; i < len; i++) {
+    if (s[i] == '=') {
+      if (!stralloc_cats(sa,"+3D")) temp_nomem();
+    } else if (s[i] == '+') {
+        if (!stralloc_cats(sa,"+2B")) temp_nomem();
+    } else if ((int) s[i] < 33 || (int) s[i] > 126) {
+        if (!stralloc_cats(sa,"+3F")) temp_nomem(); /* ok. not correct */
+    } else if (!stralloc_catb(sa,s+i,1)) {
+        temp_nomem();
+    }
+  }
+
+  return sa->len;
+}
+
+void mailfrom_xtext()
+{
+  if (!xtext(&xuser,user.s,user.len)) temp_nomem();
+  substdio_puts(&smtpto,"MAIL FROM:<");
+  substdio_put(&smtpto,sender.s,sender.len);
+  substdio_puts(&smtpto,"> AUTH=");
+  substdio_put(&smtpto,xuser.s,xuser.len);
+  substdio_puts(&smtpto,"\r\n");
+  substdio_flush(&smtpto);
+}
+
+int mailfrom_plain()
+{
+  substdio_puts(&smtpto,"AUTH PLAIN\r\n");
+  substdio_flush(&smtpto);
+  if (smtpcode() != 334) { quit("ZConnected to "," but authentication was rejected (AUTH PLAIN)."); return -1; }
+
+  if (!stralloc_cat(&plain,&user)) temp_nomem(); /* <authorization-id> */
+  if (!stralloc_0(&plain)) temp_nomem();
+  if (!stralloc_cat(&plain,&user)) temp_nomem(); /* <authentication-id> */
+  if (!stralloc_0(&plain)) temp_nomem();
+  if (!stralloc_cat(&plain,&pass)) temp_nomem(); /* password */
+  if (b64encode(&plain,&auth)) quit("ZConnected to "," but unable to base64encode (plain).");
+  substdio_put(&smtpto,auth.s,auth.len);
+  substdio_puts(&smtpto,"\r\n");
+  substdio_flush(&smtpto);
+  if (smtpcode() == 235) { mailfrom_xtext(); return 0; }
+  else if (smtpcode() == 432) { quit("ZConnected to "," but password expired."); return 1; }
+  else { quit("ZConnected to "," but authentication was rejected (plain)."); return 1; }
+
+  return 0;
+}
+
+int mailfrom_login()
+{
+  substdio_puts(&smtpto,"AUTH LOGIN\r\n");
+  substdio_flush(&smtpto);
+  if (smtpcode() != 334) { quit("ZConnected to "," but authentication was rejected (AUTH LOGIN)."); return -1; }
+
+  if (!stralloc_copys(&auth,"")) temp_nomem();
+  if (b64encode(&user,&auth)) quit("ZConnected to "," but unable to base64encode user.");
+  substdio_put(&smtpto,auth.s,auth.len);
+  substdio_puts(&smtpto,"\r\n");
+  substdio_flush(&smtpto);
+  if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (username).");
+
+  if (!stralloc_copys(&auth,"")) temp_nomem();
+  if (b64encode(&pass,&auth)) quit("ZConnected to "," but unable to base64encode pass.");
+  substdio_put(&smtpto,auth.s,auth.len);
+  substdio_puts(&smtpto,"\r\n");
+  substdio_flush(&smtpto);
+  if (smtpcode() == 235) { mailfrom_xtext(); return 0; }
+  else if (smtpcode() == 432) { quit("ZConnected to "," but password expired."); return 1; }
+  else { quit("ZConnected to "," but authentication was rejected (password)."); return 1; }
+}
+
+int mailfrom_cram()
+{
+  int j;
+  unsigned char h;
+  unsigned char digest[16];
+  unsigned char digascii[33];
+  static char hextab[]="0123456789abcdef";
+
+  substdio_puts(&smtpto,"AUTH CRAM-MD5\r\n");
+  substdio_flush(&smtpto);
+  if (smtpcode() != 334) { quit("ZConnected to "," but authentication was rejected (AUTH CRAM-MD5)."); return -1; }
+
+  if (str_chr(smtptext.s+4,' ')) { 			/* Challenge */
+    if(!stralloc_copys(&slop,"")) temp_nomem();
+    if (!stralloc_copyb(&slop,smtptext.s+4,smtptext.len-5)) temp_nomem();
+    if (b64decode(slop.s,slop.len,&chal)) quit("ZConnected to "," but unable to base64decode challenge.");
+  }
+
+  hmac_md5(chal.s,chal.len,pass.s,pass.len,digest);
+
+  for (j = 0;j < 16;j++)				/* HEX => ASCII */
+  {
+    digascii[2*j] = hextab[digest[j] >> 4];
+    digascii[2*j+1] = hextab[digest[j] & 0xf];
+  }
+  digascii[32]=0;
+
+  slop.len = 0;
+  if (!stralloc_copys(&slop,"")) temp_nomem();
+  if (!stralloc_cat(&slop,&user)) temp_nomem();		 /* user-id */
+  if (!stralloc_cats(&slop," ")) temp_nomem();
+  if (!stralloc_catb(&slop,digascii,32)) temp_nomem();   /* digest */
+
+  if (!stralloc_copys(&auth,"")) temp_nomem();
+  if (b64encode(&slop,&auth)) quit("ZConnected to "," but unable to base64encode username+digest.");
+  substdio_put(&smtpto,auth.s,auth.len);
+  substdio_puts(&smtpto,"\r\n");
+  substdio_flush(&smtpto);
+  if (smtpcode() == 235) { mailfrom_xtext(); return 0; }
+  else if (smtpcode() == 432) { quit("ZConnected to "," but password expired."); return 1; }
+  else { quit("ZConnected to "," but authentication was rejected (username+digest)."); return 1; }
+}
+
+void smtp_auth()
+{
+  int i, j;
+
+  for (i = 0; i + 8 < smtptext.len; i += str_chr(smtptext.s+i,'\n')+1)
+    if (!str_diffn(smtptext.s+i+4,"AUTH",4)) {
+      if (j = str_chr(smtptext.s+i+8,'C') > 0)
+        if (case_starts(smtptext.s+i+8+j,"CRAM"))
+          if (mailfrom_cram() >= 0) return;
+
+      if (j = str_chr(smtptext.s+i+8,'P') > 0)
+        if (case_starts(smtptext.s+i+8+j,"PLAIN"))
+          if (mailfrom_plain() >= 0) return;
+
+      if (j = str_chr(smtptext.s+i+8,'L') > 0)
+        if (case_starts(smtptext.s+i+8+j,"LOGIN"))
+          if (mailfrom_login() >= 0) return;
+
+      err_authprot();
+      mailfrom();
+    }
+}
+
 void smtp()
 {
   unsigned long code;
   int flagbother;
   int i;
  
-  if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
+  code = smtpcode();
+  if (code >= 500) quit("DConnected to "," but greeting failed");
+  if (code != 220) quit("ZConnected to "," but greeting failed");
  
-  substdio_puts(&smtpto,"HELO ");
+  substdio_puts(&smtpto,"EHLO ");
   substdio_put(&smtpto,helohost.s,helohost.len);
   substdio_puts(&smtpto,"\r\n");
   substdio_flush(&smtpto);
-  if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
- 
-  substdio_puts(&smtpto,"MAIL FROM:<");
-  substdio_put(&smtpto,sender.s,sender.len);
-  substdio_puts(&smtpto,">\r\n");
-  substdio_flush(&smtpto);
+
+  if (smtpcode() != 250) {
+    substdio_puts(&smtpto,"HELO ");
+    substdio_put(&smtpto,helohost.s,helohost.len);
+    substdio_puts(&smtpto,"\r\n");
+    substdio_flush(&smtpto);
+    code = smtpcode();
+    if (code >= 500) quit("DConnected to "," but my name was rejected");
+    if (code != 250) quit("ZConnected to "," but my name was rejected");
+  }
+
+  if (user.len && pass.len)
+    smtp_auth();
+  else
+    mailfrom();
+
   code = smtpcode();
   if (code >= 500) quit("DConnected to "," but sender was rejected");
   if (code >= 400) quit("ZConnected to "," but sender was rejected");
@@ -324,48 +509,102 @@ void getcontrols()
     case 1:
       if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break;
   }
+
+  switch(control_readfile(&authsenders,"control/authsenders",0)) {
+    case -1:
+       temp_control();
+    case 0:
+      if (!constmap_init(&mapauthsenders,"",0,1)) temp_nomem(); break;
+    case 1:
+      if (!constmap_init(&mapauthsenders,authsenders.s,authsenders.len,1)) temp_nomem(); break;
+  }
 }
 
-void main(argc,argv)
+int main(argc,argv)
 int argc;
 char **argv;
 {
   static ipalloc ip = {0};
-  int i;
+  int i, j;
   unsigned long random;
   char **recips;
   unsigned long prefme;
   int flagallaliases;
   int flagalias;
   char *relayhost;
- 
+
   sig_pipeignore();
   if (argc < 4) perm_usage();
   if (chdir(auto_qmail) == -1) temp_chdir();
   getcontrols();
  
- 
   if (!stralloc_copys(&host,argv[1])) temp_nomem();
- 
+
+  authsender = 0;
   relayhost = 0;
-  for (i = 0;i <= host.len;++i)
-    if ((i == 0) || (i == host.len) || (host.s[i] == '.'))
-      if (relayhost = constmap(&maproutes,host.s + i,host.len - i))
+
+  addrmangle(&sender,argv[2],&flagalias,0);
+
+  for (i = 0;i <= sender.len;++i)
+    if ((i == 0) || (i == sender.len) || (sender.s[i] == '.') || (sender.s[i] == '@'))
+      if (authsender = constmap(&mapauthsenders,sender.s + i,sender.len - i))
         break;
-  if (relayhost && !*relayhost) relayhost = 0;
- 
-  if (relayhost) {
-    i = str_chr(relayhost,':');
-    if (relayhost[i]) {
-      scan_ulong(relayhost + i + 1,&port);
-      relayhost[i] = 0;
+
+  if (authsender && !*authsender) authsender = 0;
+
+  if (authsender) {
+    i = str_chr(authsender,'|');
+    if (authsender[i]) {
+      j = str_chr(authsender + i + 1,'|');
+      if (authsender[j]) {
+        authsender[i] = 0;
+        authsender[i + j + 1] = 0;
+        if (!stralloc_copys(&user,"")) temp_nomem();
+        if (!stralloc_copys(&user,authsender + i + 1)) temp_nomem();
+        if (!stralloc_copys(&pass,"")) temp_nomem();
+        if (!stralloc_copys(&pass,authsender + i + j + 2)) temp_nomem();
+      }
+    }
+    i = str_chr(authsender,':');
+    if (authsender[i]) {
+      scan_ulong(authsender + i + 1,&port);
+      authsender[i] = 0;
     }
-    if (!stralloc_copys(&host,relayhost)) temp_nomem();
-  }
 
+    if (!stralloc_copys(&relayhost,authsender)) temp_nomem();
+    if (!stralloc_copys(&host,authsender)) temp_nomem();
+
+  }
+  else {					/* default smtproutes -- authenticated */
+    for (i = 0;i <= host.len;++i)
+      if ((i == 0) || (i == host.len) || (host.s[i] == '.'))
+        if (relayhost = constmap(&maproutes,host.s + i,host.len - i))
+          break;
+
+    if (relayhost && !*relayhost) relayhost = 0;
+
+    if (relayhost) {
+      i = str_chr(relayhost,'|');
+      if (relayhost[i]) {
+        j = str_chr(relayhost + i + 1,'|');
+        if (relayhost[j]) {
+          relayhost[i] = 0;
+          relayhost[i + j + 1] = 0;
+          if (!stralloc_copys(&user,"")) temp_nomem();
+          if (!stralloc_copys(&user,relayhost + i + 1)) temp_nomem();
+          if (!stralloc_copys(&pass,"")) temp_nomem();
+          if (!stralloc_copys(&pass,relayhost + i + j + 2)) temp_nomem();
+        }
+      }
+      i = str_chr(relayhost,':');
+      if (relayhost[i]) {
+        scan_ulong(relayhost + i + 1,&port);
+        relayhost[i] = 0;
+      }
+      if (!stralloc_copys(&host,relayhost)) temp_nomem();
+    }
+  }
 
-  addrmangle(&sender,argv[2],&flagalias,0);
- 
   if (!saa_readyplus(&reciplist,0)) temp_nomem();
   if (ipme_init() != 1) temp_oserr();
  
diff --git a/qmail-showctl.c b/qmail-showctl.c
index a24aa63..dbd93fd 100644
--- a/qmail-showctl.c
+++ b/qmail-showctl.c
@@ -214,6 +214,7 @@ void main()
     _exit(111);
   }
 
+  do_lst("authsenders","No authenticated SMTP sender.","Authenicated SMTP sender: ","");
   do_lst("badmailfrom","Any MAIL FROM is allowed.",""," not accepted in MAIL FROM.");
   do_str("bouncefrom",0,"MAILER-DAEMON","Bounce user name is ");
   do_str("bouncehost",1,"bouncehost","Bounce host name is ");
@@ -265,8 +266,7 @@ void main()
   while (d = readdir(dir)) {
     if (str_equal(d->d_name,".")) continue;
     if (str_equal(d->d_name,"..")) continue;
-    if (str_equal(d->d_name,"bouncefrom")) continue;
-    if (str_equal(d->d_name,"bouncehost")) continue;
+    if (str_equal(d->d_name,"authsenders")) continue;
     if (str_equal(d->d_name,"badmailfrom")) continue;
     if (str_equal(d->d_name,"bouncefrom")) continue;
     if (str_equal(d->d_name,"bouncehost")) continue;
diff --git a/qmail-smtpd.8 b/qmail-smtpd.8
index c4640b8..785d5ba 100644
--- a/qmail-smtpd.8
+++ b/qmail-smtpd.8
@@ -23,7 +23,30 @@ or
 header fields.
 
 .B qmail-smtpd
-supports ESMTP, including the 8BITMIME and PIPELINING options.
+supports ESMTP, including the 8BITMIME, DATA, PIPELINING, SIZE, and AUTH options.
+.B qmail-smtpd
+includes a \'MAIL FROM:\' parameter parser and obeys \'Auth\' and \'Size\' advertisements.
+.B qmail-smtpd
+can accept LOGIN, PLAIN, and CRAM-MD5 AUTH types. It invokes
+.IR checkprogram ,
+which reads on file descriptor 3 the username, a 0 byte, the password
+or CRAM-MD5 digest/response derived from the SMTP client,
+another 0 byte, a CRAM-MD5 challenge (if applicable to the AUTH type),
+and a final 0 byte.
+.I checkprogram
+invokes
+.I subprogram
+upon successful authentication, which should in turn return 0 to
+.BR qmail-smtpd ,
+effectively setting the environment variables $RELAYCLIENT and $TCPREMOTEINFO
+(any supplied value replaced with the authenticated username).
+.B qmail-smtpd
+will reject the authentication attempt if it receives a nonzero return
+value from
+.I checkprogram
+or
+.IR subprogram .
+
 .SH TRANSPARENCY
 .B qmail-smtpd
 converts the SMTP newline convention into the UNIX newline convention
@@ -169,6 +192,67 @@ Number of seconds
 .B qmail-smtpd
 will wait for each new buffer of data from the remote SMTP client.
 Default: 1200.
+
+.SH "ENVIRONMENT VARIABLES READ"
+Environment variables may be defined globally in the
+.B qmail-smtpd
+startup script and/or individually as part of the
+.B tcpserver's
+cdb database.
+The environment variables may be quoted ("variable", or 'variable') and
+in case of global use, have to be exported.
+.B qmail-smtpd
+supports the following legacy environment variables, typically
+provided by
+.B tcpserver
+or
+.B sslserver
+or
+.BR tcp-env :
+.IR TCPREMOTEIP ,
+.IR TCPREMOTEHOST
+.IR TCPREMOTEINFO
+and
+.IR TCPLOCALPORT
+as well as
+.IR RELAYCLIENT .
+
+.B qmail-smtpd
+may use the following environment variables for SMTP authentication:
+.TP 5
+.IR SMTPAUTH
+is used to enable SMTP Authentication for the AUTH types
+LOGIN and PLAIN.
+In case
+.TP 5
+.IR SMTPAUTH='+cram'
+is defined,
+.B qmail-smtpd
+honors LOGIN, PLAIN, and additionally CRAM-MD5 authentication.
+Simply
+.TP 5
+.IR SMTPAUTH='cram'
+restricts authentication just to CRAM-MD5.
+If however
+.TP 5
+.IR SMTPAUTH='!'
+starts with an exclamation mark, AUTH is required.
+You can enforce 'Submission' using this option
+and binding
+.B qmail-smtpd
+to the SUBMISSION port \'587'\.
+In particular,
+.TP 5
+.IR SMTPAUTH='!cram'
+may be useful.
+In opposite, if
+.TP 5
+.IR SMTPAUTH='-'
+starts with a dash, AUTH is disabled for particular
+connections.
+
+Note: The use of 'cram' requires a CRAM-MD5 enabled PAM.
+
 .SH "SEE ALSO"
 tcp-env(1),
 tcp-environ(5),
diff --git a/qmail-smtpd.c b/qmail-smtpd.c
index 54df00c..4ca7293 100644
--- a/qmail-smtpd.c
+++ b/qmail-smtpd.c
@@ -23,6 +23,9 @@
 #include "timeoutread.h"
 #include "timeoutwrite.h"
 #include "commands.h"
+#include "wait.h"
+
+#define AUTHSLEEP 5
 
 #define MAXHOPS 100
 unsigned int databytes = 0;
@@ -49,6 +52,7 @@ void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); _
 void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); }
 void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }
 
+void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); }
 void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
 void err_unimpl(arg) char *arg; { out("502 unimplemented (#5.5.1)\r\n"); }
@@ -59,6 +63,17 @@ void err_noop(arg) char *arg; { out("250 ok\r\n"); }
 void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); }
 void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); }
 
+int err_child() { out("454 oops, problem with child and I can't auth (#4.3.0)\r\n"); return -1; }
+int err_fork() { out("454 oops, child won't start and I can't auth (#4.3.0)\r\n"); return -1; }
+int err_pipe() { out("454 oops, unable to open pipe and I can't auth (#4.3.0)\r\n"); return -1; }
+int err_write() { out("454 oops, unable to write pipe and I can't auth (#4.3.0)\r\n"); return -1; }
+void err_authd() { out("503 you're already authenticated (#5.5.0)\r\n"); }
+void err_authmail() { out("503 no auth during mail transaction (#5.5.0)\r\n"); }
+int err_noauth() { out("504 auth type unimplemented (#5.5.1)\r\n"); return -1; }
+int err_authabrt() { out("501 auth exchange canceled (#5.0.0)\r\n"); return -1; }
+int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; }
+void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); }
+void err_submission() { out("530 Authorization required (#5.7.1) \r\n"); }
 
 stralloc greeting = {0};
 
@@ -76,11 +91,14 @@ void smtp_quit(arg) char *arg;
   smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
 }
 
+char *protocol;
 char *remoteip;
 char *remotehost;
 char *remoteinfo;
 char *local;
+char *localport;
 char *relayclient;
+char *auth;
 
 stralloc helohost = {0};
 char *fakehelo; /* pointer into helohost, or 0 */
@@ -91,6 +109,7 @@ void dohelo(arg) char *arg; {
   fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0;
 }
 
+int smtpauth = 0;
 int liphostok = 0;
 stralloc liphost = {0};
 int bmfok = 0;
@@ -109,7 +128,6 @@ void setup()
   if (liphostok == -1) die_control();
   if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
   if (timeout <= 0) timeout = 1;
-
   if (rcpthosts_init() == -1) die_control();
 
   bmfok = control_readfile(&bmf,"control/badmailfrom",0);
@@ -122,19 +140,32 @@ void setup()
   if (x) { scan_ulong(x,&u); databytes = u; }
   if (!(databytes + 1)) --databytes;
  
+  protocol = "SMTP";
   remoteip = env_get("TCPREMOTEIP");
   if (!remoteip) remoteip = "unknown";
   local = env_get("TCPLOCALHOST");
   if (!local) local = env_get("TCPLOCALIP");
   if (!local) local = "unknown";
+  localport = env_get("TCPLOCALPORT");
+  if (!localport) localport = "0";
   remotehost = env_get("TCPREMOTEHOST");
   if (!remotehost) remotehost = "unknown";
   remoteinfo = env_get("TCPREMOTEINFO");
   relayclient = env_get("RELAYCLIENT");
+  auth = env_get("SMTPAUTH");
+  if (auth) {
+    smtpauth = 1;
+    case_lowers(auth);
+    if (!case_diffs(auth,"-")) smtpauth = 0;
+    if (!case_diffs(auth,"!")) smtpauth = 11;
+    if (case_starts(auth,"cram")) smtpauth = 2;
+    if (case_starts(auth,"+cram")) smtpauth = 3;
+    if (case_starts(auth,"!cram")) smtpauth = 12;
+    if (case_starts(auth,"!+cram")) smtpauth = 13;
+  }
   dohelo(remotehost);
 }
 
-
 stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */
 
 int addrparse(arg)
@@ -216,11 +247,72 @@ int addrallowed()
   return r;
 }
 
-
+char *auth;
+int seenauth = 0;
 int seenmail = 0;
 int flagbarf; /* defined if seenmail */
+int flagsize;
 stralloc mailfrom = {0};
 stralloc rcptto = {0};
+stralloc fuser = {0};
+stralloc mfparms = {0};
+
+int mailfrom_size(arg) char *arg;
+{
+  long r;
+  unsigned long sizebytes = 0;
+
+  scan_ulong(arg,&r);
+  sizebytes = r;
+  if (databytes) if (sizebytes > databytes) return 1;
+  return 0;
+}
+
+void mailfrom_auth(arg,len)
+char *arg;
+int len;
+{
+  if (!stralloc_copys(&fuser,"")) die_nomem();
+  if (case_starts(arg,"<>")) { if (!stralloc_cats(&fuser,"unknown")) die_nomem(); }
+  else
+    while (len) {
+      if (*arg == '+') {
+        if (case_starts(arg,"+3D")) { arg=arg+2; len=len-2; if (!stralloc_cats(&fuser,"=")) die_nomem(); }
+        if (case_starts(arg,"+2B")) { arg=arg+2; len=len-2; if (!stralloc_cats(&fuser,"+")) die_nomem(); }
+      }
+      else
+        if (!stralloc_catb(&fuser,arg,1)) die_nomem();
+      arg++; len--;
+    }
+  if(!stralloc_0(&fuser)) die_nomem();
+  if (!remoteinfo) {
+    remoteinfo = fuser.s;
+    if (!env_unset("TCPREMOTEINFO")) die_read();
+    if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem();
+  }
+}
+
+void mailfrom_parms(arg) char *arg;
+{
+  int i;
+  int len;
+
+    len = str_len(arg);
+    if (!stralloc_copys(&mfparms,"")) die_nomem();
+    i = byte_chr(arg,len,'>');
+    if (i > 4 && i < len) {
+      while (len) {
+        arg++; len--;
+        if (*arg == ' ' || *arg == '\0' ) {
+           if (case_starts(mfparms.s,"SIZE=")) if (mailfrom_size(mfparms.s+5)) { flagsize = 1; return; }
+           if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s+5,mfparms.len-5);
+           if (!stralloc_copys(&mfparms,"")) die_nomem();
+        }
+        else
+          if (!stralloc_catb(&mfparms,arg,1)) die_nomem();
+      }
+    }
+}
 
 void smtp_helo(arg) char *arg;
 {
@@ -229,17 +321,30 @@ void smtp_helo(arg) char *arg;
 }
 void smtp_ehlo(arg) char *arg;
 {
-  smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
+  char size[FMT_ULONG];
+  size[fmt_ulong(size,(unsigned int) databytes)] = 0;
+  smtp_greet("250-");
+  out("\r\n250-PIPELINING\r\n250-8BITMIME\r\n");
+  if (smtpauth == 1 || smtpauth == 11) out("250-AUTH LOGIN PLAIN\r\n");
+  if (smtpauth == 2 || smtpauth == 12) out("250-AUTH CRAM-MD5\r\n");
+  if (smtpauth == 3 || smtpauth == 13) out("250-AUTH LOGIN PLAIN CRAM-MD5\r\n");
+  out("250 SIZE "); out(size); out("\r\n");
   seenmail = 0; dohelo(arg);
 }
 void smtp_rset(arg) char *arg;
 {
-  seenmail = 0;
+  seenmail = 0; seenauth = 0;
+  mailfrom.len = 0; rcptto.len = 0;
   out("250 flushed\r\n");
 }
 void smtp_mail(arg) char *arg;
 {
+  if (smtpauth)
+    if (smtpauth > 10 && !seenauth) { err_submission(); return; }
   if (!addrparse(arg)) { err_syntax(); return; }
+  flagsize = 0;
+  mailfrom_parms(arg);
+  if (flagsize) { err_size(); return; }
   flagbarf = bmfcheck();
   seenmail = 1;
   if (!stralloc_copys(&rcptto,"")) die_nomem();
@@ -378,7 +483,7 @@ void smtp_data(arg) char *arg; {
   qp = qmail_qp(&qqt);
   out("354 go ahead\r\n");
  
-  received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo);
+  received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo);
   blast(&hops);
   hops = (hops >= MAXHOPS);
   if (hops) qmail_fail(&qqt);
@@ -388,16 +493,228 @@ void smtp_data(arg) char *arg; {
   qqx = qmail_close(&qqt);
   if (!*qqx) { acceptmessage(qp); return; }
   if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; }
-  if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return; }
+  if (databytes) if (!bytestooverflow) { err_size(); return; }
   if (*qqx == 'D') out("554 "); else out("451 ");
   out(qqx + 1);
   out("\r\n");
 }
 
+/* this file is too long ----------------------------------------- SMTP AUTH */
+
+char unique[FMT_ULONG + FMT_ULONG + 3];
+static stralloc authin = {0};   /* input from SMTP client */
+static stralloc user = {0};     /* authorization user-id */
+static stralloc pass = {0};     /* plain passwd or digest */
+static stralloc resp = {0};     /* b64 response */
+static stralloc chal = {0};     /* plain challenge */
+static stralloc slop = {0};     /* b64 challenge */
+
+char **childargs;
+char ssauthbuf[512];
+substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf));
+
+int authgetl(void) {
+  int i;
+
+  if (!stralloc_copys(&authin,"")) die_nomem();
+  for (;;) {
+    if (!stralloc_readyplus(&authin,1)) die_nomem(); /* XXX */
+    i = substdio_get(&ssin,authin.s + authin.len,1);
+    if (i != 1) die_read();
+    if (authin.s[authin.len] == '\n') break;
+    ++authin.len;
+  }
+
+  if (authin.len > 0) if (authin.s[authin.len - 1] == '\r') --authin.len;
+  authin.s[authin.len] = 0;
+  if (*authin.s == '*' && *(authin.s + 1) == 0) { return err_authabrt(); }
+  if (authin.len == 0) { return err_input(); }
+  return authin.len;
+}
+
+int authenticate(void)
+{
+  int child;
+  int wstat;
+  int pi[2];
+
+  if (!stralloc_0(&user)) die_nomem();
+  if (!stralloc_0(&pass)) die_nomem();
+  if (!stralloc_0(&chal)) die_nomem();
+
+  if (pipe(pi) == -1) return err_pipe();
+  switch(child = fork()) {
+    case -1:
+      return err_fork();
+    case 0:
+      close(pi[1]);
+      if(fd_copy(3,pi[0]) == -1) return err_pipe();
+      sig_pipedefault();
+        execvp(*childargs, childargs);
+      _exit(1);
+  }
+  close(pi[0]);
+
+  substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf);
+  if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write();
+  if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write();
+  if (smtpauth == 2 || smtpauth == 3 || smtpauth == 12 || smtpauth == 13)
+    if (substdio_put(&ssauth,chal.s,chal.len) == -1) return err_write();
+  if (substdio_flush(&ssauth) == -1) return err_write();
+
+  close(pi[1]);
+  if (!stralloc_copys(&chal,"")) die_nomem();
+  if (!stralloc_copys(&slop,"")) die_nomem();
+  byte_zero(ssauthbuf,sizeof ssauthbuf);
+  if (wait_pid(&wstat,child) == -1) return err_child();
+  if (wait_crashed(wstat)) return err_child();
+  if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */
+  return 0; /* yes */
+}
+
+int auth_login(arg) char *arg;
+{
+  int r;
+
+  if (*arg) {
+    if (r = b64decode(arg,str_len(arg),&user) == 1) return err_input();
+  }
+  else {
+    out("334 VXNlcm5hbWU6\r\n"); flush();       /* Username: */
+    if (authgetl() < 0) return -1;
+    if (r = b64decode(authin.s,authin.len,&user) == 1) return err_input();
+  }
+  if (r == -1) die_nomem();
+
+  out("334 UGFzc3dvcmQ6\r\n"); flush();         /* Password: */
+
+  if (authgetl() < 0) return -1;
+  if (r = b64decode(authin.s,authin.len,&pass) == 1) return err_input();
+  if (r == -1) die_nomem();
+
+  if (!user.len || !pass.len) return err_input();
+  return authenticate();
+}
+
+int auth_plain(arg) char *arg;
+{
+  int r, id = 0;
+
+  if (*arg) {
+    if (r = b64decode(arg,str_len(arg),&resp) == 1) return err_input();
+  }
+  else {
+    out("334 \r\n"); flush();
+    if (authgetl() < 0) return -1;
+    if (r = b64decode(authin.s,authin.len,&resp) == 1) return err_input();
+  }
+  if (r == -1 || !stralloc_0(&resp)) die_nomem();
+  while (resp.s[id]) id++;                       /* "authorize-id\0userid\0passwd\0" */
+
+  if (resp.len > id + 1)
+    if (!stralloc_copys(&user,resp.s + id + 1)) die_nomem();
+  if (resp.len > id + user.len + 2)
+    if (!stralloc_copys(&pass,resp.s + id + user.len + 2)) die_nomem();
+
+  if (!user.len || !pass.len) return err_input();
+  return authenticate();
+}
+
+int auth_cram()
+{
+  int i, r;
+  char *s;
+
+  s = unique;                                           /* generate challenge */
+  s += fmt_uint(s,getpid());
+  *s++ = '.';
+  s += fmt_ulong(s,(unsigned long) now());
+  *s++ = '@';
+  *s++ = 0;
+  if (!stralloc_copys(&chal,"<")) die_nomem();
+  if (!stralloc_cats(&chal,unique)) die_nomem();
+  if (!stralloc_cats(&chal,local)) die_nomem();
+  if (!stralloc_cats(&chal,">")) die_nomem();
+  if (b64encode(&chal,&slop) < 0) die_nomem();
+  if (!stralloc_0(&slop)) die_nomem();
+
+  out("334 ");                                          /* "334 base64_challenge \r\n" */
+  out(slop.s);
+  out("\r\n");
+  flush();
+
+  if (authgetl() < 0) return -1;                        /* got response */
+  if (r = b64decode(authin.s,authin.len,&resp) == 1) return err_input();
+  if (r == -1 || !stralloc_0(&resp)) die_nomem();
+
+  i = str_rchr(resp.s,' ');
+  s = resp.s + i;
+  while (*s == ' ') ++s;
+  resp.s[i] = 0;
+  if (!stralloc_copys(&user,resp.s)) die_nomem();       /* userid */
+  if (!stralloc_copys(&pass,s)) die_nomem();            /* digest */
+
+  if (!user.len || !pass.len) return err_input();
+  return authenticate();
+}
+
+struct authcmd {
+  char *text;
+  int (*fun)();
+} authcmds[] = {
+  { "login",auth_login }
+, { "plain",auth_plain }
+, { "cram-md5",auth_cram }
+, { 0,err_noauth }
+};
+
+void smtp_auth(arg)
+char *arg;
+{
+  int i;
+  char *cmd = arg;
+
+  if (!smtpauth || !*childargs) { out("503 auth not available (#5.3.3)\r\n"); return; }
+  if (seenauth) { err_authd(); return; }
+  if (seenmail) { err_authmail(); return; }
+
+  if (!stralloc_copys(&user,"")) die_nomem();
+  if (!stralloc_copys(&pass,"")) die_nomem();
+  if (!stralloc_copys(&resp,"")) die_nomem();
+  if (!stralloc_copys(&chal,"")) die_nomem();
+
+  i = str_chr(cmd,' ');
+  arg = cmd + i;
+  while (*arg == ' ') ++arg;
+  cmd[i] = 0;
+
+  for (i = 0;authcmds[i].text;++i)
+    if (case_equals(authcmds[i].text,cmd)) break;
+
+  switch (authcmds[i].fun(arg)) {
+    case 0:
+      seenauth = 1;
+      protocol = "ESMTPA";
+      relayclient = "";
+      remoteinfo = user.s;
+      if (!env_unset("TCPREMOTEINFO")) die_read();
+      if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem();
+      if (!env_put2("RELAYCLIENT",relayclient)) die_nomem();
+      out("235 ok, go ahead (#2.0.0)\r\n");
+      break;
+    case 1:
+      err_authfail(user.s,authcmds[i].text);
+  }
+}
+
+
+/* this file is too long --------------------------------------------- GO ON */
+
 struct commands smtpcommands[] = {
   { "rcpt", smtp_rcpt, 0 }
 , { "mail", smtp_mail, 0 }
 , { "data", smtp_data, flush }
+, { "auth", smtp_auth, flush }
 , { "quit", smtp_quit, flush }
 , { "helo", smtp_helo, flush }
 , { "ehlo", smtp_ehlo, flush }
@@ -408,8 +725,11 @@ struct commands smtpcommands[] = {
 , { 0, err_unimpl, flush }
 } ;
 
-void main()
+void main(argc,argv)
+int argc;
+char **argv;
 {
+  childargs = argv + 1;
   sig_pipeignore();
   if (chdir(auto_qmail) == -1) die_control();
   setup();
*   255e0cc6c1a967fd19d63e26fa40666dda2b624d● 2020-11-22 (refs/pull/191/merge)
|\    Merge bce502e3c16ff758282dbedb8d304b26af10e48a● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * bce502e3c16ff758282dbedb8d304b26af10e48a● 2020-11-22 (refs/pull/191/head, Dakon-remote-SIZE)
| |   qmail-remote: add support for SIZE extension (RfC 1870)
| |   
| | * 43b62148d7be380f620961603bd7eee404637078● 2020-11-21 (refs/pull/190/merge)
| |/|   Merge c87ee6782d52d2ad98b2ae497d8da16fe6f85197● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
|/| | 
| | | 
| | * c87ee6782d52d2ad98b2ae497d8da16fe6f85197● 2020-11-21 (refs/pull/190/head, Dakon-smtpcode-test)
| | |   qmail-remote: verify the SMTP result code of remote servers much stricter
| | | 
| | * 9e9ca937cd366019e94f9d0f2ad789b42a13541a● 2020-11-21
| | |   tests: show several cases where smtpcode() is wrong
| | | 
| | * eb622233c9e90d2b05921e96b7ca696d59f2b588● 2020-11-21
| | |   split smtpcode() out of qmail-remote.c
| | | 
| | * 37892c36a2fc3ba409c8e839d306895c783a087d● 2020-11-21
| |/    tests: prevent duplication in Makefile
|/|   
| |   
| | * 5dea5a2436077983244c33fd8d4279f52863866d● 2020-11-21 (refs/pull/173/merge)
| |/|   Merge 6897896cb410a34f6fd4e80741a28d58678b17d7● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
|/|/  
| | 
| * 6897896cb410a34f6fd4e80741a28d58678b17d7● 2020-11-21 (refs/pull/173/head, Dakon-remote-EHLO)
| |   qmail-remote: add infrastructure for EHLO parsing
| | 
| * aa36dde7dae059ae1e7834f62f6f7dfb747d85bb● 2020-11-21
|/    tests: prevent duplication in Makefile
|   
| * 344f926b724063a2a4d30c52507489bcce0b8219 2020-11-20 (refs/pull/187/merge)
|/|   Merge db03acdb8f82e3eb0c2c930dd7766606eecebfef● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * db03acdb8f82e3eb0c2c930dd7766606eecebfef● 2020-11-20 (refs/pull/187/head, schmonz-Wincompatible-library-redeclaration)
|/    Fix 2 warnings from -Wincompatible-library-redeclaration.
|   
| * ed2491a3431b69cea3790d14b8b06a155eb72407● 2020-11-20 (refs/pull/148/merge)
|/|   Merge 2d6324e65cad8e21902ef3beae0ef25bc91ded19 into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * 2d6324e65cad8e21902ef3beae0ef25bc91ded19 2020-11-20 (refs/pull/148/head, schmonz-builds-symlinks)
|/    Symlink "CI" configs somewhere easier to see.
|   
| * 9bceeddb027b370666ce940f2c2667e5ee1fe08d● 2020-11-20 (refs/pull/61/merge)
|/|   Merge a01cad9bad65dbd367c7cbdbf2525147936dcef7● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * a01cad9bad65dbd367c7cbdbf2525147936dcef7● 2020-11-20 (refs/pull/61/head, instqueue)
|/    Extract an "instqueue" program from instpackage.
|   
| * f3e108b0ae7c350dd0b25c00b851291710fd2b4f● 2020-11-20 (refs/pull/188/merge)
|/|   Merge 19e6a13d399d8e0ea920856b5c54f989791da670 into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * 19e6a13d399d8e0ea920856b5c54f989791da670 2020-11-20 (refs/pull/188/head, schmonz-Wempty-body)
|/    Fix 1 warning from -Wempty-body.
|   
| * 0060f6f1c66d3ab4f6ba4cb82d486cdf71f46b14 2020-11-20 (refs/pull/186/merge)
|/|   Merge 0da4bfab6dba99cd345cd875307bc89363976d0c into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * 0da4bfab6dba99cd345cd875307bc89363976d0c 2020-11-20 (refs/pull/186/head, schmonz-Wpointer-sign)
|/    Fix 3 warnings from -Wpointer-sign.
|   
| * 9ff26c2c12ffe91eb07bd2d223038d8653c4a4ff● 2020-11-20 (refs/pull/185/merge)
|/|   Merge 11904fe2ca6fd3a648f16f4c40422c2c614518ec into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * 11904fe2ca6fd3a648f16f4c40422c2c614518ec 2020-11-20 (refs/pull/185/head, schmonz-Wdangling-else)
|/    Fix 5 warnings from -Wdangling-else.
|   
| * dcdf735e376a32057398055e113f91e966ac3394● 2020-11-20 (refs/pull/184/merge)
|/|   Merge 0daadf1888f7c75d04a5f6b929126f81041f179d into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * 0daadf1888f7c75d04a5f6b929126f81041f179d 2020-11-20 (refs/pull/184/head, schmonz-Wparentheses)
|/    Fix 17 warnings from -Wparentheses.
|   
| * 1963d79845b6b8c04236b87dc72eb18dd6daa128 2020-11-17 (refs/pull/76/merge)
|/|   Merge d3d6059b189131c1e83c131b661295e8776a6f08● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * d3d6059b189131c1e83c131b661295e8776a6f08● 2020-11-17 (refs/pull/76/head, opensuse_buildservice)
| |   moved debian directory one level up
| | 
| * d5a72a0a7943f48b75bda600cb4cf849e83e8d06● 2020-11-16
| |   updated maintainer email to packages@notqmail.org
| | 
| * 26750829cecf1f4c58b9ebfecb028b08aaf86080● 2020-11-16
| |   removed usage of files in /tmp
| | 
| * 8e302f768203e967ca537f931a4378e3725a76a5● 2020-11-16
| |   updated maintainer email address
| | 
| * 22614794d647daa5444718de471ff98d316b0d22● 2020-11-16
| |   removed not used README, removed binutils from build-requires, fixed clean target in rules
| | 
| * 608e75bfc883e9d9d40c447dfa79aaadafe5ade7● 2020-11-16
| |   refactored obs build files
| | 
| * 88da78b07d8d89203f3c559bd5e3ddb9cab0f5cd● 2020-11-16
| |   fixed syntax eror and include changelog
| | 
| * edd8c8d2912e3286aacbfc823f9b29022882b0da● 2020-11-16
| |   fix for systemd on ubuntu/debian
| | 
| * 3856e3e0b9b634e35f6fea4b544107dc6a0de291● 2020-11-16
| |   1. Change Source to https://github.com/notqmail/notqmail/releases/download/notqmail-1.08/notqmail-1.08.tar.xz in notqmail.spec 2. use _service file to fetch source directly from github 3. Build can now be triggered and fetch source directly from github 4. Revised version number to 1.08 5. Updated ChangeLogs in notqmail.spec and debian/changelog 6. Updated date/timestamp in ChangeLogs
| | 
| * 4df1cc31542aa887961e5fb4d080646415d95ab9● 2020-11-16
| |   do not install obsolete components
| | 
| * aa829ef67ddf9873b063dca3d1df262ac628aedd● 2020-11-16
|/    added files for binary builds on openSUSE build service
|   
| * 8f20490968427dc2ba3fa7b0132af057f4e79a21 2020-11-17 (refs/pull/183/merge)
|/|   Merge f93f6599229c668a6a175d3f1d34e4b87a0de8d4● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * f93f6599229c668a6a175d3f1d34e4b87a0de8d4● 2020-11-17 (refs/pull/183/head, Dakon-own-headers)
|/    always include the own header first in all C files
|   
| * e86ec1c6c39cf75f3473f38543cf10704226cbc3● 2020-11-17 (refs/pull/141/merge)
|/|   Merge 7945bd30458d143d590961fdb63cc11db09adf4d into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
| | 
| * 7945bd30458d143d590961fdb63cc11db09adf4d 2020-05-26 (refs/pull/141/head, docker)
| |   added comments on /etc/mtab creation
| | 
| * 0f1bfce28d09c1e1ff5dec31e71f4ebc3c472966● 2020-05-26
| |   moved alternatives command out of subshell
| | 
| * aa5ac4192f1046058e7d88b0df4a9969b97bda22● 2020-05-23
| |   added Dockerfiles for notqmail docker/podman container
| |   
| | * 38187677ea721800434c829725366cacfaed729e 2020-11-16 (refs/pull/153/merge)
| |/|   Merge 2654ffe3730b0e570e68ae6d62292c713fd4d013 into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
|/| | 
| | | 
| | * 2654ffe3730b0e570e68ae6d62292c713fd4d013 2020-11-16 (refs/pull/153/head, Dakon-remote-groups)
| | |   reduce prot_uid() to a define
| | | 
| | * f46913371291354772f53cd6db507509a356d1ec● 2020-11-16
| |/    allow additional groups for qmail-remote
|/|   
| |   
| | * 0c77528ab05539a47d2c71094ceef4e5bb10717e 2020-11-15 (refs/pull/84/merge)
| |/|   Merge 07d83d2fc7c9557071788639881c410dd7e16c6a into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
|/| | 
| | | 
| | * 07d83d2fc7c9557071788639881c410dd7e16c6a 2020-11-09 (refs/pull/84/head, substdio-ssize_t)
| | |   replace "sizeof foo" with sizeof(foo)
| | | 
| | * 7472c9a9d4c13b6ebf90eac3c4621b76f20e8f12● 2020-11-09
| | |   add generator macro for substdio wrappers around qmail_put()
| | | 
| | * 6effe94e0b08c100f7b5b3c41c22ff2d24841ca5● 2020-11-09
| | |   add generator macros for substdio wrappers around timeoutread() and timeoutwrite()
| | | 
| | * 7a631eb072f764e24e51b9733f5f419cd6be5ef9● 2020-11-09
| | |   fix read() return value handling in getln2()
| | | 
| | * 688cb90ecb7f926164a8e87b2f8528fb509814ce● 2020-11-09
| | |   improve checks for return value of read() and write() and it's wrappers
| | | 
| | * 9f89b45a42716f513cd1db3e8ec86167743d9e9c● 2020-11-09
| | |   convert some additional substdio functions to return ssize_t
| | | 
| | * fa84c121d0eed62f4fc635d2503d2acb36ebd698● 2020-11-09
| | |   simplify qmail_puts()
| | | 
| | * c404ae0b74c59723f20dda79e69e1d1d0c30956f● 2020-11-09
| | |   use size_t and ssize_t in substdio
| | |   
| | | * 03b8497487b7ebc0580d92059ae77171fff71601 2020-11-14 (refs/pull/149/merge)
| |_|/|   Merge eb0013ebf7f2303e77c97e8166f402a57aca33fa● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
|/| | | 
| | | | 
| | | * eb0013ebf7f2303e77c97e8166f402a57aca33fa● 2020-11-09 (refs/pull/149/head, Dakon-make-dupl)
| | | |   Makefile: remove duplication for all object file rules
| | | | 
| | | * e88b156256aaa9de17cbc43349eb22984dc0a9d2● 2020-11-09
| | | |   Makefile: remove code duplication for library components
| | | | 
| | | * 7a665bfa033d154fc31aa721fc4834fe3f4ca541● 2020-11-09
| | | |   Makefile: reduce code duplication for building username files
| | | | 
| | | * 7391853b304957f4fddbd7cb6f6320f1b419cd4f● 2020-11-09
| | |/    tests: remove duplication in Makefile
| | |   
| | | * cd2ca43c5702a244fd01f8450186ac6e6db54cb7● 2020-11-14 (refs/pull/172/merge)
| |_|/|   Merge 806e063f2dc921db7cd7e8119bba274bcfdbff2c into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
|/| | | 
| | | | 
| | | * 806e063f2dc921db7cd7e8119bba274bcfdbff2c 2020-11-14 (refs/pull/172/head, Dakon-ehlo)
| |_|/    qmail-smtpd: introduce an array of EHLO string generators
|/| |   
| | |   
| | | * f4456a26f3a67c049e90414db224e38f705f45b8● 2020-11-14 (refs/pull/143/merge)
| |_|/|   Merge 910f8eed7bc2bf315257d5b754c29fd5eb080b17● into aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 
|/| | | 
| | | | 
| | | * 910f8eed7bc2bf315257d5b754c29fd5eb080b17● 2020-11-14 (refs/pull/143/head, Dakon-remove-strchr)
| | | |   remove manually unrolled loops in byte*.c
| | | | 
| | | * 889f6db1aa77a735d01c1db6ff1ace2361579b1e● 2020-11-14
| | | |   remove stale declaration case_startb() from case.h
| | | | 
| | | * e3a6c07b0103235348d69f62e7bc78dd9d5cb49d● 2020-11-14
| | | |   add parameters to byte.h declarations
| | | | 
| | | * 630fd56a97b3004373e448fb0642069b62b53f0d● 2020-11-14
| | | |   add parameters to case.h declarations
| | | | 
| | | * 2799acf48cf9167b745a386dee546cd671e2b0f1● 2020-11-14
| | | |   add parameters to str.h declarations
| | | | 
| | | * 8f3ba91e966a01c440dfb19fca834b6647dd5f82● 2020-11-14
| | | |   replace case_diffs() with strcasecmp()
| | | | 
| | | * 7cf5ac84f84802405068e9e68eb0cd4e45c01a02● 2020-11-14
| | | |   tests: add tests for case_diffs()
| | | | 
| | | * 673e52ef69aaaf236929b0fc8cc760d5a813480a● 2020-11-14
| | | |   tests: remove duplication in makefile
| | | | 
| | | * 4ac7c5a079cf0a2feb04d78981789f164b95052d● 2020-11-14
| | | |   replace most usages of str_rchr() with direct strrchr()
| | | | 
| | | * b392039259909a13ef38b73d8feff971ff960eee● 2020-11-14
| | | |   replace str_rchr() with strrchr()
| | | | 
| | | * 42c03dca4e39c14dc6435bb4d1c23880b204facc● 2020-11-14
| | | |   tests: add tests for str_rchr()
| | | | 
| | | * f59f3d9b8bcb19a5b716b0b34d4c059f23fe3cf2● 2020-11-14
| | | |   replace str_start() with strncmp()
| | | | 
| | | * 4d426f559a3400d987df5117a94a754debf56f8d● 2020-11-14
| | | |   tests: add test for str_start()
| | | | 
| | | * 736a65338ce15de0c25c5e579818e040f6dbd8a2● 2020-11-14
| | | |   use strchrnul() to implement str_chr() if present
| | | | 
| | | * a8d5f963ef869904c6f0c0004cb142c4a983ae3c● 2020-11-14
| | | |   replace str_chr() implementation with strchr()
| | | | 
| | | * 8c6fa8a9320cea24410f8fe57d8f5d6c114f284c● 2020-11-14
| |_|/    tests: add test for str_chr()
|/| |   
| | |   
| | | * 713650d9b486b7ee73653b4e658abae1ec8ba1a1 2020-11-12 (refs/pull/182/merge)
| | |/|   Merge aedd8beb2484608eb97ee3299e7f3b8cdde061ce● into 52546d2557ba3afa4b5740b2d944b26a20b064ed 
| |_|/  
|/| |   
| | | 
* | | aedd8beb2484608eb97ee3299e7f3b8cdde061ce● 2020-11-12 (HEAD -> master, refs/pull/182/head, Dakon-ids-object)
| |/    put all auto_user*.o and auto_group*.o files in a library ids.a
|/|   
| |   
| | * e1fad27e380c809c0b76ca486bb6192c513b11fe● 2020-11-09 (Dakon-const)
| | |   constify some remaining function arguments
| | | 
| | * 72c07c7318909ef9dd1a585932b50e3b2d882777● 2020-11-09
| | |   fixup-control
| | | 
| | * 18a8c284dbbd4c7889b31c59711e8ae4dc64a4be● 2020-11-09
| | |   constify init_[gu]id() arguments
| | | 
| | * ddf898cb2d12d49be05932c2cf2bf23785b63f50● 2020-11-09
| | |   constify scan_*long() function arguments
| | | 
| | * 08240bfdbd050f7f8fb1b4885aa86091d0f7eeeb● 2020-11-09
| | |   constify the install helper functions
| | | 
| | * 7535cfdf7a5d597cb18b3b406dfc40889bd3adaa● 2020-11-09
| | |   constify random function arguments in qmail main binaries
| | | 
| | * 4314fff6d55e1a32bda53ade08b3af9b3df382f6● 2020-11-09
| | |   remove unused function env_pick()
| | | 
| | * 477142ac013348e959a2a7fa38ec86d097bffb18● 2020-11-09
| | |   constify arguments to env_*()
| | | 
| | * 13e8f85c78d29185c719203cc578d8767eb520fa● 2020-11-09
| | |   return const char* from error_str()
| | | 
| | * cd66050b08c82eced7a99320ce6069e985153ae6● 2020-11-09
| | |   constify the arguments to strerr_die() and strerr_warn()
| | | 
| | * 97b37a6e70fdaa444b6668b713c71d768b2c7a38● 2020-11-09
| | |   constify argument to constmap() and it's helper hash()
| | | 
| | * d01effae6b4925f1a359c2b524bb09ccec9fe2c0● 2020-11-09
| | |   constify filename arguments passed to control_*()
| | | 
| | * 7c3105c64895a058540676366585588d49beeb13● 2020-11-09
| | |   constify filename arguments passed to open_*()
| | | 
| | * e53b5686e7593f87f771ebc2b8a735b77fea2b3d● 2020-11-09
| | |   constify arguments to cdb functions
| | | 
| | * 887ab553329cb1c184d0ab49c20e0db56e481aa4● 2020-11-09
| | |   tests: add test for cdb_hash() and cdb_unpack()
| | | 
| | * 2634d3dc7ebb093f54d12165756e04ffb009c273● 2020-11-09
| | |   tests: add abstraction to Makefile to simplify adding further entries
| | | 
| | * 497e03027075810da62b702400a92e2ed20f9890● 2020-11-09
| |/    rename puts() to put_str() in auto-*.c
|/|   
| |   
| | * 9046eb28dbeede1280012a38aa4701b5bb1d9915 2020-11-09 (Dakon-inject-fix)
| |/    DEBUG: try to get qmail-inject behave as before 1.08
|/|   
| | 
* | 52546d2557ba3afa4b5740b2d944b26a20b064ed 2020-11-08 (refs/pull/171/head)
| |   get rid of error_* variables and just #define them to their errno equivalents
| |     
| | *   e9805387b16e88ef957a0a254efd418e905fb39c● 2020-11-08 (Dakon-1.09)
| | |\    Merge remote-tracking branch 'origin/Dakon-remote-EHLO' into Dakon-1.09
| | | | 
| | | * 33dc39a9df7ebe70984d781d0d111e64e30f08e7 2020-11-08
| | | |   qmail-remote: add infrastructure for EHLO parsing
| | | | 
| | | * 56ffd3b94a80a983594f6be24d8e10502468b3b0● 2020-11-08
| |_|/    tests: prevent duplication in Makefile
|/| |   
| | |   
| | *   d9cf8e1dc4436c44f5b59a8dbc7c17d5a7a3fbe3● 2020-07-26
| | |\    Merge branch 'Dakon-ehlo' into Dakon-1.09
| | | | 
| | | * a09a08c7aa68f2944f4d9f9513560cca7f0b224c● 2020-07-26
| | | |   qmail-smtpd: introduce an array of EHLO string generators
| | | |   
| | * |   c949664e762cc566c4adb7648798c327a630c0f3● 2020-07-25
| | |\ \    Merge remote-tracking branch 'origin/Dakon-errno' into Dakon-1.09
| | | | | 
| | | * | 61ebb79d1c748c1ddae7d18cc531581dabe133cc● 2020-07-22
| | | |/    get rid of error_* variables and just #define them to their errno equivalents
| | | |   
| | * |   5a9247de38b0b6493c3cb4c91baf811f4b04c9d6● 2020-07-22
| | |\ \    Merge remote-tracking branch 'origin/Dakon-local-race' into Dakon-1.09
| | | | | 
| | | * | af02dc0fdbbe8db8d3aa12345bdd550727da2039● 2020-07-08
| | | |/    qmail-local: close race window when creating file in tmp/
| | | |   
| | * |   cb78a7220d93563a3429e2efec6b8a2cb1d94375● 2020-07-22
| | |\ \    Merge remote-tracking branch 'origin/Dakon-remote-groups' into Dakon-1.09
| | | | | 
| | | * | 6e98316046f67de310a7ae7efc312d9977e39a3c● 2020-07-08
| | | | |   reduce prot_uid() to a define
| | | | | 
| | | * | 7d883cc30e8afc8d14cd7de55357324beb420fbf● 2020-07-08
| | | | |   allow additional groups for qmail-remote
| | | | | 
| | | * | ccb533b736e064c879142b3bdffa61189c04d74c● 2020-07-08
| | | |/    put all auto_user*.o and auto_group*.o files in a library uids.a
| | | |   
| | * |   839ae630541638c0c764fd8476f8474f1b874076● 2020-07-22
| | |\ \    Merge remote-tracking branch 'origin/crcrlf' into Dakon-1.09
| | | | | 
| | | * | b822661d68e5b71e1fdb485ab8ade7dc222e0ef1● 2020-07-22
| | | |/    qmail-remote: avoid recoding CRLF to CRCRLF
| | | |   
| | * |   40bfd404e8e1f11a783ce55013b7e4731e7bfc78● 2020-07-22
| | |\ \    Merge remote-tracking branch 'origin/Dakon-make-dupl' into Dakon-1.09
| | | | | 
| | | * | 91fc59eb2e2d2db04fb005067f68443a8cd25eaa 2020-07-22
| | | | |   Makefile: remove duplication for all object file rules
| | | | | 
| | | * | 167bf163c8e7a99053d33a43e6561088f6b3c86b● 2020-07-22
| | | | |   Makefile: remove code duplication for library components
| | | | | 
| | | * | 7aecbda1cf94582eb0f5d911df61fd070a16ca6c● 2020-07-22
| | | |/    Makefile: reduce code duplication for building username files
| | | |   
| | * |   d4db4ffbece97e2afde828ae7d9d1c839800721c● 2020-07-22
| | |\ \    Merge remote-tracking branch 'origin/Dakon-inject-fix' into Dakon-1.09
| | | | | 
| | | * | 8cd0ab7a403339150121d930700a72b345cb03bd● 2020-06-14
| | | | |   DEBUG: try to get qmail-inject behave as before 1.08
| | | | |   
| | * | |   a285446f4a7f201d85127b071bd5135884ab377f● 2020-07-22
| | |\ \ \    Merge remote-tracking branch 'origin/Dakon-remove-strchr' into Dakon-1.09
| | | | | | 
| | | * | | c64752d156cc448bf73b400cfd5ce542cb436761● 2020-07-08
| | | | | |   remove manually unrolled loops in byte*.c
| | | | | | 
| | | * | | 176556e9106fd985fc14ef1fe381f3e1aedfa059● 2020-07-08
| | | | | |   remove stale declaration case_startb() from case.h
| | | | | | 
| | | * | | 520b3e365591465f191eca33821b6e1830636838● 2020-07-08
| | | | | |   add parameters to byte.h declarations
| | | | | | 
| | | * | | c0047e37b1b53b76220457a5d17f8760ad97ddfd● 2020-07-08
| | | | | |   add parameters to case.h declarations
| | | | | | 
| | | * | | dff9b48f07f2b991283635c1ed557f0a91598c86● 2020-07-08
| | | | | |   add parameters to str.h declarations
| | | | | | 
| | | * | | a02e771a67ba21b6512299eed2821a7a453eed25● 2020-07-08
| | | | | |   replace case_diffs() with strcasecmp()
| | | | | | 
| | | * | | 696cc3bb8878745aa8eb4008291755af04030b86● 2020-07-08
| | | | | |   tests: add tests for case_diffs()
| | | | | | 
| | | * | | 7779cfca8df008b1f12f05e2a9e0c99b28144d1b● 2020-07-08
| | | | | |   tests: remove duplication in makefile
| | | | | | 
| | | * | | 7e65d675afcca8e9b5e1596ca724555f1b54bf53● 2020-07-08
| | | | | |   replace most usages of str_rchr() with direct strrchr()
| | | | | | 
| | | * | | 7163823567528c6fe93efd7c057e8cf4e3bb0381● 2020-07-08
| | | | | |   replace str_rchr() with strrchr()
| | | | | | 
| | | * | | 84c23792315e0db950c3db95ac733e84443cd47d● 2020-07-08
| | | | | |   tests: add tests for str_rchr()
| | | | | | 
| | | * | | 266cb0d40106648d0e250fe00f452b06cca8ca93● 2020-07-08
| | | | | |   replace str_start() with strncmp()
| | | | | | 
| | | * | | f70c8bba74fd70a540e16c8e7c9a9295db7a2dd9● 2020-07-08
| | | | | |   tests: add test for str_start()
| | | | | | 
| | | * | | 741a1568f36ae3c40d8a0e4d04daf8aae6e27359● 2020-07-08
| | | | | |   use strchrnul() to implement str_chr() if present
| | | | | | 
| | | * | | 6a96746cfbb0d9ad7166d308711c0c4d117aaaac● 2020-07-08
| | | | | |   replace str_chr() implementation with strchr()
| | | | | | 
| | | * | | ec4cfe478f2b3ae69db8d3008f21d9fc93b25d13● 2020-07-08
| | | | |/    tests: add test for str_chr()
| | | |/|   
| | | | |   
| | * | |   d3dc1817a97b30fd2f42b753d087e302b8dbfba1● 2020-07-22
| | |\ \ \    Merge remote-tracking branch 'origin/substdio-ssize_t' into Dakon-1.09
| | | |/ /  
| | |/| |   
| | | | | 
| | | * | af95e606586406ebed6134554857eaf855992b2d● 2020-07-08
| | | | |   fix read() return value handling in getln2()
| | | | | 
| | | * | 185e3b6888820f9a0969cabac86edc453aab4d77● 2020-07-08
| | | | |   improve checks for return value of read() and write() and it's wrappers
| | | | | 
| | | * | 559f2406c6badc92ef8d8f74b39bb00b4937e368● 2020-07-08
| | | | |   convert some additional substdio functions to return ssize_t
| | | | | 
| | | * | 1223a08da72c85883fa103b6f69147616a1124da● 2020-07-08
| | | | |   simplify qmail_puts()
| | | | | 
| | | * | 32db5c0257284b92ce722de3ac4919b436f6646b● 2020-07-08
| | |/ /    use size_t and ssize_t in substdio
| | | |   
| | | | * d23f758f1e0b5a61e5baf1a0d4f041988b71b47f 2020-11-08 (refs/pull/171/merge)
| |_|_|/|   Merge 0079c27b10f293ab11cbc76c45be283854dbe46d into 63e5f20194aba81a970f919d73d3d2e6f29e18af 
|/| | | | 
| | | | | 
| | | | * 0079c27b10f293ab11cbc76c45be283854dbe46d 2020-10-19 (Dakon-errno)
| | | | |   get rid of error_* variables and just #define them to their errno equivalents
| | | | | 
* | | | | 63e5f20194aba81a970f919d73d3d2e6f29e18af 2020-11-08
| | | | |   Add some tests for prioq.
| | | | |   
| | | | | * e224bd6c02a9d093d0e0fc8294517bc6a48377dd 2020-11-08 (refs/pull/179/head)
| |_|_|_|/    Add some tests for prioq.
|/| | | |   
| | | | |     
| | | | | *   85c19150d716e3051e86b824b3fc59a1ccc912ae 2020-11-08 (refs/pull/65/merge)
| | | | | |\    Merge ca02043fb46f131ed507d81b3df33cbac051c129 into 0b1896650c2ba7100df450d698752090e6ba3b22 
| | | | | | | 
| | | | | | * ca02043fb46f131ed507d81b3df33cbac051c129 2020-10-19 (refs/pull/65/head, std-functions)
| | | | | | |   add needed system header for getpid()
| | | | | | | 
| | | | | | * 8b7043415736c33eddb6e010bcba6dd0feec69f5● 2020-10-19
| | | | | | |   add needed system header for chdir()
| | | | | | | 
| | | | | | * b9b7c7d808582b352aaff60e3783c886a180b736● 2020-10-19
| | | | | | |   add needed system headers for setuid() and setgid()
| | | | | | | 
| | | | | | * 91c500d36f56cd656d975dfc607fe9899af26e4a● 2020-10-19
| | | | | | |   add needed system header for close()
| | | | | | | 
| | | | | | * 3b77883f36a1bb328a872c83a15392f68e998498● 2020-10-19
| | | | | | |   add needed system headers for umask()
| | | | | | | 
| | | | | | * fc8951e2f4d401b39d2f733dd8fdfc3f3c3948d6● 2020-10-19
| | | | | | |   get rid of error_* variables and just #define them to their errno equivalents
| | | | | | | 
| | | | | | * c251a2222ffcc7ec733427b9f3b1041cd6edd22c● 2020-10-19
| | | | | | |   get rid of byte_zero() and use the default memset() instead
| | | | | | | 
| | | | | | * 42bef0d487632051185f77cc6332ab86c4ef0dd8● 2020-10-19
| | | | | | |   fix read() return value handling in getln2()
| | | | | | | 
| | | | | | * 55a6d4a130ee161f1da6d2116016e2adb3be1859● 2020-10-19
| | | | | | |   improve checks for return value of read() and write() and it's wrappers
| | | | | | | 
| | | | | | * bf9c7dabf7f1f9be0adaa2a10ded833054f8a01b● 2020-10-19
| | | | | | |   convert some additional substdio functions to return ssize_t
| | | | | | | 
| | | | | | * 163fd6258fc7766fc2e9911e428d8002eea17ca6● 2020-10-19
| | | | | | |   simplify qmail_puts()
| | | | | | | 
| | | | | | * 8f0f07e93bf5a8a0bfe6ed57b6d0ad9b2e63946b● 2020-10-19
| | | | | |/    use size_t and ssize_t in substdio
| | | | |/|   
| | | | | |   
| | | | | | * e0243345a407e7000f13a0f34cc173d78b948055 2020-11-07 (refs/pull/122/merge)
| | | | | |/|   Merge 02ff7ddcee1680a573260e05f2f9456ddffe87b2 into 0b1896650c2ba7100df450d698752090e6ba3b22 
| | | | | | | 
| | | | | | * 02ff7ddcee1680a573260e05f2f9456ddffe87b2 2020-05-24 (refs/pull/122/head)
| | | | | | |   generate compile, load, makelib directly with cat
| | | | | | | 
| | | | | | * 7214b3383ce390ab07cdde60f9f8a912cc95b666● 2020-05-24
| | | | | | |   Make "ar" and "ranlib" configurable like "cc" and "ld" are
| | | | | | |   
| | | | | | | * 447fcab0269ad31fb2a73748789d3133f98dd6bc 2020-11-07 (refs/pull/181/merge)
| | | | | | |/|   Merge b2a089c9c561fe73a11b75356b7427005fa84b76 into 0b1896650c2ba7100df450d698752090e6ba3b22 
| | | | | |/|/  
| |_|_|_|_|/|   
|/| | | | | |   
| | | | | | | 
* | | | | | | b2a089c9c561fe73a11b75356b7427005fa84b76 2020-11-07 (refs/pull/181/head, Dakon-CI-GitHub)
| | | | | | |   GitHub: add CI build without obsolete functions
| | | | | | | 
* | | | | | | 6281b2176efb32293f75976e30885a6bd4ac1170● 2020-11-07
| | | | | | |   GitHub: add build set without catman pages
| | | | | | | 
* | | | | | | 172ce82f8484f597dc10411882ee34710eb80b1e● 2020-11-07
| |_|_|_|/ /    GitHub: also build on MacOS and with clang
|/| | | | |   
| | | | | |   
| | | | | | * acf8ff62ecee706bd61185712a21e91337ace76b 2020-11-07 (refs/pull/179/merge)
| |_|_|_|_|/|   Merge dd3963dfe79b62aa7c8ddbb12fa0d97e698f8e66 into 0b1896650c2ba7100df450d698752090e6ba3b22 
|/| | | | | | 
| | | | | | | 
| | | | | | * dd3963dfe79b62aa7c8ddbb12fa0d97e698f8e66 2020-11-04 (tests-prioq)
| | | | | | |   Add some tests for prioq.
| | | | | | | 
* | | | | | | 0b1896650c2ba7100df450d698752090e6ba3b22 2020-11-04 (refs/pull/180/head)
| |_|_|_|_|/    add .gitattributes to keep some files out of release tarballs
|/| | | | |   
| | | | | |   
| | | | | | * 3950904fcf3c327a3ac88448850bc8a706ce12f6 2020-11-03 (refs/pull/89/merge)
| |_|_|_|_|/|   Merge fc3642a947c7c264bd72dbd023fa8253a730a844 into 129357b0a0eb10ec2b714ad198f63d9d016b8d59 
|/| | | | | | 
| | | | | | | 
| | | | | | * fc3642a947c7c264bd72dbd023fa8253a730a844 2020-11-03 (refs/pull/89/head, notqmail-tai-leapsecs)
| | | | | | |   code cleanup
| | | | | | | 
| | | | | | * 7e1dba3eddee53417c3ece7dc5d811baf088e5d1● 2020-10-25
| | | | | |/    Fix leap second handling on systems running TAI
| | | | |/|   
| | | | | | 
* | | | | | 129357b0a0eb10ec2b714ad198f63d9d016b8d59 2020-10-19 (refs/pull/119/head)
| |_|_|/ /    qmail-local: close race window when creating file in tmp/
|/| | | |   
| | | | |   
| | | | | * fc5a1ba10f074a0b534a9e06c574dcf59306cdfd 2020-11-03 (refs/pull/90/merge)
| |_|_|_|/|   Merge 5c6612203203c23ca5c3ece01ecf813d324b92b3 into 83e8e3215d2f664d6bb369562fcabb427fb18b5a 
|/| | | | | 
| | | | | | 
| | | | | * 5c6612203203c23ca5c3ece01ecf813d324b92b3 2020-10-19 (refs/pull/90/head, notqmail-maildir-uniqueness)
| | | | | |   Improve Maildir file uniqueness in qmail-local.c
| | | | | | 
* | | | | | 83e8e3215d2f664d6bb369562fcabb427fb18b5a 2020-09-12 (refs/pull/18/head)
| |_|_|_|/    qmail-remote: avoid recoding CRLF to CRCRLF
|/| | | |   
| | | | | 
* | | | | 0117ad3ff8a1354e0c6af3ebe2435c9bd5c4483a 2020-08-31 (refs/pull/176/head)
| |/ / /    GitHub: enable codescan
|/| | |   
| | | |   
| | | | * 920b644c4d7382b2a26dabab6177debbf0cfb08f 2020-07-26 (patches/notqmail/smtp-tls)
| | | | |   qmail-smtpd: factor out STARTTLS ehlo into it's own function
| | | | | 
| | | | * f4113db4af13aaf6e6a25be0254f8d617268701f● 2020-07-26
| | | | |   qmail-smtpd: move SSL implementation to it's own file
| | | | | 
| | | | * a9f70304662a87f5c475758626ff5f16e0ed0e02● 2020-07-26
| | | | |   Remove TLS define from the C code and conf-cc.
| | | | | 
| | | | * 2861b834b0bfe45cdbb5218b0fe89bdb034fc27d● 2020-07-26
| | | | |   Do not add directories to PATH in Makefile-cert.mk, update_tmprsadh.sh.
| | | | | 
| | | | * 600e3b74136872bdc8554c06ea76462a65cbf03d● 2020-07-26
| | | | |   conf-cc: remove -I/usr/local/ssl/include
| | | | | 
| | | | * a60a2ee8656f13e8a034166601024f5ab5c1d1cd● 2020-07-26
| | | | |   Makefile: remove -L/usr/local/ssl/lib qmail-remote, qmail-smtpd
| | | | | 
| | | | * f9031840b23a5729683b252ed6794d4085bdc485● 2020-07-26
| | | | |   Remove trailing whitespace in Makefile qmail-remote[.8c] qmail-smtpd.[8c]
| | | | | 
| | | | * 6579adb2672b297e9b099bd5f3c120608be09134● 2020-07-26
| | | | |   https://inoa.net/qmail-tls/ version 20200107
| | | | |   
| | | | | * d950cc34491afe90432cafcaeda61d1c1a9508e9 2020-07-26 (patches/Gentoo/qmail-spp-tls)
| | | | | |   Combined TLS and qmail-SPP patch
| | | | | | 
| | | | | * c467ba6880aaecfe1d3f592a7738de88cb5ac79a● 2020-06-07
| | | | |/    SMTP authentication for qmail-smtpd, qmail-remote, v0.8.3
| | | | |   
| | | | | * 0dc6a3aa9cb3440fe589ca5384ea27d683f05625 2020-07-25 (patches/Gentoo/auth+tls)
| | | | |/    combined TLS and AUTH patches
| | | | |   
| | | | | * 6c91888f9360aeb1133dfdf94164d0a45d3aabf5 2020-07-08 (patches/notqmail/ext-todo)
| | | | | |   qmail-todo: remove unneeded define
| | | | | | 
| | | | | * ef65fa7ad25d633c4b142544fe591dd856df3134● 2020-07-08
| | | | | |   qmail-todo: add fixes that were already done in the notqmail code
| | | | | | 
| | | | | * cef9ded6c5cf43cfcea594f21405c219b3e7ee7a● 2020-07-08
| | | | | |   move EXTTODO to EXTTODO.md
| | | | | | 
| | | | | * f840a046b9cc6db12b1a10f1a5f8557d2eb8c9c7● 2020-07-08
| | | | | |   Remove all code guarded by ifndef EXTERNAL_TODO.
| | | | | | 
| | | | | * f574065202647086b0d317ac0c084ce1a85f843a● 2020-07-08
| | | | | |   remove EXTERNAL_TODO define.
| | | | | | 
| | | | | * e41e83528d509d6237d2e45de833c1155c8b10a7● 2020-07-08
| |_|_|_|/    add ext_todo-20030105.patch
|/| | | |   
| | | | | 
* | | | | b52f6d20817fd850144b087bcc668407947dfb1a 2020-07-08 (refs/pull/159/head)
| | | | |   reintroduce alloc_re()
| | | | | 
* | | | | 0f35ad122eaba02b66fcd8432dd06ae71141b978 2020-07-08 (refs/pull/162/head)
| | | | |   qmail-remote: fix warnings about get() being used with wrong pointer signedness
| | | | | 
* | | | | b832c07698ea195277d30558d0e8e070cca625cd 2020-07-08 (refs/pull/155/head)
| | | | |   move auto_uidq variable into spawn.c
| | | | | 
* | | | | a0b5dd0044200f84234b7e7243be9bfb72c3f4c7● 2020-07-08
| | | | |   move extern declaration of hier() to hier.h
| | | | | 
* | | | | ade7b953a30ece73625e97a4bd0ad76e5ca3ed3a● 2020-07-08
| | | | |   move extern declarations out of spawn.c into a dedicated header
| | | | | 
* | | | | 4d9143831d8100617b8423a1deb342229f0bffbe● 2020-07-08
| | | | |   use C89 declarations in hier.h
| | | | | 
* | | | | 8e2f1b03fdd61685d2c0f09e9392542c558a8bff 2020-07-08 (refs/pull/170/head)
| | | | |   qmail-smtpd: allow [] to appear in received lines
| | | | | 
* | | | | 7fbaaa3d09293232ad0d88ce89fdda940c2c2919 2020-07-06 (refs/pull/169/head)
| | | | |   remove orphaned now.c
| | | | | 
* | | | | 1c58ce6710051a30ec908f31c30523b6a89c9e7e 2020-07-04 (refs/pull/163/head)
| | | | |   trynpbg1.c: add missing include
| | | | | 
* | | | | 096e794bad8dd074caa67315a96d069121081571● 2020-07-04
| | | | |   select.h: do not redeclare select() if including <sys/select.h>
| | | | | 
* | | | | f3a2c387477fbf28948c54afc4f8c475535d04cf 2020-07-04 (refs/pull/164/head)
| | | | |   qmail-send: use utimes() instead of utime()
| | | | |   
| | | | | * 100498b616a97f8c7a18e1e62b9b2c93fb6a4b8e 2020-07-01 (refs/pull/106/merge)
| |_|_|_|/|   Merge 6d05348d2044e2a9854e8e4f7d26c1573a6b2d5e into 619e7fcc9c90fe318d00d6e168e554f7b160e0ec 
|/| | | | | 
| | | | | | 
| | | | | * 6d05348d2044e2a9854e8e4f7d26c1573a6b2d5e 2020-07-01 (refs/pull/106/head, Dakon-compile)
| |_|_|_|/    get rid of "compile" command
|/| | | |   
| | | | | 
* | | | | 619e7fcc9c90fe318d00d6e168e554f7b160e0ec 2020-06-30 (refs/pull/161/head)
| | | | |   add missing includes for NULL
| | | | |   
| | | | | * 2bb94bec4d8b58fcecab170289d52f2f8c670d82 2020-06-21 (refs/pull/160/head)
| |_|_|_|/    check presence of struct utimbuf and use it if present
|/| | | |   
| | | | | 
* | | | | f3a33fdc5300a516682296018c580a13dc4af821 2020-06-21 (refs/pull/158/head)
| | | | |   make now() an inline function
| | | | | 
* | | | | 8a5ef2bef9844e066cab9f4a48fccfc4c40b3de0 2020-06-18 (refs/pull/93/head)
| | | | |   remove inefficient maildirwatch
| | | | | 
* | | | | 8bdeb55fde017cf79c5dafb199d6a04f8c8bea00 2020-06-15 (refs/pull/154/head)
| | | | |   TARGETS: drop needless auto_uid*.o and auto_gid*.o entries
| | | | | 
* | | | | 2a497f1483239b111ce7cba7279f171aa7e02821 2020-06-14 (refs/pull/152/head)
| | | | |   use NULL instead of casting 0 to a pointer type
| | | | | 
* | | | | 763638654f6d62ebb129f1b60a2fbf9d409590f4● 2020-06-14
| | | | |   dns: remove dns_cname, unused.
| | | | | 
* | | | | 796dbc19914bd6039cca7b6e19c9d38a8eb3a10f● 2020-06-14
| | | | |   qmail-remote: remove flagalias and flagallaliases, now useless
| | | | | 
* | | | | 0ed82f58cd3869b3d0196b692c65685b8d1faf8b● 2020-06-14
| | | | |   qmail-remote: remove flagcname, deprecated feature
| | | | |   
| | | | | * 81825951ac448e66376349e9e761a0489996b003 2020-06-14 (refs/pull/121/head)
| | | | | |   dns: remove dns_cname, unused.
| | | | | | 
| | | | | * 2858e23e275d06192af329bfe2bdbb9e30f8a5c0● 2020-06-14
| | | | | |   qmail-remote: remove flagalias and flagallaliases, now useless
| | | | | | 
| | | | | * 56de24543a6aa33b38aa94ec00c52983bbd5dc71● 2020-06-14
| |_|_|_|/    qmail-remote: remove flagcname, deprecated feature
|/| | | |   
| | | | | 
* | | | | 17dc89aeebb0dc3bdcab9a34da6d44c40fd337dc 2020-06-14 (refs/pull/150/head)
| | | | |   predate: use better version of calling time()
| | | | | 
* | | | | c556526488eee88c58b4cb91a9bb31a3f97170ee 2020-06-13 (refs/pull/151/head)
| | | | |   get rid of alloc_re()
| | | | | 
* | | | | 63d64d7cf894b83b43ce7c9ef9aa0b4cc0129723● 2020-06-13
| |/ / /    alloc.h: make first argument of alloc_re() void**
|/| | |   
| | | | 
* | | | 23acf56fffa0b317acdf5fad76387a9bda838f1c 2020-06-11 (refs/pull/145/head)
| | | |   use "return" to leave main() instead of _exit()
| | | | 
* | | | 3212ea53fde91e4394a5195b5fcd2d48d447735d● 2020-06-11
| | | |   make all main() functions return int
| | | | 
* | | | cff53ac08dadec27debcbfe6ea9bf76ae979247c 2020-06-11 (refs/pull/144/head)
| | | |   make most output of auto-str readable
| | | | 
* | | | 21d898f96dd02101759fcea39980aa81381b532a 2020-06-11 (refs/pull/146/head)
| | | |   add all missing headers
| | | | 
* | | | b34b6bdc740c611ffbba62269a13a559a3bc9aac● 2020-06-11
| | | |   add missing include in byte.h
| | | | 
* | | | 7dd9d3d076820faf6cb71d1bd6b1aed44fee9a0b● 2020-06-11
| | | |   get rid of seek.a
| | | | 
* | | | b39f9cae21ae20f36b836f8811b08adcb7881178● 2020-06-11
| | | |   Fix Markdown formatting in examples.
| | | | 
* | | | b7fce5a9aba53123a8f8f2cb353d034cd0ce39c3● 2020-06-11
| | | |   Replace --- with ### for headings.
| | | | 
* | | | 44bedb7d602e26e5e9f24e8489a564f46e8a4973● 2020-06-11
| | | |   Make THANKS an unordered list.
| | | | 
* | | | 0d0816c0fd11a85c7667c1c933628864b4980580● 2020-06-11
| | | |   Format unordered lists more consistently.
| | | | 
* | | | 95b68a746c390564b531e0c269b4ec5e9762b0b4● 2020-06-11
| | | |   Wrap URLs in <>.
| | | | 
* | | | 544752f57e23395f409a724aa427f9228a704813● 2020-06-11
| | | |   Make CHANGES an unordered list.
| | | | 
* | | | c488390edf026bbbb62439990274a6ee9c72cc3b● 2020-06-11
| | | |   Tabs to spaces.
| | | | 
* | | | c0a12823677de70f50b79a1f59b932e081b720b1● 2020-06-11
| | | |   Replace ```foo``` with `foo` for one-liners.
| | | | 
* | | | e2009717cb61419bc817b2fbef3e2a0951b7e8eb● 2020-06-11
| | | |   Replace ``foo'' with "foo".
| | | | 
* | | | e276badd22c5bb81d6c0ebdde6da4d670a9332d9● 2020-06-11
| | | |   Replace --- with -- when it's simulating em-dash.
| | | | 
* | | | 8b510badbbbbb5e4888f1b2d2ba525c9aa51a2c6● 2020-06-11
| | | |   Improve README Markdown.
| | | | 
* | | | 07e448198e2a00743d0fe5cd5f7263b564cd583f● 2020-06-11
| |/ /    Append .md suffix to text docs. Adjust references.
|/| |   
| | |   
| | | * 079513a911aed8d10f90ae496922cf18d5e45180 2020-06-10 (refs/pull/36/head)
| | | |   Fix Markdown formatting in examples.
| | | | 
| | | * 0a7996e281b884eb2ed41487f513071da06da5ad● 2020-06-10
| | | |   Replace --- with ### for headings.
| | | | 
| | | * a0b2188e8ad54cf088f3d7ff6693cfd460217611● 2020-06-10
| | | |   Make THANKS an unordered list.
| | | | 
| | | * 48dcdd63577d11b6185720f1cb73b7d8526984ae● 2020-06-10
| | | |   Format unordered lists more consistently.
| | | | 
| | | * c1c3e31ae7f3069e7cf18e56f81e2b821f6241d3● 2020-06-10
| | | |   Wrap URLs in <>.
| | | | 
| | | * d6a49c5bb7f03a7d73b2bad730ca1730f91cb86d● 2020-06-10
| | | |   Make CHANGES an unordered list.
| | | | 
| | | * e271049010e0e8fde24cec3b88ed9281af3a5b64● 2020-06-10
| | | |   Tabs to spaces.
| | | | 
| | | * 3db562602211d1837486613ed3f09e80468528f3● 2020-06-10
| | | |   Replace ```foo``` with `foo` for one-liners.
| | | | 
| | | * 3e0fa0d9a90fc6ce78a70644cc6f7de6f9be80ab● 2020-06-10
| | | |   Replace ``foo'' with "foo".
| | | | 
| | | * d77c7225f7cf1c977d1c67611de0d959afde6a0c● 2020-06-10
| | | |   Replace --- with -- when it's simulating em-dash.
| | | | 
| | | * 2e86dabbe4140ac3413a56a304fd774791e923ca● 2020-06-10
| | | |   Improve README Markdown.
| | | | 
| | | * 9746afb1dadbe99094cf1659a0ea311c4d82fe7e● 2020-06-10
| |_|/    Append .md suffix to text docs. Adjust references.
|/| |   
| | |   
| | | * b36d52a0dd7315a969f2a9a7455717466e45be23 2020-06-07 (patches/Gentoo/qmail-spp)
| | | |   qmail SPP patch
| | | | 
| | | * 92520a31d1628a8da91343721b8d3c111ac5bb14● 2020-06-06
| | |/    SMTP authentication for qmail-smtpd, qmail-remote, v0.8.3
| | |   
| | | * c31fe4d0324f03fc9466c9bb8720102b4c773760 2020-06-07 (patches/notqmail/qmail-spp-0.42)
| | | |   qmail-spp: remove needless initialization of global and static variables
| | | | 
| | | * 8060d75fe20619b93def79090d16446d33b540fb● 2020-06-07
| | | |   qmail-spp: fix incorrect usage of vfork()
| | | | 
| | | * c3c68df605ba3fa2e161dfca02085debfb31a2bd● 2020-06-07
| | |/    qmail SPP patch
| | |   
| | | * fc17cd1927fde8ee434f76ed899d5c7086197d38 2020-06-07 (patches/netqmail/qmail-spp-0.42)
| | | |   qmail SPP patch
| | | |   
| | | | * 4aa45158ceaed4b575c681c4f8a85f7bd843b829 2020-06-03 (patches/notqmail/rcptcheck)
| |_|_|/    RCPTCHECK patch
|/| | |   
| | | | 
* | | | 2bd54624f2c71c17b3b7ab5c955e3b17cdc9c53b 2020-05-24 (refs/pull/103/head)
| | | |   tests: remove now useless tests again
| | | | 
* | | | 3f6f81b6a15af234493af55c05948b73ef966126● 2020-05-24
| | | |   get rid of str_copy() and use the default strcpy() instead
| | | | 
* | | | 11047ed0a85a6afa5d147e3c5080326cfe4a5fe0● 2020-05-24
| | | |   get rid of byte_diff() and use the default memcmp() instead
| | | | 
* | | | 8759bd432bd7154d537e78284a3771668829e9c3● 2020-05-24
| | | |   qmail-local: replace !byte_diff() with byte_equal()
| | | | 
* | | | 7959e15d7b7326fef40d64f187af87612288b78e● 2020-05-24
| | | |   get rid of str_diffn() and use the default strncmp() instead
| | | | 
* | | | f7ec63b8edb59a179aa98e670df9aaffcd8eaf34● 2020-05-24
| | | |   get rid of str_diff() and use the default strcmp() instead
| | | | 
* | | | 3f9f95ccac176b30c0a8064589c0638561178023● 2020-05-24
| | | |   get rid of str_len() and just use the default strlen() instead
| | | | 
* | | | a10fd0cb80e1297d01f0fd2a4d96c4ea01c0b7bb● 2020-05-24
| | | |   tests: verify byte_diff() and some str_* functions
| | | | 
* | | | 213e9f2465744fe34d2c16e9acaa582f5011da98● 2020-05-24
| | | |   tests: add results to .gitignore
| | | | 
* | | | 626e9a5a860a4a187bd0188b0019c72514da1ef7● 2020-05-23
| | | |   Remove qsmhook, long since replaced by preline.
| | | |   
| | | | * c175631f5f621d71c7fce328060de6869afc141f 2020-05-23 (refs/pull/87/head)
| |_|_|/    Remove qsmhook, long since replaced by preline.
|/| | |   
| | | | 
* | | | 1beb767af91f28fd619421a46c885a8a48034ef3● 2020-05-23
| | | |   scan_*.c: convert to prototypes
| | | | 
* | | | c9e89f04af23f5ac55744476b9c88ada4b8fbb93● 2020-05-23
| | | |   scan.h: use prototypes, remove missing functions
| | | |     
| | | | *   7cac39099b81c588733965899242bd22a8034aee 2020-05-23 (refs/pull/129/head)
| | | | |\    Merge branch 'master' into scan-prototypes
| |_|_|_|/  
|/| | | |   
| | | | | 
* | | | | 5a214f931f1b5575e3cf4b037179eb5f665028c1 2020-05-23 (refs/pull/140/head)
| | | | |   remove unused substdio_bget()
| | | | |   
| | | | *   0a69ff2b142c4a5c84379de09761b2bb82dfe5c9● 2020-05-23
| | | | |\    Merge branch 'master' into scan-prototypes
| |_|_|_|/  
|/| | | |   
| | | | | 
* | | | | 72c58ae8b2b8d5185449c120fd0844be1933a899 2020-05-23 (refs/pull/126/head)
| | | | |   fmt_*.c: convert to prototypes
| | | | | 
* | | | | ada4bb3eddc37f74d9318b06551b601b62a45328● 2020-05-23
|/ / / /    fmt.h: use prototypes, remove missing functions
| | | | 
| | | * 6228fcbb1e523cedad8f608ec89f730d3cbe105a● 2020-05-23
| | | |   scan_*.c: convert to prototypes
| | | | 
| | | * c28f0ff4b98530c9512aec2adee919b160a2c86e● 2020-05-23
| |_|/    scan.h: use prototypes, remove missing functions
|/| |   
| | | 
* | | e90b5a7888155c1714468ad7c2860e714cd603e7 2020-05-23 (refs/pull/139/head, refs/pull/105/head)
| | |   use POSIX compliant calling of head and tail
| | | 
* | | 1720e0b1be1ffc2ededf8366c6b4a5a831b31d52 2020-05-23 (refs/pull/124/head)
| | |   remove the custom allocator
| | | 
* | | 618c2d113760f1a98c33a135dd81693879c7e1d6● 2020-05-23
| | |   remove the "alloc" parameter from cdbmake_add() and cdbmake_split()
| | | 
* | | 43b7cb5e1c97005a3995c5d46da6ec5d4142e76e 2020-05-23 (refs/pull/130/head)
| | |   use default strdup() instead of open coding it
| | | 
* | | 2b3f38616ec0ae151e8556566fce4b4a3139fdd1 2020-05-22 (refs/pull/137/head)
| | |   add back accidentially removed typecast
| | |   
| | | * 2689abf6277e9f1bbb0ff4cee4a800905a8944c8 2020-05-22 (patches/netqmail/badmailfrom-wildcard)
| | | |   grammar cleanup in qmail-smtpd.8 to match the rest of that manpage.
| | | | 
| | | * 58d671f8e3b07f84a1e352edf88ff68d13f5c77e● 2020-05-22
| | |/    badmailfrom wildcard patch
| | |   
| | | * 3a22b45974ddd1230da0dfa21f886c3401bee020 2020-05-21 (notqmail-big-todo)
| |_|/    Apply Russell Nelson's big-todo.103.patch.
|/| |   
| | |   
| | | * 28f8ec8d5cbecf4d3d1f446a06ef64df4f220a69 2020-05-21 (patches/notqmail/smtp-auth)
| | | |   Remove FILES.auth.
| | | | 
| | | * b224a3ceb63ff8ebc57648bf304e079d0bf55023● 2020-05-21
| |_|/    SMTP authentication for qmail-smtpd, qmail-remote, v0.8.3
|/| |   
| | | 
* | | f6c2a90177f88c0353c75fb4aaa74d2ff3b1c533 2020-05-20 (refs/pull/99/head)
|/ /    remove obsolete mail client wrappers
| | 
* | bf692cf45ec6d679ba194f80862f17db4c415eb4● 2020-05-20 (tag: notqmail-1.08)
| |   Note CVE and other overflow fixes in CHANGES.
| | 
* | a385b5e9b2fb8f84c48a14d49452918ad2f3fa45● 2020-05-20
| |   This is notqmail 1.08.
| |   
| | * 69f8ce0c4bbc48937c41283dbc65201eb8ed0a58 2020-05-20 (refs/pull/135/head)
| | |   Note CVE and other overflow fixes in CHANGES.
| | | 
| | * 7846b4ee3215af2efceaeddd4eeb456754f8248e● 2020-05-20
| |/    This is notqmail 1.08.
|/|   
| | 
* | 0ed8a00eec3520d2dcbcd73c8eaacc96ccfbd8e8● 2020-05-20
| |   Add missing include for strncmp, found in CI.
| | 
* | 95f86dafbb94c00dbbecd01fadb7c0c659aafe51● 2020-05-20
| |   Let NROFF be redefined in the environment.
| |   
| | * 1b937a7bd138665ab3fc0ffd86a86b7c3ef3f8da 2020-05-20 (refs/pull/132/head)
| | |   Add missing include for strncmp, found in CI.
| | | 
| | * 795244f93f76697445a99da2fddee656c6c77d58● 2020-05-20
| |/    Let NROFF be redefined in the environment.
|/|   
| | 
* | aa064ddaf2116a5ff210048dc30d75ce06169bd5 2020-05-19 (refs/pull/134/head)
| |   Make: make catman dependency rule portable
| | 
* | 6ba74b15e1beae4526cbe8a73411be9acf25e21b● 2020-05-19
| |   CI: make the NROFF tests to actually override nroff
| | 
* | 348e57528018d5b93e8d7e81d622d553c4a86401 2020-05-19 (refs/pull/133/head)
| |   use unsigned variables in qmail-send
| | 
* | 22b04144743507f991d142a4b67f6fe550c64361● 2020-05-19
| |   use unsigned variables to store the result of str_len()
| | 
* | 9aba4fcedcb5005df99354261f0a427808a8f2d6● 2020-05-19
| |   use unsigned variables in qmail-pop3d
| | 
* | e4fa409afaf82ba7e3beab24cbb1bb6268ca7604● 2020-05-19
| |   use unsigned variables for array offsets in main() of qmail-local
| | 
* | ba8c208bbdde16cc8da9ee7ff0b14086a65b37c3● 2020-05-19
| |   fix possible length calculation overflow in stralloc_catb() and stralloc_copyb()
| | 
* | ad73be052759c9472bcd1b871bd402eacf80da78● 2020-05-19
| |   fix string length calculation overflow in quote() helper
| | 
* | 628b8661ef57c9d5badd1a808482f88a31c4da4d● 2020-05-19
| |   fix possible signed integer overflow in commands() (CVE-2005-1514)
| | 
* | 0cbc0ef8319a4b077cf1abc93c498d53eecb68ef● 2020-05-19
| |   fix possible overflows in array allocation length calculations
| | 
* | b105c46dd05027f2cdb551e721253b3b8319ba16● 2020-05-19
| |   fix signedness wraparound in substdio_bput()
| | 
* | 6d879abedf97733273fc1011d44b26f8980d04fa● 2020-05-19
| |   unwrap lines in substdio_bput()
| | 
* | e794b49925c1a1762aece35a5d7e09f1444d1ab7● 2020-05-19
| |   fix signedness wraparound in substdio_put() (CVE-2005-1515)
| | 
* | 2fe3ac71d35e68d1d42273a3925b9f7dc8020742● 2020-05-19
| |   genalloc: make sure allocation sizes never overflow
| | 
* | 8038bf6547e85382dcb6696c55bec8d8b127e668● 2020-05-19
| |   genalloc: make sure the new count variable does not overflow
| | 
* | 105e01c5cbdd7f042043f595794f12ff8664dda3● 2020-05-19
| |   add compat version of __builtin_{add,mul}_overflow()
| | 
* | edf54c818e5549026098acd95ae44f0ddf6a7722 2020-05-19 (refs/pull/128/head)
| |   include alloc.h in gen_allocdefs.h
| | 
* | 8fd5473a2572c7ac39459f5059f1cc8bdc32d59c● 2020-05-19
| |   genalloc: unfold tail code
| | 
* | 8b68e39ca627bf0bbb3432beed0143e088af4307● 2020-05-19
| |   genalloc: invert code flow
| | 
* | a41404c584fb9c7f6a8d0980fac2dd6016ccf2cc● 2020-05-18
| |   genalloc: do not rename parameter names
| | 
* | 5806288c361b44e976e7db89a79c11efd7af068a● 2020-05-18
| |   genalloc: generate C89 function interfaces
| | 
* | 20c4811b01dce3946ee30fe13795c67316acda29● 2020-05-18
| |   genalloc: unify GEN_ALLOC_readyplus and GEN_ALLOC_ready internals
| | 
* | 721a288c135438335a7a5031f3237612d3213e1a● 2020-05-18
| |   genalloc: reorder callers
| | 
* | 9175e79ba34ff745dfdb0948ba04aedff07f2f8e● 2020-05-18
| |   genalloc: reorder functions in header
| | 
* | d52e4b288fe54c6b056d51b0e42768f95d6563d0 2020-05-18 (refs/pull/131/head)
| |   add GitHub actions test build
| | 
* | 30a44402454eca17beb8339a8b661cc8683be5b3 2020-05-14 (refs/pull/92/head)
| |   qmail-pop3d: exit 1, pronto, if running as root.
| | 
* | 2a469cc632ac74bc2cb915e6f8cd0ccc330d88f6● 2020-05-14
| |   qmail-popup: leave kid's stderr alone for logging.
| | 
* | 691e99b6dff1aef5dfe8e5ab5e73da8bc3145bc7 2020-05-14 (refs/pull/79/head)
| |   add exit.h to qmail-pw2u.c and qmail-qmtpd.c.
| | 
* | 174a1ba70e9b8e3109570a4cbc2ff70614aacbd6● 2020-05-14
| |   remove exit.h from forward.c, maildirwatch.c.
| | 
* | 1a5f99f9b545d78a7c9354f6f10162fb6fd42653● 2020-05-14
| |   include unistd.h in exit.h to declare _exit.
| | 
* | 7e89111010ad51dedb0038a052d4991f06e24944 2020-05-12 (refs/pull/72/head)
| |   change function signatures to C89 style that were touched in last commit
| | 
* | f7b6124770eb34b2e8ff835928cf30e8f6e8d976● 2020-05-12
| |   remove HASSHORTSETGROUPS test, use system headers and types instead.
| | 
* | b75af9b4adebaa3208029df33a82f5fdabf230b0 2020-05-11 (refs/pull/113/head)
| |   rename local variables shadowing global variables of the same name
| | 
* | 8fa4b8b8dc70bab372d2ffd8fcb05546bfe7e2cc 2020-05-11 (refs/pull/102/head)
| |   add minimal unittest documentation
| | 
* | 0609d1b3eb8381cf3144f362c3e7bad668d5511c● 2020-05-10
| |   tests: check stralloc allocation size behavior
| | 
* | edb4c964489bdf862bf0db918ebe264bf12bb3e3● 2020-05-10
| |   Add a test target and one unit test, using Check.
| |   
| | * e8a1e037afc8729bd65d4bda36dedf444f301c0f 2020-05-19 (netqmail-CVE-2005-minimal)
| | |   fix additional length overflows
| | | 
| | * bb92ea678c2a2a524d2ee6e9d598275a659168d2● 2020-05-19
| | |   mimimum fix for CVE-2005-1513
| | | 
| | * dc617a2f2d31e4c448b806791b3f8736cf9d1ffb● 2020-05-19
| | |   fix possible signed integer overflow in commands() (CVE-2005-1514)
| | | 
| | * 5540e1b47ac043033e6661b4e04dcaf958db0110● 2020-05-19
| |/    fix signedness wraparound in substdio_put() (CVE-2005-1515)
| |   
| | * 6d02c0e233d29091e38f9760201a2f70c6375e9e 2020-05-06 (refs/pull/107/merge)
| |/|   Merge bef9faf2a0ce5ccdb505eff63d926320bd390d7d into 2ad04dbba5e70dd1ce9ebef8c492ec846371e42b 
|/| | 
| | | 
| | * bef9faf2a0ce5ccdb505eff63d926320bd390d7d 2019-10-17 (refs/pull/107/head, Dakon-configure)
| | |   TravisCI: use configure
| | | 
| | * 09549b2d779ce50649a4afe5ab6fc2c522f30fe8● 2019-10-17
| | |   remove needless space in conf-qmail
| | | 
| | * bb01855879a6f0cf9f47f92997aaa7ecd6e916a2● 2019-10-17
| | |   add configure program for easy configuration
| | | 
* | | 2ad04dbba5e70dd1ce9ebef8c492ec846371e42b 2020-04-14 (refs/pull/125/head)
| | |   CirrusCI: disable 11.2 image for the moment
| | | 
* | | 53d89cb9b5f7efba9a52565889b5b54dcedfae07● 2020-04-14
| | |   CirrusCI: update to FreeBSD 12.1
| | | 
* | | 83cba28f3d70445f150bbcbebec16a1a2612ef29 2020-03-07 (refs/pull/116/head)
| | |   allow to override nroff during build, and optionally skip installing cat pages
| | |   
| | | * 3b4861cbd406e4b30b157baa7d206562cd8fae49 2020-04-13 (refs/pull/123/head)
| |_|/    remove alloc.c, wrapper over malloc and use malloc directly
|/| |   
| | | 
* | | 7c7122a2d3a18af32c977ea9b34ebe526cc2fa0e 2020-02-03 (refs/pull/108/head)
| | |   remove the need for exit.h in named pipe bug check
| | |   
| | | * 69793eb3052733e038abb68f36f24cfd6c2474e1 2020-02-03 (refs/pull/117/head, Dakon-queue-perm)
| |_|/    make the queue directory world readable
|/| |   
| | | 
* | | 10057e900be66128f16fb7fb8d4d2a08f6934742 2020-02-03 (refs/pull/118/head)
| | |   Add acknowledgement for the bug fix contribution to qmail-local.c
| | | 
* | | e09fa0bd55f42d93a3c174405da411706a7c885a 2020-01-02 (refs/pull/114/head)
| | |   optionally create a systemd service file
| | | 
* | | 8f0f1403e461b588596a8c34316ce5494f79540e 2019-12-30 (refs/pull/54/head)
| | |   replace many pobox.com URLs
| | | 
* | | 3300f247a6c11e7bc5488314062ae5defe7c8299 2019-12-28 (refs/pull/110/head)
| | |   add deprecation message to obsolete mail client wrappers
| | | 
* | | 1961479e0099897c37621362bf872306cb70dcc1 2019-12-27 (refs/pull/111/head)
| | |   move some variables to a more local scope
| | | 
* | | 75a935b5def0bc2fe3e282c643ca5f48fe8c9a90 2019-12-27 (refs/pull/109/head)
| | |   fix possible integer overflow in alloc()
| | |   
| | | * f9103270f603eda4147ebc06861f9a49f19c2dc0 2019-12-27 (refs/pull/50/head, spawn-filter)
| | | |   ignore regex compilation error for invalid regular expressions
| | | |     
| | | | *   a1be2d963a220e72bcdc41e2bbf4ec297b97e07d 2019-12-27 (refs/pull/37/head)
| | | | |\    Merge branch 'master' into alloc_overflow-fix
| |_|_|_|/  
|/| | | |   
| | | | | 
* | | | | cd8193f4bfaaa2650c2472763ec6bf41ae882539 2019-12-26 (refs/pull/85/head)
| |/ / /    add missing return types to main()
|/| | |   
| | | | 
* | | | ecf4d7faa041aed1345f47d931f0e2e8fa6a6b70 2019-09-22 (refs/pull/101/head)
| | | |   use system headers for files introduced since netqmail-1.06
| | | | 
* | | | b05ec6cbdacdf40d6c75326394461e22b7f8ab20● 2019-09-22
| | | |   Apply Jonathan de Boyne Pollard's any-to-cname patch.
| | | | 
| | | * b0f59739fc3db8dbe9d4159df5915bc8764a7e18● 2019-08-31
| | | |   added #ifdef HAS_BUILTIN_OVERFLOW to use __builtin_add_overflow()
| | | | 
| | | * 0c5582375e974669d0f2d1f378243bcc4cb347bc● 2019-08-31
| | | |   added trybltnoverflow.c to check for builtin_overflow_add support in the compiler
| | | | 
| | | * 45269a8a147bac37e5d7157f758d54d8ddbd7ed5● 2019-08-31
| | | |   added check for compiler suport for builtin_overflow_add()
| | | | 
| | | * 2159c37da559026eda20f11e2b538bf05ead7be1● 2019-08-31
| | | |   use __builtin_add_overflow
| | | | 
| | | * 6d1578c0f488b31d70cf3d4476a414066e446f3f● 2019-08-31
| | | |   fix overflow in alloc.c
| | | |     
| | | | *   51847d8909892c9486444f338df0118618c017ac 2019-09-22 (refs/pull/97/head)
| | | | |\    Merge branch 'master' into notqmail-dns-any-to-cname
| |_|_|_|/  
|/| | | |   
| | | | | 
* | | | | 9ef349af5c83f54b4d62fdcc90e9603aa55c149d 2019-09-22 (refs/pull/100/head)
| | | | |   change function signatures to C89 style that were touched since netqmail-1.06
| | | | | 
* | | | | b8fb15d71f70bddff87ea5aa2b56b0da0f91bea7● 2019-09-22
| | | | |   ipme: fix detection of multiple IP addresses on the same link
| | | | | 
* | | | | 390afb7cf05fbafef68788c6388037bf87d1f862● 2019-09-22
| | | | |   ask kernel for the correct buffer size to satisfy SIOCGIFCONF before looping
| | | | | 
| | | | * 97a635e8a7fd4d57c8ec6614484ed03cd2831d76● 2019-09-01
| | | |/    Apply Jonathan de Boyne Pollard's any-to-cname patch.
| | | |   
| | | | * 9d6c05d092e3cf94a6591cd5420f8026fcd4691f 2019-09-22 (refs/pull/96/head)
| | | | |   ipme: fix detection of multiple IP addresses on the same link
| | | | | 
| | | | * d24a34857afc33ed11da9ba62736c0bb9b3e5b94● 2019-09-22
| |_|_|/    ask kernel for the correct buffer size to satisfy SIOCGIFCONF before looping
|/| | |   
| | | | 
* | | | cc9df61c573e7cd0bc2f2758d5cd65f95c4614d1● 2019-09-04
| | | |   use <stdint.h> to get a really portable 32 bit unsigned type
| | | |   
| | | | * 43e2641de84d22c85f5955e44dd1a260aaa5a036 2019-09-04 (refs/pull/30/head)
| |_|_|/    use <stdint.h> to get a really portable 32 bit unsigned type
|/| | |   
| | | | 
* | | | 56e7c4a74087d47889355c2c55352cc4d0482020 2019-09-03 (refs/pull/8/head)
| | | |   qmail-inject: do not parse header recipients if "-a" is given
| | | |   
| | | | * 6b61c52ebc65fa49391a9399684af687346caf1b 2019-09-03 (refs/pull/50/merge)
| |_|_|/|   Merge b27c6ae498c547570ba813638011fddc44aa7c46● into fc0227c2a792f6674674447395bd7c4209df831c● 
|/| | |/  
| | |/|   
| | | | 
| | * | b27c6ae498c547570ba813638011fddc44aa7c46● 2019-09-03
| | | |   removed wildmat funciton
| | | | 
| | * | a656f62e79c28b89da2ea1e1534a495d06cb7447● 2019-09-03
| | | |   removed wildmat function
| | | | 
| | * | 9ad653402daf55dc0a13469848008ac73f202a48● 2019-09-03
| | | |   updated for adding spawn-filter
| | | | 
| | * | 7d377c1be84aa4889a217e99ad6fc1272efe1e5b● 2019-09-03
| | | |   added reference to spawn-filter
| | | | 
| | * | ca1ee988b2b61a77b362a762bf181fe9fd676e5a● 2019-09-03
| | | |   added note on QMAILLOCAL environment variable
| | | | 
| | * | 8241af826fc313a59bd2c224353fffc997fc0bb3● 2019-09-03
| | | |   added note on QMAILREMOTE environment variable
| | | | 
| | * | 20a989d6eda1008784809306d4358aaf05cf3439● 2019-09-03
| | | |   added reference to filterargs control file used by spawn-filter
| | | | 
| | * | 88201e311beeb006c97c0483bddcf6cf6ceba310● 2019-09-03
| | | |   fix dependencies to envread()
| | | | 
| | * | 10dcf812b6bf30613461c7bf45a0485c0bfcc35c● 2019-09-03
| |/ /    added spawn-filter for alternate qmail-remote/qmail-local
|/| |   
| | | 
* | | fc0227c2a792f6674674447395bd7c4209df831c● 2019-09-02
| | |   remove TODO.
| | |   
| | | * 907100f60cb062d133cc2663bcb4b1c8117e79bc 2019-09-02 (refs/pull/68/head)
| |_|/    remove TODO.
|/| |   
| | | 
* | | e604c91941478c74b73f17946847ab0d4546b7bc● 2019-09-01
| |/    CI: add FreeBSD builds via CirrusCI
|/|   
| |   
| | * 893f4bd344d612c0b271059e4476b8eddeb87a97 2019-09-01 (refs/pull/98/head)
| |/    CI: add FreeBSD builds via CirrusCI
|/|   
| |   
| | * 7bea29adb781f06a9a1c633e965d6b46f84e7542 2019-08-27 (refs/pull/70/merge)
| |/|   Merge 110bf49647758f0720b3f38244612a147a46586d into 143784b98ec99a96da60edccd2095cbbc77c6577● 
|/| | 
| | | 
| | * 110bf49647758f0720b3f38244612a147a46586d 2019-08-27 (refs/pull/70/head)
| |/    remove register storage class declaration from codebase.
|/|   
| |   
| | * 005c5752ae4c25fcead04bb4cbe3677470324f8a 2019-08-27 (refs/pull/77/merge)
| |/|   Merge 3b2ef5d932be9bf5e23719de28f938f60096e6a6 into 143784b98ec99a96da60edccd2095cbbc77c6577● 
|/| | 
| | | 
| | * 3b2ef5d932be9bf5e23719de28f938f60096e6a6 2019-08-27 (refs/pull/77/head)
| | |   quote.c, quote.h function declarations are now C89.
| | | 
| | * 33db3bf64737c3bf77582debcce108f18021955a● 2019-08-27
| | |   fifo.c, fifo.h function declarations are now C89.
| | | 
| | * 76f3576a7e2aa8a47761923480d3cf7acf061e5f● 2019-08-27
| | |   wait_*.c, wait.h function declarations are now C89.
| | | 
| | * 659d0c21f41b4062db882b235e56d26e053c079e● 2019-08-27
| | |   ndelay*.c, ndelay.h function declarations are now C89.
| | | 
| | * 8a9d80d97d04082ef7ca9a184f7b1ec44d19db8e● 2019-08-27
| | |   seek_*.c, seek.h function declarations are now C89.
| | | 
| | * 7032a3693baefe6f6305d4d06f81a658a227dad0● 2019-08-27
| | |   open_*.c, open.h function declarations are now C89.
| | | 
| | * ac7a2eb21283d05b981b6856e127fe3fb7f1f5bf● 2019-08-27
| | |   prot.c, prot.h function declarations are now C89.
| | | 
| | * 0e2316ba85fe6276dabb5b8ed80f09b924c97cfb● 2019-08-27
| | |   lock_*.c, lock.h function declarations are now C89.
| | | 
| | * cb274e19e432f6e622e22f5c8d2a3da761336d79● 2019-08-27
| | |   fd_copy.c, fd_move,c, fd.h function declarations are now C89.
| | | 
| | * 7b70927c94213cdfb4a5477a6eb6fa6d87171f56● 2019-08-27
| | |   coe.c, coe.h function declarations are now C89.
| | | 
| | * ca2ce0932b3d72ad8f1b141449f31d0c7533c5ea● 2019-08-27
| | |   all main entry-point declarations are now C89.
| | | 
| | * dce6c4d36643c114f7e79642ece726ed8100b093● 2019-08-27
| |/    add missing return types to main()
|/|   
| | 
* | 143784b98ec99a96da60edccd2095cbbc77c6577● 2019-08-27
| |   Run alternate qmail-remote by setting QMAILREMOTE.
| |   
| | * e8e169c03815f9650bd2108bdb8e7a57fd5cf5ab 2019-08-27 (refs/pull/71/merge)
| |/|   Merge 60d60d0afe18096a3913fd28d2731ebac5ea4572 into 7db974d412ac0e6e7ed80df9738ebbb3d1eaa582● 
|/| | 
| | | 
| | * 60d60d0afe18096a3913fd28d2731ebac5ea4572 2019-08-25 (refs/pull/71/head)
| | |   Remove the install script.
| | |   
| | | * 175529d0dfe0900978a8975baa1dd986474425d9 2019-08-26 (refs/pull/46/head)
| |_|/    Run alternate qmail-remote by setting QMAILREMOTE.
|/| |   
| | |   
| | | * 33f38ece6530c617b216400bb74accfb331eb874 2019-08-26 (refs/pull/67/merge)
| |_|/|   Merge 59f3d296e9af096f4d4ae78e0f5b39583377db84 into 7db974d412ac0e6e7ed80df9738ebbb3d1eaa582● 
|/| | | 
| | | | 
| | | * 59f3d296e9af096f4d4ae78e0f5b39583377db84 2019-08-25 (refs/pull/67/head)
| | |/    remove qmail-upq.
| | | 
* | | 7db974d412ac0e6e7ed80df9738ebbb3d1eaa582● 2019-08-25
| | |   add forward declaration for scan_8long()
| | | 
* | | f224e8c03268b5f9d9feae0da928af2e54b6dde6● 2019-08-25
| | |   add forward declarations for cdbmss_*
| | | 
* | | c4425a94f38d291daaab5659cacdf2ac806be710● 2019-08-25
| | |   add forward declarations for functions from hier.c
| | |   
| | | * a2bc2ec3cc30a42f52057dfe4755f492267e5fc3 2019-08-25 (refs/pull/64/head)
| | | |   add forward declaration for scan_8long()
| | | | 
| | | * 9c3711f127614ac1b9d58b5ac8b6e303f81b3ba3● 2019-08-25
| | | |   add forward declarations for cdbmss_*
| | | | 
| | | * e6ae57c2911e3bfadc6801d7bddb56167d7d212a● 2019-08-25
| |_|/    add forward declarations for functions from hier.c
|/| |   
| | | 
* | | 089e7543ed6d517804586f0404bab870949eb549● 2019-08-25
| |/    TravisCI: avoid needless indirection for environment variable
|/|   
| |   
| | * 5b99ccbd5ea74f97cb2b6b26cf74876a687f0465 2019-08-25 (refs/pull/58/head)
| |/    TravisCI: avoid needless indirection for environment variable
|/|   
| |   
| | * 889c75e0946caf787717fef369e5adece91f21bf 2019-08-25 (refs/pull/35/merge)
| |/|   Merge 8756cbb9b76e78c0f2a205b3a51f8f5de7d9c61c into eed60957b5cf8de9abf8fd3bac4d329586536e01● 
|/| | 
| | | 
| | * 8756cbb9b76e78c0f2a205b3a51f8f5de7d9c61c 2019-08-25 (refs/pull/35/head)
| | |   last commit: remove auto_qmail
| | | 
| | * 54b487e69367f29aa0391842032a9caa8a3e78c0● 2019-08-25
| | |   make qmail-inject die_chdir error message more sendmail-like.
| | | 
| | * 3192536f3bdfd40f14565e6285d40e079b381dd0● 2019-08-25
| | |   auto_qmail_users
| | | 
| | * 7651981c5449ebed250d575f8f36fe0a873fac4f● 2019-08-25
| | |   auto_qmail_queue optional
| | | 
| | * 93caecb490f9aefc542c620712a99a18bd7e60d8● 2019-08-25
| | |   auto_qmail_queue
| | | 
| | * cf70c28ea80b4165264cb5f8edfa668484a6c912● 2019-08-25
| | |   auto_qmail_control
| | | 
| | * 3391e88392cfdc3cae8d2e646df093f6c8faedae● 2019-08-25
| | |   auto_qmail_bin
| | | 
| | * 0332428342f143e8a05426ddf570eb7ac93b02e8● 2019-08-25
| | |   QMAILUSERS
| | | 
| | * e196e01e0c374ef178c47bec7f7d66064a425f31● 2019-08-25
| | |   QMAILQUEUE
| | | 
| | * 3a86ef6d27017870bfc43f69ebcfb7be731b4025● 2019-08-25
| | |   QMAILCONTROL
| | | 
| | * 3fa401ff50bde3d32fd7a953baff459b45e1be9e● 2019-08-25
| | |   QMAILBIN
| | | 
| | * a5bb55d36b76276c2f8c43bc753d5375b0cd6664● 2019-08-25
| | |   QMAILALIAS
| | | 
| | * 319df5061985451951b5a63fc140f55bbd597af9● 2019-08-25
| | |   qmail-smtpd: auto_qmail_bin, auto_qmail_control
| | | 
| | * ed3898ff913eddccadbdb61b53f324b0009177dc● 2019-08-25
| | |   qmail-showctl: report all auto_qmail_* directory paths.
| | | 
| | * a3f218bc413c963d6786a737c5acad0620c4d6b8● 2019-08-25
| | |   qmail-send: auto_qmail_bin, auto_qmail_control, and auto_qmail_queue
| | | 
| | * 59f98deb22a50c870cb160f55fd61a9ba62f9c66● 2019-08-25
| | |   qmail-rspawn: chdir to auto_qmail_bin before execv.
| | | 
| | * 0c42822c60d9e6c83138d6848b81031abf758df6● 2019-08-25
| | |   qmail-remote: auto_qmail_control, auto_qmail_queue.
| | | 
| | * 9baccd9877f4171c48607296f3fba4a105d4738f● 2019-08-25
| | |   qmail-qmtpd: auto_qmail_bin, auto_qmail_control
| | | 
| | * 0fcda4cd6f789fda4e0c7a9d0f9b4340079d2c25● 2019-08-25
| | |   qmail-qmqpd: auto_qmail_bin, auto_qmail_queue
| | | 
| | * 41b73ee684108fa6bc31ad74f6265a3d0ebd3118● 2019-08-25
| | |   qmail-lspawn: depend on -bin, -qmail, and -users.
| | | 
| | * 538ec2bc2a635182ed0ef66a056a223f66df233c● 2019-08-25
| | |   qmail-inject: auto_qmail_bin, auto_qmail_control
| | | 
| | * 5d59a9f3d69f131a9ad385105e8422d41d0232ba● 2019-08-25
| | |   add conf-qmail-* dependencies to various install targets.
| | | 
| | * e3147339447241b3577a5dce7a015a03df6662ba● 2019-08-25
| | |   split conf-qmail in to per-directory configuration.
| | | 
| | * 3986a7f3cb4f8aed853f1b23bd66178fdb7d6d27● 2019-08-25
| | |   Makefile: de-SPLIT.
| | | 
| | * 65a0e659d4dadb70d4353c74e077fd0c19b82866● 2019-08-25
| | |   Makefile: de-SPAWN.
| | | 
| | * 94a36e83c8bbd8d7294b7a22eb8b42e40b7607ab● 2019-08-25
| | |   Makefile: de-BREAK.
| | | 
| | * dd97c9dbb96df1dc81a0857519084900047b5748● 2019-08-25
| |/    Makefile: de-QMAILHOME.
|/|   
| |   
| | * 5eeef0ea6fab500b6efc7045fa05198a0cada19a 2019-08-25 (refs/pull/43/merge)
| |/|   Merge 7a10f657054cf31cdeefdcde7c5b03c1a1bd5b2d into eed60957b5cf8de9abf8fd3bac4d329586536e01● 
|/| | 
| | | 
| | * 7a10f657054cf31cdeefdcde7c5b03c1a1bd5b2d 2019-08-25 (refs/pull/43/head, pr-remove-readwrite-h)
| |/    cleanup: remove readwrite.h, use unistd.h instead.
|/|   
| |   
| | * 8096d4422bc2a4635845c9e82891e2553f38ef34 2019-08-25 (refs/pull/44/merge)
| |/|   Merge ab198937360aaf0d7f8382be557a226d9efb30c5 into eed60957b5cf8de9abf8fd3bac4d329586536e01● 
|/| | 
| | | 
| | * ab198937360aaf0d7f8382be557a226d9efb30c5 2019-08-25 (refs/pull/44/head)
| | |   cleanup: remove exit.h, use unistd.h instead.
| | | 
| | * 7743d6aa95300c8d6380dfb97151c5c4baf65424● 2019-08-25
| | |   remove exit.h from forward.c, maildirwatch.c.
| | | 
| | * bb1b4a78ea5f42bd2be2d358c741598f8731e89c● 2019-08-25
| | |   add exit.h to qmail-pw2u.c and qmail-qmtpd.c.
| | | 
| | * b83e827e60990db19f31565c8163798a170a3eb9● 2019-08-25
| |/    include unistd.h in exit.h to declare _exit.
|/|   
| |   
| | * d13b047c943e839c6cf39f2a6a692ca14ddef047 2019-08-25 (TravisCI)
| |/    TravisCI: test external patch(es)
|/|   
| |   
| | * babf55fedf46d889f7295ca01332f995993157ef 2019-08-25 (refs/pull/45/head)
| |/    use uid_t and gid_t
|/|   
| | 
* | eed60957b5cf8de9abf8fd3bac4d329586536e01● 2019-08-25
| |   remove systype and attendant platform detection.
| |   
| | * 97c43155ea650c46a0746c070adee5f9a09fc3c9 2019-08-25 (refs/pull/34/head)
| |/    remove systype and attendant platform detection.
|/|   
| | 
* | 77f058cb8c01cc257624b0f4e1d07979b69a4e12● 2019-08-25
| |   remove dnsmxip.
| | 
* | 123fa007ca4e6e5ba55c62775c5d24a6c3ab794d● 2019-08-25
| |   remove dnscname.
| |   
| | * cb838b5400f2fe2eb00623ccf352a9f8f882be13 2019-08-25 (refs/pull/69/head)
| | |   remove dnsmxip.
| | | 
| | * aa5b01854d3d7fc03cefb47f53507371b2d1fb89● 2019-08-25
| |/    remove dnscname.
|/|   
| | 
* | fcfed83f715a788718280bdbeb2f4a44a4ab1011● 2019-08-25
| |   remove unused variable r from maildir.c.
| |   
| | * f844095392010bcd8c582dd5563061946b9067f8 2019-08-25 (refs/pull/78/head)
| |/    remove unused variable r from maildir.c.
|/|   
| | 
* | d9fb9363e2db1648d7405ba543899d5020189ec3● 2019-08-25
| |   use correct system headers for fork()
| |   
| | * 60ea85e1ff5085abcf88491d3bbe6c461a7b9b06 2019-08-25 (refs/pull/82/head)
| |/    use correct system headers for fork()
|/|   
| | 
* | 77d529483b0359852224104b43e9321061fe0718● 2019-08-25
| |   include stdlib.h and stop redeclaring malloc, free in alloc.c
| |   
| | * 14ef2aeef1f5ce1808f67810f552547982758cf8 2019-08-24 (refs/pull/81/head)
| |/    include stdlib.h and stop redeclaring malloc, free in alloc.c
|/|   
| | 
* | ff45251efbbb6518cabc8ec39a89cd3eff73af27● 2019-08-24
| |   include unistd.h in readwrite.h to declare read, write.
| |   
| | * 69cb502d9cdaed04bdb09227f2eb3d980de94ef0 2019-08-24 (refs/pull/80/head)
| |/    include unistd.h in readwrite.h to declare read, write.
|/|   
| |   
| | * 184d858dbdbd009ffaf491aa774d93ed9f479f18 2019-08-22 (refs/pull/75/head)
| |/    lock_*.c, lock.h are now C89.
|/|   
| |   
| | * 3d4ce629ee8255aa6fe1906e76c024ecc339de45 2019-08-22 (refs/pull/74/head)
| |/    fd_copy.c, fd_move,c, fd.h are now C89.
|/|   
| |   
| | * 453002bc430736f9af8864bca455812b6c21a2c0 2019-08-22 (refs/pull/73/head)
| |/    coe.c, coe.h are now C89.
|/|   
| |   
| | * b04d366fe85c5f969e6242089b1a941d1083a753 2019-08-19 (notqmail-smtpd-spf)
| |/    Apply Jana Saout's qmail-spf-rc5.patch
|/|   
| |   
| | * 2dc6aeb56c981323ac42d6e43884f55c1d72f459 2019-08-19 (notqmail-smtpd-logging)
| | |   qmail-smtpd: log the name of any unimplemented command.
| | | 
| | * b873edd626323298def9443549ad29e9419e9a68● 2019-08-19
| | |   qmail-smtpd: log pid in square brackets after program name.
| | | 
| | * 80714fed9893544a961c7f59ac9f0fda42cb3e52● 2019-08-19
| | |   add errbits.[ch] deps to errbits.o, qmail-smtpd.o in Makefile.
| | | 
| | * af0baaccd3ed3ffa8166d056e8ac76a4935ec433● 2019-08-19
| |/    Apply Andrew Richards' qmail-logmsg logging patch, v1.3.
|/|   
| |   
| | * b2f5ad68ffcb6d15c9cc2bf3ddf4e43e2d4991fa 2019-08-19 (notqmail-dns-oversize)
| |/    Apply Christopher K. Davis's oversize DNS packet patch.
|/|   
| |   
| | * 23a0d13119135568632cb11ef272c1c6feb98092 2019-08-19 (notqmail-big-concurrency)
| | |   conf-spawn cannot be higher than 65535 (0xff)
| | | 
| | * 77d05636ad5a623dbaaaa3aaf1967ae92fb095af● 2019-08-19
| | |   restore conf-spawn to original default, 120.
| | | 
| | * ce050fefe84350be81a41e61b22134bdf5abfa32● 2019-08-19
| |/    Apply Johannes Erdfelt's big-concurrency.patch
|/|   
| |   
| | * e8d2f9954684b62e68ed9205fa5c5919da213e0d 2019-08-19 (notqmail-badmailfrom-x-relayclient)
| |/    qmail-smtpd: ignore badmailfrom when RELAYCLIENT is set.
|/|   
| |   
| | * 2d346400a663401aecfd1da75c648408f7a8fff9 2019-08-19 (notqmail-badmailfrom-wildcard)
| | |   grammar cleanup in qmail-smtpd.8 to match the rest of that manpage.
| | | 
| | * 2b6d23258d67ab2dc061aa049500c7e970663c93● 2019-08-19
| |/    Apply Tom Clegg's badmailfrom wildcard patch.
|/|   
| | 
* | 3a48c5b56a3031afad411545ecff77be4368e300● 2019-08-19 (tag: notqmail-1.07)
| |   notqmail 1.07
| |   
| | * 3acb67b3f966d114323ae82af50e207ec777e4e4 2019-08-19 (refs/pull/63/head)
| |/    notqmail 1.07
|/|   
| | 
* | 1b28ced36c341d3b94c053ab9e04313304ca3d44● 2019-08-14
| |   remove SYSDEPS, the list of platform-specific build artifacts.
| |   
| | * 68d3c62e023bfbcc0b03cc1e19d1f280acd95b31 2019-08-13 (refs/pull/33/head)
| |/    remove SYSDEPS, the list of platform-specific build artifacts.
|/|   
| |   
| | * 5faa255aa26891bf2f2459328d3833c54a1ab9e0 2019-08-13 (refs/pull/62/head)
| |/    Remove one last reference to SYSDEPS.
|/|   
| | 
* | 0057e5ff94114dd10781808cb41ffa5eb5f4a5bf● 2019-08-10
| |   remove incorrect usage of vfork()
| |   
| | * 4220b97412faac10576e3a602fd0a8238e4a72d0 2019-08-10 (refs/pull/38/head)
| |/    remove incorrect usage of vfork()
|/|   
| | 
* | 75b8eb439b60646480e2b3afb7cfe00f96213616● 2019-08-06
| |   TravisCI: force one build without utmpx
| | 
* | f9efcbfdc2d47795d193c9a851a9c4b6d41661d5● 2019-08-06
| |   Fix the non-compiling utmp case, found on OpenBSD.
| |   
| | * 492f803a596bd2b18b9723ac8a88a35bb84b3d54 2019-08-06 (refs/pull/57/head)
| | |   TravisCI: force one build without utmpx
| | | 
| | * 267983a6c90e2a1cda4da93ee9e1a72a9abcda4b● 2019-08-06
| |/    Fix the non-compiling utmp case, found on OpenBSD.
|/|   
| |   
| | * 4c5b794c9a8daa92049e346d60bed7b124715787 2019-08-05 (refs/pull/56/head)
| | |   CHANGES: don't build or install catted manpages.
| | | 
| | * d4706c3cbf6794349fec875d60fbbb922cdaa5d5● 2019-08-05
| | |   Don't build catted manpages (*.0).
| | | 
| | * 4abca1b6d3c38d2dc060675f22a8a0e598e9bec3● 2019-08-05
| | |   Don't install catted manpages (*.0).
| | | 
| | * 9b97b849840aab676905075c3c90275c7e2fdb77● 2019-08-05
| |/    Don't refer to catted manpages (*.0).
|/|   
| | 
* | ea3a0e4107ab96c1f7916a05a4d9b9412f506c66● 2019-08-05
| |   Update docs: we're not netqmail, we're notqmail.
| |   
| | * 76dc19c3081c67d07ddfd33c049fd60d80c3d4ad 2019-08-05 (refs/pull/42/head)
| |/    Update docs: we're not netqmail, we're notqmail.
|/|   
| | 
* | d4dcbf2dcce24ed7e42c2b328762f0f9576ae2cd● 2019-08-05
| |   man rules are variously missing dependency on conf-qmail.
| |   
| | * 2dcd4ae135110921bf00ecc05d9d0c68e2c88f4a 2019-08-05 (refs/pull/55/head)
| |/    man rules are variously missing dependency on conf-qmail.
|/|   
| | 
* | c589f2da2f17e64ce0402f2466a361ec28b8e5e8● 2019-08-05
| |   add more missing local includes
| |   
| | * 483e592774c3b823d072586075812a368115f8d2 2019-08-05 (refs/pull/53/head)
| |/    add more missing local includes
|/|   
| | 
* | fb2b0571a7c09a140188b4442c42fcc74cc1963a● 2019-08-04
| |   CI: build & package before creating user accounts.
| | 
* | de6a762737e86ae714b38d5323b9d5c9237f9a8b● 2019-08-04
| |   split install in to instpackage, instchown.
| | 
* | 2f552835c907eee2db06cda5a6b7cfe09cb319ee● 2019-08-04
| |   Remove support for precompiled var-qmail packages.
| | 
* | 580bf26e8a211fdff3ad3083e5e771662a921e3a● 2019-08-04
| |   detect qmail system uid/gid at runtime.
| | 
* | 1fabc9dcfa3e670875895d60fd5432318cb0e5ff● 2019-08-04
| |   add missing mode argument to recursive mkdir_p.
| |   
| | * a49421670f68d4091692b3abd0e39085d6addcd8 2019-08-04 (refs/pull/15/head)
| | |   CI: build & package before creating user accounts.
| | | 
| | * 439fe87a82f80f9ee84a9e9c1ba744fee80f732f● 2019-08-04
| | |   split install in to instpackage, instchown.
| | | 
| | * 429896534fbc7bc10c4ae833d6f065a2a2733aba● 2019-08-04
| | |   Remove support for precompiled var-qmail packages.
| | | 
| | * 65f0e3b413c79696bbeadc8a9b99f69d2e9e4869● 2019-08-04
| | |   detect qmail system uid/gid at runtime.
| | | 
| | * 4b0f26eb82117b9a9928853e5b642bc6cc49011b● 2019-08-02
| |/    add missing mode argument to recursive mkdir_p.
|/|   
| | 
* | bb7ec78bf79e6ee69cd44ed3c8102b6ec66b9bc5● 2019-07-22
| |   Point SMTP HELP at notqmail's home page.
| |   
| | * 9e1e1512b0019601d1ea0412b4a0a98ff662c6cf 2019-07-22 (refs/pull/39/head)
| |/    Point SMTP HELP at notqmail's home page.
|/|   
| | 
* | 5d18a307a5048c92555755e5e6c3fa55e58c93be● 2019-07-21
| |   CHANGES: add Mac OS X portability changes.
| |   
| | * 1d2e326ddeb6864e3f71f9a675ac5d15e034d34a 2019-07-21 (refs/pull/40/head)
| |/    CHANGES: add Mac OS X portability changes.
|/|   
| | 
* | f1196059ec92ee2b50e6729bfd0fdf06365d18f0● 2019-07-21
| |   define BIND_8_COMPAT before including arpa/nameser.h in dns.c
| | 
* | 71580a477d784996287da2e6590070b7ecbdb47f● 2019-07-21
| |   explicitly initialize strerr.
| | 
* | df0004cf7a42e503facab6235fcfee6c026ade8e● 2019-07-21
| |   rename INSTALL to INSTALL.md, SENDMAIL to SENDMAIL.md.
| |   
| | * fdf3b7278f00da7d2178d892d2cc44affe5337b9 2019-07-20 (refs/pull/16/head)
| | |   define BIND_8_COMPAT before including arpa/nameser.h in dns.c
| | | 
| | * e5f3c504eb787f36b693744bff50c1641213e8b5● 2019-07-20
| | |   explicitly initialize strerr.
| | | 
| | * d36ffd156abd88052fbb9cf3e73343a2058471e9● 2019-07-20
| |/    rename INSTALL to INSTALL.md, SENDMAIL to SENDMAIL.md.
|/|   
| | 
* | 3357eb2476698649929e19d423ef24ca73c356dc● 2019-07-20
| |   symlink TARGETS to .gitignore.
| | 
* | 131db6a9399cee16eb4eca59dd9112308d1c44f0● 2019-07-20
| |   remove phony targets from TARGETS, add them as .PHONY prerequisites.
| |   
| | * 69135fde2d86861a79d909c7123817b31fc94cf3 2019-07-20 (refs/pull/25/head)
| | |   symlink TARGETS to .gitignore.
| | | 
| | * dd8bf671b438c5b139c49d889cf927a3fc3bb90d● 2019-07-20
| |/    remove phony targets from TARGETS, add them as .PHONY prerequisites.
|/|   
| | 
* | e55694bdbbce60572c4a59a1a6dc69cde012f308● 2019-07-19
| |   control_readfile() called with less arguments
| |     
| | *   c69e518e87d2eac3df03a2db800b461305bbff6f 2019-07-20 (refs/pull/31/head)
| | |\    Merge branch 'master' into qmail-showctl-bug
| |_|/  
|/| |   
| | | 
* | | 97c5ef197909671816d3001a2914b5568f962756● 2019-07-19
| | |   remove FILES, shar target from Makefile.
| | |   
| | *   3af66d03984d299967144e7b3ae22170c6e9823e● 2019-07-19
| | |\    Merge branch 'master' into qmail-showctl-bug
| |_|/  
|/| |   
| | | 
| | * 15245e87348f23de24d9794646f65214f4bac56a● 2019-07-19
| | |   control_readfile() called with less arguments
| | |   
| | | * 99e9dab766cb7b8e1e82f7f8c0660be8f22af102 2019-07-19 (refs/pull/27/head)
| |_|/    remove FILES, shar target from Makefile.
|/| |   
| | |   
| | | * 31621bbe07dc355fbcc727ef42cf308c4e5b2613 2019-07-19 (refs/pull/32/head)
| |_|/    remove FILES.
|/| |   
| | | 
* | | 3772dd95f6584cc6788fa4ff28d7b232a4c8d43a● 2019-07-19
| |/    add missing project includes to several .c files
|/|   
| |   
| | * a1eaa877d18d9d0542a4849465aa2700105f7cba 2019-07-16 (refs/pull/20/head)
| |/    add missing project includes to several .c files
|/|   
| | 
* | ac43d259085369f64209b105db0139e85a6bd816● 2019-07-15
| |   add qtmp.h to SYSDEPS.
| |   
| | * 38699fb9fa955720061f3a71dc1f5eb7b3aa0d4c 2019-07-15 (refs/pull/29/head)
| |/    add qtmp.h to SYSDEPS.
|/|   
| | 
* | 47baf7859ec511c4939fbf5b44e292bb60485aac● 2019-07-15
| |   Fix build on utmpx-only systems, such as FreeBSD.
| |   
| | * f3d015dd01f83edc73c7934c59b39adf296d2e0c 2019-07-15 (refs/pull/24/head)
| |/    Fix build on utmpx-only systems, such as FreeBSD.
|/|   
| |   
| | * b0ed55726f91658a78aba4978ff57f4b4e409c68 2019-07-14 (refs/pull/22/head)
| | |   Remove support for precompiled var-qmail packages.
| | | 
| | * 02dd7473e0a8baa1ef23a52f2215847060b42bbd● 2019-07-14
| |/    remove shar target from Makefile.
|/|   
| | 
* | 1dd7b07f688d0fa38353914d2a2c4d4393abd430● 2019-07-13
| |   honor DESTDIR on install
| |   
| | * ff3a5002ec9031e4b93874da527cec90cef6be82 2019-07-13 (refs/pull/4/head)
| |/    honor DESTDIR on install
|/|   
| |   
| | * acbe245ec56b0520b294c894ea29ad6e8ce5f34f 2019-07-13 (netqmail-smtpd-logging)
| | |   add errbits.[ch] to FILES, fix errbits.o, qmail-smtpd.o Makefile deps
| | | 
| | * a0982661b24df01e65f84ef96708bc002a313c76● 2019-07-12
| |/    Apply Andrew Richards' qmail-logmsg logging patch, v1.3.
| |   
| | * 1550b0b0867bc8c8753ecb6b9558677cfc67591a 2019-07-13 (netqmail-smtp-auth)
| | |   Remove FILES.auth, add new files to FILES.
| | | 
| | * 36d7678ec9c9c8f61406e946d263bd3afd6100a1● 2019-07-12
| |/    Apply Erwin Hoffmann's SMTP authentication for qmail-smtpd, qmail-remote.
| |   
| | * 9cec488b10b3a3a085676f7757248ad5d6c6aa96 2019-07-13 (netqmail-ext-todo)
| | |   Remove all code guarded by ifndef EXTERNAL_TODO.
| | | 
| | * a95253370cfdbd2c79e1f2e9fa1c9a0002f66cb1● 2019-07-13
| | |   remove EXTERNAL_TODO define.
| | | 
| | * 0df8ccc44c94e3f7a9dca8fed078b7a84970f19b● 2019-07-12
| |/    add ext_todo-20030105.patch
| |   
| | * f032501bb363ad450a7cb801d867c79a5d3c21c1 2019-07-13 (netqmail-big-concurrency)
| | |   conf-spawn cannot be higher than 65535 (0xff)
| | | 
| | * 37efcbd2c442fb0a0aae8e8c172f377c13eb6ea9● 2019-07-13
| | |   restore conf-spawn to original default, 120.
| | | 
| | * 94962395482052f12ca28bfcf7c170178a67caae● 2019-07-12
| |/    Apply Johannes Erdfelt's big-concurrency.patch
| |   
| | * f6ee08feae86931bb9e05e79e9c17f4eb1709c3c 2019-07-13 (netqmail-smtpd-spf)
| |/    Apply Jana Saout's qmail-spf-rc5.patch
| |   
| | * 980428a420c7670ec7bae40149088f894247d1f7 2019-07-13 (netqmail-smtp-tls)
| | |   Remove TLS define from the C code and conf-cc.
| | | 
| | * 1468ae0084e8c710db605d47ae22da429a28c9da● 2019-07-13
| | |   Do not add directories to PATH in Makefile-cert.mk, update_tmprsadh.sh.
| | | 
| | * adb025ec4dbe4fa012f5861be12534e75e114045● 2019-07-13
| | |   conf-cc: remove -I/usr/local/ssl/include
| | | 
| | * c88bcfb7d0e19ceade1a946c38a50f40e7fbe15e● 2019-07-13
| | |   Makefile: remove -L/usr/local/ssl/lib qmail-remote, qmail-smtpd
| | | 
| | * c38f92e425942a777da28f9f2245c040e72d8678● 2019-07-13
| | |   Remove trailing whitespace in Makefile qmail-remote[.8c] qmail-smtpd.[8c]
| | | 
| | * 01cda8253b0ab4a19995dd7f5d6eba5cc005a6aa● 2019-07-13
| |/    Apply Frederik Vermeulen's qmail-smtp-tls 20190517
| |   
| | * 2160c4deec0ebc671bb1b3f171d48110b20f010b 2019-07-12 (netqmail-dns-oversize)
| |/    Apply Christopher K. Davis's oversize DNS packet patch.
| |   
| | * e13e7a335b6b98854113655f44774f32b3d0ad99 2019-07-12 (netqmail-big-todo)
| |/    Apply Russell Nelson's big-todo.103.patch.
| |   
| | * 78475d20b2ce03b91387de7f74e94a63e6fddbf7 2019-07-12 (netqmail-badmailfrom-x-relayclient)
| |/    qmail-smtpd: ignore badmailfrom when RELAYCLIENT is set.
| |   
| | * 384b1ed10155d4bf6f2cb1e133f0fc55bea45b1d 2019-07-12 (refs/pull/21/head)
| |/    TravisCI: test external patch(es)
|/|   
| |   
| | * 42a67e3d3abdfa2e87e6cacb559d5b27ee906d2e 2019-07-12 (refs/pull/13/head)
| |/    add .gitignore
|/|   
| |   
* |   774f27053a7eaec5799e3a4a33b583d5a464439c● 2019-07-11
|\ \    Merge pull request #19 from notqmail/TravisCI
| | | 
| * | 1b61fb158fb6af56fef8bd9af08f307616b3d10a 2019-07-11 (refs/pull/19/head)
|/ /    add TravisCI control file
| |   
| | * e3327ba437d777489d45cb526a36be587ac1eb75 2019-07-09 (refs/pull/11/head)
| |/    detect qmail system uid/gid at runtime.
|/|   
| |   
| | * 2eaa01ea04644bbe44cf9f49ca2c9032d6403334 2019-07-09 (refs/pull/12/head)
| |/    Fix build on utmpx-only systems, such as FreeBSD.
|/|   
| | 
* | 6fbd90376ebf2fdb2d4cf16dbc3ac4f6d5074c86● 2019-07-08
|/    qmail.o rule is missing dependency on env.h via qmail.c.
|   
| * ee04fb5d58c9b3b51e6ce0d16c127109b8a32f23 2019-07-08 (refs/pull/5/head)
| |   added destdir argument to be passed as command line argument
| | 
| * e8fed2ec03831d63e7f5718cd52c5a8bd0165ec6● 2019-07-08
|/    use DESTDIR variable and pass it as argument to install
|   
| * 8d48e8d99ecc6e9ab5dd4cdab61484ab2bb582a0 2019-07-07 (refs/pull/3/head)
|/    destdir: build as non-root, without hardcoded IDs.
|   
| * b928f08d979a064345d8b857dccba4bef848a2f2 2019-07-06 (refs/pull/1/head)
|/    qmail.o rule is missing dependency on env.h via qmail.c.
| 
* 08a0b794f3c12c7cbfa8e6217028d32cf841c3ba 2016-01-17 (tag: netqmail-1.06, netqmail)
|   netqmail 1.06
| 
* 39cfb0cfb64b3e35500f70f174d45921b5e65bfd 2016-01-17 (tag: netqmail-1.05)
|   netqmail 1.05
| 
* c4de3cc1ac2b75d87b551c9b88513d14ba57410d● 2016-01-17
|   This patch improves ISO C conformance of qmail code -- specifically, of qmail-lspawn, qmail-newmrh, qmail-newu, qmail-pop3d, qmail-popup, qmail-rspawn, and qmail-smtpd.  This fixes two known bugs:
| 
* 2bb7433cc9aaa89edf223d57e904553b31cce4b9 2016-01-17 (tag: netqmail-1.04)
|   netqmail 1.04
| 
* f5df10d17375e5f1137c4e59f0e527a12a991ed7 2016-01-17 (tag: qmail-1.03, qmail)
|   qmail 1.03
| 
* d15ee51c9ddb9d233ad5ebc28fddf1de8378657d 2016-01-17 (tag: qmail-1.02)
|   qmail 1.02
| 
* af9625ddf9464e85fd781e8ad889201ce340d9fc 2009-12-18 (tag: qmail-1.01)
    qmail 1.01