sasl.c revision 98121
190792Sgshapiro/* 294334Sgshapiro * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * By using this file, you agree to the terms and conditions set 690792Sgshapiro * forth in the LICENSE file which can be found at the top level of 790792Sgshapiro * the sendmail distribution. 890792Sgshapiro * 990792Sgshapiro */ 1090792Sgshapiro 1194334Sgshapiro#include <sm/gen.h> 1298121SgshapiroSM_RCSID("@(#)$Id: sasl.c,v 8.18 2002/05/25 00:26:42 gshapiro Exp $") 1394334Sgshapiro 1490792Sgshapiro#if SASL 1590792Sgshapiro# include <stdlib.h> 1690792Sgshapiro# include <sendmail.h> 1790792Sgshapiro# include <errno.h> 1890792Sgshapiro 1990792Sgshapiro/* 2090792Sgshapiro** In order to ensure that storage leaks are tracked, and to prevent 2190792Sgshapiro** conflicts between the sm_heap package and sasl, we tell sasl to 2290792Sgshapiro** use the following heap allocation functions. Unfortunately, 2390792Sgshapiro** the sasl package incorrectly specifies the size of a block 2490792Sgshapiro** using unsigned long: for portability, it should be size_t. 2590792Sgshapiro*/ 2690792Sgshapiro 2790792Sgshapirovoid *sm_sasl_malloc __P((unsigned long)); 2890792Sgshapirostatic void *sm_sasl_calloc __P((unsigned long, unsigned long)); 2990792Sgshapirostatic void *sm_sasl_realloc __P((void *, unsigned long)); 3090792Sgshapirovoid sm_sasl_free __P((void *)); 3190792Sgshapiro 3290792Sgshapiro/* 3398121Sgshapiro** SASLv1: 3490792Sgshapiro** We can't use an rpool for Cyrus-SASL memory management routines, 3590792Sgshapiro** since the encryption/decryption routines in Cyrus-SASL 3690792Sgshapiro** allocate/deallocate a buffer each time. Since rpool 3790792Sgshapiro** don't release memory until the very end, memory consumption is 3890792Sgshapiro** proportional to the size of an e-mail, which is unacceptable. 3990792Sgshapiro*/ 4090792Sgshapiro 4190792Sgshapiro/* 4290792Sgshapiro** SM_SASL_MALLOC -- malloc() for SASL 4390792Sgshapiro** 4490792Sgshapiro** Parameters: 4590792Sgshapiro** size -- size of requested memory. 4690792Sgshapiro** 4790792Sgshapiro** Returns: 4890792Sgshapiro** pointer to memory. 4990792Sgshapiro*/ 5090792Sgshapiro 5190792Sgshapirovoid * 5290792Sgshapirosm_sasl_malloc(size) 5390792Sgshapiro unsigned long size; 5490792Sgshapiro{ 5590792Sgshapiro return sm_malloc((size_t) size); 5690792Sgshapiro} 5790792Sgshapiro 5890792Sgshapiro/* 5990792Sgshapiro** SM_SASL_CALLOC -- calloc() for SASL 6090792Sgshapiro** 6190792Sgshapiro** Parameters: 6290792Sgshapiro** nelem -- number of elements. 6390792Sgshapiro** elemsize -- size of each element. 6490792Sgshapiro** 6590792Sgshapiro** Returns: 6690792Sgshapiro** pointer to memory. 6790792Sgshapiro** 6890792Sgshapiro** Notice: 6990792Sgshapiro** this isn't currently used by SASL. 7090792Sgshapiro*/ 7190792Sgshapiro 7290792Sgshapirostatic void * 7390792Sgshapirosm_sasl_calloc(nelem, elemsize) 7490792Sgshapiro unsigned long nelem; 7590792Sgshapiro unsigned long elemsize; 7690792Sgshapiro{ 7790792Sgshapiro size_t size; 7890792Sgshapiro void *p; 7990792Sgshapiro 8090792Sgshapiro size = (size_t) nelem * (size_t) elemsize; 8190792Sgshapiro p = sm_malloc(size); 8290792Sgshapiro if (p == NULL) 8390792Sgshapiro return NULL; 8490792Sgshapiro memset(p, '\0', size); 8590792Sgshapiro return p; 8690792Sgshapiro} 8790792Sgshapiro 8890792Sgshapiro/* 8990792Sgshapiro** SM_SASL_REALLOC -- realloc() for SASL 9090792Sgshapiro** 9190792Sgshapiro** Parameters: 9290792Sgshapiro** p -- pointer to old memory. 9390792Sgshapiro** size -- size of requested memory. 9490792Sgshapiro** 9590792Sgshapiro** Returns: 9690792Sgshapiro** pointer to new memory. 9790792Sgshapiro*/ 9890792Sgshapiro 9990792Sgshapirostatic void * 10090792Sgshapirosm_sasl_realloc(o, size) 10190792Sgshapiro void *o; 10290792Sgshapiro unsigned long size; 10390792Sgshapiro{ 10490792Sgshapiro return sm_realloc(o, (size_t) size); 10590792Sgshapiro} 10690792Sgshapiro 10790792Sgshapiro/* 10890792Sgshapiro** SM_SASL_FREE -- free() for SASL 10990792Sgshapiro** 11090792Sgshapiro** Parameters: 11190792Sgshapiro** p -- pointer to free. 11290792Sgshapiro** 11390792Sgshapiro** Returns: 11490792Sgshapiro** none 11590792Sgshapiro*/ 11690792Sgshapiro 11790792Sgshapirovoid 11890792Sgshapirosm_sasl_free(p) 11990792Sgshapiro void *p; 12090792Sgshapiro{ 12190792Sgshapiro sm_free(p); 12290792Sgshapiro} 12390792Sgshapiro 12490792Sgshapiro/* 12590792Sgshapiro** SM_SASL_INIT -- sendmail specific SASL initialization 12690792Sgshapiro** 12790792Sgshapiro** Parameters: 12890792Sgshapiro** none. 12990792Sgshapiro** 13090792Sgshapiro** Returns: 13190792Sgshapiro** none 13290792Sgshapiro** 13390792Sgshapiro** Side Effects: 13490792Sgshapiro** installs memory management routines for SASL. 13590792Sgshapiro*/ 13690792Sgshapiro 13790792Sgshapirovoid 13890792Sgshapirosm_sasl_init() 13990792Sgshapiro{ 14090792Sgshapiro sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc, 14190792Sgshapiro sm_sasl_realloc, sm_sasl_free); 14290792Sgshapiro} 14390792Sgshapiro/* 14490792Sgshapiro** INTERSECT -- create the intersection between two lists 14590792Sgshapiro** 14690792Sgshapiro** Parameters: 14790792Sgshapiro** s1, s2 -- lists of items (separated by single blanks). 14890792Sgshapiro** rpool -- resource pool from which result is allocated. 14990792Sgshapiro** 15090792Sgshapiro** Returns: 15190792Sgshapiro** the intersection of both lists. 15290792Sgshapiro*/ 15390792Sgshapiro 15490792Sgshapirochar * 15590792Sgshapirointersect(s1, s2, rpool) 15690792Sgshapiro char *s1, *s2; 15790792Sgshapiro SM_RPOOL_T *rpool; 15890792Sgshapiro{ 15990792Sgshapiro char *hr, *h1, *h, *res; 16090792Sgshapiro int l1, l2, rl; 16190792Sgshapiro 16290792Sgshapiro if (s1 == NULL || s2 == NULL) /* NULL string(s) -> NULL result */ 16390792Sgshapiro return NULL; 16490792Sgshapiro l1 = strlen(s1); 16590792Sgshapiro l2 = strlen(s2); 16690792Sgshapiro rl = SM_MIN(l1, l2); 16790792Sgshapiro res = (char *) sm_rpool_malloc(rpool, rl + 1); 16890792Sgshapiro if (res == NULL) 16990792Sgshapiro return NULL; 17090792Sgshapiro *res = '\0'; 17190792Sgshapiro if (rl == 0) /* at least one string empty? */ 17290792Sgshapiro return res; 17390792Sgshapiro hr = res; 17490792Sgshapiro h1 = s1; 17590792Sgshapiro h = s1; 17690792Sgshapiro 17790792Sgshapiro /* walk through s1 */ 17890792Sgshapiro while (h != NULL && *h1 != '\0') 17990792Sgshapiro { 18090792Sgshapiro /* is there something after the current word? */ 18190792Sgshapiro if ((h = strchr(h1, ' ')) != NULL) 18290792Sgshapiro *h = '\0'; 18390792Sgshapiro l1 = strlen(h1); 18490792Sgshapiro 18590792Sgshapiro /* does the current word appear in s2 ? */ 18690792Sgshapiro if (iteminlist(h1, s2, " ") != NULL) 18790792Sgshapiro { 18890792Sgshapiro /* add a blank if not first item */ 18990792Sgshapiro if (hr != res) 19090792Sgshapiro *hr++ = ' '; 19190792Sgshapiro 19290792Sgshapiro /* copy the item */ 19390792Sgshapiro memcpy(hr, h1, l1); 19490792Sgshapiro 19590792Sgshapiro /* advance pointer in result list */ 19690792Sgshapiro hr += l1; 19790792Sgshapiro *hr = '\0'; 19890792Sgshapiro } 19990792Sgshapiro if (h != NULL) 20090792Sgshapiro { 20190792Sgshapiro /* there are more items */ 20290792Sgshapiro *h = ' '; 20390792Sgshapiro h1 = h + 1; 20490792Sgshapiro } 20590792Sgshapiro } 20690792Sgshapiro return res; 20790792Sgshapiro} 20898121Sgshapiro# if SASL >= 20000 20998121Sgshapiro/* 21098121Sgshapiro** IPTOSTRING -- create string for SASL_IP*PORT property 21198121Sgshapiro** (borrowed from lib/iptostring.c in Cyrus-IMAP) 21298121Sgshapiro** 21398121Sgshapiro** Parameters: 21498121Sgshapiro** addr -- (pointer to) socket address 21598121Sgshapiro** addrlen -- length of socket address 21698121Sgshapiro** out -- output string (result) 21798121Sgshapiro** outlen -- maximum length of output string 21898121Sgshapiro** 21998121Sgshapiro** Returns: 22098121Sgshapiro** true iff successful. 22198121Sgshapiro** 22298121Sgshapiro** Side Effects: 22398121Sgshapiro** creates output string if successful. 22498121Sgshapiro** sets errno if unsuccessful. 22598121Sgshapiro*/ 22698121Sgshapiro 22798121Sgshapiro# include <arpa/inet.h> 22898121Sgshapiro 22998121Sgshapiro# ifndef NI_WITHSCOPEID 23098121Sgshapiro# define NI_WITHSCOPEID 0 23198121Sgshapiro# endif 23298121Sgshapiro# ifndef NI_MAXHOST 23398121Sgshapiro# define NI_MAXHOST 1025 23498121Sgshapiro# endif 23598121Sgshapiro# ifndef NI_MAXSERV 23698121Sgshapiro# define NI_MAXSERV 32 23798121Sgshapiro# endif 23898121Sgshapiro 23998121Sgshapirobool 24098121Sgshapiroiptostring(addr, addrlen, out, outlen) 24198121Sgshapiro SOCKADDR *addr; 24298121Sgshapiro SOCKADDR_LEN_T addrlen; 24398121Sgshapiro char *out; 24498121Sgshapiro unsigned outlen; 24598121Sgshapiro{ 24698121Sgshapiro char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; 24798121Sgshapiro 24898121Sgshapiro if (addr == NULL || out == NULL) 24998121Sgshapiro { 25098121Sgshapiro errno = EINVAL; 25198121Sgshapiro return false; 25298121Sgshapiro } 25398121Sgshapiro 25498121Sgshapiro# if NETINET6 25598121Sgshapiro if (getnameinfo((struct sockaddr *) addr, addrlen, 25698121Sgshapiro hbuf, sizeof hbuf, pbuf, sizeof pbuf, 25798121Sgshapiro NI_NUMERICHOST | NI_WITHSCOPEID | NI_NUMERICSERV) != 0) 25898121Sgshapiro return false; 25998121Sgshapiro# else /* NETINET6 */ 26098121Sgshapiro if (addr->sa.sa_family != AF_INET) 26198121Sgshapiro { 26298121Sgshapiro errno = EINVAL; 26398121Sgshapiro return false; 26498121Sgshapiro } 26598121Sgshapiro if (inet_ntop(AF_INET, &(addr->sin.sin_addr), 26698121Sgshapiro hbuf, sizeof hbuf) == NULL) 26798121Sgshapiro { 26898121Sgshapiro errno = EINVAL; 26998121Sgshapiro return false; 27098121Sgshapiro } 27198121Sgshapiro sm_snprintf(pbuf, sizeof pbuf, "%d", ntohs(addr->sin.sin_port)); 27298121Sgshapiro# endif /* NETINET6 */ 27398121Sgshapiro 27498121Sgshapiro if (outlen < strlen(hbuf) + strlen(pbuf) + 2) 27598121Sgshapiro { 27698121Sgshapiro errno = ENOMEM; 27798121Sgshapiro return false; 27898121Sgshapiro } 27998121Sgshapiro sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf); 28098121Sgshapiro return true; 28198121Sgshapiro} 28298121Sgshapiro# endif /* SASL >= 20000 */ 28390792Sgshapiro#endif /* SASL */ 284