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