From nobody@FreeBSD.org  Sun Nov  1 22:04:10 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 3423A106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  1 Nov 2009 22:04:10 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 22F3E8FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  1 Nov 2009 22:04:10 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id nA1M49J2080447
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 1 Nov 2009 22:04:09 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id nA1M49Wn080445;
	Sun, 1 Nov 2009 22:04:09 GMT
	(envelope-from nobody)
Message-Id: <200911012204.nA1M49Wn080445@www.freebsd.org>
Date: Sun, 1 Nov 2009 22:04:09 GMT
From: Aragon Gouveia <aragon@phat.za.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] mail/ssmtp CRAM-MD5 broken
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         140175
>Category:       ports
>Synopsis:       [patch] mail/ssmtp CRAM-MD5 broken
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    glarkin
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Nov 01 22:10:01 UTC 2009
>Closed-Date:    Fri Dec 04 22:25:04 EST 2009
>Last-Modified:  Sat Dec  5 03:30:06 UTC 2009
>Originator:     Aragon Gouveia
>Release:        8.0-BETA3
>Organization:
>Environment:
FreeBSD igor.geek.sh 8.0-BETA3 FreeBSD 8.0-BETA3 #0: Thu Sep 17 14:02:41 SAST 2009     root@igor.geek.sh:/usr/obj/usr/src/sys/IGOR  amd64

>Description:
SSMTP bundles MD5 code with it (md5auth/md5c.c) instead of linking against system libraries, and this bundled code seems to generate broken HMAC-MD5 hashes, which breaks SSMTP's support for CRAM-MD5 SMTP authentication, at least on FreeBSD 8.0.

Attached is a patch to the port that unlinks md5auth/md5c.c from the build, and links ssmtp against the system -lmd.

>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff -uNr ssmtp.orig/files/patch-configure ssmtp/files/patch-configure
--- ssmtp.orig/files/patch-configure	2003-10-02 01:08:01.000000000 +0200
+++ ssmtp/files/patch-configure	2009-11-01 23:54:36.000000000 +0200
@@ -9,3 +9,16 @@
  fi
  enableval=""
  
