summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Mills <mills@cc.umanitoba.ca>2011-12-28 10:05:46 -0600
committerGary Mills <mills@cc.umanitoba.ca>2011-12-28 10:05:46 -0600
commitd0fccfcda73f8b52d101bd2b0f7885a766f7e354 (patch)
tree7a2875c1a57869060cf7eff56eb256eb51461cc7
parenteb8977cfee9bc778b53a12021468aae042e63374 (diff)
downloadillumos-joyent-d0fccfcda73f8b52d101bd2b0f7885a766f7e354.tar.gz
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>
-rw-r--r--usr/src/cmd/sendmail/src/Makefile10
-rw-r--r--usr/src/cmd/sendmail/src/sasl.c287
2 files changed, 293 insertions, 4 deletions
diff --git a/usr/src/cmd/sendmail/src/Makefile b/usr/src/cmd/sendmail/src/Makefile
index 31513f702f..e171e139d3 100644
--- a/usr/src/cmd/sendmail/src/Makefile
+++ b/usr/src/cmd/sendmail/src/Makefile
@@ -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 @@ include ../Makefile.cmd
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 @@ MAPFILES = $(MAPFILE.INT) $(MAPFILE.NGB)
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 @@ LDLIBS += ../libsmutil/libsmutil.a ../libsm/libsm.a -lresolv -lsocket \
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 \
diff --git a/usr/src/cmd/sendmail/src/sasl.c b/usr/src/cmd/sendmail/src/sasl.c
new file mode 100644
index 0000000000..6f9e4a50df
--- /dev/null
+++ b/usr/src/cmd/sendmail/src/sasl.c
@@ -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 */