2 * Copyright (c) 2001-2002 Proofpoint, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
12 SM_RCSID("@(#)$Id: sasl.c,v 8.24 2013-11-22 20:51:56 ca Exp $")
16 # include <sendmail.h>
20 ** In order to ensure that storage leaks are tracked, and to prevent
21 ** conflicts between the sm_heap package and sasl, we tell sasl to
22 ** use the following heap allocation functions. Unfortunately,
23 ** older sasl packages incorrectly specifies the size of a block
24 ** using unsigned long: for portability, it should be size_t.
27 # if defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a
28 # define SM_SASL_SIZE_T size_t
29 # else /* defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a */
30 # define SM_SASL_SIZE_T unsigned long
31 # endif /* defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a */
33 void *sm_sasl_malloc __P((SM_SASL_SIZE_T));
34 static void *sm_sasl_calloc __P((SM_SASL_SIZE_T, SM_SASL_SIZE_T));
35 static void *sm_sasl_realloc __P((void *, SM_SASL_SIZE_T));
36 void sm_sasl_free __P((void *));
40 ** We can't use an rpool for Cyrus-SASL memory management routines,
41 ** since the encryption/decryption routines in Cyrus-SASL
42 ** allocate/deallocate a buffer each time. Since rpool
43 ** don't release memory until the very end, memory consumption is
44 ** proportional to the size of an e-mail, which is unacceptable.
48 ** SM_SASL_MALLOC -- malloc() for SASL
51 ** size -- size of requested memory.
61 return sm_malloc((size_t) size);
65 ** SM_SASL_CALLOC -- calloc() for SASL
68 ** nelem -- number of elements.
69 ** elemsize -- size of each element.
75 ** this isn't currently used by SASL.
79 sm_sasl_calloc(nelem, elemsize)
81 SM_SASL_SIZE_T elemsize;
86 size = (size_t) nelem * (size_t) elemsize;
90 memset(p, '\0', size);
95 ** SM_SASL_REALLOC -- realloc() for SASL
98 ** p -- pointer to old memory.
99 ** size -- size of requested memory.
102 ** pointer to new memory.
106 sm_sasl_realloc(o, size)
110 return sm_realloc(o, (size_t) size);
114 ** SM_SASL_FREE -- free() for SASL
117 ** p -- pointer to free.
131 ** SM_SASL_INIT -- sendmail specific SASL initialization
140 ** installs memory management routines for SASL.
146 sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc,
147 sm_sasl_realloc, sm_sasl_free);
150 ** INTERSECT -- create the intersection between two lists
153 ** s1, s2 -- lists of items (separated by single blanks).
154 ** rpool -- resource pool from which result is allocated.
157 ** the intersection of both lists.
161 intersect(s1, s2, rpool)
165 char *hr, *h1, *h, *res;
168 if (s1 == NULL || s2 == NULL) /* NULL string(s) -> NULL result */
173 res = (char *) sm_rpool_malloc(rpool, rl + 1);
177 if (rl == 0) /* at least one string empty? */
183 /* walk through s1 */
184 while (h != NULL && *h1 != '\0')
186 /* is there something after the current word? */
187 if ((h = strchr(h1, ' ')) != NULL)
191 /* does the current word appear in s2 ? */
192 if (iteminlist(h1, s2, " ") != NULL)
194 /* add a blank if not first item */
201 /* advance pointer in result list */
207 /* there are more items */
216 ** IPTOSTRING -- create string for SASL_IP*PORT property
217 ** (borrowed from lib/iptostring.c in Cyrus-IMAP)
220 ** addr -- (pointer to) socket address
221 ** addrlen -- length of socket address
222 ** out -- output string (result)
223 ** outlen -- maximum length of output string
226 ** true iff successful.
229 ** creates output string if successful.
230 ** sets errno if unsuccessful.
233 # include <arpa/inet.h>
236 # define NI_MAXHOST 1025
239 # define NI_MAXSERV 32
243 iptostring(addr, addrlen, out, outlen)
245 SOCKADDR_LEN_T addrlen;
249 char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
252 # endif /* NETINET6 */
254 if (addr == NULL || out == NULL)
261 niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
262 # ifdef NI_WITHSCOPEID
263 if (addr->sa.sa_family == AF_INET6)
264 niflags |= NI_WITHSCOPEID;
265 # endif /* NI_WITHSCOPEID */
266 if (getnameinfo((struct sockaddr *) addr, addrlen,
267 hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags) != 0)
269 # else /* NETINET6 */
270 if (addr->sa.sa_family != AF_INET)
275 if (sm_strlcpy(hbuf, inet_ntoa(addr->sin.sin_addr), sizeof(hbuf))
281 sm_snprintf(pbuf, sizeof(pbuf), "%d", ntohs(addr->sin.sin_port));
282 # endif /* NETINET6 */
284 if (outlen < strlen(hbuf) + strlen(pbuf) + 2)
289 sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf);
292 # endif /* SASL >= 20000 */