xref: /freebsd/contrib/sendmail/src/sasl.c (revision ee2ea5ceafed78a5bd9810beb9e3ca927180c226)
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>
12 SM_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 
28 void *sm_sasl_malloc __P((unsigned long));
29 static void *sm_sasl_calloc __P((unsigned long, unsigned long));
30 static void *sm_sasl_realloc __P((void *, unsigned long));
31 void 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 
52 void *
53 sm_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 
73 static void *
74 sm_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 
100 static void *
101 sm_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 
118 void
119 sm_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 
138 void
139 sm_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 
155 char *
156 intersect(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