sasl.c revision 98121
1193326Sed/* 2193326Sed * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. 3193326Sed * All rights reserved. 4193326Sed * 5193326Sed * By using this file, you agree to the terms and conditions set 6193326Sed * forth in the LICENSE file which can be found at the top level of 7193326Sed * the sendmail distribution. 8193326Sed * 9193326Sed */ 10193326Sed 11193326Sed#include <sm/gen.h> 12193326SedSM_RCSID("@(#)$Id: sasl.c,v 8.18 2002/05/25 00:26:42 gshapiro Exp $") 13193326Sed 14193326Sed#if SASL 15193326Sed# include <stdlib.h> 16193326Sed# include <sendmail.h> 17193326Sed# include <errno.h> 18193326Sed 19193326Sed/* 20193326Sed** In order to ensure that storage leaks are tracked, and to prevent 21193326Sed** conflicts between the sm_heap package and sasl, we tell sasl to 22193326Sed** use the following heap allocation functions. Unfortunately, 23193326Sed** the sasl package incorrectly specifies the size of a block 24193326Sed** using unsigned long: for portability, it should be size_t. 25193326Sed*/ 26193326Sed 27193326Sedvoid *sm_sasl_malloc __P((unsigned long)); 28193326Sedstatic void *sm_sasl_calloc __P((unsigned long, unsigned long)); 29193326Sedstatic void *sm_sasl_realloc __P((void *, unsigned long)); 30193326Sedvoid sm_sasl_free __P((void *)); 31198893Srdivacky 32198893Srdivacky/* 33193326Sed** SASLv1: 34193326Sed** We can't use an rpool for Cyrus-SASL memory management routines, 35193326Sed** since the encryption/decryption routines in Cyrus-SASL 36193326Sed** allocate/deallocate a buffer each time. Since rpool 37193326Sed** don't release memory until the very end, memory consumption is 38193326Sed** proportional to the size of an e-mail, which is unacceptable. 39199482Srdivacky*/ 40199482Srdivacky 41199482Srdivacky/* 42199482Srdivacky** SM_SASL_MALLOC -- malloc() for SASL 43199482Srdivacky** 44199482Srdivacky** Parameters: 45199482Srdivacky** size -- size of requested memory. 46199482Srdivacky** 47199482Srdivacky** Returns: 48199482Srdivacky** pointer to memory. 49199482Srdivacky*/ 50199482Srdivacky 51199482Srdivackyvoid * 52199482Srdivackysm_sasl_malloc(size) 53199482Srdivacky unsigned long size; 54199482Srdivacky{ 55199482Srdivacky return sm_malloc((size_t) size); 56199482Srdivacky} 57199482Srdivacky 58199482Srdivacky/* 59199482Srdivacky** SM_SASL_CALLOC -- calloc() for SASL 60199482Srdivacky** 61199482Srdivacky** Parameters: 62199482Srdivacky** nelem -- number of elements. 63193326Sed** elemsize -- size of each element. 64193326Sed** 65198954Srdivacky** Returns: 66199482Srdivacky** pointer to memory. 67199482Srdivacky** 68199482Srdivacky** Notice: 69198954Srdivacky** this isn't currently used by SASL. 70199482Srdivacky*/ 71199482Srdivacky 72199482Srdivackystatic void * 73199482Srdivackysm_sasl_calloc(nelem, elemsize) 74199482Srdivacky unsigned long nelem; 75199482Srdivacky unsigned long elemsize; 76199482Srdivacky{ 77199482Srdivacky size_t size; 78199482Srdivacky void *p; 79193326Sed 80199482Srdivacky size = (size_t) nelem * (size_t) elemsize; 81199482Srdivacky p = sm_malloc(size); 82199482Srdivacky if (p == NULL) 83199482Srdivacky return NULL; 84199482Srdivacky memset(p, '\0', size); 85199482Srdivacky return p; 86199482Srdivacky} 87199482Srdivacky 88199482Srdivacky/* 89199482Srdivacky** SM_SASL_REALLOC -- realloc() for SASL 90199482Srdivacky** 91199482Srdivacky** Parameters: 92199482Srdivacky** p -- pointer to old memory. 93199482Srdivacky** size -- size of requested memory. 94199482Srdivacky** 95199482Srdivacky** Returns: 96199482Srdivacky** pointer to new memory. 97199482Srdivacky*/ 98199482Srdivacky 99199482Srdivackystatic void * 100199482Srdivackysm_sasl_realloc(o, size) 101199482Srdivacky void *o; 102199482Srdivacky unsigned long size; 103199482Srdivacky{ 104199482Srdivacky return sm_realloc(o, (size_t) size); 105199482Srdivacky} 106199482Srdivacky 107199482Srdivacky/* 108199482Srdivacky** SM_SASL_FREE -- free() for SASL 109199482Srdivacky** 110199482Srdivacky** Parameters: 111199482Srdivacky** p -- pointer to free. 112199482Srdivacky** 113199482Srdivacky** Returns: 114199482Srdivacky** none 115199482Srdivacky*/ 116199482Srdivacky 117199482Srdivackyvoid 118199482Srdivackysm_sasl_free(p) 119199482Srdivacky void *p; 120199482Srdivacky{ 121199482Srdivacky sm_free(p); 122199482Srdivacky} 123199482Srdivacky 124199482Srdivacky/* 125199482Srdivacky** SM_SASL_INIT -- sendmail specific SASL initialization 126199482Srdivacky** 127199482Srdivacky** Parameters: 128199482Srdivacky** none. 129199482Srdivacky** 130199482Srdivacky** Returns: 131199482Srdivacky** none 132199482Srdivacky** 133199482Srdivacky** Side Effects: 134199482Srdivacky** installs memory management routines for SASL. 135199482Srdivacky*/ 136199482Srdivacky 137199482Srdivackyvoid 138199482Srdivackysm_sasl_init() 139199482Srdivacky{ 140199482Srdivacky sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc, 141199482Srdivacky sm_sasl_realloc, sm_sasl_free); 142199482Srdivacky} 143193326Sed/* 144199482Srdivacky** INTERSECT -- create the intersection between two lists 145193326Sed** 146199482Srdivacky** Parameters: 147199482Srdivacky** s1, s2 -- lists of items (separated by single blanks). 148199482Srdivacky** rpool -- resource pool from which result is allocated. 149199482Srdivacky** 150199482Srdivacky** Returns: 151199482Srdivacky** the intersection of both lists. 152199482Srdivacky*/ 153198954Srdivacky 154199482Srdivackychar * 155199482Srdivackyintersect(s1, s2, rpool) 156199482Srdivacky char *s1, *s2; 157199482Srdivacky SM_RPOOL_T *rpool; 158199482Srdivacky{ 159199482Srdivacky char *hr, *h1, *h, *res; 160199482Srdivacky int l1, l2, rl; 161199482Srdivacky 162199482Srdivacky if (s1 == NULL || s2 == NULL) /* NULL string(s) -> NULL result */ 163199482Srdivacky return NULL; 164199482Srdivacky l1 = strlen(s1); 165199482Srdivacky l2 = strlen(s2); 166199482Srdivacky rl = SM_MIN(l1, l2); 167199482Srdivacky res = (char *) sm_rpool_malloc(rpool, rl + 1); 168199482Srdivacky if (res == NULL) 169199482Srdivacky return NULL; 170199482Srdivacky *res = '\0'; 171199482Srdivacky if (rl == 0) /* at least one string empty? */ 172199482Srdivacky return res; 173199482Srdivacky hr = res; 174199482Srdivacky h1 = s1; 175199482Srdivacky h = s1; 176199482Srdivacky 177199482Srdivacky /* walk through s1 */ 178198954Srdivacky while (h != NULL && *h1 != '\0') 179199482Srdivacky { 180199482Srdivacky /* is there something after the current word? */ 181199482Srdivacky if ((h = strchr(h1, ' ')) != NULL) 182199482Srdivacky *h = '\0'; 183199482Srdivacky l1 = strlen(h1); 184193326Sed 185199482Srdivacky /* does the current word appear in s2 ? */ 186199482Srdivacky if (iteminlist(h1, s2, " ") != NULL) 187199482Srdivacky { 188199482Srdivacky /* add a blank if not first item */ 189199482Srdivacky if (hr != res) 190199482Srdivacky *hr++ = ' '; 191193326Sed 192199482Srdivacky /* copy the item */ 193199482Srdivacky memcpy(hr, h1, l1); 194199482Srdivacky 195198954Srdivacky /* advance pointer in result list */ 196199482Srdivacky hr += l1; 197198954Srdivacky *hr = '\0'; 198199482Srdivacky } 199199482Srdivacky if (h != NULL) 200199482Srdivacky { 201198954Srdivacky /* there are more items */ 202199482Srdivacky *h = ' '; 203199482Srdivacky h1 = h + 1; 204199482Srdivacky } 205199482Srdivacky } 206199482Srdivacky return res; 207199482Srdivacky} 208199482Srdivacky# if SASL >= 20000 209198954Srdivacky/* 210198954Srdivacky** IPTOSTRING -- create string for SASL_IP*PORT property 211198954Srdivacky** (borrowed from lib/iptostring.c in Cyrus-IMAP) 212198954Srdivacky** 213198954Srdivacky** Parameters: 214193326Sed** addr -- (pointer to) socket address 215193326Sed** addrlen -- length of socket address 216199512Srdivacky** out -- output string (result) 217199512Srdivacky** outlen -- maximum length of output string 218199990Srdivacky** 219199990Srdivacky** Returns: 220199990Srdivacky** true iff successful. 221207619Srdivacky** 222193326Sed** Side Effects: 223199990Srdivacky** creates output string if successful. 224193326Sed** sets errno if unsuccessful. 225207619Srdivacky*/ 226193326Sed 227207619Srdivacky# include <arpa/inet.h> 228207619Srdivacky 229207619Srdivacky# ifndef NI_WITHSCOPEID 230199990Srdivacky# define NI_WITHSCOPEID 0 231207619Srdivacky# endif 232207619Srdivacky# ifndef NI_MAXHOST 233193326Sed# define NI_MAXHOST 1025 234193326Sed# endif 235193326Sed# ifndef NI_MAXSERV 236199990Srdivacky# define NI_MAXSERV 32 237199990Srdivacky# endif 238193326Sed 239198954Srdivackybool 240198954Srdivackyiptostring(addr, addrlen, out, outlen) 241199482Srdivacky SOCKADDR *addr; 242199482Srdivacky SOCKADDR_LEN_T addrlen; 243199482Srdivacky char *out; 244199482Srdivacky unsigned outlen; 245199482Srdivacky{ 246199482Srdivacky char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; 247199482Srdivacky 248199482Srdivacky if (addr == NULL || out == NULL) 249199482Srdivacky { 250199482Srdivacky errno = EINVAL; 251199482Srdivacky return false; 252198954Srdivacky } 253198954Srdivacky 254198954Srdivacky# if NETINET6 255198954Srdivacky if (getnameinfo((struct sockaddr *) addr, addrlen, 256199482Srdivacky hbuf, sizeof hbuf, pbuf, sizeof pbuf, 257199482Srdivacky NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV) != 0) 258199482Srdivacky return false; 259199482Srdivacky# else /* NETINET6 */ 260199482Srdivacky if (addr->sa.sa_family != AF_INET) 261198954Srdivacky { 262199482Srdivacky errno = EINVAL; 263199482Srdivacky return false; 264199482Srdivacky } 265199482Srdivacky if (inet_ntop(AF_INET, &(addr->sin.sin_addr), 266199482Srdivacky hbuf, sizeof hbuf) == NULL) 267199482Srdivacky { 268199482Srdivacky errno = EINVAL; 269199482Srdivacky return false; 270199482Srdivacky } 271199482Srdivacky sm_snprintf(pbuf, sizeof pbuf, "%d", ntohs(addr->sin.sin_port)); 272199482Srdivacky# endif /* NETINET6 */ 273199482Srdivacky 274198954Srdivacky if (outlen < strlen(hbuf) + strlen(pbuf) + 2) 275199482Srdivacky { 276199482Srdivacky errno = ENOMEM; 277199482Srdivacky return false; 278199482Srdivacky } 279199482Srdivacky sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf); 280199482Srdivacky return true; 281199482Srdivacky} 282199482Srdivacky# endif /* SASL >= 20000 */ 283199482Srdivacky#endif /* SASL */ 284198954Srdivacky