changeset 13555:69e1739e786e

1786 Sendmail should be built with SASL methods Reviewed by: Albert Lee <trisk@nexenta.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
author Gary Mills <mills@cc.umanitoba.ca>
date Wed, 28 Dec 2011 10:05:46 -0600
parents fae070bfb73a
children 6d80fb09c7b8
files usr/src/cmd/sendmail/src/Makefile usr/src/cmd/sendmail/src/sasl.c
diffstat 2 files changed, 293 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sendmail/src/Makefile	Thu Dec 29 03:08:34 2011 +0200
+++ b/usr/src/cmd/sendmail/src/Makefile	Wed Dec 28 10:05:46 2011 -0600
@@ -19,6 +19,8 @@
 # CDDL HEADER END
 #
 
+# Copyright (c) 2011 Gary Mills
+
 #
 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
@@ -34,8 +36,8 @@
 OBJS= alias.o arpadate.o bf.o collect.o conf.o control.o convtime.o daemon.o \
 	deliver.o domain.o envelope.o err.o headers.o macro.o main.o map.o \
 	mci.o milter.o mime.o parseaddr.o queue.o ratectrl.o readcf.o \
-	recipient.o savemail.o sfsasl.o sm_resolve.o srvrsmtp.o stab.o stats.o \
-	sysexits.o tls.o trace.o udb.o usersmtp.o util.o version.o
+	recipient.o sasl.o savemail.o sfsasl.o sm_resolve.o srvrsmtp.o stab.o \
+	stats.o sysexits.o tls.o trace.o udb.o usersmtp.o util.o version.o
 
 SRCS=	$(OBJS:%.o=%.c)
 
@@ -43,7 +45,7 @@
 LDFLAGS +=	$(MAPFILES:%=-M%)
 
 # EXPORT DELETE START
-CRYPTOLIBS=	-lssl -lcrypto
+CRYPTOLIBS=	-lssl -lcrypto -lsasl
 # EXPORT DELETE END
 LDLIBS += 	../libsmutil/libsmutil.a ../libsm/libsm.a -lresolv -lsocket \
 		-lnsl ../db/libdb.a -lldap -lsldap -lwrap -lumem \
@@ -52,7 +54,7 @@
 INCPATH=	-I. -I../include -I../db
 
 # EXPORT DELETE START
