140266059SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro * Copyright (c) 2001-2002 Proofpoint, Inc. and its suppliers.
340266059SGregory Neil Shapiro * All rights reserved.
440266059SGregory Neil Shapiro *
540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set
640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of
740266059SGregory Neil Shapiro * the sendmail distribution.
840266059SGregory Neil Shapiro *
940266059SGregory Neil Shapiro */
1040266059SGregory Neil Shapiro
1140266059SGregory Neil Shapiro #include <sm/gen.h>
124313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: sasl.c,v 8.24 2013-11-22 20:51:56 ca Exp $")
13605302a5SGregory Neil Shapiro
14605302a5SGregory Neil Shapiro #if SASL
1540266059SGregory Neil Shapiro # include <stdlib.h>
1640266059SGregory Neil Shapiro # include <sendmail.h>
1740266059SGregory Neil Shapiro # include <errno.h>
1840266059SGregory Neil Shapiro
1940266059SGregory Neil Shapiro /*
2040266059SGregory Neil Shapiro ** In order to ensure that storage leaks are tracked, and to prevent
2140266059SGregory Neil Shapiro ** conflicts between the sm_heap package and sasl, we tell sasl to
2240266059SGregory Neil Shapiro ** use the following heap allocation functions. Unfortunately,
23ba00ec3dSGregory Neil Shapiro ** older sasl packages incorrectly specifies the size of a block
2440266059SGregory Neil Shapiro ** using unsigned long: for portability, it should be size_t.
2540266059SGregory Neil Shapiro */
2640266059SGregory Neil Shapiro
27a944d3c6SHajimu UMEMOTO # if defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a
28a944d3c6SHajimu UMEMOTO # define SM_SASL_SIZE_T size_t
29*5b0945b5SGregory Neil Shapiro # else
30a944d3c6SHajimu UMEMOTO # define SM_SASL_SIZE_T unsigned long
31*5b0945b5SGregory Neil Shapiro # endif
32a944d3c6SHajimu UMEMOTO
33a944d3c6SHajimu UMEMOTO void *sm_sasl_malloc __P((SM_SASL_SIZE_T));
34a944d3c6SHajimu UMEMOTO static void *sm_sasl_calloc __P((SM_SASL_SIZE_T, SM_SASL_SIZE_T));
35a944d3c6SHajimu UMEMOTO static void *sm_sasl_realloc __P((void *, SM_SASL_SIZE_T));
3640266059SGregory Neil Shapiro void sm_sasl_free __P((void *));
3740266059SGregory Neil Shapiro
3840266059SGregory Neil Shapiro /*
3994c01205SGregory Neil Shapiro ** SASLv1:
4040266059SGregory Neil Shapiro ** We can't use an rpool for Cyrus-SASL memory management routines,
4140266059SGregory Neil Shapiro ** since the encryption/decryption routines in Cyrus-SASL
4240266059SGregory Neil Shapiro ** allocate/deallocate a buffer each time. Since rpool
4340266059SGregory Neil Shapiro ** don't release memory until the very end, memory consumption is
4440266059SGregory Neil Shapiro ** proportional to the size of an e-mail, which is unacceptable.
4540266059SGregory Neil Shapiro */
4640266059SGregory Neil Shapiro
4740266059SGregory Neil Shapiro /*
4840266059SGregory Neil Shapiro ** SM_SASL_MALLOC -- malloc() for SASL
4940266059SGregory Neil Shapiro **
5040266059SGregory Neil Shapiro ** Parameters:
5140266059SGregory Neil Shapiro ** size -- size of requested memory.
5240266059SGregory Neil Shapiro **
5340266059SGregory Neil Shapiro ** Returns:
5440266059SGregory Neil Shapiro ** pointer to memory.
5540266059SGregory Neil Shapiro */
5640266059SGregory Neil Shapiro
5740266059SGregory Neil Shapiro void *
sm_sasl_malloc(size)5840266059SGregory Neil Shapiro sm_sasl_malloc(size)
59a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T size;
6040266059SGregory Neil Shapiro {
6140266059SGregory Neil Shapiro return sm_malloc((size_t) size);
6240266059SGregory Neil Shapiro }
6340266059SGregory Neil Shapiro
6440266059SGregory Neil Shapiro /*
6540266059SGregory Neil Shapiro ** SM_SASL_CALLOC -- calloc() for SASL
6640266059SGregory Neil Shapiro **
6740266059SGregory Neil Shapiro ** Parameters:
6840266059SGregory Neil Shapiro ** nelem -- number of elements.
6940266059SGregory Neil Shapiro ** elemsize -- size of each element.
7040266059SGregory Neil Shapiro **
7140266059SGregory Neil Shapiro ** Returns:
7240266059SGregory Neil Shapiro ** pointer to memory.
7340266059SGregory Neil Shapiro **
7440266059SGregory Neil Shapiro ** Notice:
7540266059SGregory Neil Shapiro ** this isn't currently used by SASL.
7640266059SGregory Neil Shapiro */
7740266059SGregory Neil Shapiro
7840266059SGregory Neil Shapiro static void *
sm_sasl_calloc(nelem,elemsize)7940266059SGregory Neil Shapiro sm_sasl_calloc(nelem, elemsize)
80a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T nelem;
81a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T elemsize;
8240266059SGregory Neil Shapiro {
8340266059SGregory Neil Shapiro size_t size;
8440266059SGregory Neil Shapiro void *p;
8540266059SGregory Neil Shapiro
8640266059SGregory Neil Shapiro size = (size_t) nelem * (size_t) elemsize;
8740266059SGregory Neil Shapiro p = sm_malloc(size);
8840266059SGregory Neil Shapiro if (p == NULL)
8940266059SGregory Neil Shapiro return NULL;
9040266059SGregory Neil Shapiro memset(p, '\0', size);
9140266059SGregory Neil Shapiro return p;
9240266059SGregory Neil Shapiro }
9340266059SGregory Neil Shapiro
9440266059SGregory Neil Shapiro /*
9540266059SGregory Neil Shapiro ** SM_SASL_REALLOC -- realloc() for SASL
9640266059SGregory Neil Shapiro **
9740266059SGregory Neil Shapiro ** Parameters:
9840266059SGregory Neil Shapiro ** p -- pointer to old memory.
9940266059SGregory Neil Shapiro ** size -- size of requested memory.
10040266059SGregory Neil Shapiro **
10140266059SGregory Neil Shapiro ** Returns:
10240266059SGregory Neil Shapiro ** pointer to new memory.
10340266059SGregory Neil Shapiro */
10440266059SGregory Neil Shapiro
10540266059SGregory Neil Shapiro static void *
sm_sasl_realloc(o,size)10640266059SGregory Neil Shapiro sm_sasl_realloc(o, size)
10740266059SGregory Neil Shapiro void *o;
108a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T size;
10940266059SGregory Neil Shapiro {
11040266059SGregory Neil Shapiro return sm_realloc(o, (size_t) size);
11140266059SGregory Neil Shapiro }
11240266059SGregory Neil Shapiro
11340266059SGregory Neil Shapiro /*
11440266059SGregory Neil Shapiro ** SM_SASL_FREE -- free() for SASL
11540266059SGregory Neil Shapiro **
11640266059SGregory Neil Shapiro ** Parameters:
11740266059SGregory Neil Shapiro ** p -- pointer to free.
11840266059SGregory Neil Shapiro **
11940266059SGregory Neil Shapiro ** Returns:
12040266059SGregory Neil Shapiro ** none
12140266059SGregory Neil Shapiro */
12240266059SGregory Neil Shapiro
12340266059SGregory Neil Shapiro void
sm_sasl_free(p)12440266059SGregory Neil Shapiro sm_sasl_free(p)
12540266059SGregory Neil Shapiro void *p;
12640266059SGregory Neil Shapiro {
12740266059SGregory Neil Shapiro sm_free(p);
12840266059SGregory Neil Shapiro }
12940266059SGregory Neil Shapiro
13040266059SGregory Neil Shapiro /*
13140266059SGregory Neil Shapiro ** SM_SASL_INIT -- sendmail specific SASL initialization
13240266059SGregory Neil Shapiro **
13340266059SGregory Neil Shapiro ** Parameters:
13440266059SGregory Neil Shapiro ** none.
13540266059SGregory Neil Shapiro **
13640266059SGregory Neil Shapiro ** Returns:
13740266059SGregory Neil Shapiro ** none
13840266059SGregory Neil Shapiro **
13940266059SGregory Neil Shapiro ** Side Effects:
14040266059SGregory Neil Shapiro ** installs memory management routines for SASL.
14140266059SGregory Neil Shapiro */
14240266059SGregory Neil Shapiro
14340266059SGregory Neil Shapiro void
sm_sasl_init()14440266059SGregory Neil Shapiro sm_sasl_init()
14540266059SGregory Neil Shapiro {
14640266059SGregory Neil Shapiro sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc,
14740266059SGregory Neil Shapiro sm_sasl_realloc, sm_sasl_free);
14840266059SGregory Neil Shapiro }
14940266059SGregory Neil Shapiro /*
15040266059SGregory Neil Shapiro ** INTERSECT -- create the intersection between two lists
15140266059SGregory Neil Shapiro **
15240266059SGregory Neil Shapiro ** Parameters:
15340266059SGregory Neil Shapiro ** s1, s2 -- lists of items (separated by single blanks).
15440266059SGregory Neil Shapiro ** rpool -- resource pool from which result is allocated.
15540266059SGregory Neil Shapiro **
15640266059SGregory Neil Shapiro ** Returns:
15740266059SGregory Neil Shapiro ** the intersection of both lists.
15840266059SGregory Neil Shapiro */
15940266059SGregory Neil Shapiro
16040266059SGregory Neil Shapiro char *
intersect(s1,s2,rpool)16140266059SGregory Neil Shapiro intersect(s1, s2, rpool)
16240266059SGregory Neil Shapiro char *s1, *s2;
16340266059SGregory Neil Shapiro SM_RPOOL_T *rpool;
16440266059SGregory Neil Shapiro {
16540266059SGregory Neil Shapiro char *hr, *h1, *h, *res;
16640266059SGregory Neil Shapiro int l1, l2, rl;
16740266059SGregory Neil Shapiro
16840266059SGregory Neil Shapiro if (s1 == NULL || s2 == NULL) /* NULL string(s) -> NULL result */
16940266059SGregory Neil Shapiro return NULL;
17040266059SGregory Neil Shapiro l1 = strlen(s1);
17140266059SGregory Neil Shapiro l2 = strlen(s2);
17240266059SGregory Neil Shapiro rl = SM_MIN(l1, l2);
17340266059SGregory Neil Shapiro res = (char *) sm_rpool_malloc(rpool, rl + 1);
17440266059SGregory Neil Shapiro if (res == NULL)
17540266059SGregory Neil Shapiro return NULL;
17640266059SGregory Neil Shapiro *res = '\0';
17740266059SGregory Neil Shapiro if (rl == 0) /* at least one string empty? */
17840266059SGregory Neil Shapiro return res;
17940266059SGregory Neil Shapiro hr = res;
18040266059SGregory Neil Shapiro h1 = s1;
18140266059SGregory Neil Shapiro h = s1;
18240266059SGregory Neil Shapiro
18340266059SGregory Neil Shapiro /* walk through s1 */
18440266059SGregory Neil Shapiro while (h != NULL && *h1 != '\0')
18540266059SGregory Neil Shapiro {
18640266059SGregory Neil Shapiro /* is there something after the current word? */
18740266059SGregory Neil Shapiro if ((h = strchr(h1, ' ')) != NULL)
18840266059SGregory Neil Shapiro *h = '\0';
18940266059SGregory Neil Shapiro l1 = strlen(h1);
19040266059SGregory Neil Shapiro
19140266059SGregory Neil Shapiro /* does the current word appear in s2 ? */
19240266059SGregory Neil Shapiro if (iteminlist(h1, s2, " ") != NULL)
19340266059SGregory Neil Shapiro {
19440266059SGregory Neil Shapiro /* add a blank if not first item */
19540266059SGregory Neil Shapiro if (hr != res)
19640266059SGregory Neil Shapiro *hr++ = ' ';
19740266059SGregory Neil Shapiro
19840266059SGregory Neil Shapiro /* copy the item */
19940266059SGregory Neil Shapiro memcpy(hr, h1, l1);
20040266059SGregory Neil Shapiro
20140266059SGregory Neil Shapiro /* advance pointer in result list */
20240266059SGregory Neil Shapiro hr += l1;
20340266059SGregory Neil Shapiro *hr = '\0';
20440266059SGregory Neil Shapiro }
20540266059SGregory Neil Shapiro if (h != NULL)
20640266059SGregory Neil Shapiro {
20740266059SGregory Neil Shapiro /* there are more items */
20840266059SGregory Neil Shapiro *h = ' ';
20940266059SGregory Neil Shapiro h1 = h + 1;
21040266059SGregory Neil Shapiro }
21140266059SGregory Neil Shapiro }
21240266059SGregory Neil Shapiro return res;
21340266059SGregory Neil Shapiro }
21494c01205SGregory Neil Shapiro # if SASL >= 20000
21594c01205SGregory Neil Shapiro /*
21694c01205SGregory Neil Shapiro ** IPTOSTRING -- create string for SASL_IP*PORT property
21794c01205SGregory Neil Shapiro ** (borrowed from lib/iptostring.c in Cyrus-IMAP)
21894c01205SGregory Neil Shapiro **
21994c01205SGregory Neil Shapiro ** Parameters:
22094c01205SGregory Neil Shapiro ** addr -- (pointer to) socket address
22194c01205SGregory Neil Shapiro ** addrlen -- length of socket address
22294c01205SGregory Neil Shapiro ** out -- output string (result)
22394c01205SGregory Neil Shapiro ** outlen -- maximum length of output string
22494c01205SGregory Neil Shapiro **
22594c01205SGregory Neil Shapiro ** Returns:
22694c01205SGregory Neil Shapiro ** true iff successful.
22794c01205SGregory Neil Shapiro **
22894c01205SGregory Neil Shapiro ** Side Effects:
22994c01205SGregory Neil Shapiro ** creates output string if successful.
23094c01205SGregory Neil Shapiro ** sets errno if unsuccessful.
23194c01205SGregory Neil Shapiro */
23294c01205SGregory Neil Shapiro
23394c01205SGregory Neil Shapiro # include <arpa/inet.h>
23494c01205SGregory Neil Shapiro
23594c01205SGregory Neil Shapiro # ifndef NI_MAXHOST
23694c01205SGregory Neil Shapiro # define NI_MAXHOST 1025
23794c01205SGregory Neil Shapiro # endif
23894c01205SGregory Neil Shapiro # ifndef NI_MAXSERV
23994c01205SGregory Neil Shapiro # define NI_MAXSERV 32
24094c01205SGregory Neil Shapiro # endif
24194c01205SGregory Neil Shapiro
24294c01205SGregory Neil Shapiro bool
iptostring(addr,addrlen,out,outlen)24394c01205SGregory Neil Shapiro iptostring(addr, addrlen, out, outlen)
24494c01205SGregory Neil Shapiro SOCKADDR *addr;
24594c01205SGregory Neil Shapiro SOCKADDR_LEN_T addrlen;
24694c01205SGregory Neil Shapiro char *out;
24794c01205SGregory Neil Shapiro unsigned outlen;
24894c01205SGregory Neil Shapiro {
24994c01205SGregory Neil Shapiro char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
250b6bacd31SGregory Neil Shapiro # if NETINET6
251b6bacd31SGregory Neil Shapiro int niflags;
252*5b0945b5SGregory Neil Shapiro # endif
25394c01205SGregory Neil Shapiro
25494c01205SGregory Neil Shapiro if (addr == NULL || out == NULL)
25594c01205SGregory Neil Shapiro {
25694c01205SGregory Neil Shapiro errno = EINVAL;
25794c01205SGregory Neil Shapiro return false;
25894c01205SGregory Neil Shapiro }
25994c01205SGregory Neil Shapiro
26094c01205SGregory Neil Shapiro # if NETINET6
261b6bacd31SGregory Neil Shapiro niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
262b6bacd31SGregory Neil Shapiro # ifdef NI_WITHSCOPEID
263b6bacd31SGregory Neil Shapiro if (addr->sa.sa_family == AF_INET6)
264b6bacd31SGregory Neil Shapiro niflags |= NI_WITHSCOPEID;
265*5b0945b5SGregory Neil Shapiro # endif
26694c01205SGregory Neil Shapiro if (getnameinfo((struct sockaddr *) addr, addrlen,
267d0cef73dSGregory Neil Shapiro hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags) != 0)
26894c01205SGregory Neil Shapiro return false;
26994c01205SGregory Neil Shapiro # else /* NETINET6 */
27094c01205SGregory Neil Shapiro if (addr->sa.sa_family != AF_INET)
27194c01205SGregory Neil Shapiro {
27294c01205SGregory Neil Shapiro errno = EINVAL;
27394c01205SGregory Neil Shapiro return false;
27494c01205SGregory Neil Shapiro }
275739ac4d4SGregory Neil Shapiro if (sm_strlcpy(hbuf, inet_ntoa(addr->sin.sin_addr), sizeof(hbuf))
276739ac4d4SGregory Neil Shapiro >= sizeof(hbuf))
27794c01205SGregory Neil Shapiro {
278739ac4d4SGregory Neil Shapiro errno = ENOMEM;
27994c01205SGregory Neil Shapiro return false;
28094c01205SGregory Neil Shapiro }
281d0cef73dSGregory Neil Shapiro sm_snprintf(pbuf, sizeof(pbuf), "%d", ntohs(addr->sin.sin_port));
28294c01205SGregory Neil Shapiro # endif /* NETINET6 */
28394c01205SGregory Neil Shapiro
28494c01205SGregory Neil Shapiro if (outlen < strlen(hbuf) + strlen(pbuf) + 2)
28594c01205SGregory Neil Shapiro {
28694c01205SGregory Neil Shapiro errno = ENOMEM;
28794c01205SGregory Neil Shapiro return false;
28894c01205SGregory Neil Shapiro }
28994c01205SGregory Neil Shapiro sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf);
29094c01205SGregory Neil Shapiro return true;
29194c01205SGregory Neil Shapiro }
29294c01205SGregory Neil Shapiro # endif /* SASL >= 20000 */
29340266059SGregory Neil Shapiro #endif /* SASL */
294