+--- configure.orig	2009-11-01 23:52:55.000000000 +0200
++++ configure	2009-11-01 23:53:42.000000000 +0200
+@@ -1591,7 +1591,8 @@
+ #define MD5AUTH 1
+ EOF
+ 
+-	SRCS="$SRCS md5auth/md5c.c md5auth/hmac_md5.c"
++	SRCS="$SRCS md5auth/hmac_md5.c"
++	LIBS="$LIBS -lmd"
+ fi
+ enableval=""
+ 
+
diff -uNr ssmtp.orig/files/patch-md5auth-hmac_md5.c ssmtp/files/patch-md5auth-hmac_md5.c
--- ssmtp.orig/files/patch-md5auth-hmac_md5.c	1970-01-01 02:00:00.000000000 +0200
+++ ssmtp/files/patch-md5auth-hmac_md5.c	2009-11-01 23:56:00.000000000 +0200
@@ -0,0 +1,12 @@
+--- md5auth/hmac_md5.c.orig	2009-11-01 23:54:54.000000000 +0200
++++ md5auth/hmac_md5.c	2009-11-01 23:55:07.000000000 +0200
+@@ -1,7 +1,7 @@
+ #include "global.h"
+-#include "md5.h"
+ #include <string.h>
+ #include <sys/types.h>
++#include <md5.h>
+ 
+ /*
+ ** Function: hmac_md5 (RFC 2104)
+


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-ports-bugs->glarkin 
Responsible-Changed-By: edwin 
Responsible-Changed-When: Sun Nov 1 22:10:12 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer (via the GNATS Auto Assign Tool) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=140175 

From: Aragon Gouveia <aragon@phat.za.net>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: ports/140175: [patch] mail/ssmtp CRAM-MD5 broken
Date: Mon, 02 Nov 2009 01:03:02 +0200

 I neglected to bump PORTREVISION, sorry.  Please catch that for me. :)
 

From: Aragon Gouveia <aragon@phat.za.net>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: ports/140175: [patch] mail/ssmtp CRAM-MD5 broken
Date: Thu, 26 Nov 2009 02:08:28 +0200

 This is a multi-part message in MIME format.
 --------------050206040202080707060505
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 As requested, I've updated the port to the latest stable version from 
 upstream, 2.62-3, and included the CRAM-MD5 fix.  Patch attached.
 
 I've made some minor changes, in particular the port doesn't fetch the 
 patchlevel diff file from upstream.  I'm not sure why it was fetching it 
 previously as it didn't seem to do anything with it, and neither does 
 this new port.  The upstream patchlevel stuff is integrated in 
 files/patch-ssmtp.c and includes:
 
 debian/patches/02-CVE-2008-3962
 debian/patches/345780-standardise-bufsize
 
 There were quite a lot of local coding fixes in ssmtp.c that had to be 
 updated.  Have you tried sending these upstream?
 
 --------------050206040202080707060505
 Content-Type: text/plain;
  name="ssmtp-2.62.3.txt"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="ssmtp-2.62.3.txt"
 
 diff -uNr ssmtp.orig/Makefile ssmtp/Makefile
 --- ssmtp.orig/Makefile	2009-11-25 23:52:59.000000000 +0200
 +++ ssmtp/Makefile	2009-11-26 01:56:47.000000000 +0200
 @@ -6,19 +6,16 @@
  #
  
  PORTNAME=	ssmtp
 -PORTVERSION=	2.61.11.1
 -PORTREVISION=	2
 +PORTVERSION=	2.62.3
  CATEGORIES=	mail ipv6
  MASTER_SITES=	${MASTER_SITE_DEBIAN_POOL}
 -DISTNAME=	${PORTNAME}_2.61.orig
 +DISTNAME=	${PORTNAME}_2.62.orig
  DISTFILES=	${DISTNAME}.tar.gz \
 -		ssmtp_2.61-11.1.diff.gz
 -EXTRACT_ONLY=	${DISTNAME}.tar.gz
  
  MAINTAINER=	glarkin@FreeBSD.org
  COMMENT=	Extremely simple MTA to get mail off the system to a mail hub
  
 -WRKSRC=		${WRKDIR}/${PORTNAME}-2.61
 +WRKSRC=		${WRKDIR}/${PORTNAME}
  
  USE_OPENSSL=	yes
  
 diff -uNr ssmtp.orig/distinfo ssmtp/distinfo
 --- ssmtp.orig/distinfo	2009-11-25 23:52:59.000000000 +0200
 +++ ssmtp/distinfo	2009-11-26 01:56:57.000000000 +0200
 @@ -1,6 +1,3 @@
 -MD5 (ssmtp_2.61.orig.tar.gz) = 957e6fff08625fe34f4fc33d0925bbc9
 -SHA256 (ssmtp_2.61.orig.tar.gz) = 2151ad18cb73f9a254f796dde2b48be7318b45410b59fedbb258db5a41044fb5
 -SIZE (ssmtp_2.61.orig.tar.gz) = 53341
 -MD5 (ssmtp_2.61-11.1.diff.gz) = 96946aed2e9b5442f7f0643bcbd4e4f6
 -SHA256 (ssmtp_2.61-11.1.diff.gz) = 85a56288874a874f433ee5e48891812bb18b23c9e33fd39c5168b1843010a8cd
 -SIZE (ssmtp_2.61-11.1.diff.gz) = 33458
 +MD5 (ssmtp_2.62.orig.tar.gz) = 257ac04e62ab7e3616e220333a1140cb
 +SHA256 (ssmtp_2.62.orig.tar.gz) = e2a0a5379cd0bbb0b4b0304abeba7a8f60aa85275982c5d7930c319e7f284ed1
 +SIZE (ssmtp_2.62.orig.tar.gz) = 57127
 diff -uNr ssmtp.orig/files/patch-arpadate.c ssmtp/files/patch-arpadate.c
 --- ssmtp.orig/files/patch-arpadate.c	2009-11-25 23:52:59.000000000 +0200
 +++ ssmtp/files/patch-arpadate.c	1970-01-01 02:00:00.000000000 +0200
 @@ -1,11 +0,0 @@
 ---- arpadate.c.orig	Sun Dec  8 18:30:13 2002
 -+++ arpadate.c	Mon Apr  7 01:17:58 2003
 -@@ -79,7 +79,7 @@
 - 	time_t now;
 - 
 - 	/* RFC822 format string borrowed from GNU shellutils date.c */
 --	const char *format = "%a, %_d %b %Y %H:%M:%S %z";
 -+	const char *format = "%a, %e %b %Y %H:%M:%S %z";
 - 
 - 	now = time(NULL);
 - 
 diff -uNr ssmtp.orig/files/patch-base64.c ssmtp/files/patch-base64.c
 --- ssmtp.orig/files/patch-base64.c	2009-11-25 23:52:59.000000000 +0200
 +++ ssmtp/files/patch-base64.c	1970-01-01 02:00:00.000000000 +0200
 @@ -1,20 +0,0 @@
 ---- ./base64.c.orig	2002-05-07 09:26:43.000000000 -0400
 -+++ ./base64.c	2008-11-17 18:55:03.000000000 -0500
 -@@ -31,7 +31,7 @@
 - };
 - #define DECODE64(c)  (isascii(c) ? base64val[c] : BAD)
 - 
 --void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
 -+void to64frombits(char *out, const unsigned char *in, int inlen)
 - /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
 - {
 -     for (; inlen >= 3; inlen -= 3)
 -@@ -57,7 +57,7 @@
 -     *out = '\0';
 - }
 - 
 --int from64tobits(char *out, const char *in)
 -+int from64tobits(unsigned char *out, const char *in)
 - /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
 - {
 -     int len = 0;
 diff -uNr ssmtp.orig/files/patch-configure ssmtp/files/patch-configure
 --- ssmtp.orig/files/patch-configure	2009-11-25 23:52:59.000000000 +0200
 +++ ssmtp/files/patch-configure	2009-11-26 01:51:45.000000000 +0200
 @@ -9,3 +9,16 @@
   fi
   enableval=""
   
 +--- configure.orig	2009-11-01 23:52:55.000000000 +0200
 ++++ configure	2009-11-01 23:53:42.000000000 +0200
 +@@ -1591,7 +1591,8 @@
 + #define MD5AUTH 1
 + EOF
 + 
 +-	SRCS="$SRCS md5auth/md5c.c md5auth/hmac_md5.c"
 ++	SRCS="$SRCS md5auth/hmac_md5.c"
 ++	LIBS="$LIBS -lmd"
 + fi
 + enableval=""
 + 
 +
 diff -uNr ssmtp.orig/files/patch-md5auth-hmac_md5.c ssmtp/files/patch-md5auth-hmac_md5.c
 --- ssmtp.orig/files/patch-md5auth-hmac_md5.c	1970-01-01 02:00:00.000000000 +0200
 +++ ssmtp/files/patch-md5auth-hmac_md5.c	2009-11-26 01:49:36.000000000 +0200
 @@ -0,0 +1,12 @@
 +--- md5auth/hmac_md5.c.orig	2009-11-01 23:54:54.000000000 +0200
 ++++ md5auth/hmac_md5.c	2009-11-01 23:55:07.000000000 +0200
 +@@ -1,7 +1,7 @@
 + #include "global.h"
 +-#include "md5.h"
 + #include <string.h>
 + #include <sys/types.h>
 ++#include <md5.h>
 + 
 + /*
 + ** Function: hmac_md5 (RFC 2104)
 +
 diff -uNr ssmtp.orig/files/patch-ssmtp.c ssmtp/files/patch-ssmtp.c
 --- ssmtp.orig/files/patch-ssmtp.c	1970-01-01 02:00:00.000000000 +0200
 +++ ssmtp/files/patch-ssmtp.c	2009-11-26 01:48:53.000000000 +0200
 @@ -0,0 +1,582 @@
 +--- ssmtp.c.orig	2009-11-26 01:48:28.000000000 +0200
 ++++ ssmtp.c	2009-11-26 01:48:31.000000000 +0200
 +@@ -10,7 +10,7 @@
 +  See COPYRIGHT for the license
 + 
 + */
 +-#define VERSION "2.62"
 ++#define VERSION "2.62.3"
 + #define _GNU_SOURCE
 + 
 + #include <sys/socket.h>
 +@@ -25,6 +25,7 @@
 + #include <string.h>
 + #include <ctype.h>
 + #include <netdb.h>
 ++#include <libgen.h>
 + #ifdef HAVE_SSL
 + #include <openssl/crypto.h>
 + #include <openssl/x509.h>
 +@@ -55,21 +56,21 @@
 + 
 + #define ARPADATE_LENGTH 32		/* Current date in RFC format */
 + char arpadate[ARPADATE_LENGTH];
 +-char *auth_user = (char)NULL;
 +-char *auth_pass = (char)NULL;
 +-char *auth_method = (char)NULL;		/* Mechanism for SMTP authentication */
 +-char *mail_domain = (char)NULL;
 +-char *from = (char)NULL;		/* Use this as the From: address */
 ++char *auth_user = NULL;
 ++char *auth_pass = NULL;
 ++char *auth_method = NULL;		/* Mechanism for SMTP authentication */
 ++char *mail_domain = NULL;
 ++char *from = NULL;		/* Use this as the From: address */
 + char *hostname;
 + char *mailhost = "mailhub";
 +-char *minus_f = (char)NULL;
 +-char *minus_F = (char)NULL;
 ++char *minus_f = NULL;
 ++char *minus_F = NULL;
 + char *gecos;
 +-char *prog = (char)NULL;
 ++char *prog = NULL;
 + char *root = NULL;
 +-char *tls_cert = "/etc/ssl/certs/ssmtp.pem";	/* Default Certificate */
 +-char *uad = (char)NULL;
 +-char *config_file = (char)NULL;		/* alternate configuration file */
 ++char *tls_cert = "/usr/local/etc/ssmtp/ssmtp.pem";	/* Default Certificate */
 ++char *uad = NULL;
 ++char *config_file = NULL;		/* alternate configuration file */
 + 
 + headers_t headers, *ht;
 + 
 +@@ -261,7 +262,7 @@
 + 
 + 	p = (str + strlen(str));
 + 	while(isspace(*--p)) {
 +-		*p = (char)NULL;
 ++		*p = '\0';
 + 	}
 + 
 + 	return(p);
 +@@ -279,7 +280,7 @@
 + #endif
 + 
 + 	/* Simple case with email address enclosed in <> */
 +-	if((p = strdup(str)) == (char *)NULL) {
 ++	if((p = strdup(str)) == NULL) {
 + 		die("addr_parse(): strdup()");
 + 	}
 + 
 +@@ -287,7 +288,7 @@
 + 		q++;
 + 
 + 		if((p = strchr(q, '>'))) {
 +-			*p = (char)NULL;
 ++			*p = '\0';
 + 		}
 + 
 + #if 0
 +@@ -310,7 +311,7 @@
 + 	q = strip_post_ws(p);
 + 	if(*q == ')') {
 + 		while((*--q != '('));
 +-		*q = (char)NULL;
 ++		*q = '\0';
 + 	}
 + 	(void)strip_post_ws(p);
 + 
 +@@ -347,28 +348,26 @@
 + /*
 + standardise() -- Trim off '\n's and double leading dots
 + */
 +-void standardise(char *str)
 ++bool_t standardise(char *str, bool_t *linestart)
 + {
 + 	size_t sl;
 + 	char *p;
 +-
 +-	if((p = strchr(str, '\n'))) {
 +-		*p = (char)NULL;
 +-	}
 ++	bool_t leadingdot = False;
 + 
 + 	/* Any line beginning with a dot has an additional dot inserted;
 +-	not just a line consisting solely of a dot. Thus we have to slide
 +-	the buffer down one */
 +-	sl = strlen(str);
 ++	not just a line consisting solely of a dot. Thus we have to move
 ++	the buffer start up one */
 + 
 +-	if(*str == '.') {
 +-		if((sl + 2) > BUF_SZ) {
 +-			die("standardise() -- Buffer overflow");
 +-		}
 +-		(void)memmove((str + 1), str, (sl + 1));	/* Copy trailing \0 */
 ++	if(*linestart && *str == '.') {
 ++		leadingdot = True;
 ++	}
 ++	*linestart = False;
 + 
 +-		*str = '.';
 ++	if((p = strchr(str, '\n'))) {
 ++		*p = '\0';
 ++		*linestart = True;
 + 	}
 ++	return(leadingdot);
 + }
 + 
 + /*
 +@@ -386,7 +385,7 @@
 + 		while(fgets(buf, sizeof(buf), fp)) {
 + 			/* Make comments invisible */
 + 			if((p = strchr(buf, '#'))) {
 +-				*p = (char)NULL;
 ++				*p = '\0';
 + 			}
 + 
 + 			/* Ignore malformed lines and comments */
 +@@ -485,6 +484,11 @@
 + 				die("from_format() -- snprintf() failed");
 + 			}
 + 		}
 ++		else {
 ++			if(snprintf(buf, BUF_SZ, "%s", str) == -1) {
 ++				die("from_format() -- snprintf() failed");
 ++			}
 ++		}
 + 	}
 + 
 + #if 0
 +@@ -516,11 +520,11 @@
 + #endif
 + 
 + 	/* Ignore missing usernames */
 +-	if(*str == (char)NULL) {
 ++	if(*str == '\0') {
 + 		return;
 + 	}
 + 
 +-	if((rt->string = strdup(str)) == (char *)NULL) {
 ++	if((rt->string = strdup(str)) == NULL) {
 + 		die("rcpt_save() -- strdup() failed");
 + 	}
 + 
 +@@ -545,7 +549,7 @@
 + 	(void)fprintf(stderr, "*** rcpt_parse(): str = [%s]\n", str);
 + #endif
 + 
 +-	if((p = strdup(str)) == (char *)NULL) {
 ++	if((p = strdup(str)) == NULL) {
 + 		die("rcpt_parse(): strdup() failed");
 + 	}
 + 	q = p;
 +@@ -573,7 +577,7 @@
 + 		}
 + 
 + 		/* End of string? */
 +-		if(*(q + 1) == (char)NULL) {
 ++		if(*(q + 1) == '\0') {
 + 			got_addr = True;
 + 		}
 + 
 +@@ -581,7 +585,7 @@
 + 		if((*q == ',') && (in_quotes == False)) {
 + 			got_addr = True;
 + 
 +-			*q = (char)NULL;
 ++			*q = '\0';
 + 		}
 + 
 + 		if(got_addr) {
 +@@ -665,7 +669,7 @@
 + 	(void)fprintf(stderr, "header_save(): str = [%s]\n", str);
 + #endif
 + 
 +-	if((p = strdup(str)) == (char *)NULL) {
 ++	if((p = strdup(str)) == NULL) {
 + 		die("header_save() -- strdup() failed");
 + 	}
 + 	ht->string = p;
 +@@ -673,7 +677,7 @@
 + 	if(strncasecmp(ht->string, "From:", 5) == 0) {
 + #if 1
 + 		/* Hack check for NULL From: line */
 +-		if(*(p + 6) == (char)NULL) {
 ++		if(*(p + 6) == '\0') {
 + 			return;
 + 		}
 + #endif
 +@@ -736,19 +740,19 @@
 + void header_parse(FILE *stream)
 + {
 + 	size_t size = BUF_SZ, len = 0;
 +-	char *p = (char *)NULL, *q;
 ++	char *p = NULL, *q;
 + 	bool_t in_header = True;
 +-	char l = (char)NULL;
 ++	char l = '\0';
 + 	int c;
 + 
 + 	while(in_header && ((c = fgetc(stream)) != EOF)) {
 + 		/* Must have space for up to two more characters, since we
 + 			may need to insert a '\r' */
 +-		if((p == (char *)NULL) || (len >= (size - 1))) {
 ++		if((p == NULL) || (len >= (size - 1))) {
 + 			size += BUF_SZ;
 + 
 + 			p = (char *)realloc(p, (size * sizeof(char)));
 +-			if(p == (char *)NULL) {
 ++			if(p == NULL) {
 + 				die("header_parse() -- realloc() failed");
 + 			}
 + 			q = (p + len);
 +@@ -773,9 +777,9 @@
 + 						in_header = False;
 + 
 + 				default:
 +-						*q = (char)NULL;
 ++						*q = '\0';
 + 						if((q = strrchr(p, '\n'))) {
 +-							*q = (char)NULL;
 ++							*q = '\0';
 + 						}
 + 						header_save(p);
 + 
 +@@ -806,9 +810,9 @@
 + 						in_header = False;
 + 
 + 				default:
 +-						*q = (char)NULL;
 ++						*q = '\0';
 + 						if((q = strrchr(p, '\n'))) {
 +-							*q = (char)NULL;
 ++							*q = '\0';
 + 						}
 + 						header_save(p);
 + 
 +@@ -873,11 +877,11 @@
 + 		char *rightside;
 + 		/* Make comments invisible */
 + 		if((p = strchr(buf, '#'))) {
 +-			*p = (char)NULL;
 ++			*p = '\0';
 + 		}
 + 
 + 		/* Ignore malformed lines and comments */
 +-		if(strchr(buf, '=') == (char *)NULL) continue;
 ++		if(strchr(buf, '=') == NULL) continue;
 + 
 + 		/* Parse out keywords */
 + 		p=firsttok(&begin, "= \t\n");
 +@@ -887,7 +891,7 @@
 + 		}
 + 		if(p && q) {
 + 			if(strcasecmp(p, "Root") == 0) {
 +-				if((root = strdup(q)) == (char *)NULL) {
 ++				if((root = strdup(q)) == NULL) {
 + 					die("parse_config() -- strdup() failed");
 + 				}
 + 
 +@@ -896,7 +900,7 @@
 + 				}
 + 			}
 + 			else if(strcasecmp(p, "MailHub") == 0) {
 +-				if((mailhost = strdup(q)) == (char *)NULL) {
 ++				if((mailhost = strdup(q)) == NULL) {
 + 					die("parse_config() -- strdup() failed");
 + 				}
 + 
 +@@ -946,7 +950,7 @@
 + 					mail_domain = strdup(q);
 + 				}
 + 
 +-				if(mail_domain == (char *)NULL) {
 ++				if(mail_domain == NULL) {
 + 					die("parse_config() -- strdup() failed");
 + 				}
 + 				rewrite_domain = True;
 +@@ -1022,7 +1026,7 @@
 + 				}
 + 			}
 + 			else if(strcasecmp(p, "TLSCert") == 0) {
 +-				if((tls_cert = strdup(q)) == (char *)NULL) {
 ++				if((tls_cert = strdup(q)) == NULL) {
 + 					die("parse_config() -- strdup() failed");
 + 				}
 + 
 +@@ -1033,7 +1037,7 @@
 + #endif
 + 			/* Command-line overrides these */
 + 			else if(strcasecmp(p, "AuthUser") == 0 && !auth_user) {
 +-				if((auth_user = strdup(q)) == (char *)NULL) {
 ++				if((auth_user = strdup(q)) == NULL) {
 + 					die("parse_config() -- strdup() failed");
 + 				}
 + 
 +@@ -1042,7 +1046,7 @@
 + 				}
 + 			}
 + 			else if(strcasecmp(p, "AuthPass") == 0 && !auth_pass) {
 +-				if((auth_pass = strdup(q)) == (char *)NULL) {
 ++				if((auth_pass = strdup(q)) == NULL) {
 + 					die("parse_config() -- strdup() failed");
 + 				}
 + 
 +@@ -1051,7 +1055,7 @@
 + 				}
 + 			}
 + 			else if(strcasecmp(p, "AuthMethod") == 0 && !auth_method) {
 +-				if((auth_method = strdup(q)) == (char *)NULL) {
 ++				if((auth_method = strdup(q)) == NULL) {
 + 					die("parse_config() -- strdup() failed");
 + 				}
 + 
 +@@ -1104,11 +1108,11 @@
 + #ifdef INET6
 + 	struct addrinfo hints, *ai0, *ai;
 + 	char servname[NI_MAXSERV];
 +-	int s;
 ++	int s = -1;
 + #else
 + 	struct sockaddr_in name;
 + 	struct hostent *hent;
 +-	int s, namelen;
 ++	int s = -1, namelen;
 + #endif
 + 
 + #ifdef HAVE_SSL
 +@@ -1301,7 +1305,7 @@
 + 			buf[i++] = c;
 + 		}
 + 	}
 +-	buf[i] = (char)NULL;
 ++	buf[i] = '\0';
 + 
 + 	return(buf);
 + }
 +@@ -1356,12 +1360,12 @@
 + */
 + ssize_t smtp_write(int fd, char *format, ...)
 + {
 +-	char buf[(BUF_SZ + 1)];
 ++	char buf[(BUF_SZ + 2)];
 + 	va_list ap;
 + 	ssize_t outbytes = 0;
 + 
 + 	va_start(ap, format);
 +-	if(vsnprintf(buf, (BUF_SZ - 2), format, ap) == -1) {
 ++	if(vsnprintf(buf, (BUF_SZ - 1), format, ap) == -1) {
 + 		die("smtp_write() -- vsnprintf() failed");
 + 	}
 + 	va_end(ap);
 +@@ -1399,16 +1403,18 @@
 + */
 + int ssmtp(char *argv[])
 + {
 +-	char buf[(BUF_SZ + 1)], *p, *q;
 ++	char b[(BUF_SZ + 2)], *buf = b+1, *p, *q;
 + #ifdef MD5AUTH
 + 	char challenge[(BUF_SZ + 1)];
 + #endif
 + 	struct passwd *pw;
 + 	int i, sock;
 + 	uid_t uid;
 +-	bool_t minus_v_save;
 ++	bool_t minus_v_save, leadingdot, linestart = True;
 + 	int timeout = 0;
 ++	int bufsize = sizeof(b)-1;
 + 
 ++	b[0] = '.';
 + 	outbytes = 0;
 + 	ht = &headers;
 + 
 +@@ -1423,14 +1429,14 @@
 + 	}
 + 
 + 	if((p = strtok(pw->pw_gecos, ";,"))) {
 +-		if((gecos = strdup(p)) == (char *)NULL) {
 ++		if((gecos = strdup(p)) == NULL) {
 + 			die("ssmtp() -- strdup() failed");
 + 		}
 + 	}
 + 	revaliases(pw);
 + 
 + 	/* revaliases() may have defined this */
 +-	if(uad == (char *)NULL) {
 ++	if(uad == NULL) {
 + 		uad = append_domain(pw->pw_name);
 + 	}
 + 
 +@@ -1478,7 +1484,7 @@
 + 	/* Try to log in if username was supplied */
 + 	if(auth_user) {
 + #ifdef MD5AUTH
 +-		if(auth_pass == (char *)NULL) {
 ++		if(auth_pass == NULL) {
 + 			auth_pass = strdup("");
 + 		}
 + 
 +@@ -1491,12 +1497,12 @@
 + 			}
 + 			strncpy(challenge, strchr(buf,' ') + 1, sizeof(challenge));
 + 
 +-			memset(buf, 0, sizeof(buf));
 ++			memset(buf, 0, bufsize);
 + 			crammd5(challenge, auth_user, auth_pass, buf);
 + 		}
 + 		else {
 + #endif
 +-		memset(buf, 0, sizeof(buf));
 ++		memset(buf, 0, bufsize);
 + 		to64frombits(buf, auth_user, strlen(auth_user));
 + 		if (use_oldauth) {
 + 			outbytes += smtp_write(sock, "AUTH LOGIN %s", buf);
 +@@ -1508,7 +1514,7 @@
 + 				die("Server didn't like our AUTH LOGIN (%s)", buf);
 + 			}
 + 			/* we assume server asked us for Username */
 +-			memset(buf, 0, sizeof(buf));
 ++			memset(buf, 0, bufsize);
 + 			to64frombits(buf, auth_user, strlen(auth_user));
 + 			outbytes += smtp_write(sock, buf);
 + 		}
 +@@ -1517,7 +1523,7 @@
 + 		if(smtp_read(sock, buf) != 3) {
 + 			die("Server didn't accept AUTH LOGIN (%s)", buf);
 + 		}
 +-		memset(buf, 0, sizeof(buf));
 ++		memset(buf, 0, bufsize);
 + 
 + 		to64frombits(buf, auth_pass, strlen(auth_pass));
 + #ifdef MD5AUTH
 +@@ -1626,28 +1632,40 @@
 + 	  stdio functions like fgets in the first place */
 + 	fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
 + 
 +-	/* don't hang forever when reading from stdin */
 +-	while(!feof(stdin) && timeout < MEDWAIT) {
 +-		if (!fgets(buf, sizeof(buf), stdin)) {
 ++	while(!feof(stdin)) {
 ++		if (!fgets(buf, bufsize, stdin)) {
 + 			/* if nothing was received, then no transmission
 + 			 * over smtp should be done */
 + 			sleep(1);
 +-			timeout++;
 ++			/* don't hang forever when reading from stdin */
 ++			if (++timeout >= MEDWAIT) {
 ++				log_event(LOG_ERR, "killed: timeout on stdin while reading body -- message saved to dead.letter.");
 ++				die("Timeout on stdin while reading body");
 ++			}
 + 			continue;
 + 		}
 + 		/* Trim off \n, double leading .'s */
 +-		standardise(buf);
 +-
 +-		outbytes += smtp_write(sock, "%s", buf);
 ++		leadingdot = standardise(buf, &linestart);
 + 
 ++		if (linestart || feof(stdin)) {
 ++			linestart = True;
 ++			outbytes += smtp_write(sock, "%s", leadingdot ? b : buf);
 ++		} else {
 ++			if (log_level > 0) {
 ++				log_event(LOG_INFO, "Sent a very long line in chunks");
 ++			}
 ++			if (leadingdot) {
 ++				outbytes += fd_puts(sock, b, sizeof(b));
 ++			} else {
 ++				outbytes += fd_puts(sock, buf, bufsize);
 ++			}
 ++		}
 + 		(void)alarm((unsigned) MEDWAIT);
 + 	}
 +-	/* End of body */
 +-
 +-	if (timeout >= MEDWAIT) {
 +-		log_event(LOG_ERR, "killed: timeout on stdin while reading body -- message saved to dead.letter.");
 +-		die("Timeout on stdin while reading body");
 ++	if(!linestart) {
 ++		smtp_write(sock, "");
 + 	}
 ++	/* End of body */
 + 
 + 	outbytes += smtp_write(sock, ".");
 + 	(void)alarm((unsigned) MAXWAIT);
 +@@ -1714,7 +1732,7 @@
 + 		j = 0;
 + 
 + 		add = 1;
 +-		while(argv[i][++j] != (char)NULL) {
 ++		while(argv[i][++j] != '\0') {
 + 			switch(argv[i][j]) {
 + #ifdef INET6
 + 			case '6':
 +@@ -1732,14 +1750,14 @@
 + 					if((!argv[i][(j + 1)])
 + 						&& argv[(i + 1)]) {
 + 						auth_user = strdup(argv[i+1]);
 +-						if(auth_user == (char *)NULL) {
 ++						if(auth_user == NULL) {
 + 							die("parse_options() -- strdup() failed");
 + 						}
 + 						add++;
 + 					}
 + 					else {
 + 						auth_user = strdup(argv[i]+j+1);
 +-						if(auth_user == (char *)NULL) {
 ++						if(auth_user == NULL) {
 + 							die("parse_options() -- strdup() failed");
 + 						}
 + 					}
 +@@ -1749,14 +1767,14 @@
 + 					if((!argv[i][(j + 1)])
 + 						&& argv[(i + 1)]) {
 + 						auth_pass = strdup(argv[i+1]);
 +-						if(auth_pass == (char *)NULL) {
 ++						if(auth_pass == NULL) {
 + 							die("parse_options() -- strdup() failed");
 + 						}
 + 						add++;
 + 					}
 + 					else {
 + 						auth_pass = strdup(argv[i]+j+1);
 +-						if(auth_pass == (char *)NULL) {
 ++						if(auth_pass == NULL) {
 + 							die("parse_options() -- strdup() failed");
 + 						}
 + 					}
 +@@ -1847,14 +1865,14 @@
 + 			case 'F':
 + 				if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
 + 					minus_F = strdup(argv[(i + 1)]);
 +-					if(minus_F == (char *)NULL) {
 ++					if(minus_F == NULL) {
 + 						die("parse_options() -- strdup() failed");
 + 					}
 + 					add++;
 + 				}
 + 				else {
 + 					minus_F = strdup(argv[i]+j+1);
 +-					if(minus_F == (char *)NULL) {
 ++					if(minus_F == NULL) {
 + 						die("parse_options() -- strdup() failed");
 + 					}
 + 				}
 +@@ -1866,14 +1884,14 @@
 + 			case 'r':
 + 				if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
 + 					minus_f = strdup(argv[(i + 1)]);
 +-					if(minus_f == (char *)NULL) {
 ++					if(minus_f == NULL) {
 + 						die("parse_options() -- strdup() failed");
 + 					}
 + 					add++;
 + 				}
 + 				else {
 + 					minus_f = strdup(argv[i]+j+1);
 +-					if(minus_f == (char *)NULL) {
 ++					if(minus_f == NULL) {
 + 						die("parse_options() -- strdup() failed");
 + 					}
 + 				}
 diff -uNr ssmtp.orig/files/ssmtp.c ssmtp/files/ssmtp.c
 --- ssmtp.orig/files/ssmtp.c	2009-11-25 23:52:59.000000000 +0200
 +++ ssmtp/files/ssmtp.c	1970-01-01 02:00:00.000000000 +0200
 @@ -1,542 +0,0 @@
 ---- ssmtp.c.orig	2004-07-23 01:58:48.000000000 -0400
 -+++ ssmtp.c	2009-01-15 14:13:10.000000000 -0500
 -@@ -12,8 +12,9 @@
 -  See COPYRIGHT for the license
 - 
 - */
 --#define VERSION "2.60.4"
 -+#define VERSION "2.61-11.1"
 - 
 -+#include <sys/types.h>
 - #include <sys/socket.h>
 - #include <netinet/in.h>
 - #include <sys/param.h>
 -@@ -54,20 +55,20 @@
 - 
 - #define ARPADATE_LENGTH 32		/* Current date in RFC format */
 - char arpadate[ARPADATE_LENGTH];
 --char *auth_user = (char)NULL;
 --char *auth_pass = (char)NULL;
 --char *auth_method = (char)NULL;		/* Mechanism for SMTP authentication */
 --char *mail_domain = (char)NULL;
 --char *from = (char)NULL;		/* Use this as the From: address */
 -+char *auth_user = NULL;
 -+char *auth_pass = NULL;
 -+char *auth_method = NULL;		/* Mechanism for SMTP authentication */
 -+char *mail_domain = NULL;
 -+char *from = NULL;		/* Use this as the From: address */
 - char hostname[MAXHOSTNAMELEN] = "localhost";
 - char *mailhost = "mailhub";
 --char *minus_f = (char)NULL;
 --char *minus_F = (char)NULL;
 -+char *minus_f = NULL;
 -+char *minus_F = NULL;
 - char *gecos;
 --char *prog = (char)NULL;
 -+char *prog = NULL;
 - char *root = NULL;
 - char *tls_cert = "/etc/ssl/certs/ssmtp.pem";	/* Default Certificate */
 --char *uad = (char)NULL;
 -+char *uad = NULL;
 - 
 - headers_t headers, *ht;
 - 
 -@@ -220,16 +221,16 @@
 - 	char buf[MAXPATHLEN +1], *p;
 - 
 - 	if((p = strrchr(str, '/'))) {
 --		if(strncpy(buf, ++p, MAXPATHLEN) == (char *)NULL) {
 -+		if(strncpy(buf, ++p, MAXPATHLEN) == NULL) {
 - 			die("basename() -- strncpy() failed");
 - 		}
 - 	}
 - 	else {
 --		if(strncpy(buf, str, MAXPATHLEN) == (char *)NULL) {
 -+		if(strncpy(buf, str, MAXPATHLEN) == NULL) {
 - 			die("basename() -- strncpy() failed");
 - 		}
 - 	}
 --	buf[MAXPATHLEN] = (char)NULL;
 -+	buf[MAXPATHLEN] = '\0';
 - 
 - 	return(strdup(buf));
 - }
 -@@ -256,7 +257,7 @@
 - 
 - 	p = (str + strlen(str));
 - 	while(isspace(*--p)) {
 --		*p = (char)NULL;
 -+		*p = '\0';
 - 	}
 - 
 - 	return(p);
 -@@ -274,7 +275,7 @@
 - #endif
 - 
 - 	/* Simple case with email address enclosed in <> */
 --	if((p = strdup(str)) == (char *)NULL) {
 -+	if((p = strdup(str)) == NULL) {
 - 		die("addr_parse(): strdup()");
 - 	}
 - 
 -@@ -282,7 +283,7 @@
 - 		q++;
 - 
 - 		if((p = strchr(q, '>'))) {
 --			*p = (char)NULL;
 -+			*p = '\0';
 - 		}
 - 
 - #if 0
 -@@ -305,7 +306,7 @@
 - 	q = strip_post_ws(p);
 - 	if(*q == ')') {
 - 		while((*--q != '('));
 --		*q = (char)NULL;
 -+		*q = '\0';
 - 	}
 - 	(void)strip_post_ws(p);
 - 
 -@@ -323,7 +324,7 @@
 - {
 - 	char buf[(BUF_SZ + 1)];
 - 
 --	if(strchr(str, '@') == (char *)NULL) {
 -+	if(strchr(str, '@') == NULL) {
 - 		if(snprintf(buf, BUF_SZ, "%s@%s", str,
 - #ifdef REWRITE_DOMAIN
 - 			rewrite_domain == True ? mail_domain : hostname
 -@@ -348,7 +349,7 @@
 - 	char *p;
 - 
 - 	if((p = strchr(str, '\n'))) {
 --		*p = (char)NULL;
 -+		*p = '\0';
 - 	}
 - 
 - 	/* Any line beginning with a dot has an additional dot inserted;
 -@@ -374,31 +375,58 @@
 - {
 - 	char buf[(BUF_SZ + 1)], *p;
 - 	FILE *fp;
 -+#ifdef USERPREFS
 -+	char *file=NULL;
 -+	if (pw->pw_dir != NULL) {
 -+		file = (char *)malloc (strlen (pw->pw_dir) + 1 + strlen (".ssmtprc") + 1);
 -+		sprintf (file, "%s/.ssmtprc", pw->pw_dir);
 -+	}
 -+
 -+	if ((file != NULL) && (fp = fopen(file, "r")) ) {
 -+		while(fgets(buf, sizeof(buf), fp)) {
 -+				/* Make comments invisible */
 -+				if((p = strchr(buf, '#'))) {
 -+					*p = '\0';
 -+				}
 - 
 -+			/* Ignore malformed lines and comments */
 -+				if(strchr(buf, '@') == NULL) {
 -+					continue;
 -+				}
 -+				if((p = strtok(buf, "\n"))) {
 -+                                        if((uad = strdup(p)) == NULL) {
 -+                                                die("revaliases() -- strdup() failed");
 -+                                        }
 -+				}
 -+			}
 -+		fclose(fp);
 - 	/* Try to open the reverse aliases file */
 --	if((fp = fopen(REVALIASES_FILE, "r"))) {
 -+	} else if ((fp = fopen(REVALIASES_FILE, "r"))) {
 -+#else
 -+	if ((fp = fopen(REVALIASES_FILE, "r"))) {
 -+#endif
 - 		/* Search if a reverse alias is defined for the sender */
 - 		while(fgets(buf, sizeof(buf), fp)) {
 - 			/* Make comments invisible */
 - 			if((p = strchr(buf, '#'))) {
 --				*p = (char)NULL;
 -+				*p = '\0';
 - 			}
 - 
 - 			/* Ignore malformed lines and comments */
 --			if(strchr(buf, ':') == (char *)NULL) {
 -+			if(strchr(buf, ':') == NULL) {
 - 				continue;
 - 			}
 - 
 - 			/* Parse the alias */
 - 			if(((p = strtok(buf, ":"))) && !strcmp(p, pw->pw_name)) {
 - 				if((p = strtok(NULL, ": \t\r\n"))) {
 --					if((uad = strdup(p)) == (char *)NULL) {
 -+					if((uad = strdup(p)) == NULL) {
 - 						die("revaliases() -- strdup() failed");
 - 					}
 - 				}
 - 
 - 				if((p = strtok(NULL, " \t\r\n:"))) {
 --					if((mailhost = strdup(p)) == (char *)NULL) {
 -+					if((mailhost = strdup(p)) == NULL) {
 - 						die("revaliases() -- strdup() failed");
 - 					}
 - 
 -@@ -435,7 +463,7 @@
 - 	}
 - 
 - 	/* Remove the real name if necessary - just send the address */
 --	if((p = addr_parse(str)) == (char *)NULL) {
 -+	if((p = addr_parse(str)) == NULL) {
 - 		die("from_strip() -- addr_parse() failed");
 - 	}
 - #if 0
 -@@ -511,11 +539,11 @@
 - #endif
 - 
 - 	/* Ignore missing usernames */
 --	if(*str == (char)NULL) {
 -+	if(*str == '\0') {
 - 		return;
 - 	}
 - 
 --	if((rt->string = strdup(str)) == (char *)NULL) {
 -+	if((rt->string = strdup(str)) == NULL) {
 - 		die("rcpt_save() -- strdup() failed");
 - 	}
 - 
 -@@ -540,7 +568,7 @@
 - 	(void)fprintf(stderr, "*** rcpt_parse(): str = [%s]\n", str);
 - #endif
 - 
 --	if((p = strdup(str)) == (char *)NULL) {
 -+	if((p = strdup(str)) == NULL) {
 - 		die("rcpt_parse(): strdup() failed");
 - 	}
 - 	q = p;
 -@@ -568,7 +596,7 @@
 - 		}
 - 
 - 		/* End of string? */
 --		if(*(q + 1) == (char)NULL) {
 -+		if(*(q + 1) == '\0') {
 - 			got_addr = True;
 - 		}
 - 
 -@@ -576,7 +604,7 @@
 - 		if((*q == ',') && (in_quotes == False)) {
 - 			got_addr = True;
 - 
 --			*q = (char)NULL;
 -+			*q = '\0';
 - 		}
 - 
 - 		if(got_addr) {
 -@@ -599,19 +627,21 @@
 - {
 - 	int i;
 - 	unsigned char digest[MD5_DIGEST_LEN];
 --	unsigned char digascii[MD5_DIGEST_LEN * 2];
 -+	char digascii[MD5_DIGEST_LEN * 2];
 - 	unsigned char challenge[(BUF_SZ + 1)];
 --	unsigned char response[(BUF_SZ + 1)];
 --	unsigned char secret[(MD5_BLOCK_LEN + 1)]; 
 -+	char response[(BUF_SZ + 1)];
 -+	char secret[(MD5_BLOCK_LEN + 1)]; 
 -+	int challenge_len;
 - 
 - 	memset (secret,0,sizeof(secret));
 - 	memset (challenge,0,sizeof(challenge));
 - 	strncpy (secret, password, sizeof(secret));	
 - 	if (!challengeb64 || strlen(challengeb64) > sizeof(challenge) * 3 / 4)
 - 		return 0;
 --	from64tobits(challenge, challengeb64);
 -+	challenge_len = from64tobits(challenge, challengeb64);
 - 
 --	hmac_md5(challenge, strlen(challenge), secret, strlen(secret), digest);
 -+	hmac_md5(challenge, challenge_len, 
 -+		 (unsigned char *)secret, strlen(secret), digest);
 - 
 - 	for (i = 0; i < MD5_DIGEST_LEN; i++) {
 - 		digascii[2 * i] = hextab[digest[i] >> 4];
 -@@ -625,7 +655,7 @@
 - 	strncpy (response, username, sizeof(response) - sizeof(digascii) - 2);
 - 	strcat (response, " ");
 - 	strcat (response, digascii);
 --	to64frombits(responseb64, response, strlen(response));
 -+	to64frombits(responseb64, (unsigned char *)response, strlen(response));
 - 
 - 	return 1;
 - }
 -@@ -660,7 +690,7 @@
 - 	(void)fprintf(stderr, "header_save(): str = [%s]\n", str);
 - #endif
 - 
 --	if((p = strdup(str)) == (char *)NULL) {
 -+	if((p = strdup(str)) == NULL) {
 - 		die("header_save() -- strdup() failed");
 - 	}
 - 	ht->string = p;
 -@@ -668,7 +698,7 @@
 - 	if(strncasecmp(ht->string, "From:", 5) == 0) {
 - #if 1
 - 		/* Hack check for NULL From: line */
 --		if(*(p + 6) == (char)NULL) {
 -+		if(*(p + 6) == '\0') {
 - 			return;
 - 		}
 - #endif
 -@@ -727,19 +757,19 @@
 - void header_parse(FILE *stream)
 - {
 - 	size_t size = BUF_SZ, len = 0;
 --	char *p = (char *)NULL, *q;
 -+	char *p = NULL, *q = NULL;
 - 	bool_t in_header = True;
 --	char l = (char)NULL;
 -+	char l = '\0';
 - 	int c;
 - 
 - 	while(in_header && ((c = fgetc(stream)) != EOF)) {
 - 		/* Must have space for up to two more characters, since we
 - 			may need to insert a '\r' */
 --		if((p == (char *)NULL) || (len >= (size - 1))) {
 -+		if((p == NULL) || (len >= (size - 1))) {
 - 			size += BUF_SZ;
 - 
 - 			p = (char *)realloc(p, (size * sizeof(char)));
 --			if(p == (char *)NULL) {
 -+			if(p == NULL) {
 - 				die("header_parse() -- realloc() failed");
 - 			}
 - 			q = (p + len);
 -@@ -764,9 +794,9 @@
 - 						in_header = False;
 - 
 - 				default:
 --						*q = (char)NULL;
 -+						*q = '\0';
 - 						if((q = strrchr(p, '\n'))) {
 --							*q = (char)NULL;
 -+							*q = '\0';
 - 						}
 - 						header_save(p);
 - 
 -@@ -796,17 +826,17 @@
 - 	while(fgets(buf, sizeof(buf), fp)) {
 - 		/* Make comments invisible */
 - 		if((p = strchr(buf, '#'))) {
 --			*p = (char)NULL;
 -+			*p = '\0';
 - 		}
 - 
 - 		/* Ignore malformed lines and comments */
 --		if(strchr(buf, '=') == (char *)NULL) continue;
 -+		if(strchr(buf, '=') == NULL) continue;
 - 
 - 		/* Parse out keywords */
 --		if(((p = strtok(buf, "= \t\n")) != (char *)NULL)
 --			&& ((q = strtok(NULL, "= \t\n:")) != (char *)NULL)) {
 -+		if(((p = strtok(buf, "= \t\n")) != NULL)
 -+			&& ((q = strtok(NULL, "= \t\n:")) != NULL)) {
 - 			if(strcasecmp(p, "Root") == 0) {
 --				if((root = strdup(q)) == (char *)NULL) {
 -+				if((root = strdup(q)) == NULL) {
 - 					die("parse_config() -- strdup() failed");
 - 				}
 - 
 -@@ -815,7 +845,7 @@
 - 				}
 - 			}
 - 			else if(strcasecmp(p, "MailHub") == 0) {
 --				if((mailhost = strdup(q)) == (char *)NULL) {
 -+				if((mailhost = strdup(q)) == NULL) {
 - 					die("parse_config() -- strdup() failed");
 - 				}
 - 
 -@@ -851,7 +881,7 @@
 - 					mail_domain = strdup(q);
 - 				}
 - 
 --				if(mail_domain == (char *)NULL) {
 -+				if(mail_domain == NULL) {
 - 					die("parse_config() -- strdup() failed");
 - 				}
 - 				rewrite_domain = True;
 -@@ -927,7 +957,7 @@
 - 				}
 - 			}
 - 			else if(strcasecmp(p, "TLSCert") == 0) {
 --				if((tls_cert = strdup(q)) == (char *)NULL) {
 -+				if((tls_cert = strdup(q)) == NULL) {
 - 					die("parse_config() -- strdup() failed");
 - 				}
 - 
 -@@ -938,7 +968,7 @@
 - #endif
 - 			/* Command-line overrides these */
 - 			else if(strcasecmp(p, "AuthUser") == 0 && !auth_user) {
 --				if((auth_user = strdup(q)) == (char *)NULL) {
 -+				if((auth_user = strdup(q)) == NULL) {
 - 					die("parse_config() -- strdup() failed");
 - 				}
 - 
 -@@ -947,7 +977,7 @@
 - 				}
 - 			}
 - 			else if(strcasecmp(p, "AuthPass") == 0 && !auth_pass) {
 --				if((auth_pass = strdup(q)) == (char *)NULL) {
 -+				if((auth_pass = strdup(q)) == NULL) {
 - 					die("parse_config() -- strdup() failed");
 - 				}
 - 
 -@@ -956,7 +986,7 @@
 - 				}
 - 			}
 - 			else if(strcasecmp(p, "AuthMethod") == 0 && !auth_method) {
 --				if((auth_method = strdup(q)) == (char *)NULL) {
 -+				if((auth_method = strdup(q)) == NULL) {
 - 					die("parse_config() -- strdup() failed");
 - 				}
 - 
 -@@ -982,11 +1012,11 @@
 - #ifdef INET6
 - 	struct addrinfo hints, *ai0, *ai;
 - 	char servname[NI_MAXSERV];
 --	int s;
 -+	int s = -1;
 - #else
 - 	struct sockaddr_in name;
 - 	struct hostent *hent;
 --	int s, namelen;
 -+	int s = -1, namelen;
 - #endif
 - 
 - #ifdef HAVE_SSL
 -@@ -996,7 +1026,7 @@
 - 	/* Init SSL stuff */
 - 	SSL_CTX *ctx;
 - 	SSL_METHOD *meth;
 --	X509 *server_cert;
 -+	const X509 *server_cert;
 - 
 - 	SSL_load_error_strings();
 - 	SSLeay_add_ssl_algorithms();
 -@@ -1179,7 +1209,7 @@
 - 			buf[i++] = c;
 - 		}
 - 	}
 --	buf[i] = (char)NULL;
 -+	buf[i] = '\0';
 - 
 - 	return(buf);
 - }
 -@@ -1293,14 +1323,14 @@
 - 	}
 - 
 - 	if((p = strtok(pw->pw_gecos, ";,"))) {
 --		if((gecos = strdup(p)) == (char *)NULL) {
 -+		if((gecos = strdup(p)) == NULL) {
 - 			die("ssmtp() -- strdup() failed");
 - 		}
 - 	}
 - 	revaliases(pw);
 - 
 - 	/* revaliases() may have defined this */
 --	if(uad == (char *)NULL) {
 -+	if(uad == NULL) {
 - 		uad = append_domain(pw->pw_name);
 - 	}
 - 
 -@@ -1349,7 +1379,7 @@
 - 	/* Try to log in if username was supplied */
 - 	if(auth_user) {
 - #ifdef MD5AUTH
 --		if(auth_pass == (char *)NULL) {
 -+		if(auth_pass == NULL) {
 - 			auth_pass = strdup("");
 - 		}
 - 
 -@@ -1377,7 +1407,7 @@
 - 		}
 - 		memset(buf, 0, sizeof(buf));
 - 
 --		to64frombits(buf, auth_pass, strlen(auth_pass));
 -+		to64frombits(buf, (unsigned char *)auth_pass, strlen(auth_pass));
 - #ifdef MD5AUTH
 - 		}
 - #endif
 -@@ -1549,7 +1579,7 @@
 - 		j = 0;
 - 
 - 		add = 1;
 --		while(argv[i][++j] != (char)NULL) {
 -+		while(argv[i][++j] != '\0') {
 - 			switch(argv[i][j]) {
 - #ifdef INET6
 - 			case '6':
 -@@ -1567,14 +1597,14 @@
 - 					if((!argv[i][(j + 1)])
 - 						&& argv[(i + 1)]) {
 - 						auth_user = strdup(argv[i+1]);
 --						if(auth_user == (char *)NULL) {
 -+						if(auth_user == NULL) {
 - 							die("parse_options() -- strdup() failed");
 - 						}
 - 						add++;
 - 					}
 - 					else {
 - 						auth_user = strdup(argv[i]+j+1);
 --						if(auth_user == (char *)NULL) {
 -+						if(auth_user == NULL) {
 - 							die("parse_options() -- strdup() failed");
 - 						}
 - 					}
 -@@ -1584,14 +1614,14 @@
 - 					if((!argv[i][(j + 1)])
 - 						&& argv[(i + 1)]) {
 - 						auth_pass = strdup(argv[i+1]);
 --						if(auth_pass == (char *)NULL) {
 -+						if(auth_pass == NULL) {
 - 							die("parse_options() -- strdup() failed");
 - 						}
 - 						add++;
 - 					}
 - 					else {
 - 						auth_pass = strdup(argv[i]+j+1);
 --						if(auth_pass == (char *)NULL) {
 -+						if(auth_pass == NULL) {
 - 							die("parse_options() -- strdup() failed");
 - 						}
 - 					}
 -@@ -1669,14 +1699,14 @@
 - 			case 'F':
 - 				if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
 - 					minus_F = strdup(argv[(i + 1)]);
 --					if(minus_F == (char *)NULL) {
 -+					if(minus_F == NULL) {
 - 						die("parse_options() -- strdup() failed");
 - 					}
 - 					add++;
 - 				}
 - 				else {
 - 					minus_F = strdup(argv[i]+j+1);
 --					if(minus_F == (char *)NULL) {
 -+					if(minus_F == NULL) {
 - 						die("parse_options() -- strdup() failed");
 - 					}
 - 				}
 -@@ -1688,14 +1718,14 @@
 - 			case 'r':
 - 				if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
 - 					minus_f = strdup(argv[(i + 1)]);
 --					if(minus_f == (char *)NULL) {
 -+					if(minus_f == NULL) {
 - 						die("parse_options() -- strdup() failed");
 - 					}
 - 					add++;
 - 				}
 - 				else {
 - 					minus_f = strdup(argv[i]+j+1);
 --					if(minus_f == (char *)NULL) {
 -+					if(minus_f == NULL) {
 - 						die("parse_options() -- strdup() failed");
 - 					}
 - 				}
 diff -uNr ssmtp.orig/files/ssmtp.h ssmtp/files/ssmtp.h
 --- ssmtp.orig/files/ssmtp.h	2009-11-25 23:52:59.000000000 +0200
 +++ ssmtp/files/ssmtp.h	1970-01-01 02:00:00.000000000 +0200
 @@ -1,10 +0,0 @@
 ---- ./ssmtp.h.orig	2002-09-27 09:18:24.000000000 -0400
 -+++ ./ssmtp.h	2008-11-17 18:55:03.000000000 -0500
 -@@ -37,5 +37,5 @@
 - void get_arpadate(char *);
 - 
 - /* base64.c */
 --void to64frombits(unsigned char *, const unsigned char *, int);
 --int from64tobits(char *, const char *);
 -+void to64frombits(char *, const unsigned char *, int);
 -+int from64tobits(unsigned char *, const char *);
 
 --------------050206040202080707060505--

From: Greg Larkin <glarkin@FreeBSD.org>
To: Aragon Gouveia <aragon@phat.za.net>, bug-followup@FreeBSD.org
Cc:  
Subject: Re: ports/140175: [patch] mail/ssmtp CRAM-MD5 broken
Date: Tue, 01 Dec 2009 17:53:17 -0500

 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
 Aragon Gouveia wrote:
 > The following reply was made to PR ports/140175; it has been noted by GNATS.
 > 
 > From: Aragon Gouveia <aragon@phat.za.net>
 > To: bug-followup@FreeBSD.org
 > Cc:  
 > Subject: Re: ports/140175: [patch] mail/ssmtp CRAM-MD5 broken
 > Date: Thu, 26 Nov 2009 02:08:28 +0200
 > 
 >  This is a multi-part message in MIME format.
 >  --------------050206040202080707060505
 >  Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 >  Content-Transfer-Encoding: 7bit
 >  
 >  As requested, I've updated the port to the latest stable version from 
 >  upstream, 2.62-3, and included the CRAM-MD5 fix.  Patch attached.
 >  
 >  I've made some minor changes, in particular the port doesn't fetch the 
 >  patchlevel diff file from upstream.  I'm not sure why it was fetching it 
 >  previously as it didn't seem to do anything with it, and neither does 
 >  this new port.  The upstream patchlevel stuff is integrated in 
 >  files/patch-ssmtp.c and includes:
 >  
 >  debian/patches/02-CVE-2008-3962
 >  debian/patches/345780-standardise-bufsize
 >  
 >  There were quite a lot of local coding fixes in ssmtp.c that had to be 
 >  updated.  Have you tried sending these upstream?
 >  
 [...]
 
 Hi Aragon,
 
 Thank you for preparing the new patch, and I have been working on
 incorporating it into my local development area.
 
 I discovered pretty quickly that FreeBSD <7.2 doesn't include the
 strndup function in libc, so ssmtp doesn't link on those versions.
 Lately, I've been using GNU gnulib (http://www.gnu.org/software/gnulib/)
 to work around problems like these, and I am working on some additional
 patches to incorporate GNU strndup into this project.
 
 Thank you,
 Greg
 - --
 Greg Larkin
 
 http://www.FreeBSD.org/           - The Power To Serve
 http://www.sourcehosting.net/     - Ready. Set. Code.
 http://twitter.com/sourcehosting/ - Follow me, follow you
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.7 (MingW32)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
 
 iD8DBQFLFZ5d0sRouByUApARAkEoAJ9rD0v/gQnu5TqybTeyGXm+VVDhuACeORN9
 9KVJVnenQIPpN1KDGrhbNBY=
 =nVf4
 -----END PGP SIGNATURE-----
 

From: Aragon Gouveia <aragon@phat.za.net>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: ports/140175: [patch] mail/ssmtp CRAM-MD5 broken
Date: Fri, 04 Dec 2009 02:56:25 +0200

 This is a multi-part message in MIME format.
 --------------000808000802060807060100
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Attached is a patch that incorporates everything previously plus a 
 version conditional patch with a strndup() implementation for older 
 FreeBSD versions.  I tested this on a 7.1-RELEASE system.
 
 I don't actually know how you made sense of my previous patch - it got 
 severely bastardised somewhere in my rolling process which I only 
 noticed now.  This patch should be sane!
 
 --------------000808000802060807060100
 Content-Type: text/plain;
  name="ssmtp.txt"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="ssmtp.txt"
 
 diff -uNr ssmtp.orig/Makefile ssmtp/Makefile
 --- ssmtp.orig/Makefile	2009-01-28 01:10:03.000000000 +0200
 +++ ssmtp/Makefile	2009-12-04 02:25:07.000000000 +0200
 @@ -6,19 +6,16 @@
  #
  
  PORTNAME=	ssmtp
 -PORTVERSION=	2.61.11.1
 -PORTREVISION=	2
 +PORTVERSION=	2.62.3
  CATEGORIES=	mail ipv6
  MASTER_SITES=	${MASTER_SITE_DEBIAN_POOL}
 -DISTNAME=	${PORTNAME}_2.61.orig
 +DISTNAME=	${PORTNAME}_2.62.orig
  DISTFILES=	${DISTNAME}.tar.gz \
 -		ssmtp_2.61-11.1.diff.gz
 -EXTRACT_ONLY=	${DISTNAME}.tar.gz
  
  MAINTAINER=	glarkin@FreeBSD.org
  COMMENT=	Extremely simple MTA to get mail off the system to a mail hub
  
 -WRKSRC=		${WRKDIR}/${PORTNAME}-2.61
 +WRKSRC=		${WRKDIR}/${PORTNAME}
  
  USE_OPENSSL=	yes
  
 diff -uNr ssmtp.orig/distinfo ssmtp/distinfo
 --- ssmtp.orig/distinfo	2007-09-18 22:31:05.000000000 +0200
 +++ ssmtp/distinfo	2009-12-04 02:25:07.000000000 +0200
 @@ -1,6 +1,3 @@
 -MD5 (ssmtp_2.61.orig.tar.gz) = 957e6fff08625fe34f4fc33d0925bbc9
 -SHA256 (ssmtp_2.61.orig.tar.gz) = 2151ad18cb73f9a254f796dde2b48be7318b45410b59fedbb258db5a41044fb5
 -SIZE (ssmtp_2.61.orig.tar.gz) = 53341
 -MD5 (ssmtp_2.61-11.1.diff.gz) = 96946aed2e9b5442f7f0643bcbd4e4f6
 -SHA256 (ssmtp_2.61-11.1.diff.gz) = 85a56288874a874f433ee5e48891812bb18b23c9e33fd39c5168b1843010a8cd
 -SIZE (ssmtp_2.61-11.1.diff.gz) = 33458
 +MD5 (ssmtp_2.62.orig.tar.gz) = 257ac04e62ab7e3616e220333a1140cb
 +SHA256 (ssmtp_2.62.orig.tar.gz) = e2a0a5379cd0bbb0b4b0304abeba7a8f60aa85275982c5d7930c319e7f284ed1
 +SIZE (ssmtp_2.62.orig.tar.gz) = 57127
 diff -uNr ssmtp.orig/files/patch-arpadate.c ssmtp/files/patch-arpadate.c
 --- ssmtp.orig/files/patch-arpadate.c	2003-04-14 03:29:12.000000000 +0200
 +++ ssmtp/files/patch-arpadate.c	1970-01-01 02:00:00.000000000 +0200
 @@ -1,11 +0,0 @@
 ---- arpadate.c.orig	Sun Dec  8 18:30:13 2002
 -+++ arpadate.c	Mon Apr  7 01:17:58 2003
 -@@ -79,7 +79,7 @@
 - 	time_t now;
 - 
 - 	/* RFC822 format string borrowed from GNU shellutils date.c */
 --	const char *format = "%a, %_d %b %Y %H:%M:%S %z";
 -+	const char *format = "%a, %e %b %Y %H:%M:%S %z";
 - 
 - 	now = time(NULL);
 - 
 diff -uNr ssmtp.orig/files/patch-base64.c ssmtp/files/patch-base64.c
 --- ssmtp.orig/files/patch-base64.c	2008-11-19 23:23:49.000000000 +0200
 +++ ssmtp/files/patch-base64.c	1970-01-01 02:00:00.000000000 +0200
 @@ -1,20 +0,0 @@
 ---- ./base64.c.orig	2002-05-07 09:26:43.000000000 -0400
 -+++ ./base64.c	2008-11-17 18:55:03.000000000 -0500
 -@@ -31,7 +31,7 @@
 - };
 - #define DECODE64(c)  (isascii(c) ? base64val[c] : BAD)
 - 
 --void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
 -+void to64frombits(char *out, const unsigned char *in, int inlen)
 - /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
 - {
 -     for (; inlen >= 3; inlen -= 3)
 -@@ -57,7 +57,7 @@
 -     *out = '\0';
 - }
 - 
 --int from64tobits(char *out, const char *in)
 -+int from64tobits(unsigned char *out, const char *in)
 - /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
 - {
 -     int len = 0;
 diff -uNr ssmtp.orig/files/patch-configure ssmtp/files/patch-configure
 --- ssmtp.orig/files/patch-configure	2003-10-02 01:08:01.000000000 +0200
 +++ ssmtp/files/patch-configure	2009-12-04 02:25:07.000000000 +0200
 @@ -9,3 +9,16 @@
   fi
   enableval=""
   
 +--- configure.orig	2009-11-01 23:52:55.000000000 +0200
 ++++ configure	2009-11-01 23:53:42.000000000 +0200
 +@@ -1591,7 +1591,8 @@
 + #define MD5AUTH 1
 + EOF
 + 
 +-	SRCS="$SRCS md5auth/md5c.c md5auth/hmac_md5.c"
 ++	SRCS="$SRCS md5auth/hmac_md5.c"
 ++	LIBS="$LIBS -lmd"
 + fi
 + enableval=""
 + 
 +
 diff -uNr ssmtp.orig/files/patch-md5auth-hmac_md5.c ssmtp/files/patch-md5auth-hmac_md5.c
 --- ssmtp.orig/files/patch-md5auth-hmac_md5.c	1970-01-01 02:00:00.000000000 +0200
 +++ ssmtp/files/patch-md5auth-hmac_md5.c	2009-12-04 02:25:07.000000000 +0200
 @@ -0,0 +1,12 @@
 +--- md5auth/hmac_md5.c.orig	2009-11-01 23:54:54.000000000 +0200
 ++++ md5auth/hmac_md5.c	2009-11-01 23:55:07.000000000 +0200
 +@@ -1,7 +1,7 @@
 + #include "global.h"
 +-#include "md5.h"
 + #include <string.h>
 + #include <sys/types.h>
 ++#include <md5.h>
 + 
 + /*
 + ** Function: hmac_md5 (RFC 2104)
 +
 diff -uNr ssmtp.orig/files/patch-ssmtp.c ssmtp/files/patch-ssmtp.c
 --- ssmtp.orig/files/patch-ssmtp.c	2009-01-15 21:20:47.000000000 +0200
 +++ ssmtp/files/patch-ssmtp.c	2009-12-04 02:25:07.000000000 +0200
 @@ -1,17 +1,23 @@
 ---- ssmtp.c.orig	2004-07-23 01:58:48.000000000 -0400
 -+++ ssmtp.c	2009-01-15 14:13:10.000000000 -0500
 -@@ -12,8 +12,9 @@
 +--- ssmtp.c.orig	2008-03-06 22:01:22.000000000 +0200
 ++++ ssmtp.c	2009-12-04 02:22:14.000000000 +0200
 +@@ -10,7 +10,7 @@
    See COPYRIGHT for the license
   
   */
 --#define VERSION "2.60.4"
 -+#define VERSION "2.61-11.1"
 +-#define VERSION "2.62"
 ++#define VERSION "2.62.3"
 + #define _GNU_SOURCE
   
 -+#include <sys/types.h>
   #include <sys/socket.h>
 - #include <netinet/in.h>
 - #include <sys/param.h>
 -@@ -54,20 +55,20 @@
 +@@ -25,6 +25,7 @@
 + #include <string.h>
 + #include <ctype.h>
 + #include <netdb.h>
 ++#include <libgen.h>
 + #ifdef HAVE_SSL
 + #include <openssl/crypto.h>
 + #include <openssl/x509.h>
 +@@ -55,21 +56,21 @@
   
   #define ARPADATE_LENGTH 32		/* Current date in RFC format */
   char arpadate[ARPADATE_LENGTH];
 @@ -25,7 +31,7 @@
  +char *auth_method = NULL;		/* Mechanism for SMTP authentication */
  +char *mail_domain = NULL;
  +char *from = NULL;		/* Use this as the From: address */
 - char hostname[MAXHOSTNAMELEN] = "localhost";
 + char *hostname;
   char *mailhost = "mailhub";
  -char *minus_f = (char)NULL;
  -char *minus_F = (char)NULL;
 @@ -35,33 +41,41 @@
  -char *prog = (char)NULL;
  +char *prog = NULL;
   char *root = NULL;
 - char *tls_cert = "/etc/ssl/certs/ssmtp.pem";	/* Default Certificate */
 +-char *tls_cert = "/etc/ssl/certs/ssmtp.pem";	/* Default Certificate */
  -char *uad = (char)NULL;
 +-char *config_file = (char)NULL;		/* alternate configuration file */
 ++char *tls_cert = "/usr/local/etc/ssmtp/ssmtp.pem";	/* Default Certificate */
  +char *uad = NULL;
 ++char *config_file = NULL;		/* alternate configuration file */
   
   headers_t headers, *ht;
   
 -@@ -220,16 +221,16 @@
 - 	char buf[MAXPATHLEN +1], *p;
 - 
 - 	if((p = strrchr(str, '/'))) {
 --		if(strncpy(buf, ++p, MAXPATHLEN) == (char *)NULL) {
 -+		if(strncpy(buf, ++p, MAXPATHLEN) == NULL) {
 - 			die("basename() -- strncpy() failed");
 - 		}
 - 	}
 - 	else {
 --		if(strncpy(buf, str, MAXPATHLEN) == (char *)NULL) {
 -+		if(strncpy(buf, str, MAXPATHLEN) == NULL) {
 - 			die("basename() -- strncpy() failed");
 - 		}
 - 	}
 --	buf[MAXPATHLEN] = (char)NULL;
 -+	buf[MAXPATHLEN] = '\0';
 - 
 - 	return(strdup(buf));
 +@@ -239,6 +240,24 @@
   }
 -@@ -256,7 +257,7 @@
 + #endif /* _GNU_SOURCE */
 + 
 ++#if defined(__FreeBSD_version) && __FreeBSD_version < 701101
 ++char *
 ++strndup(const char *str, size_t n)
 ++{
 ++	size_t len;
 ++	char *copy;
 ++
 ++	for (len = 0; len < n && str[len]; len++)
 ++		continue;
 ++
 ++	if ((copy = malloc(len + 1)) == NULL)
 ++		return (NULL);
 ++	memcpy(copy, str, len);
 ++	copy[len] = '\0';
 ++	return (copy);
 ++}
 ++#endif
 ++
 + /*
 + strip_pre_ws() -- Return pointer to first non-whitespace character
 + */
 +@@ -261,7 +280,7 @@
   
   	p = (str + strlen(str));
   	while(isspace(*--p)) {
 @@ -70,7 +84,7 @@
   	}
   
   	return(p);
 -@@ -274,7 +275,7 @@
 +@@ -279,7 +298,7 @@
   #endif
   
   	/* Simple case with email address enclosed in <> */
 @@ -79,7 +93,7 @@
   		die("addr_parse(): strdup()");
   	}
   
 -@@ -282,7 +283,7 @@
 +@@ -287,7 +306,7 @@
   		q++;
   
   		if((p = strchr(q, '>'))) {
 @@ -88,7 +102,7 @@
   		}
   
   #if 0
 -@@ -305,7 +306,7 @@
 +@@ -310,7 +329,7 @@
   	q = strip_post_ws(p);
   	if(*q == ')') {
   		while((*--q != '('));
 @@ -97,60 +111,48 @@
   	}
   	(void)strip_post_ws(p);
   
 -@@ -323,7 +324,7 @@
 +@@ -347,28 +366,26 @@
 + /*
 + standardise() -- Trim off '\n's and double leading dots
 + */
 +-void standardise(char *str)
 ++bool_t standardise(char *str, bool_t *linestart)
   {
 - 	char buf[(BUF_SZ + 1)];
 - 
 --	if(strchr(str, '@') == (char *)NULL) {
 -+	if(strchr(str, '@') == NULL) {
 - 		if(snprintf(buf, BUF_SZ, "%s@%s", str,
 - #ifdef REWRITE_DOMAIN
 - 			rewrite_domain == True ? mail_domain : hostname
 -@@ -348,7 +349,7 @@
 + 	size_t sl;
   	char *p;
 - 
 - 	if((p = strchr(str, '\n'))) {
 +-
 +-	if((p = strchr(str, '\n'))) {
  -		*p = (char)NULL;
 -+		*p = '\0';
 - 	}
 +-	}
 ++	bool_t leadingdot = False;
   
   	/* Any line beginning with a dot has an additional dot inserted;
 -@@ -374,31 +375,58 @@
 - {
 - 	char buf[(BUF_SZ + 1)], *p;
 - 	FILE *fp;
 -+#ifdef USERPREFS
 -+	char *file=NULL;
 -+	if (pw->pw_dir != NULL) {
 -+		file = (char *)malloc (strlen (pw->pw_dir) + 1 + strlen (".ssmtprc") + 1);
 -+		sprintf (file, "%s/.ssmtprc", pw->pw_dir);
 +-	not just a line consisting solely of a dot. Thus we have to slide
 +-	the buffer down one */
 +-	sl = strlen(str);
 ++	not just a line consisting solely of a dot. Thus we have to move
 ++	the buffer start up one */
 + 
 +-	if(*str == '.') {
 +-		if((sl + 2) > BUF_SZ) {
 +-			die("standardise() -- Buffer overflow");
 +-		}
 +-		(void)memmove((str + 1), str, (sl + 1));	/* Copy trailing \0 */
 ++	if(*linestart && *str == '.') {
 ++		leadingdot = True;
  +	}
 -+
 -+	if ((file != NULL) && (fp = fopen(file, "r")) ) {
 -+		while(fgets(buf, sizeof(buf), fp)) {
 -+				/* Make comments invisible */
 -+				if((p = strchr(buf, '#'))) {
 -+					*p = '\0';
 -+				}
 - 
 -+			/* Ignore malformed lines and comments */
 -+				if(strchr(buf, '@') == NULL) {
 -+					continue;
 -+				}
 -+				if((p = strtok(buf, "\n"))) {
 -+                                        if((uad = strdup(p)) == NULL) {
 -+                                                die("revaliases() -- strdup() failed");
 -+                                        }
 -+				}
 -+			}
 -+		fclose(fp);
 - 	/* Try to open the reverse aliases file */
 --	if((fp = fopen(REVALIASES_FILE, "r"))) {
 -+	} else if ((fp = fopen(REVALIASES_FILE, "r"))) {
 -+#else
 -+	if ((fp = fopen(REVALIASES_FILE, "r"))) {
 -+#endif
 - 		/* Search if a reverse alias is defined for the sender */
 ++	*linestart = False;
 + 
 +-		*str = '.';
 ++	if((p = strchr(str, '\n'))) {
 ++		*p = '\0';
 ++		*linestart = True;
 + 	}
 ++	return(leadingdot);
 + }
 + 
 + /*
 +@@ -386,7 +403,7 @@
   		while(fgets(buf, sizeof(buf), fp)) {
   			/* Make comments invisible */
   			if((p = strchr(buf, '#'))) {
 @@ -159,36 +161,19 @@
   			}
   
   			/* Ignore malformed lines and comments */
 --			if(strchr(buf, ':') == (char *)NULL) {
 -+			if(strchr(buf, ':') == NULL) {
 - 				continue;
 +@@ -485,6 +502,11 @@
 + 				die("from_format() -- snprintf() failed");
   			}
 - 
 - 			/* Parse the alias */
 - 			if(((p = strtok(buf, ":"))) && !strcmp(p, pw->pw_name)) {
 - 				if((p = strtok(NULL, ": \t\r\n"))) {
 --					if((uad = strdup(p)) == (char *)NULL) {
 -+					if((uad = strdup(p)) == NULL) {
 - 						die("revaliases() -- strdup() failed");
 - 					}
 - 				}
 - 
 - 				if((p = strtok(NULL, " \t\r\n:"))) {
 --					if((mailhost = strdup(p)) == (char *)NULL) {
 -+					if((mailhost = strdup(p)) == NULL) {
 - 						die("revaliases() -- strdup() failed");
 - 					}
 - 
 -@@ -435,7 +463,7 @@
 + 		}
 ++		else {
 ++			if(snprintf(buf, BUF_SZ, "%s", str) == -1) {
 ++				die("from_format() -- snprintf() failed");
 ++			}
 ++		}
   	}
   
 - 	/* Remove the real name if necessary - just send the address */
 --	if((p = addr_parse(str)) == (char *)NULL) {
 -+	if((p = addr_parse(str)) == NULL) {
 - 		die("from_strip() -- addr_parse() failed");
 - 	}
   #if 0
 -@@ -511,11 +539,11 @@
 +@@ -516,11 +538,11 @@
   #endif
   
   	/* Ignore missing usernames */
 @@ -202,7 +187,7 @@
   		die("rcpt_save() -- strdup() failed");
   	}
   
 -@@ -540,7 +568,7 @@
 +@@ -545,7 +567,7 @@
   	(void)fprintf(stderr, "*** rcpt_parse(): str = [%s]\n", str);
   #endif
   
 @@ -211,7 +196,7 @@
   		die("rcpt_parse(): strdup() failed");
   	}
   	q = p;
 -@@ -568,7 +596,7 @@
 +@@ -573,7 +595,7 @@
   		}
   
   		/* End of string? */
 @@ -220,7 +205,7 @@
   			got_addr = True;
   		}
   
 -@@ -576,7 +604,7 @@
 +@@ -581,7 +603,7 @@
   		if((*q == ',') && (in_quotes == False)) {
   			got_addr = True;
   
 @@ -229,43 +214,7 @@
   		}
   
   		if(got_addr) {
 -@@ -599,19 +627,21 @@
 - {
 - 	int i;
 - 	unsigned char digest[MD5_DIGEST_LEN];
 --	unsigned char digascii[MD5_DIGEST_LEN * 2];
 -+	char digascii[MD5_DIGEST_LEN * 2];
 - 	unsigned char challenge[(BUF_SZ + 1)];
 --	unsigned char response[(BUF_SZ + 1)];
 --	unsigned char secret[(MD5_BLOCK_LEN + 1)]; 
 -+	char response[(BUF_SZ + 1)];
 -+	char secret[(MD5_BLOCK_LEN + 1)]; 
 -+	int challenge_len;
 - 
 - 	memset (secret,0,sizeof(secret));
 - 	memset (challenge,0,sizeof(challenge));
 - 	strncpy (secret, password, sizeof(secret));	
 - 	if (!challengeb64 || strlen(challengeb64) > sizeof(challenge) * 3 / 4)
 - 		return 0;
 --	from64tobits(challenge, challengeb64);
 -+	challenge_len = from64tobits(challenge, challengeb64);
 - 
 --	hmac_md5(challenge, strlen(challenge), secret, strlen(secret), digest);
 -+	hmac_md5(challenge, challenge_len, 
 -+		 (unsigned char *)secret, strlen(secret), digest);
 - 
 - 	for (i = 0; i < MD5_DIGEST_LEN; i++) {
 - 		digascii[2 * i] = hextab[digest[i] >> 4];
 -@@ -625,7 +655,7 @@
 - 	strncpy (response, username, sizeof(response) - sizeof(digascii) - 2);
 - 	strcat (response, " ");
 - 	strcat (response, digascii);
 --	to64frombits(responseb64, response, strlen(response));
 -+	to64frombits(responseb64, (unsigned char *)response, strlen(response));
 - 
 - 	return 1;
 - }
 -@@ -660,7 +690,7 @@
 +@@ -665,7 +687,7 @@
   	(void)fprintf(stderr, "header_save(): str = [%s]\n", str);
   #endif
   
 @@ -274,7 +223,7 @@
   		die("header_save() -- strdup() failed");
   	}
   	ht->string = p;
 -@@ -668,7 +698,7 @@
 +@@ -673,7 +695,7 @@
   	if(strncasecmp(ht->string, "From:", 5) == 0) {
   #if 1
   		/* Hack check for NULL From: line */
 @@ -283,12 +232,12 @@
   			return;
   		}
   #endif
 -@@ -727,19 +757,19 @@
 +@@ -736,19 +758,19 @@
   void header_parse(FILE *stream)
   {
   	size_t size = BUF_SZ, len = 0;
  -	char *p = (char *)NULL, *q;
 -+	char *p = NULL, *q = NULL;
 ++	char *p = NULL, *q;
   	bool_t in_header = True;
  -	char l = (char)NULL;
  +	char l = '\0';
 @@ -307,7 +256,7 @@
   				die("header_parse() -- realloc() failed");
   			}
   			q = (p + len);
 -@@ -764,9 +794,9 @@
 +@@ -773,9 +795,9 @@
   						in_header = False;
   
   				default:
 @@ -319,8 +268,20 @@
   						}
   						header_save(p);
   
 -@@ -796,17 +826,17 @@
 - 	while(fgets(buf, sizeof(buf), fp)) {
 +@@ -806,9 +828,9 @@
 + 						in_header = False;
 + 
 + 				default:
 +-						*q = (char)NULL;
 ++						*q = '\0';
 + 						if((q = strrchr(p, '\n'))) {
 +-							*q = (char)NULL;
 ++							*q = '\0';
 + 						}
 + 						header_save(p);
 + 
 +@@ -873,11 +895,11 @@
 + 		char *rightside;
   		/* Make comments invisible */
   		if((p = strchr(buf, '#'))) {
  -			*p = (char)NULL;
 @@ -332,17 +293,17 @@
  +		if(strchr(buf, '=') == NULL) continue;
   
   		/* Parse out keywords */
 --		if(((p = strtok(buf, "= \t\n")) != (char *)NULL)
 --			&& ((q = strtok(NULL, "= \t\n:")) != (char *)NULL)) {
 -+		if(((p = strtok(buf, "= \t\n")) != NULL)
 -+			&& ((q = strtok(NULL, "= \t\n:")) != NULL)) {
 + 		p=firsttok(&begin, "= \t\n");
 +@@ -887,7 +909,7 @@
 + 		}
 + 		if(p && q) {
   			if(strcasecmp(p, "Root") == 0) {
  -				if((root = strdup(q)) == (char *)NULL) {
  +				if((root = strdup(q)) == NULL) {
   					die("parse_config() -- strdup() failed");
   				}
   
 -@@ -815,7 +845,7 @@
 +@@ -896,7 +918,7 @@
   				}
   			}
   			else if(strcasecmp(p, "MailHub") == 0) {
 @@ -351,7 +312,7 @@
   					die("parse_config() -- strdup() failed");
   				}
   
 -@@ -851,7 +881,7 @@
 +@@ -946,7 +968,7 @@
   					mail_domain = strdup(q);
   				}
   
 @@ -360,7 +321,7 @@
   					die("parse_config() -- strdup() failed");
   				}
   				rewrite_domain = True;
 -@@ -927,7 +957,7 @@
 +@@ -1022,7 +1044,7 @@
   				}
   			}
   			else if(strcasecmp(p, "TLSCert") == 0) {
 @@ -369,7 +330,7 @@
   					die("parse_config() -- strdup() failed");
   				}
   
 -@@ -938,7 +968,7 @@
 +@@ -1033,7 +1055,7 @@
   #endif
   			/* Command-line overrides these */
   			else if(strcasecmp(p, "AuthUser") == 0 && !auth_user) {
 @@ -378,7 +339,7 @@
   					die("parse_config() -- strdup() failed");
   				}
   
 -@@ -947,7 +977,7 @@
 +@@ -1042,7 +1064,7 @@
   				}
   			}
   			else if(strcasecmp(p, "AuthPass") == 0 && !auth_pass) {
 @@ -387,7 +348,7 @@
   					die("parse_config() -- strdup() failed");
   				}
   
 -@@ -956,7 +986,7 @@
 +@@ -1051,7 +1073,7 @@
   				}
   			}
   			else if(strcasecmp(p, "AuthMethod") == 0 && !auth_method) {
 @@ -396,7 +357,7 @@
   					die("parse_config() -- strdup() failed");
   				}
   
 -@@ -982,11 +1012,11 @@
 +@@ -1104,11 +1126,11 @@
   #ifdef INET6
   	struct addrinfo hints, *ai0, *ai;
   	char servname[NI_MAXSERV];
 @@ -410,16 +371,7 @@
   #endif
   
   #ifdef HAVE_SSL
 -@@ -996,7 +1026,7 @@
 - 	/* Init SSL stuff */
 - 	SSL_CTX *ctx;
 - 	SSL_METHOD *meth;
 --	X509 *server_cert;
 -+	const X509 *server_cert;
 - 
 - 	SSL_load_error_strings();
 - 	SSLeay_add_ssl_algorithms();
 -@@ -1179,7 +1209,7 @@
 +@@ -1301,7 +1323,7 @@
   			buf[i++] = c;
   		}
   	}
 @@ -428,7 +380,43 @@
   
   	return(buf);
   }
 -@@ -1293,14 +1323,14 @@
 +@@ -1356,12 +1378,12 @@
 + */
 + ssize_t smtp_write(int fd, char *format, ...)
 + {
 +-	char buf[(BUF_SZ + 1)];
 ++	char buf[(BUF_SZ + 2)];
 + 	va_list ap;
 + 	ssize_t outbytes = 0;
 + 
 + 	va_start(ap, format);
 +-	if(vsnprintf(buf, (BUF_SZ - 2), format, ap) == -1) {
 ++	if(vsnprintf(buf, (BUF_SZ - 1), format, ap) == -1) {
 + 		die("smtp_write() -- vsnprintf() failed");
 + 	}
 + 	va_end(ap);
 +@@ -1399,16 +1421,18 @@
 + */
 + int ssmtp(char *argv[])
 + {
 +-	char buf[(BUF_SZ + 1)], *p, *q;
 ++	char b[(BUF_SZ + 2)], *buf = b+1, *p, *q;
 + #ifdef MD5AUTH
 + 	char challenge[(BUF_SZ + 1)];
 + #endif
 + 	struct passwd *pw;
 + 	int i, sock;
 + 	uid_t uid;
 +-	bool_t minus_v_save;
 ++	bool_t minus_v_save, leadingdot, linestart = True;
 + 	int timeout = 0;
 ++	int bufsize = sizeof(b)-1;
 + 
 ++	b[0] = '.';
 + 	outbytes = 0;
 + 	ht = &headers;
 + 
 +@@ -1423,14 +1447,14 @@
   	}
   
   	if((p = strtok(pw->pw_gecos, ";,"))) {
 @@ -445,7 +433,7 @@
   		uad = append_domain(pw->pw_name);
   	}
   
 -@@ -1349,7 +1379,7 @@
 +@@ -1478,7 +1502,7 @@
   	/* Try to log in if username was supplied */
   	if(auth_user) {
   #ifdef MD5AUTH
 @@ -454,16 +442,93 @@
   			auth_pass = strdup("");
   		}
   
 -@@ -1377,7 +1407,7 @@
 +@@ -1491,12 +1515,12 @@
 + 			}
 + 			strncpy(challenge, strchr(buf,' ') + 1, sizeof(challenge));
 + 
 +-			memset(buf, 0, sizeof(buf));
 ++			memset(buf, 0, bufsize);
 + 			crammd5(challenge, auth_user, auth_pass, buf);
   		}
 - 		memset(buf, 0, sizeof(buf));
 + 		else {
 + #endif
 +-		memset(buf, 0, sizeof(buf));
 ++		memset(buf, 0, bufsize);
 + 		to64frombits(buf, auth_user, strlen(auth_user));
 + 		if (use_oldauth) {
 + 			outbytes += smtp_write(sock, "AUTH LOGIN %s", buf);
 +@@ -1508,7 +1532,7 @@
 + 				die("Server didn't like our AUTH LOGIN (%s)", buf);
 + 			}
 + 			/* we assume server asked us for Username */
 +-			memset(buf, 0, sizeof(buf));
 ++			memset(buf, 0, bufsize);
 + 			to64frombits(buf, auth_user, strlen(auth_user));
 + 			outbytes += smtp_write(sock, buf);
 + 		}
 +@@ -1517,7 +1541,7 @@
 + 		if(smtp_read(sock, buf) != 3) {
 + 			die("Server didn't accept AUTH LOGIN (%s)", buf);
 + 		}
 +-		memset(buf, 0, sizeof(buf));
 ++		memset(buf, 0, bufsize);
   
 --		to64frombits(buf, auth_pass, strlen(auth_pass));
 -+		to64frombits(buf, (unsigned char *)auth_pass, strlen(auth_pass));
 + 		to64frombits(buf, auth_pass, strlen(auth_pass));
   #ifdef MD5AUTH
 +@@ -1626,28 +1650,40 @@
 + 	  stdio functions like fgets in the first place */
 + 	fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
 + 
 +-	/* don't hang forever when reading from stdin */
 +-	while(!feof(stdin) && timeout < MEDWAIT) {
 +-		if (!fgets(buf, sizeof(buf), stdin)) {
 ++	while(!feof(stdin)) {
 ++		if (!fgets(buf, bufsize, stdin)) {
 + 			/* if nothing was received, then no transmission
 + 			 * over smtp should be done */
 + 			sleep(1);
 +-			timeout++;
 ++			/* don't hang forever when reading from stdin */
 ++			if (++timeout >= MEDWAIT) {
 ++				log_event(LOG_ERR, "killed: timeout on stdin while reading body -- message saved to dead.letter.");
 ++				die("Timeout on stdin while reading body");
 ++			}
 + 			continue;
   		}
 - #endif
 -@@ -1549,7 +1579,7 @@
 + 		/* Trim off \n, double leading .'s */
 +-		standardise(buf);
 +-
 +-		outbytes += smtp_write(sock, "%s", buf);
 ++		leadingdot = standardise(buf, &linestart);
 + 
 ++		if (linestart || feof(stdin)) {
 ++			linestart = True;
 ++			outbytes += smtp_write(sock, "%s", leadingdot ? b : buf);
 ++		} else {
 ++			if (log_level > 0) {
 ++				log_event(LOG_INFO, "Sent a very long line in chunks");
 ++			}
 ++			if (leadingdot) {
 ++				outbytes += fd_puts(sock, b, sizeof(b));
 ++			} else {
 ++				outbytes += fd_puts(sock, buf, bufsize);
 ++			}
 ++		}
 + 		(void)alarm((unsigned) MEDWAIT);
 + 	}
 +-	/* End of body */
 +-
 +-	if (timeout >= MEDWAIT) {
 +-		log_event(LOG_ERR, "killed: timeout on stdin while reading body -- message saved to dead.letter.");
 +-		die("Timeout on stdin while reading body");
 ++	if(!linestart) {
 ++		smtp_write(sock, "");
 + 	}
 ++	/* End of body */
 + 
 + 	outbytes += smtp_write(sock, ".");
 + 	(void)alarm((unsigned) MAXWAIT);
 +@@ -1714,7 +1750,7 @@
   		j = 0;
   
   		add = 1;
 @@ -472,7 +537,7 @@
   			switch(argv[i][j]) {
   #ifdef INET6
   			case '6':
 -@@ -1567,14 +1597,14 @@
 +@@ -1732,14 +1768,14 @@
   					if((!argv[i][(j + 1)])
   						&& argv[(i + 1)]) {
   						auth_user = strdup(argv[i+1]);
 @@ -489,7 +554,7 @@
   							die("parse_options() -- strdup() failed");
   						}
   					}
 -@@ -1584,14 +1614,14 @@
 +@@ -1749,14 +1785,14 @@
   					if((!argv[i][(j + 1)])
   						&& argv[(i + 1)]) {
   						auth_pass = strdup(argv[i+1]);
 @@ -506,7 +571,7 @@
   							die("parse_options() -- strdup() failed");
   						}
   					}
 -@@ -1669,14 +1699,14 @@
 +@@ -1847,14 +1883,14 @@
   			case 'F':
   				if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
   					minus_F = strdup(argv[(i + 1)]);
 @@ -523,7 +588,7 @@
   						die("parse_options() -- strdup() failed");
   					}
   				}
 -@@ -1688,14 +1718,14 @@
 +@@ -1866,14 +1902,14 @@
   			case 'r':
   				if((!argv[i][(j + 1)]) && argv[(i + 1)]) {
   					minus_f = strdup(argv[(i + 1)]);
 diff -uNr ssmtp.orig/files/patch-ssmtp.h ssmtp/files/patch-ssmtp.h
 --- ssmtp.orig/files/patch-ssmtp.h	2008-11-19 23:23:49.000000000 +0200
 +++ ssmtp/files/patch-ssmtp.h	1970-01-01 02:00:00.000000000 +0200
 @@ -1,10 +0,0 @@
 ---- ./ssmtp.h.orig	2002-09-27 09:18:24.000000000 -0400
 -+++ ./ssmtp.h	2008-11-17 18:55:03.000000000 -0500
 -@@ -37,5 +37,5 @@
 - void get_arpadate(char *);
 - 
 - /* base64.c */
 --void to64frombits(unsigned char *, const unsigned char *, int);
 --int from64tobits(char *, const char *);
 -+void to64frombits(char *, const unsigned char *, int);
 -+int from64tobits(unsigned char *, const char *);
 
 --------------000808000802060807060100--
State-Changed-From-To: open->closed 
State-Changed-By: glarkin 
State-Changed-When: Fri Dec 4 22:24:42 EST 2009 
State-Changed-Why:  
Committed with minor tweaks to keep portlint happy, thank you! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=140175 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: ports/140175: commit references a PR
Date: Sat,  5 Dec 2009 03:20:09 +0000 (UTC)

 glarkin     2009-12-05 03:20:00 UTC
 
   FreeBSD ports repository
 
   Modified files:
     mail/ssmtp           Makefile distinfo 
     mail/ssmtp/files     patch-configure patch-ssmtp.c 
   Added files:
     mail/ssmtp/files     patch-md5auth-hmac_md5.c 
   Removed files:
     mail/ssmtp/files     patch-arpadate.c patch-base64.c 
                          patch-ssmtp.h 
   Log:
   - Updated to 2.62.3
   - Link against system MD5 libs instead of included modules to fix
     CRAM-MD5 authentication
   
   PR:             ports/140175
   Submitted by:   Aragon Gouveia <aragon@phat.za.net>
   
   Revision  Changes    Path
   1.29      +3 -7      ports/mail/ssmtp/Makefile
   1.11      +3 -6      ports/mail/ssmtp/distinfo
   1.2       +0 -11     ports/mail/ssmtp/files/patch-arpadate.c (dead)
   1.2       +0 -20     ports/mail/ssmtp/files/patch-base64.c (dead)
   1.3       +13 -0     ports/mail/ssmtp/files/patch-configure
   1.1       +12 -0     ports/mail/ssmtp/files/patch-md5auth-hmac_md5.c (new)
   1.5       +252 -187  ports/mail/ssmtp/files/patch-ssmtp.c
   1.2       +0 -10     ports/mail/ssmtp/files/patch-ssmtp.h (dead)
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: ports/140175: commit references a PR
Date: Sat,  5 Dec 2009 03:22:21 +0000 (UTC)

 glarkin     2009-12-05 03:22:07 UTC
 
   FreeBSD doc repository (ports committer)
 
   Modified files:
     en_US.ISO8859-1/articles/contributors contrib.additional.sgml 
   Log:
   - Added new contributor: Aragon Gouveia <aragon@phat.za.net>
   
   PR:             ports/140175
   
   Revision  Changes    Path
   1.883     +5 -0      doc/en_US.ISO8859-1/articles/contributors/contrib.additional.sgml
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
>Unformatted:
