sasl.c revision 98121
190792Sgshapiro/*
294334Sgshapiro * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers.
390792Sgshapiro *	All rights reserved.
490792Sgshapiro *
590792Sgshapiro * By using this file, you agree to the terms and conditions set
690792Sgshapiro * forth in the LICENSE file which can be found at the top level of
790792Sgshapiro * the sendmail distribution.
890792Sgshapiro *
990792Sgshapiro */
1090792Sgshapiro
1194334Sgshapiro#include <sm/gen.h>
1298121SgshapiroSM_RCSID("@(#)$Id: sasl.c,v 8.18 2002/05/25 00:26:42 gshapiro Exp $")
1394334Sgshapiro
1490792Sgshapiro#if SASL
1590792Sgshapiro# include <stdlib.h>
1690792Sgshapiro# include <sendmail.h>
1790792Sgshapiro# include <errno.h>
1890792Sgshapiro
1990792Sgshapiro/*
2090792Sgshapiro**  In order to ensure that storage leaks are tracked, and to prevent
2190792Sgshapiro**  conflicts between the sm_heap package and sasl, we tell sasl to
2290792Sgshapiro**  use the following heap allocation functions.  Unfortunately,
2390792Sgshapiro**  the sasl package incorrectly specifies the size of a block
2490792Sgshapiro**  using unsigned long: for portability, it should be size_t.
2590792Sgshapiro*/
2690792Sgshapiro
2790792Sgshapirovoid *sm_sasl_malloc __P((unsigned long));
2890792Sgshapirostatic void *sm_sasl_calloc __P((unsigned long, unsigned long));
2990792Sgshapirostatic void *sm_sasl_realloc __P((void *, unsigned long));
3090792Sgshapirovoid sm_sasl_free __P((void *));
3190792Sgshapiro
3290792Sgshapiro/*
3398121Sgshapiro**  SASLv1:
3490792Sgshapiro**  We can't use an rpool for Cyrus-SASL memory management routines,
3590792Sgshapiro**	since the encryption/decryption routines in Cyrus-SASL
3690792Sgshapiro**	allocate/deallocate a buffer each time. Since rpool
3790792Sgshapiro**	don't release memory until the very end, memory consumption is
3890792Sgshapiro**	proportional to the size of an e-mail, which is unacceptable.
3990792Sgshapiro*/
4090792Sgshapiro
4190792Sgshapiro/*
4290792Sgshapiro**  SM_SASL_MALLOC -- malloc() for SASL
4390792Sgshapiro**
4490792Sgshapiro**	Parameters:
4590792Sgshapiro**		size -- size of requested memory.
4690792Sgshapiro**
4790792Sgshapiro**	Returns:
4890792Sgshapiro**		pointer to memory.
4990792Sgshapiro*/
5090792Sgshapiro
5190792Sgshapirovoid *
5290792Sgshapirosm_sasl_malloc(size)
5390792Sgshapiro	unsigned long size;
5490792Sgshapiro{
5590792Sgshapiro	return sm_malloc((size_t) size);
5690792Sgshapiro}
5790792Sgshapiro
5890792Sgshapiro/*
5990792Sgshapiro**  SM_SASL_CALLOC -- calloc() for SASL
6090792Sgshapiro**
6190792Sgshapiro**	Parameters:
6290792Sgshapiro**		nelem -- number of elements.
6390792Sgshapiro**		elemsize -- size of each element.
6490792Sgshapiro**
6590792Sgshapiro**	Returns:
6690792Sgshapiro**		pointer to memory.
6790792Sgshapiro**
6890792Sgshapiro**	Notice:
6990792Sgshapiro**		this isn't currently used by SASL.
7090792Sgshapiro*/
7190792Sgshapiro
7290792Sgshapirostatic void *
7390792Sgshapirosm_sasl_calloc(nelem, elemsize)
7490792Sgshapiro	unsigned long nelem;
7590792Sgshapiro	unsigned long elemsize;
7690792Sgshapiro{
7790792Sgshapiro	size_t size;
7890792Sgshapiro	void *p;
7990792Sgshapiro
8090792Sgshapiro	size = (size_t) nelem * (size_t) elemsize;
8190792Sgshapiro	p = sm_malloc(size);
8290792Sgshapiro	if (p == NULL)
8390792Sgshapiro		return NULL;
8490792Sgshapiro	memset(p, '\0', size);
8590792Sgshapiro	return p;
8690792Sgshapiro}
8790792Sgshapiro
8890792Sgshapiro/*
8990792Sgshapiro**  SM_SASL_REALLOC -- realloc() for SASL
9090792Sgshapiro**
9190792Sgshapiro**	Parameters:
9290792Sgshapiro**		p -- pointer to old memory.
9390792Sgshapiro**		size -- size of requested memory.
9490792Sgshapiro**
9590792Sgshapiro**	Returns:
9690792Sgshapiro**		pointer to new memory.
9790792Sgshapiro*/
9890792Sgshapiro
9990792Sgshapirostatic void *
10090792Sgshapirosm_sasl_realloc(o, size)
10190792Sgshapiro	void *o;
10290792Sgshapiro	unsigned long size;
10390792Sgshapiro{
10490792Sgshapiro	return sm_realloc(o, (size_t) size);
10590792Sgshapiro}
10690792Sgshapiro
10790792Sgshapiro/*
10890792Sgshapiro**  SM_SASL_FREE -- free() for SASL
10990792Sgshapiro**
11090792Sgshapiro**	Parameters:
11190792Sgshapiro**		p -- pointer to free.
11290792Sgshapiro**
11390792Sgshapiro**	Returns:
11490792Sgshapiro**		none
11590792Sgshapiro*/
11690792Sgshapiro
11790792Sgshapirovoid
11890792Sgshapirosm_sasl_free(p)
11990792Sgshapiro	void *p;
12090792Sgshapiro{
12190792Sgshapiro	sm_free(p);
12290792Sgshapiro}
12390792Sgshapiro
12490792Sgshapiro/*
12590792Sgshapiro**  SM_SASL_INIT -- sendmail specific SASL initialization
12690792Sgshapiro**
12790792Sgshapiro**	Parameters:
12890792Sgshapiro**		none.
12990792Sgshapiro**
13090792Sgshapiro**	Returns:
13190792Sgshapiro**		none
13290792Sgshapiro**
13390792Sgshapiro**	Side Effects:
13490792Sgshapiro**		installs memory management routines for SASL.
13590792Sgshapiro*/
13690792Sgshapiro
13790792Sgshapirovoid
13890792Sgshapirosm_sasl_init()
13990792Sgshapiro{
14090792Sgshapiro	sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc,
14190792Sgshapiro		       sm_sasl_realloc, sm_sasl_free);
14290792Sgshapiro}
14390792Sgshapiro/*
14490792Sgshapiro**  INTERSECT -- create the intersection between two lists
14590792Sgshapiro**
14690792Sgshapiro**	Parameters:
14790792Sgshapiro**		s1, s2 -- lists of items (separated by single blanks).
14890792Sgshapiro**		rpool -- resource pool from which result is allocated.
14990792Sgshapiro**
15090792Sgshapiro**	Returns:
15190792Sgshapiro**		the intersection of both lists.
15290792Sgshapiro*/
15390792Sgshapiro
15490792Sgshapirochar *
15590792Sgshapirointersect(s1, s2, rpool)
15690792Sgshapiro	char *s1, *s2;
15790792Sgshapiro	SM_RPOOL_T *rpool;
15890792Sgshapiro{
15990792Sgshapiro	char *hr, *h1, *h, *res;
16090792Sgshapiro	int l1, l2, rl;
16190792Sgshapiro
16290792Sgshapiro	if (s1 == NULL || s2 == NULL)	/* NULL string(s) -> NULL result */
16390792Sgshapiro		return NULL;
16490792Sgshapiro	l1 = strlen(s1);
16590792Sgshapiro	l2 = strlen(s2);
16690792Sgshapiro	rl = SM_MIN(l1, l2);
16790792Sgshapiro	res = (char *) sm_rpool_malloc(rpool, rl + 1);
16890792Sgshapiro	if (res == NULL)
16990792Sgshapiro		return NULL;
17090792Sgshapiro	*res = '\0';
17190792Sgshapiro	if (rl == 0)	/* at least one string empty? */
17290792Sgshapiro		return res;
17390792Sgshapiro	hr = res;
17490792Sgshapiro	h1 = s1;
17590792Sgshapiro	h = s1;
17690792Sgshapiro
17790792Sgshapiro	/* walk through s1 */
17890792Sgshapiro	while (h != NULL && *h1 != '\0')
17990792Sgshapiro	{
18090792Sgshapiro		/* is there something after the current word? */
18190792Sgshapiro		if ((h = strchr(h1, ' ')) != NULL)
18290792Sgshapiro			*h = '\0';
18390792Sgshapiro		l1 = strlen(h1);
18490792Sgshapiro
18590792Sgshapiro		/* does the current word appear in s2 ? */
18690792Sgshapiro		if (iteminlist(h1, s2, " ") != NULL)
18790792Sgshapiro		{
18890792Sgshapiro			/* add a blank if not first item */
18990792Sgshapiro			if (hr != res)
19090792Sgshapiro				*hr++ = ' ';
19190792Sgshapiro
19290792Sgshapiro			/* copy the item */
19390792Sgshapiro			memcpy(hr, h1, l1);
19490792Sgshapiro
19590792Sgshapiro			/* advance pointer in result list */
19690792Sgshapiro			hr += l1;
19790792Sgshapiro			*hr = '\0';
19890792Sgshapiro		}
19990792Sgshapiro		if (h != NULL)
20090792Sgshapiro		{
20190792Sgshapiro			/* there are more items */
20290792Sgshapiro			*h = ' ';
20390792Sgshapiro			h1 = h + 1;
20490792Sgshapiro		}
20590792Sgshapiro	}
20690792Sgshapiro	return res;
20790792Sgshapiro}
20898121Sgshapiro# if SASL >= 20000
20998121Sgshapiro/*
21098121Sgshapiro**  IPTOSTRING -- create string for SASL_IP*PORT property
21198121Sgshapiro**                (borrowed from lib/iptostring.c in Cyrus-IMAP)
21298121Sgshapiro**
21398121Sgshapiro**	Parameters:
21498121Sgshapiro**		addr -- (pointer to) socket address
21598121Sgshapiro**		addrlen -- length of socket address
21698121Sgshapiro**		out -- output string (result)
21798121Sgshapiro**		outlen -- maximum length of output string
21898121Sgshapiro**
21998121Sgshapiro**	Returns:
22098121Sgshapiro**		true iff successful.
22198121Sgshapiro**
22298121Sgshapiro**	Side Effects:
22398121Sgshapiro**		creates output string if successful.
22498121Sgshapiro**		sets errno if unsuccessful.
22598121Sgshapiro*/
22698121Sgshapiro
22798121Sgshapiro#  include <arpa/inet.h>
22898121Sgshapiro
22998121Sgshapiro#  ifndef NI_WITHSCOPEID
23098121Sgshapiro#   define NI_WITHSCOPEID	0
23198121Sgshapiro#  endif
23298121Sgshapiro#  ifndef NI_MAXHOST
23398121Sgshapiro#   define NI_MAXHOST	1025
23498121Sgshapiro#  endif
23598121Sgshapiro#  ifndef NI_MAXSERV
23698121Sgshapiro#   define NI_MAXSERV	32
23798121Sgshapiro#  endif
23898121Sgshapiro
23998121Sgshapirobool
24098121Sgshapiroiptostring(addr, addrlen, out, outlen)
24198121Sgshapiro	SOCKADDR *addr;
24298121Sgshapiro	SOCKADDR_LEN_T addrlen;
24398121Sgshapiro	char *out;
24498121Sgshapiro	unsigned outlen;
24598121Sgshapiro{
24698121Sgshapiro	char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
24798121Sgshapiro
24898121Sgshapiro	if (addr == NULL || out == NULL)
24998121Sgshapiro	{
25098121Sgshapiro		errno = EINVAL;
25198121Sgshapiro		return false;
25298121Sgshapiro	}
25398121Sgshapiro
25498121Sgshapiro#  if NETINET6
25598121Sgshapiro	if (getnameinfo((struct sockaddr *) addr, addrlen,
25698121Sgshapiro			hbuf, sizeof hbuf, pbuf, sizeof pbuf,
25798121Sgshapiro			NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV) != 0)
25898121Sgshapiro		return false;
25998121Sgshapiro#  else /* NETINET6 */
26098121Sgshapiro	if (addr->sa.sa_family != AF_INET)
26198121Sgshapiro	{
26298121Sgshapiro		errno = EINVAL;
26398121Sgshapiro		return false;
26498121Sgshapiro	}
26598121Sgshapiro	if (inet_ntop(AF_INET, &(addr->sin.sin_addr),
26698121Sgshapiro		      hbuf, sizeof hbuf) == NULL)
26798121Sgshapiro	{
26898121Sgshapiro		errno = EINVAL;
26998121Sgshapiro		return false;
27098121Sgshapiro	}
27198121Sgshapiro	sm_snprintf(pbuf, sizeof pbuf, "%d", ntohs(addr->sin.sin_port));
27298121Sgshapiro#  endif /* NETINET6 */
27398121Sgshapiro
27498121Sgshapiro	if (outlen < strlen(hbuf) + strlen(pbuf) + 2)
27598121Sgshapiro	{
27698121Sgshapiro		errno = ENOMEM;
27798121Sgshapiro		return false;
27898121Sgshapiro	}
27998121Sgshapiro	sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf);
28098121Sgshapiro	return true;
28198121Sgshapiro}
28298121Sgshapiro# endif /* SASL >= 20000 */
28390792Sgshapiro#endif /* SASL */
284