140266059SGregory Neil Shapiro /* 2*5dd76dd0SGregory Neil Shapiro * Copyright (c) 2001-2002 Proofpoint, Inc. and its suppliers. 340266059SGregory Neil Shapiro * All rights reserved. 440266059SGregory Neil Shapiro * 540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set 640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of 740266059SGregory Neil Shapiro * the sendmail distribution. 840266059SGregory Neil Shapiro * 940266059SGregory Neil Shapiro */ 1040266059SGregory Neil Shapiro 1140266059SGregory Neil Shapiro #include <sm/gen.h> 12*5dd76dd0SGregory Neil Shapiro SM_RCSID("@(#)$Id: sasl.c,v 8.24 2013/11/22 20:51:56 ca Exp $") 13605302a5SGregory Neil Shapiro 14605302a5SGregory Neil Shapiro #if SASL 1540266059SGregory Neil Shapiro # include <stdlib.h> 1640266059SGregory Neil Shapiro # include <sendmail.h> 1740266059SGregory Neil Shapiro # include <errno.h> 1840266059SGregory Neil Shapiro 1940266059SGregory Neil Shapiro /* 2040266059SGregory Neil Shapiro ** In order to ensure that storage leaks are tracked, and to prevent 2140266059SGregory Neil Shapiro ** conflicts between the sm_heap package and sasl, we tell sasl to 2240266059SGregory Neil Shapiro ** use the following heap allocation functions. Unfortunately, 23ba00ec3dSGregory Neil Shapiro ** older sasl packages incorrectly specifies the size of a block 2440266059SGregory Neil Shapiro ** using unsigned long: for portability, it should be size_t. 2540266059SGregory Neil Shapiro */ 2640266059SGregory Neil Shapiro 27a944d3c6SHajimu UMEMOTO # if defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a 28a944d3c6SHajimu UMEMOTO # define SM_SASL_SIZE_T size_t 29a944d3c6SHajimu UMEMOTO # else /* defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a */ 30a944d3c6SHajimu UMEMOTO # define SM_SASL_SIZE_T unsigned long 31a944d3c6SHajimu UMEMOTO # endif /* defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a */ 32a944d3c6SHajimu UMEMOTO 33a944d3c6SHajimu UMEMOTO void *sm_sasl_malloc __P((SM_SASL_SIZE_T)); 34a944d3c6SHajimu UMEMOTO static void *sm_sasl_calloc __P((SM_SASL_SIZE_T, SM_SASL_SIZE_T)); 35a944d3c6SHajimu UMEMOTO static void *sm_sasl_realloc __P((void *, SM_SASL_SIZE_T)); 3640266059SGregory Neil Shapiro void sm_sasl_free __P((void *)); 3740266059SGregory Neil Shapiro 3840266059SGregory Neil Shapiro /* 3994c01205SGregory Neil Shapiro ** SASLv1: 4040266059SGregory Neil Shapiro ** We can't use an rpool for Cyrus-SASL memory management routines, 4140266059SGregory Neil Shapiro ** since the encryption/decryption routines in Cyrus-SASL 4240266059SGregory Neil Shapiro ** allocate/deallocate a buffer each time. Since rpool 4340266059SGregory Neil Shapiro ** don't release memory until the very end, memory consumption is 4440266059SGregory Neil Shapiro ** proportional to the size of an e-mail, which is unacceptable. 4540266059SGregory Neil Shapiro */ 4640266059SGregory Neil Shapiro 4740266059SGregory Neil Shapiro /* 4840266059SGregory Neil Shapiro ** SM_SASL_MALLOC -- malloc() for SASL 4940266059SGregory Neil Shapiro ** 5040266059SGregory Neil Shapiro ** Parameters: 5140266059SGregory Neil Shapiro ** size -- size of requested memory. 5240266059SGregory Neil Shapiro ** 5340266059SGregory Neil Shapiro ** Returns: 5440266059SGregory Neil Shapiro ** pointer to memory. 5540266059SGregory Neil Shapiro */ 5640266059SGregory Neil Shapiro 5740266059SGregory Neil Shapiro void * 5840266059SGregory Neil Shapiro sm_sasl_malloc(size) 59a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T size; 6040266059SGregory Neil Shapiro { 6140266059SGregory Neil Shapiro return sm_malloc((size_t) size); 6240266059SGregory Neil Shapiro } 6340266059SGregory Neil Shapiro 6440266059SGregory Neil Shapiro /* 6540266059SGregory Neil Shapiro ** SM_SASL_CALLOC -- calloc() for SASL 6640266059SGregory Neil Shapiro ** 6740266059SGregory Neil Shapiro ** Parameters: 6840266059SGregory Neil Shapiro ** nelem -- number of elements. 6940266059SGregory Neil Shapiro ** elemsize -- size of each element. 7040266059SGregory Neil Shapiro ** 7140266059SGregory Neil Shapiro ** Returns: 7240266059SGregory Neil Shapiro ** pointer to memory. 7340266059SGregory Neil Shapiro ** 7440266059SGregory Neil Shapiro ** Notice: 7540266059SGregory Neil Shapiro ** this isn't currently used by SASL. 7640266059SGregory Neil Shapiro */ 7740266059SGregory Neil Shapiro 7840266059SGregory Neil Shapiro static void * 7940266059SGregory Neil Shapiro sm_sasl_calloc(nelem, elemsize) 80a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T nelem; 81a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T elemsize; 8240266059SGregory Neil Shapiro { 8340266059SGregory Neil Shapiro size_t size; 8440266059SGregory Neil Shapiro void *p; 8540266059SGregory Neil Shapiro 8640266059SGregory Neil Shapiro size = (size_t) nelem * (size_t) elemsize; 8740266059SGregory Neil Shapiro p = sm_malloc(size); 8840266059SGregory Neil Shapiro if (p == NULL) 8940266059SGregory Neil Shapiro return NULL; 9040266059SGregory Neil Shapiro memset(p, '\0', size); 9140266059SGregory Neil Shapiro return p; 9240266059SGregory Neil Shapiro } 9340266059SGregory Neil Shapiro 9440266059SGregory Neil Shapiro /* 9540266059SGregory Neil Shapiro ** SM_SASL_REALLOC -- realloc() for SASL 9640266059SGregory Neil Shapiro ** 9740266059SGregory Neil Shapiro ** Parameters: 9840266059SGregory Neil Shapiro ** p -- pointer to old memory. 9940266059SGregory Neil Shapiro ** size -- size of requested memory. 10040266059SGregory Neil Shapiro ** 10140266059SGregory Neil Shapiro ** Returns: 10240266059SGregory Neil Shapiro ** pointer to new memory. 10340266059SGregory Neil Shapiro */ 10440266059SGregory Neil Shapiro 10540266059SGregory Neil Shapiro static void * 10640266059SGregory Neil Shapiro sm_sasl_realloc(o, size) 10740266059SGregory Neil Shapiro void *o; 108a944d3c6SHajimu UMEMOTO SM_SASL_SIZE_T size; 10940266059SGregory Neil Shapiro { 11040266059SGregory Neil Shapiro return sm_realloc(o, (size_t) size); 11140266059SGregory Neil Shapiro } 11240266059SGregory Neil Shapiro 11340266059SGregory Neil Shapiro /* 11440266059SGregory Neil Shapiro ** SM_SASL_FREE -- free() for SASL 11540266059SGregory Neil Shapiro ** 11640266059SGregory Neil Shapiro ** Parameters: 11740266059SGregory Neil Shapiro ** p -- pointer to free. 11840266059SGregory Neil Shapiro ** 11940266059SGregory Neil Shapiro ** Returns: 12040266059SGregory Neil Shapiro ** none 12140266059SGregory Neil Shapiro */ 12240266059SGregory Neil Shapiro 12340266059SGregory Neil Shapiro void 12440266059SGregory Neil Shapiro sm_sasl_free(p) 12540266059SGregory Neil Shapiro void *p; 12640266059SGregory Neil Shapiro { 12740266059SGregory Neil Shapiro sm_free(p); 12840266059SGregory Neil Shapiro } 12940266059SGregory Neil Shapiro 13040266059SGregory Neil Shapiro /* 13140266059SGregory Neil Shapiro ** SM_SASL_INIT -- sendmail specific SASL initialization 13240266059SGregory Neil Shapiro ** 13340266059SGregory Neil Shapiro ** Parameters: 13440266059SGregory Neil Shapiro ** none. 13540266059SGregory Neil Shapiro ** 13640266059SGregory Neil Shapiro ** Returns: 13740266059SGregory Neil Shapiro ** none 13840266059SGregory Neil Shapiro ** 13940266059SGregory Neil Shapiro ** Side Effects: 14040266059SGregory Neil Shapiro ** installs memory management routines for SASL. 14140266059SGregory Neil Shapiro */ 14240266059SGregory Neil Shapiro 14340266059SGregory Neil Shapiro void 14440266059SGregory Neil Shapiro sm_sasl_init() 14540266059SGregory Neil Shapiro { 14640266059SGregory Neil Shapiro sasl_set_alloc(sm_sasl_malloc, sm_sasl_calloc, 14740266059SGregory Neil Shapiro sm_sasl_realloc, sm_sasl_free); 14840266059SGregory Neil Shapiro } 14940266059SGregory Neil Shapiro /* 15040266059SGregory Neil Shapiro ** INTERSECT -- create the intersection between two lists 15140266059SGregory Neil Shapiro ** 15240266059SGregory Neil Shapiro ** Parameters: 15340266059SGregory Neil Shapiro ** s1, s2 -- lists of items (separated by single blanks). 15440266059SGregory Neil Shapiro ** rpool -- resource pool from which result is allocated. 15540266059SGregory Neil Shapiro ** 15640266059SGregory Neil Shapiro ** Returns: 15740266059SGregory Neil Shapiro ** the intersection of both lists. 15840266059SGregory Neil Shapiro */ 15940266059SGregory Neil Shapiro 16040266059SGregory Neil Shapiro char * 16140266059SGregory Neil Shapiro intersect(s1, s2, rpool) 16240266059SGregory Neil Shapiro char *s1, *s2; 16340266059SGregory Neil Shapiro SM_RPOOL_T *rpool; 16440266059SGregory Neil Shapiro { 16540266059SGregory Neil Shapiro char *hr, *h1, *h, *res; 16640266059SGregory Neil Shapiro int l1, l2, rl; 16740266059SGregory Neil Shapiro 16840266059SGregory Neil Shapiro if (s1 == NULL || s2 == NULL) /* NULL string(s) -> NULL result */ 16940266059SGregory Neil Shapiro return NULL; 17040266059SGregory Neil Shapiro l1 = strlen(s1); 17140266059SGregory Neil Shapiro l2 = strlen(s2); 17240266059SGregory Neil Shapiro rl = SM_MIN(l1, l2); 17340266059SGregory Neil Shapiro res = (char *) sm_rpool_malloc(rpool, rl + 1); 17440266059SGregory Neil Shapiro if (res == NULL) 17540266059SGregory Neil Shapiro return NULL; 17640266059SGregory Neil Shapiro *res = '\0'; 17740266059SGregory Neil Shapiro if (rl == 0) /* at least one string empty? */ 17840266059SGregory Neil Shapiro return res; 17940266059SGregory Neil Shapiro hr = res; 18040266059SGregory Neil Shapiro h1 = s1; 18140266059SGregory Neil Shapiro h = s1; 18240266059SGregory Neil Shapiro 18340266059SGregory Neil Shapiro /* walk through s1 */ 18440266059SGregory Neil Shapiro while (h != NULL && *h1 != '\0') 18540266059SGregory Neil Shapiro { 18640266059SGregory Neil Shapiro /* is there something after the current word? */ 18740266059SGregory Neil Shapiro if ((h = strchr(h1, ' ')) != NULL) 18840266059SGregory Neil Shapiro *h = '\0'; 18940266059SGregory Neil Shapiro l1 = strlen(h1); 19040266059SGregory Neil Shapiro 19140266059SGregory Neil Shapiro /* does the current word appear in s2 ? */ 19240266059SGregory Neil Shapiro if (iteminlist(h1, s2, " ") != NULL) 19340266059SGregory Neil Shapiro { 19440266059SGregory Neil Shapiro /* add a blank if not first item */ 19540266059SGregory Neil Shapiro if (hr != res) 19640266059SGregory Neil Shapiro *hr++ = ' '; 19740266059SGregory Neil Shapiro 19840266059SGregory Neil Shapiro /* copy the item */ 19940266059SGregory Neil Shapiro memcpy(hr, h1, l1); 20040266059SGregory Neil Shapiro 20140266059SGregory Neil Shapiro /* advance pointer in result list */ 20240266059SGregory Neil Shapiro hr += l1; 20340266059SGregory Neil Shapiro *hr = '\0'; 20440266059SGregory Neil Shapiro } 20540266059SGregory Neil Shapiro if (h != NULL) 20640266059SGregory Neil Shapiro { 20740266059SGregory Neil Shapiro /* there are more items */ 20840266059SGregory Neil Shapiro *h = ' '; 20940266059SGregory Neil Shapiro h1 = h + 1; 21040266059SGregory Neil Shapiro } 21140266059SGregory Neil Shapiro } 21240266059SGregory Neil Shapiro return res; 21340266059SGregory Neil Shapiro } 21494c01205SGregory Neil Shapiro # if SASL >= 20000 21594c01205SGregory Neil Shapiro /* 21694c01205SGregory Neil Shapiro ** IPTOSTRING -- create string for SASL_IP*PORT property 21794c01205SGregory Neil Shapiro ** (borrowed from lib/iptostring.c in Cyrus-IMAP) 21894c01205SGregory Neil Shapiro ** 21994c01205SGregory Neil Shapiro ** Parameters: 22094c01205SGregory Neil Shapiro ** addr -- (pointer to) socket address 22194c01205SGregory Neil Shapiro ** addrlen -- length of socket address 22294c01205SGregory Neil Shapiro ** out -- output string (result) 22394c01205SGregory Neil Shapiro ** outlen -- maximum length of output string 22494c01205SGregory Neil Shapiro ** 22594c01205SGregory Neil Shapiro ** Returns: 22694c01205SGregory Neil Shapiro ** true iff successful. 22794c01205SGregory Neil Shapiro ** 22894c01205SGregory Neil Shapiro ** Side Effects: 22994c01205SGregory Neil Shapiro ** creates output string if successful. 23094c01205SGregory Neil Shapiro ** sets errno if unsuccessful. 23194c01205SGregory Neil Shapiro */ 23294c01205SGregory Neil Shapiro 23394c01205SGregory Neil Shapiro # include <arpa/inet.h> 23494c01205SGregory Neil Shapiro 23594c01205SGregory Neil Shapiro # ifndef NI_MAXHOST 23694c01205SGregory Neil Shapiro # define NI_MAXHOST 1025 23794c01205SGregory Neil Shapiro # endif 23894c01205SGregory Neil Shapiro # ifndef NI_MAXSERV 23994c01205SGregory Neil Shapiro # define NI_MAXSERV 32 24094c01205SGregory Neil Shapiro # endif 24194c01205SGregory Neil Shapiro 24294c01205SGregory Neil Shapiro bool 24394c01205SGregory Neil Shapiro iptostring(addr, addrlen, out, outlen) 24494c01205SGregory Neil Shapiro SOCKADDR *addr; 24594c01205SGregory Neil Shapiro SOCKADDR_LEN_T addrlen; 24694c01205SGregory Neil Shapiro char *out; 24794c01205SGregory Neil Shapiro unsigned outlen; 24894c01205SGregory Neil Shapiro { 24994c01205SGregory Neil Shapiro char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; 250b6bacd31SGregory Neil Shapiro # if NETINET6 251b6bacd31SGregory Neil Shapiro int niflags; 252b6bacd31SGregory Neil Shapiro # endif /* NETINET6 */ 25394c01205SGregory Neil Shapiro 25494c01205SGregory Neil Shapiro if (addr == NULL || out == NULL) 25594c01205SGregory Neil Shapiro { 25694c01205SGregory Neil Shapiro errno = EINVAL; 25794c01205SGregory Neil Shapiro return false; 25894c01205SGregory Neil Shapiro } 25994c01205SGregory Neil Shapiro 26094c01205SGregory Neil Shapiro # if NETINET6 261b6bacd31SGregory Neil Shapiro niflags = (NI_NUMERICHOST | NI_NUMERICSERV); 262b6bacd31SGregory Neil Shapiro # ifdef NI_WITHSCOPEID 263b6bacd31SGregory Neil Shapiro if (addr->sa.sa_family == AF_INET6) 264b6bacd31SGregory Neil Shapiro niflags |= NI_WITHSCOPEID; 265b6bacd31SGregory Neil Shapiro # endif /* NI_WITHSCOPEID */ 26694c01205SGregory Neil Shapiro if (getnameinfo((struct sockaddr *) addr, addrlen, 267d0cef73dSGregory Neil Shapiro hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags) != 0) 26894c01205SGregory Neil Shapiro return false; 26994c01205SGregory Neil Shapiro # else /* NETINET6 */ 27094c01205SGregory Neil Shapiro if (addr->sa.sa_family != AF_INET) 27194c01205SGregory Neil Shapiro { 27294c01205SGregory Neil Shapiro errno = EINVAL; 27394c01205SGregory Neil Shapiro return false; 27494c01205SGregory Neil Shapiro } 275739ac4d4SGregory Neil Shapiro if (sm_strlcpy(hbuf, inet_ntoa(addr->sin.sin_addr), sizeof(hbuf)) 276739ac4d4SGregory Neil Shapiro >= sizeof(hbuf)) 27794c01205SGregory Neil Shapiro { 278739ac4d4SGregory Neil Shapiro errno = ENOMEM; 27994c01205SGregory Neil Shapiro return false; 28094c01205SGregory Neil Shapiro } 281d0cef73dSGregory Neil Shapiro sm_snprintf(pbuf, sizeof(pbuf), "%d", ntohs(addr->sin.sin_port)); 28294c01205SGregory Neil Shapiro # endif /* NETINET6 */ 28394c01205SGregory Neil Shapiro 28494c01205SGregory Neil Shapiro if (outlen < strlen(hbuf) + strlen(pbuf) + 2) 28594c01205SGregory Neil Shapiro { 28694c01205SGregory Neil Shapiro errno = ENOMEM; 28794c01205SGregory Neil Shapiro return false; 28894c01205SGregory Neil Shapiro } 28994c01205SGregory Neil Shapiro sm_snprintf(out, outlen, "%s;%s", hbuf, pbuf); 29094c01205SGregory Neil Shapiro return true; 29194c01205SGregory Neil Shapiro } 29294c01205SGregory Neil Shapiro # endif /* SASL >= 20000 */ 29340266059SGregory Neil Shapiro #endif /* SASL */ 294