-CRYPTOENVDEF=	-DSTARTTLS
+CRYPTOENVDEF=	-DSTARTTLS -DSASL=20115
 # EXPORT DELETE END
 ENVDEF=		-DNETINET6 -DTCPWRAPPERS $(CRYPTOENVDEF)
 SUNENVDEF=	-DSUN_EXTENSIONS -DVENDOR_DEFAULT=VENDOR_SUN \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/sendmail/src/sasl.c	Wed Dec 28 10:05:46 2011 -0600
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers.
+ *	All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ */
+
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: sasl.c,v 8.22 2006/08/15 23:24:57 ca Exp $")
+
+#if SASL
+# include <stdlib.h>
+# include <sendmail.h>
+# include <errno.h>
+
+/*
+**  In order to ensure that storage leaks are tracked, and to prevent
+**  conflicts between the sm_heap package and sasl, we tell sasl to
+**  use the following heap allocation functions.  Unfortunately,
+**  the sasl package incorrectly specifies the size of a block
+**  using unsigned long: for portability, it should be size_t.
+*/
+
+void *sm_sasl_malloc __P((unsigned long));
+static void *sm_sasl_calloc __P((unsigned long, unsigned long));
+static void *sm_sasl_realloc __P((void *, unsigned long));
+void sm_sasl_free __P((void *));
+
+/*
+**  SASLv1:
+**  We can't use an rpool for Cyrus-SASL memory management routines,
+**	since the encryption/decryption routines in Cyrus-SASL
+**	allocate/deallocate a buffer each time. Since rpool
+**	don't release memory until the very end, memory consumption is
+**	proportional to the size of an e-mail, which is unacceptable.
+*/
+
+/*
+**  SM_SASL_MALLOC -- malloc() for SASL
+**
+**	Parameters:
+**		size -- size of requested memory.
+**
+**	Returns:
+**		pointer to memory.
+*/
+
+void *
+sm_sasl_malloc(size)
+	unsigned long size;
+{
+	return sm_malloc((size_t) size);
+}
+
+/*
+**  SM_SASL_CALLOC -- calloc() for SASL
+**
+**	Parameters:
+**		nelem -- number of elements.
+**		elemsize -- size of each element.
+**
+**	Returns:
+**		pointer to memory.
+**
+**	Notice:
+**		this isn't currently used by SASL.
+*/
+
+static void *
+sm_sasl_calloc(nelem, elemsize)
+	unsigned long nelem;
+	unsigned long elemsize;
+{
+	size_t size;
+	void *p;
+
+	size = (size_t) nelem * (size_t) elemsize;
+	p = sm_malloc(size);
+	if (p == NULL)
+		return NULL;
+	memset(p, '\0', size);
+	return p;
+}
+
+/*
+**  SM_SASL_REALLOC -- realloc() for SASL
+**
+**	Parameters:
+**		p -- pointer to old memory.
+**		size -- size of requested memory.
+**
+**	Returns:
+**		pointer to new memory.
+*/
+
+static void *
+sm_sasl_realloc(o, size)
+	void *o;
+	unsigned long size;
+{
+	return sm_realloc(o, (size_t) size);
+}
+
+/*
+**  SM_SASL_FREE -- free() for SASL
+**
+**	Parameters:
+**		p -- pointer to free.
+**
+**	Returns:
+**		none
+*/
+
+void
+sm_sasl_free(p)
+	void *p;
+{
+	sm_free(p);
+}
+
+/*
+**  SM_SASL_INIT -- sendmail specific SASL initialization
+**
+**	Parameters:
+**		none.
+**
+**	Returns:
+**		none
+**
+**	Side Effects:
+**		installs memory management routines for SASL.
+*/
+
+void
+sm_sasl_init()
+{
+	sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc,
+		       sm_sasl_realloc, sm_sasl_free);
+}
+/*
+**  INTERSECT -- create the intersection between two lists
+**
+**	Parameters:
+**		s1, s2 -- lists of items (separated by single blanks).
+**		rpool -- resource pool from which result is allocated.
+**
+**	Returns:
+**		the intersection of both lists.
+*/
+
+char *
+intersect(s1, s2, rpool)
+	char *s1, *s2;
+	SM_RPOOL_T *rpool;
+{
+	char *hr, *h1, *h, *res;
+	int l1, l2, rl;
+
+	if (s1 == NULL || s2 == NULL)	/* NULL string(s) -> NULL result */
+		return NULL;
+	l1 = strlen(s1);
+	l2 = strlen(s2);
+	rl = SM_MIN(l1, l2);
+	res = (char *) sm_rpool_malloc(rpool, rl + 1);
+	if (res == NULL)
+		return NULL;
+	*res = '\0';
+	if (rl == 0)	/* at least one string empty? */
+		return res;
+	hr = res;
+	h1 = s1;
+	h = s1;
+
+	/* walk through s1 */
+	while (h != NULL && *h1 != '\0')
+	{
+		/* is there something after the current word? */
+		if ((h = strchr(h1, ' ')) != NULL)
+			*h = '\0';
+		l1 = strlen(h1);
+
+		/* does the current word appear in s2 ? */
+		if (iteminlist(h1, s2, " ") != NULL)
+		{
+			/* add a blank if not first item */
+			if (hr != res)
+				*hr++ = ' ';
+
+			/* copy the item */
+			memcpy(hr, h1, l1);
+
+			/* advance pointer in result list */
+			hr += l1;
+			*hr = '\0';
+		}
+		if (h != NULL)
+		{
+			/* there are more items */
+			*h = ' ';
+			h1 = h + 1;
+		}
+	}
+	return res;
+}
+# if SASL >= 20000
+/*
+**  IPTOSTRING -- create string for SASL_IP*PORT property
+**		(borrowed from lib/iptostring.c in Cyrus-IMAP)
+**
+**	Parameters:
+**		addr -- (pointer to) socket address
+**		addrlen -- length of socket address
+**		out -- output string (result)
+**		outlen -- maximum length of output string
+**
+**	Returns:
+**		true iff successful.
+**
+**	Side Effects:
+**		creates output string if successful.
+**		sets errno if unsuccessful.
+*/
+
+#  include <arpa/inet.h>
+
+#  ifndef NI_MAXHOST
+#   define NI_MAXHOST	1025
+#  endif
+#  ifndef NI_MAXSERV
+#   define NI_MAXSERV	32
+#  endif
+
+bool
+iptostring(addr, addrlen, out, outlen)
+	SOCKADDR *addr;
+	SOCKADDR_LEN_T addrlen;
+	char *out;
+	unsigned outlen;
+{
+	char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+#  if NETINET6
+	int niflags;
+#  endif /* NETINET6 */
+
+	if (addr == NULL || out == NULL)
+	{
+		errno = EINVAL;
+		return false;
+	}
+
+#  if NETINET6
+	niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#   ifdef NI_WITHSCOPEID
+	if (addr->sa.sa_family == AF_INET6)
+		niflags |= NI_WITHSCOPEID;
+#   endif /* NI_WITHSCOPEID */
+	if (getnameinfo((struct sockaddr *) addr, addrlen,
+			hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags) != 0)
+		return false;
+#  else /* NETINET6 */
+	if (addr->sa.sa_family != AF_INET)
+	{
+		errno = EINVAL;
+		return false;
+	}
+	if (sm_strlcpy(hbuf, inet_ntoa(addr->sin.sin_addr), sizeof(hbuf))
+	    >= sizeof(hbuf))
+	{
+		errno = ENOMEM;
+		return false;
+	}
+	sm_snprintf(pbuf, sizeof(pbuf), "%d", ntohs(addr->sin.sin_port));
+#  endif /* NETINET6 */
+
+	if (outlen < strlen(hbuf) + strlen(pbuf) + 2)
+	{
+		errno = ENOMEM;
+		return false;
+	}
+	sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf);
+	return true;
+}
+# endif /* SASL >= 20000 */
+#endif /* SASL */