From d0fccfcda73f8b52d101bd2b0f7885a766f7e354 Mon Sep 17 00:00:00 2001 From: Gary Mills Date: Wed, 28 Dec 2011 10:05:46 -0600 Subject: [PATCH] 1786 Sendmail should be built with SASL methods Reviewed by: Albert Lee Reviewed by: Dan McDonald Approved by: Richard Lowe --- usr/src/cmd/sendmail/src/Makefile | 10 +- usr/src/cmd/sendmail/src/sasl.c | 287 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+), 4 deletions(-) create mode 100644 usr/src/cmd/sendmail/src/sasl.c 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_RCSID("@(#)$Id: sasl.c,v 8.22 2006/08/15 23:24:57 ca Exp $") + +#if SASL +# include +# include +# include + +/* +** 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 + +# 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 */ -- 2.11.4.GIT