sasl.c revision 95154
1/*
2 * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 *
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.
8 *
9 */
10
11#include <sm/gen.h>
12SM_RCSID("@(#)$Id: sasl.c,v 1.1.1.2 2002/04/10 03:04:51 gshapiro Exp $")
13
14#if SASL
15# include <stdlib.h>
16# include <sendmail.h>
17# include <errno.h>
18# include <sasl.h>
19
20/*
21**  In order to ensure that storage leaks are tracked, and to prevent
22**  conflicts between the sm_heap package and sasl, we tell sasl to
23**  use the following heap allocation functions.  Unfortunately,
24**  the sasl package incorrectly specifies the size of a block
25**  using unsigned long: for portability, it should be size_t.
26*/
27
28void *sm_sasl_malloc __P((unsigned long));
29static void *sm_sasl_calloc __P((unsigned long, unsigned long));
30static void *sm_sasl_realloc __P((void *, unsigned long));
31void sm_sasl_free __P((void *));
32
33/*
34**  We can't use an rpool for Cyrus-SASL memory management routines,
35**	since the encryption/decryption routines in Cyrus-SASL
36**	allocate/deallocate a buffer each time. Since rpool
37**	don't release memory until the very end, memory consumption is
38**	proportional to the size of an e-mail, which is unacceptable.
39**
40*/
41
42/*
43**  SM_SASL_MALLOC -- malloc() for SASL
44**
45**	Parameters:
46**		size -- size of requested memory.
47**
48**	Returns:
49**		pointer to memory.
50*/
51
52void *
53sm_sasl_malloc(size)
54	unsigned long size;
55{
56	return sm_malloc((size_t) size);
57}
58
59/*
60**  SM_SASL_CALLOC -- calloc() for SASL
61**
62**	Parameters:
63**		nelem -- number of elements.
64**		elemsize -- size of each element.
65**
66**	Returns:
67**		pointer to memory.
68**
69**	Notice:
70**		this isn't currently used by SASL.
71*/
72
73static void *
74sm_sasl_calloc(nelem, elemsize)
75	unsigned long nelem;
76	unsigned long elemsize;
77{
78	size_t size;
79	void *p;
80
81	size = (size_t) nelem * (size_t) elemsize;
82	p = sm_malloc(size);
83	if (p == NULL)
84		return NULL;
85	memset(p, '\0', size);
86	return p;
87}
88
89/*
90**  SM_SASL_REALLOC -- realloc() for SASL
91**
92**	Parameters:
93**		p -- pointer to old memory.
94**		size -- size of requested memory.
95**
96**	Returns:
97**		pointer to new memory.
98*/
99
100static void *
101sm_sasl_realloc(o, size)
102	void *o;
103	unsigned long size;
104{
105	return sm_realloc(o, (size_t) size);
106}
107
108/*
109**  SM_SASL_FREE -- free() for SASL
110**
111**	Parameters:
112**		p -- pointer to free.
113**
114**	Returns:
115**		none
116*/
117
118void
119sm_sasl_free(p)
120	void *p;
121{
122	sm_free(p);
123}
124
125/*
126**  SM_SASL_INIT -- sendmail specific SASL initialization
127**
128**	Parameters:
129**		none.
130**
131**	Returns:
132**		none
133**
134**	Side Effects:
135**		installs memory management routines for SASL.
136*/
137
138void
139sm_sasl_init()
140{
141	sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc,
142		       sm_sasl_realloc, sm_sasl_free);
143}
144/*
145**  INTERSECT -- create the intersection between two lists
146**
147**	Parameters:
148**		s1, s2 -- lists of items (separated by single blanks).
149**		rpool -- resource pool from which result is allocated.
150**
151**	Returns:
152**		the intersection of both lists.
153*/
154
155char *
156intersect(s1, s2, rpool)
157	char *s1, *s2;
158	SM_RPOOL_T *rpool;
159{
160	char *hr, *h1, *h, *res;
161	int l1, l2, rl;
162
163	if (s1 == NULL || s2 == NULL)	/* NULL string(s) -> NULL result */
164		return NULL;
165	l1 = strlen(s1);
166	l2 = strlen(s2);
167	rl = SM_MIN(l1, l2);
168	res = (char *) sm_rpool_malloc(rpool, rl + 1);
169	if (res == NULL)
170		return NULL;
171	*res = '\0';
172	if (rl == 0)	/* at least one string empty? */
173		return res;
174	hr = res;
175	h1 = s1;
176	h = s1;
177
178	/* walk through s1 */
179	while (h != NULL && *h1 != '\0')
180	{
181		/* is there something after the current word? */
182		if ((h = strchr(h1, ' ')) != NULL)
183			*h = '\0';
184		l1 = strlen(h1);
185
186		/* does the current word appear in s2 ? */
187		if (iteminlist(h1, s2, " ") != NULL)
188		{
189			/* add a blank if not first item */
190			if (hr != res)
191				*hr++ = ' ';
192
193			/* copy the item */
194			memcpy(hr, h1, l1);
195
196			/* advance pointer in result list */
197			hr += l1;
198			*hr = '\0';
199		}
200		if (h != NULL)
201		{
202			/* there are more items */
203			*h = ' ';
204			h1 = h + 1;
205		}
206	}
207	return res;
208}
209#endif /* SASL */
210