sasl.c revision 102528
112891Swpaul/* 212891Swpaul * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. 312891Swpaul * All rights reserved. 412891Swpaul * 512891Swpaul * By using this file, you agree to the terms and conditions set 612891Swpaul * forth in the LICENSE file which can be found at the top level of 712891Swpaul * the sendmail distribution. 812891Swpaul * 912891Swpaul */ 1012891Swpaul 1112891Swpaul#include <sm/gen.h> 1212891SwpaulSM_RCSID("@(#)$Id: sasl.c,v 8.19.2.1 2002/07/13 18:04:56 ca Exp $") 1312891Swpaul 1412891Swpaul#if SASL 1512891Swpaul# include <stdlib.h> 1612891Swpaul# include <sendmail.h> 1712891Swpaul# include <errno.h> 1812891Swpaul 1912891Swpaul/* 2012891Swpaul** In order to ensure that storage leaks are tracked, and to prevent 2112891Swpaul** conflicts between the sm_heap package and sasl, we tell sasl to 2212891Swpaul** use the following heap allocation functions. Unfortunately, 2312891Swpaul** the sasl package incorrectly specifies the size of a block 2412891Swpaul** using unsigned long: for portability, it should be size_t. 2512891Swpaul*/ 2612891Swpaul 2712891Swpaulvoid *sm_sasl_malloc __P((unsigned long)); 2812891Swpaulstatic void *sm_sasl_calloc __P((unsigned long, unsigned long)); 2912891Swpaulstatic void *sm_sasl_realloc __P((void *, unsigned long)); 3012891Swpaulvoid sm_sasl_free __P((void *)); 3150479Speter 3212891Swpaul/* 33200478Shrs** SASLv1: 3412891Swpaul** We can't use an rpool for Cyrus-SASL memory management routines, 3512891Swpaul** since the encryption/decryption routines in Cyrus-SASL 3612891Swpaul** allocate/deallocate a buffer each time. Since rpool 3712891Swpaul** don't release memory until the very end, memory consumption is 3824946Sjmg** proportional to the size of an e-mail, which is unacceptable. 3912891Swpaul*/ 4024946Sjmg 4112891Swpaul/* 4212891Swpaul** SM_SASL_MALLOC -- malloc() for SASL 43175951Smatteo** 4412891Swpaul** Parameters: 4512891Swpaul** size -- size of requested memory. 4624946Sjmg** 4712891Swpaul** Returns: 4857673Ssheldonh** pointer to memory. 4957673Ssheldonh*/ 5012891Swpaul 5112891Swpaulvoid * 5212891Swpaulsm_sasl_malloc(size) 5312891Swpaul unsigned long size; 5412891Swpaul{ 5512891Swpaul return sm_malloc((size_t) size); 5630827Scharnier} 5730827Scharnier 5812891Swpaul/* 5912891Swpaul** SM_SASL_CALLOC -- calloc() for SASL 6012891Swpaul** 6124946Sjmg** Parameters: 6224946Sjmg** nelem -- number of elements. 6399968Scharnier** elemsize -- size of each element. 6430827Scharnier** 6530827Scharnier** Returns: 6630827Scharnier** pointer to memory. 6724946Sjmg** 6830827Scharnier** Notice: 6930827Scharnier** this isn't currently used by SASL. 7030827Scharnier*/ 7112891Swpaul 7224946Sjmgstatic void * 7312891Swpaulsm_sasl_calloc(nelem, elemsize) 7412891Swpaul unsigned long nelem; 7557673Ssheldonh unsigned long elemsize; 7657673Ssheldonh{ 7712891Swpaul size_t size; 7812891Swpaul void *p; 7930827Scharnier 8030827Scharnier size = (size_t) nelem * (size_t) elemsize; 8130827Scharnier p = sm_malloc(size); 8212891Swpaul if (p == NULL) 8312891Swpaul return NULL; 8424946Sjmg memset(p, '\0', size); 8512891Swpaul return p; 8612891Swpaul} 8712891Swpaul 8812891Swpaul/* 8957673Ssheldonh** SM_SASL_REALLOC -- realloc() for SASL 9057673Ssheldonh** 9112891Swpaul** Parameters: 9224946Sjmg** p -- pointer to old memory. 9312891Swpaul** size -- size of requested memory. 9412891Swpaul** 9512891Swpaul** Returns: 9612891Swpaul** pointer to new memory. 9712891Swpaul*/ 9812891Swpaul 9924946Sjmgstatic void * 10057673Ssheldonhsm_sasl_realloc(o, size) 10157673Ssheldonh void *o; 10212891Swpaul unsigned long size; 10312891Swpaul{ 10430827Scharnier return sm_realloc(o, (size_t) size); 10556416Smpp} 10630827Scharnier 10757673Ssheldonh/* 10857673Ssheldonh** SM_SASL_FREE -- free() for SASL 10912891Swpaul** 110141851Sru** Parameters: 11112891Swpaul** p -- pointer to free. 11212891Swpaul** 11324946Sjmg** Returns: 11424946Sjmg** none 11599968Scharnier*/ 116109724Smtm 11712891Swpaulvoid 11830827Scharniersm_sasl_free(p) 11912891Swpaul void *p; 12056416Smpp{ 12156416Smpp sm_free(p); 12256416Smpp} 12330827Scharnier 124101828Sru/* 12556416Smpp** SM_SASL_INIT -- sendmail specific SASL initialization 12630827Scharnier** 12712891Swpaul** Parameters: 12812891Swpaul** none. 12957673Ssheldonh** 13057673Ssheldonh** Returns: 13130827Scharnier** none 13230827Scharnier** 13330827Scharnier** Side Effects: 13412891Swpaul** installs memory management routines for SASL. 13530827Scharnier*/ 13656416Smpp 13730827Scharniervoid 13824946Sjmgsm_sasl_init() 13912891Swpaul{ 14012891Swpaul sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc, 14112891Swpaul sm_sasl_realloc, sm_sasl_free); 14261248Sasmodai} 14357673Ssheldonh/* 14457673Ssheldonh** INTERSECT -- create the intersection between two lists 145194968Sbrian** 146194968Sbrian** Parameters: 147194968Sbrian** s1, s2 -- lists of items (separated by single blanks). 148194968Sbrian** rpool -- resource pool from which result is allocated. 149194968Sbrian** 15012891Swpaul** Returns: 15157695Ssheldonh** the intersection of both lists. 15257695Ssheldonh*/ 15312891Swpaul 15412891Swpaulchar * 15512891Swpaulintersect(s1, s2, rpool) 15612891Swpaul char *s1, *s2; 15712891Swpaul SM_RPOOL_T *rpool; 15812891Swpaul{ 15956416Smpp char *hr, *h1, *h, *res; 16079755Sdd int l1, l2, rl; 16130827Scharnier 16212891Swpaul if (s1 == NULL || s2 == NULL) /* NULL string(s) -> NULL result */ 16312891Swpaul return NULL; 16412891Swpaul l1 = strlen(s1); 16512891Swpaul l2 = strlen(s2); 16612891Swpaul rl = SM_MIN(l1, l2); 16712891Swpaul res = (char *) sm_rpool_malloc(rpool, rl + 1); 16812891Swpaul if (res == NULL) 16912891Swpaul return NULL; 17012891Swpaul *res = '\0'; 17157673Ssheldonh if (rl == 0) /* at least one string empty? */ 17257673Ssheldonh return res; 17324946Sjmg hr = res; 17412891Swpaul h1 = s1; 17512891Swpaul h = s1; 17612891Swpaul 17757673Ssheldonh /* walk through s1 */ 17857673Ssheldonh while (h != NULL && *h1 != '\0') 17912891Swpaul { 18012891Swpaul /* is there something after the current word? */ 18130827Scharnier if ((h = strchr(h1, ' ')) != NULL) 18230827Scharnier *h = '\0'; 18312891Swpaul l1 = strlen(h1); 18444227Sghelmer 18544227Sghelmer /* does the current word appear in s2 ? */ 18644227Sghelmer if (iteminlist(h1, s2, " ") != NULL) 18744227Sghelmer { 18844227Sghelmer /* add a blank if not first item */ 18912891Swpaul if (hr != res) 19030827Scharnier *hr++ = ' '; 19130827Scharnier 19212891Swpaul /* copy the item */ 19312891Swpaul memcpy(hr, h1, l1); 19412891Swpaul 19512891Swpaul /* advance pointer in result list */ 19624946Sjmg hr += l1; 19724946Sjmg *hr = '\0'; 19824946Sjmg } 19912891Swpaul if (h != NULL) 20012891Swpaul { 20112891Swpaul /* there are more items */ 20230827Scharnier *h = ' '; 20356416Smpp h1 = h + 1; 20430827Scharnier } 20568716Sru } 20630827Scharnier return res; 20712891Swpaul} 20812891Swpaul# if SASL >= 20000 20924946Sjmg/* 21012891Swpaul** IPTOSTRING -- create string for SASL_IP*PORT property 21124946Sjmg** (borrowed from lib/iptostring.c in Cyrus-IMAP) 21212891Swpaul** 21312891Swpaul** Parameters: 21412891Swpaul** addr -- (pointer to) socket address 21512891Swpaul** addrlen -- length of socket address 21612891Swpaul** out -- output string (result) 21730827Scharnier** outlen -- maximum length of output string 21868716Sru** 21930827Scharnier** Returns: 22030827Scharnier** true iff successful. 22130827Scharnier** 22212891Swpaul** Side Effects: 22312891Swpaul** creates output string if successful. 22414240Swpaul** sets errno if unsuccessful. 22524946Sjmg*/ 22630827Scharnier 22730827Scharnier# include <arpa/inet.h> 22830827Scharnier 22957673Ssheldonh# ifndef NI_WITHSCOPEID 23057673Ssheldonh# define NI_WITHSCOPEID 0 23124946Sjmg# endif 23214240Swpaul# ifndef NI_MAXHOST 23314240Swpaul# define NI_MAXHOST 1025 23414240Swpaul# endif 23514240Swpaul# ifndef NI_MAXSERV 23624946Sjmg# define NI_MAXSERV 32 23714240Swpaul# endif 23814240Swpaul 23924946Sjmgbool 24014240Swpauliptostring(addr, addrlen, out, outlen) 24114240Swpaul SOCKADDR *addr; 24214240Swpaul SOCKADDR_LEN_T addrlen; 24357695Ssheldonh char *out; 24457695Ssheldonh unsigned outlen; 24514240Swpaul{ 24614240Swpaul char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; 24724946Sjmg 24824946Sjmg if (addr == NULL || out == NULL) 24957673Ssheldonh { 25057673Ssheldonh errno = EINVAL; 25114240Swpaul return false; 25214240Swpaul } 25314240Swpaul 25414240Swpaul# if NETINET6 25514240Swpaul if (getnameinfo((struct sockaddr *) addr, addrlen, 25630884Sjseger hbuf, sizeof hbuf, pbuf, sizeof pbuf, 25714240Swpaul NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV) != 0) 25814240Swpaul return false; 25914240Swpaul# else /* NETINET6 */ 26014240Swpaul if (addr->sa.sa_family != AF_INET) 26114240Swpaul { 26214240Swpaul errno = EINVAL; 26314240Swpaul return false; 26424946Sjmg } 26514240Swpaul if (sm_strlcpy(hbuf, inet_ntoa(addr->sin.sin_addr), sizeof(hbuf)) 26657673Ssheldonh >= sizeof(hbuf)) 26757673Ssheldonh { 26814240Swpaul errno = ENOMEM; 26957673Ssheldonh return false; 27057673Ssheldonh } 27114240Swpaul sm_snprintf(pbuf, sizeof pbuf, "%d", ntohs(addr->sin.sin_port)); 27214240Swpaul# endif /* NETINET6 */ 27324946Sjmg 27414240Swpaul if (outlen < strlen(hbuf) + strlen(pbuf) + 2) 27514240Swpaul { 27624946Sjmg errno = ENOMEM; 27724946Sjmg return false; 27899968Scharnier } 27924946Sjmg sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf); 28090321Smarkm return true; 28157673Ssheldonh} 28281462Sru# endif /* SASL >= 20000 */ 28381462Sru#endif /* SASL */ 28414240Swpaul