New mailsend

This commit is contained in:
Olusesan Ameye
2020-07-24 12:20:50 -04:00
parent c1c731c9e9
commit 5b946a5b00
20 changed files with 3898 additions and 656 deletions
+71 -16
View File
@@ -2,9 +2,30 @@
# Makefile automatically generated by genmake 1.0, May-03-00
# genmake 1.0 by muquit@muquit.com, http://www.muquit.com/
##
srcdir = .
top_srcdir = .
CC= gcc
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1 -DUNIX
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_LIMITS_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_GETADDRINFO=1 -DUNIX
PROGNAME= mailsend
INSTALL = /usr/bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
DESTDIR =
prefix = /usr/local
exec_prefix = ${prefix}
datarootdir = ${prefix}/share
datadir = ${datarootdir}
bindir = ${exec_prefix}/bin
mandir = ${datarootdir}/man
man1dir = $(mandir)/man1
BINDIR = $(DESTDIR)$(bindir)
MAN1DIR = $(DESTDIR)$(man1dir)
#BINDIR= /usr/bin
MANPAGE= doc/mailsend.1.gz
#MANDIR= /usr/share/man/man1
MUTILS_INCLUDE= -I./libs/libmutils
MSOCK_INCLUDE= -I./libs/libmsock
@@ -14,38 +35,72 @@ MUTILS_LIB= ./libs/libmutils/libmutils.a
MSOCK_LIB=./libs/libmsock/libmsock.a
SLL_LIB= ./libs/libsll/libsll.a
OPENSSL_DIR=/usr/
OPENSSL_INC=-I/usr/include
#OPENSSL_LIBS=-L/usr/lib -lssl -lcrypto -ldl
OPENSSL_DIR=
OPENSSL_INC=
OPENSSL_LIBS=
INCLUDES= -I. -I/usr/include/malloc $(MUTILS_INCLUDE) $(MSOCK_INCLUDE) $(SLL_INCLUDE) $(OPENSSL_INC)
STRIP=/usr/bin/strip
INCLUDES= -I. $(MUTILS_INCLUDE) $(MSOCK_INCLUDE) $(SLL_INCLUDE) $(OPENSSL_INC)
DEFINES= $(INCLUDES) $(DEFS) -DHAVE_STRING_H=1 -DHAVE_STDLIB_H=1 \
-DHAVE_MATH_H=1
CFLAGS= -g -O2 -Wall $(DEFINES)
LIBS=$(MSOCK_LIB) $(SLL_LIB) $(MUTILS_LIB) -L/usr/lib -lssl -lcrypto -ldl
LIBS=$(MSOCK_LIB) $(SLL_LIB) $(MUTILS_LIB) $(OPENSSL_LIBS) -lresolv
SRCS = main.c smtp.c utils.c setget.c
OBJS = main.o smtp.o utils.o setget.o
SRCS = main.c smtp.c utils.c setget.c examples.c
OBJS = main.o smtp.o utils.o setget.o examples.o
.c.o:
rm -f $@
$(CC) $(CFLAGS) -c $*.c
all: mlibs $(PROGNAME)
all: $(PROGNAME)
$(PROGNAME) : $(OBJS)
$(PROGNAME) : mlibs $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(PROGNAME) $(LIBS)
cp -f $(PROGNAME) ../modules/
mlibs:
install: installdirs install-bin install-man
install-bin: $(BINDIR) $(PROGNAME)
$(INSTALL_PROGRAM) $(PROGNAME) $(BINDIR)/$(PROGNAME)
install-man:
$(INSTALL_DATA) $(MANPAGE) $(MAN1DIR)
installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir}
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1
deb:
@ruby ./mk_debian_package.rb
help:
@echo "make - to compile"
@echo "make install - to install"
@echo "make docs - generate document"
@echo "make deb - create debian package"
docs:
@ruby scripts/mk_doc.rb
ex:
@ruby scripts/mk_examples.rb > examples.c
libmsock: libmutils
(cd libs/libmsock && make)
libmutils:
(cd libs/libmutils && make)
(cd libs/libsll && make)
libsll:
(cd libs/libsll && make)
mlibs: libmsock libsll
clean:
(cd libs/libmsock && make clean)
(cd libs/libmutils && make clean)
(cd libs/libsll && make clean)
+(cd libs/libmsock && make clean)
+(cd libs/libmutils && make clean)
+(cd libs/libsll && make clean)
rm -f *.o *~ core $(PROGNAME)
+5 -5
View File
@@ -3,16 +3,16 @@
# genmake 1.0 by ma_muquit@fccc.edu, RCS
##
CC= gcc
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_LIMITS_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_GETADDRINFO=1
AR= ar cq
RANLIB= ranlib
LIBNAME= libmsock.a
OPENSSL_DIR=/usr/
OPENSSL_INC=-I/usr//include
OPENSSL_LIBS=-L/usr//lib -lssl -lcrypto
OPENSSL_DIR=
OPENSSL_INC=
OPENSSL_LIBS=
INCLUDES= -I. -I/usr/include/malloc $(OPENSSL_INC)
INCLUDES= -I. $(OPENSSL_INC)
DEFINES= $(INCLUDES) $(DEFS) -DSYS_UNIX=1
CFLAGS= -O $(DEFINES)
+443 -22
View File
@@ -9,6 +9,29 @@ static SSL *s_ssl=NULL;
static SOCKET s_sock;
static int ssl_status=0;
static FILE *s_logfp = NULL;
#ifdef WINNT
#undef UNICODE
#endif /* WINNT */
static int debug = 0;
void msock_set_logfp(FILE *logfp)
{
if (logfp != NULL)
{
s_logfp = logfp;
}
else
{
s_logfp = stderr;
}
}
void msock_set_debug(int d)
{
debug = d;
}
void msock_set_socket(SOCKET sfd)
{
@@ -63,7 +86,37 @@ struct in_addr *atoAddr(char *address)
return ((struct in_addr *) NULL);
}
#ifdef WINNT
void msock_print_winsock_error(void)
{
int
error_code = WSAGetLastError();
LPSTR
error_string = NULL;
if (s_logfp == NULL)
{
s_logfp = stderr;
}
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error_code,
0,
(LPSTR) &error_string,
0,
0);
(void) fprintf(s_logfp,"Winsock error[%d]: %s\n",
error_code,
error_string);
LocalFree(error_string);
return;
}
/* returns 0 on success -1 on failure */
int initWinSock(void)
{
@@ -76,23 +129,149 @@ int initWinSock(void)
int
err;
version_requested=MAKEWORD(2,0);
version_requested=MAKEWORD(2,2);
err=WSAStartup(version_requested,&wsa_data);
if (err != 0)
{
(void) fprintf(stderr," Unable to initialize winsock (%d)\n",err);
msock_print_error();
return(-1);
}
return(0);
}
/*
** Adapted from libevent2
*/
int msock_get_errno(SOCKET sock_fd)
{
int
optval,
optvallen = sizeof(optval);
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK && sock_fd >= 0)
{
if (getsockopt(sock_fd, SOL_SOCKET, SO_ERROR, (void*)&optval,
&optvallen))
return err;
if (optval)
return optval;
}
return err;
}
#endif /* WINNT */
/* returns SOCKET on success INVALID_SOCKET on failure */
SOCKET clientSocket(char *address,int port)
void msock_print_error(void)
{
if (s_logfp == NULL)
{
s_logfp = stderr;
}
#ifdef WINNT
msock_print_winsock_error();
#else
(void) fprintf(s_logfp,"Socket Error: [%d]: %s\n",
errno,
strerror(errno));
#endif /* WINNT */
}
#ifdef HAVE_GETADDRINFO
void msock_print_ipaddr(struct addrinfo *res)
{
#ifdef WINNT
INT
iRetval;
struct sockaddr_in
*sockaddr_ipv4;
LPSOCKADDR
sockaddr_ip;
char
ipstringbuffer[46];
DWORD
ipbufferlength = 46;
#else
struct sockaddr
*sa;
char
buf[1024];
#endif /* WINNT */
if (res == NULL) return;
if (debug == 0) return;
#ifdef WINNT
/*
** Ref: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738520%28v=vs.85%29.aspx
*/
sockaddr_ip = (LPSOCKADDR) res->ai_addr;
ipbufferlength = 46;
iRetval = WSAAddressToString(sockaddr_ip, (DWORD) res->ai_addrlen, NULL,
ipstringbuffer, &ipbufferlength );
if (iRetval)
{
(void) fprintf(stderr," WSAAddressToString failed with %u\n",
WSAGetLastError() );
}
else
{
if (debug)
{
(void) fprintf(stderr," IP address: %s\n",ipstringbuffer);
}
}
#else
sa = (struct sockaddr *) res->ai_addr;
switch (sa->sa_family)
{
case AF_INET:
{
inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
buf,sizeof(buf) - 1);
if (debug)
{
(void) fprintf(stderr," IPv4 address: %s\n",buf);
}
break;
}
case AF_INET6:
{
inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
buf,sizeof(buf) - 1);
if (debug)
{
(void) fprintf(stderr," IPv6 address: %s\n",buf);
}
break;
}
default:
{
(void) fprintf(stderr,"Error: Uknown AF family\n");
}
}
#endif /* WINNT */
}
#else
void msock_print_ipaddr(void *res)
{
;
}
#endif /* HAVE_GETADDRINFO */
/*
** It is assumed that the socket is a blocking socket. In order to
** timeout the connect(), socket is made non-blocking and changed
** back to blocking after a successful connect, because lot of other calls
** are blocking. Someday I might change everything to non-blocking.
**
** returns a blocking SOCKET on success INVALID_SOCKET on failure
*/
SOCKET clientSocket(int use, char *address,int port, int connect_timeout)
{
SOCKET
s;
sock_fd;
struct sockaddr_in
sa;
@@ -100,46 +279,205 @@ SOCKET clientSocket(char *address,int port)
struct in_addr
*addr;
struct timeval
tv;
fd_set
fdset;
int
eno,
rc;
#ifdef HAVE_GETADDRINFO
char
service[64];
struct addrinfo
hints,
*cur,
*res,
*ressave;
#endif /* HAVE_GETADDRINFO */
#ifdef WINNT
rc=initWinSock();
if (rc != 0)
return(INVALID_SOCKET);
#endif /* WINNT */
addr=atoAddr(address);
if (addr == NULL)
#ifdef HAVE_GETADDRINFO
if (debug)
{
(void) fprintf(stderr," Invalid address: %s\n",address);
(void) fprintf(stderr,"> libmsock: using getaddrinfo\n");
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = PF_UNSPEC;
if (use == MSOCK_USE_IPV4)
{
hints.ai_family = PF_INET;
}
if (use == MSOCK_USE_IPV6)
{
hints.ai_family = PF_INET6;
}
(void) snprintf(service, sizeof(service) -1, "%d", port);
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
rc = getaddrinfo(address, service, &hints, &res);
if (rc != 0)
{
(void) fprintf(stderr,"Error: Could not find host \"%s\"\n",address);
return(INVALID_SOCKET);
}
ressave = res;
rc = (-1);
for (cur=res; cur != NULL; cur = cur->ai_next)
{
if (debug)
{
switch (cur->ai_family)
{
case AF_UNSPEC:
{
if (debug)
{
(void) fprintf(stderr,"> AF_UNSPEC\n");
}
break;
}
case AF_INET:
{
if (debug)
{
(void) fprintf(stderr,"> AF_INET IPv4\n");
}
break;
}
case AF_INET6:
{
if (debug)
{
(void) fprintf(stderr,"> AF_INET6\n");
}
break;
}
}
msock_print_ipaddr(cur);
}
sock_fd = socket(cur->ai_family,
cur->ai_socktype,
cur->ai_protocol);
if (sock_fd >= 0)
{
msock_make_socket_nonblocking(sock_fd);
/*
** Try the current addrinfo
** Patch by https://code.google.com/p/mailsend/issues/detail?id=34
*/
rc = connect(sock_fd, cur->ai_addr, cur->ai_addrlen);
eno = msock_get_errno(sock_fd);
if (debug)
{
(void) fprintf(stderr,"> EINPROGRESS=%d,EWOULDBLOCK=%d\n",
EINPROGRESS,EWOULDBLOCK);
(void) fprintf(stderr,"> connect(): socket=%d,rc=%d, errno=%d\n",
sock_fd,rc,eno);
}
if (rc != 0)
{
if (eno == EINPROGRESS ||
eno == EWOULDBLOCK)
{
/*
** our socket is non blocking.
** we need this to timout connection .
** we'll make the socket blocking again at the end
*/
rc = 0;
if (debug)
{
(void) fprintf(stderr,"> Try socket %d\n",sock_fd);
}
break;
}
}
else
{
msock_close_socket(sock_fd);
}
}
}
freeaddrinfo(ressave);
if (rc != 0)
{
(void) fprintf(stderr,"Could not connect to %s:%d\n",address,port);
return(INVALID_SOCKET);
}
#else
addr=atoAddr(address);
if (addr == NULL)
{
(void) fprintf(stderr,"Error: Invalid address: %s\n",address);
return(INVALID_SOCKET);
}
memset((char *) &sa,0,sizeof(sa));
sa.sin_family=AF_INET;
sa.sin_port=htons(port);
sa.sin_addr.s_addr=addr->s_addr;
/* open the socket */
s=socket(AF_INET,SOCK_STREAM,PF_UNSPEC);
if (s == INVALID_SOCKET)
sock_fd=socket(AF_INET,SOCK_STREAM,PF_UNSPEC);
if (sock_fd == INVALID_SOCKET)
{
(void) fprintf(stderr," Could not create socket\n");
return(INVALID_SOCKET);
}
/* make the socket non-blocking */
msock_make_socket_nonblocking(sock_fd);
rc=connect(sock_fd,(struct sockaddr *) &sa,sizeof(sa));
#endif /* HAVE_GETADDRINFO */
/* connect */
rc=connect(s,(struct sockaddr *) &sa,sizeof(sa));
if (rc < 0)
return(INVALID_SOCKET);
if (rc != 0 )
{
eno = msock_get_errno(sock_fd);
if (eno == ECONNREFUSED)
{
msock_print_error();
msock_close_socket(sock_fd);
return(INVALID_SOCKET);
}
}
FD_ZERO(&fdset);
FD_SET(sock_fd, &fdset);
return(s);
tv.tv_sec = connect_timeout;
tv.tv_usec = 0;
rc = select(sock_fd + 1, NULL, &fdset, NULL, &tv);
if (rc == -1)
{
(void) fprintf(stderr,"Fatal select() error\n");
msock_close_socket(sock_fd);
return (INVALID_SOCKET);
}
if (rc == 0)
{
(void) fprintf(stderr,"Error: Connection to %s:%d timed out after %d seconds\n",
address, port, connect_timeout);
msock_close_socket(sock_fd);
return (INVALID_SOCKET);
}
/* make the socket blocking again*/
msock_make_socket_blocking(sock_fd);
return(sock_fd);
}
/*
** this function writes a character string out to a socket.
** it returns -1 if the connection is closed while it is trying to
@@ -201,12 +539,12 @@ int sockPuts(SOCKET sock,char *str)
return (sockWrite(sock,str,strlen(str)));
}
int sockGets(SOCKET sockfd,char *str,size_t count)
int sockGets(SOCKET sockfd,char *str,size_t count, int read_timeout)
{
int
bytesRead;
int
size_t
totalCount=0;
char
@@ -216,6 +554,34 @@ int sockGets(SOCKET sockfd,char *str,size_t count)
char
lastRead=0;
#if defined(SO_RCVTIMEO)
struct timeval
tv;
#ifdef WINNT
DWORD
dwTime = read_timeout * 1000;
#endif /* WINNT */
#endif /* SO_RCVTIMEO*/
#if defined(SO_RCVTIMEO)
tv.tv_sec = read_timeout;
tv.tv_usec = 0;
if (debug)
{
(void) fprintf(stderr,"> Setting read timeout to: %d seconds\n", read_timeout);
}
#ifndef WINNT
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
#else
if (debug)
{
(void) fprintf(stderr,"> Windows Setting read timeout to: %d seconds\n", read_timeout);
}
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&dwTime, sizeof(dwTime));
#endif
#endif /* SO_RCVTIMEO*/
currentPosition=str;
while (lastRead != 10)
@@ -226,6 +592,8 @@ int sockGets(SOCKET sockfd,char *str,size_t count)
/*
** the other side may have closed unexpectedly
*/
msock_print_error();
(void) fprintf(stderr,"Error: Connection is closed unexpectedly\n");
return (-1);
}
lastRead=buf[0];
@@ -249,7 +617,7 @@ int sockGetsSSL(SSL *ssl,char *str,size_t count)
int
bytesRead;
int
size_t
totalCount=0;
char
@@ -268,6 +636,8 @@ int sockGetsSSL(SSL *ssl,char *str,size_t count)
/*
** the other side may have closed unexpectedly
*/
msock_print_error();
(void) fprintf(stderr,"Error: Connection is closed unexpectedly\n");
return (-1);
}
lastRead=buf[0];
@@ -289,11 +659,11 @@ int sockGetsSSL(SSL *ssl,char *str,size_t count)
/* must be called after msock_set_socket() */
/* must be called after msock_set_ssl() if SSL is on */
int msock_gets(char *str,size_t count)
int msock_gets(char *str,size_t count, int read_timeout)
{
if (! msock_is_ssl_on())
{
return(sockGets(msock_get_socket(),str,count));
return(sockGets(msock_get_socket(),str,count, read_timeout));
}
else
{
@@ -335,3 +705,54 @@ void msock_close(void)
msock_close_socket(msock_get_socket());
}
/*
** Make a socket non-blocking
*/
void msock_make_socket_nonblocking(SOCKET sock_fd)
{
#ifndef WINNT
int
flags;
#else
unsigned long
mode = 1L;
#endif /* WINNT */
if (sock_fd == INVALID_SOCKET)
{
return;
}
#ifdef WINNT
ioctlsocket(sock_fd, FIONBIO, &mode);
#else
/* Stevens: Page 411 */
flags = fcntl(sock_fd, F_GETFL);
fcntl(sock_fd, F_SETFL, (flags | O_NONBLOCK));
#endif /* WINNT */
}
/*
** Make a socket blocking
*/
void msock_make_socket_blocking(SOCKET sock_fd)
{
#ifndef WINNT
int
flags;
#else
unsigned long
mode = 0L;
#endif /* WINNT */
if (sock_fd == INVALID_SOCKET)
{
return;
}
#ifdef WINNT
ioctlsocket(sock_fd, FIONBIO, &mode);
#else
/* Stevens: Page 411 */
flags = fcntl(sock_fd, F_GETFL);
fcntl(sock_fd, F_SETFL, (flags & ~O_NONBLOCK));
#endif /* WINNT */
}
+31 -5
View File
@@ -8,8 +8,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <windows.h>
/*#include <windows.h>*/
#include <winsock2.h>
/* http://support.microsoft.com/kb/955045 */
/* for getaddrinfo in win2k */
#include <ws2tcpip.h>
#include <wspiapi.h>
#define snprintf _snprintf
#else
#include <stdio.h>
@@ -53,8 +58,17 @@
#endif /* HAVE_OPENSSL */
SOCKET clientSocket(char *,int);
int sockGets(SOCKET,char *,size_t);
#include "werrno.h"
#define MSOCK_USE_IPV4 0x01
#define MSOCK_USE_IPV6 0x02
#define MSOCK_USE_AUTO 0x03
/**
* familty can be USE_IPV4, USE_IPV6 or USE_AUTO
*/
SOCKET clientSocket(int use, char *server_addr,int port, int connect_timeout);
int sockGets(SOCKET,char *,size_t, int read_timoeut);
int sockPuts(SOCKET sock,char *str);
void msock_set_socket(SOCKET sock);
@@ -62,10 +76,22 @@ SOCKET msock_get_socket(void);
void msock_turn_ssl_on(void);
void msock_turn_ssl_off(void);
int msock_is_ssl_on(void);
int msock_gets(char *buf,size_t bufsiz);
int msock_gets(char *buf,size_t bufsiz, int connect_timeout);
int msock_puts(char *str);
void msock_close_socket(SOCKET fd);
void msock_close(void);
void msock_make_socket_nonblocking(SOCKET sock_fd);
void msock_make_socket_blocking(SOCKET sock_fd);
void msock_print_error(void);
void msock_set_logfp(FILE *logfp);
void msock_set_debug(int debug);
#ifdef WINNT
int msock_get_errno(SOCKET sock_fd);
#else
#define msock_get_errno(sock_fd) (errno)
#endif /* WINNT */
#ifdef HAVE_OPENSSL
+10 -9
View File
@@ -1,23 +1,24 @@
#
# ma_muquit@fccc.edu
# jul-29-199
#
# jul-29-1999
CC= gcc
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_LIMITS_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_GETADDRINFO=1
AR= ar cq
RANLIB= ranlib
LIBNAME= libmutils.a
INCLUDES= -I. -I/usr/include/malloc
OPENSSL_DIR=
OPENSSL_INC=
OPENSSL_LIBS=
# replace -O with -g in order to debug
INCLUDES= -I. $(OPENSSL_INC)
DEFINES= $(INCLUDES) $(DEFS) -DSYS_UNIX=1
CFLAGS= -O $(DEFINES)
SRCS = string.c mutils.c mime.c
OBJS = string.o mutils.o mime.o
SRCS = string.c mutils.c mutils_mime.c mutils_blob.c \
mutils_error.c mutils_temp.c mutils_time.c
OBJS = string.o mutils.o mutils_mime.o mutils_blob.o \
mutils_error.o mutils_temp.o mutils_time.o
.c.o:
rm -f $@
View File
View File
+750 -12
View File
@@ -6,6 +6,263 @@
static int
lock_fd=(-1);
static const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* taken from Parrot code */
const char Parrot_utf8skip[256] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ascii */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* bogus */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* bogus */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* bogus */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* bogus */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* scripts */
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* scripts */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* cjk etc. */
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6 /* cjk etc. */
};
#define UTF8_IS_START(c) ((c) >= 0xC2 && (c) <= 0xF4)
#define UTF8SKIP(c) Parrot_utf8skip[c]
#define UTF8_IS_CONTINUATION(c) (((c) & 0xC0) == 0x80)
void mutils_liberate_memory(void **memory)
{
if (memory == NULL)
return;
if (*memory)
free(*memory);
*memory=(void *) NULL;
}
void mutils_liberate(void **memory)
{
if (memory == NULL)
return;
if (*memory)
free(*memory);
*memory=(void *) NULL;
}
void mutils_free_zero(void *buf,int size)
{
if (buf)
{
memset(buf,0,size);
mutils_liberate_memory(&buf);
}
}
/**
* @brief same as mutils_acquire_memory
*/
void *mutils_acquire_memory(size_t size)
{
void
*ptr;
if (size == 0)
{
mutils_error("%s (%d) - allocation size is specified as 0\n",MUTILS_CFL);
return(NULL);
}
ptr=malloc(size);
if (ptr)
{
memset(ptr,0,size);
}
return(ptr);
}
/*
** changes the size of the memory and returns a pointer to the (possibly
** moved) block. The contents will be unchanged up to the lesser of the new
** and old sizes.
*/
void mutils_reacquire_memory(void **memory,const size_t size)
{
void
*allocation;
if (memory == NULL)
return;
if (*memory == (void *) NULL)
{
*memory=mutils_acquire_memory(size);
return;
}
allocation=realloc(*memory,size);
if (allocation == (void *) NULL)
mutils_liberate_memory((void **) memory);
*memory=allocation;
}
/* from my hod program, muquit, Nov-10-2000 */
static void mutils_hex_or_oct_dump(FILE *fp,int base,unsigned char *buf,int length)
{
int
ii,
i;
unsigned char
hexbuf[16];
int
count=0;
int
line = 0;
int
c;
unsigned char
*p=buf;
if (length <= 0)
return;
*hexbuf='\0';
(void) fprintf (fp,
(base == 16) ? "%11d" : "%11d",0);
(void) fflush (fp);
for (i=1; i<base;i++)
{
(void) fprintf (fp,
(base == 16) ? "%3x" : "%4o", i);
}
(void) fprintf (fp,
(base == 16) ? " " : " ");
for (i=0; i <base; i++)
{
(void) fprintf (fp, "%x", i);
}
(void) fprintf (fp,"\n");
for (ii=0; ii < length; ii++, p++)
{
c=*p;
hexbuf[count] = (unsigned char) c;
if (count++ == 0)
{
if (base == 16)
{
/*
(void) fprintf (fp, "%8x: ",line * 0x10);
*/
/* print offset in decimal */
(void) fprintf(fp,"%8d: ",line * base);
}
else
{
(void) fprintf (fp, "%8o: ",line * 0x08);
}
}
(void) fprintf (fp,
(base == 16) ? "%02x " : "%03o ", hexbuf[count-1]);
if (count == base)
{
(void) fprintf (fp," ");
for (i=0; i <base; i++)
{
/* 127 is non-printable - muquit@muquit.com Oct-03-2002 */
if (hexbuf[i] >= 32 && hexbuf[i] < 127)
(void) fprintf (fp,"%c", hexbuf[i]);
else
(void) fprintf (fp,".");
}
count=0;
line++;
(void) fprintf (fp,"\n");
}
} /* while c!= EOF*/
(void) fflush (fp);
/*
** pad if necessary
*/
if (count < base)
{
int
j;
for (j=count; j <base; j++)
{
(void) fprintf (fp,
(base == 16) ? " " : " ");
}
(void) fprintf (fp," ");
for (i=0; i < count; i++)
{
/* 127 is non-printable - muquit@muquit.com Oct-03-2002 */
if (hexbuf[i] >= 32 && hexbuf[i] < 127)
{
(void) fprintf (fp,"%c", hexbuf[i]);
}
else
(void) fprintf (fp,".");
}
(void) fprintf (fp,"\n");
(void) fflush (fp);
} /* count < base .. */
}
void mutils_hex_dump(FILE *fp,unsigned char *buf,int length)
{
mutils_hex_or_oct_dump(fp,16,buf,length);
}
void mutils_hex_print(FILE *fp,unsigned char *bytes,int len)
{
int
i;
for (i=0; i < len; i++)
{
(void) fprintf(fp,"%02x ",bytes[i]);
if ((i % 16) == 15)
fprintf(fp, "\n");
}
(void) fprintf(fp,"\n");
}
void mutils_oct_dump(FILE *fp,unsigned char *buf,int length)
{
mutils_hex_or_oct_dump(fp,8,buf,length);
}
/*
** mutilsHowmanyCommas()
@@ -224,9 +481,7 @@ int
/* initialize */
*port=80;
*hostname='\0';
*page='\0';
*tmpbuf='\0';
*hostname = *page = *tmpbuf = '\0';
tmpbuf_len=sizeof(tmpbuf);
@@ -324,8 +579,7 @@ char *mutilsSpacesToChar(char *str,int c)
{
char
*ibuf,
*obuf,
*nbuf;
*obuf;
register int
i,
@@ -708,6 +962,7 @@ void mutilsStripTrailingSpace (char *str)
** make a temporary filename
** filename - returns
*/
#if 0
int mutilsTmpFilename(char *filename)
{
#define TMP_DIR "/tmp"
@@ -726,6 +981,7 @@ int mutilsTmpFilename(char *filename)
return(mktemp(filename));
#endif /* ! HAVE_MKSTEMP */
}
#endif /* 0 */
/*
@@ -767,9 +1023,7 @@ int mutilsTmpFilename(char *filename)
* Development History:
* 3/26/92, jps, first cut
*/
char *mutilsBasename(path)
char
*path;
char *mutilsBasename(char *path)
{
char
*cptr;
@@ -788,6 +1042,80 @@ char
}
/*
** Return the extension of a file in a path
** Parameters:
** path - path of a file
** Return Values:
** pointer to the extension
** Side Effects:
** none
** Comments:
** If that is /usr/local/file.pdf, pointer to
** pdf will be returned
** Development History:
** muquit@muquit.com Dec-15-2013 - needed to detect mime type based on extension
*/
char *mutilsExtension(char *path)
{
char
*base,
*cptr;
base = mutilsBasename(path);
for (cptr = base + strlen(base); cptr >= base; --cptr)
{
switch (*cptr)
{
case '.':
{
return ++cptr;
}
}
}
return path;
}
char *mutilsExtensionLower(char *path)
{
char
*ext;
return (mutilsStrLower(mutilsExtension(path)));
}
/*
** Return the basename of a path
** Parameters:
** path - path in Unix or windows style
**
** Return Values:
** pointer to the basename on success
** pointer to the path on failure
** Side Effects:
** no memory is allocated, pointer is returned
** pointing to the basename
** Comments:
** If path is say /usr/local/foo, foo will be returned
** on success. if path is c:\foo\bar, pointer to bar
** will be returned. if path is blah, pointer ot
** blah will be returned
** Development History:
** muquit@muquit.com Dec-15-2013
** didn't know I already had it
*/
char *mutils_basename(const char *path)
{
char
*bn = path;
bn = strrchr(path,'/');
if (bn == NULL)
{
bn = strrchr(path,'\\');
}
return (bn == NULL) ? path : ++bn;
}
/*
** mutilsDotLock()
** open a file for locking purpose. If the system is Unix, use
@@ -985,9 +1313,6 @@ char
*f,
*p;
int
len;
if (file == NULL || *file == '\0')
return (NULL);
@@ -1142,15 +1467,41 @@ static void _fs_give (void **block)
*block = NULL;
}
/*
**
** Given the length of a plain text string, return the
** length
**
** Parameters:
** len - length of plain text string
**
** Side Effects:
** none
**
** Comments:
** taken from apache apr util library
**
** Return Values:
** length of base64 encoded string
**
** Development History:
** muquit@muquit.com Oct-12-2013 first cut
*/
int mutils_base64_encode_len(int len)
{
return ((len + 2) / 3 * 4) + 1;
}
/**
* @Deprecated
* @brief encode content to base64
* @param src pointer to source
* @param srcl Length of the source
* @param len length of base64 encoded string (returns)
*
* @return Ponter to encoded strin gon success, NULL on failure. The
* caller is responsile to free the memory
* caller is responsile to free the memory
*
* Adapted from from c-client source
*/
@@ -1215,6 +1566,82 @@ unsigned char *mutils_encode_base64(void *src,unsigned long srcl,unsigned long *
return (ret); /* return the resulting string */
}
/*
** Endode a string to base64
**
** Parameters:
** string - plain text/binary string
** len - length of the plain text string
**
** Return Values:
** Pointer to null terminated base 64 string. Memory is allocated for
** the string
** NULL in case of error.
** Comments:
** reason not to use mutils_encode_base64(), it adds crlf after 60
** characters, which broke smtp auth with longer base64 encoded string.
**
** The caller is responsible to free the memory of the returned string.
**
** Adapted from apache apr util library. Does not support EBCDIC.
**
** Side Effects:
** none
**
** Development History:
** muquit@muquit.com Oct-12-2013 first cut
*/
char *mutils_encode_base64_noformat(const char *string, int len)
{
int
encode_len,
i;
char
*p,
*encoded = NULL;
if (len == 0)
{
return NULL;
}
encode_len = mutils_base64_encode_len(len);
encoded = (char *) malloc(encode_len);
MUTILS_CHECK_MALLOC(encoded);
memset(encoded, 0, encode_len);
p = encoded;
for (i = 0; i < len - 2; i += 3)
{
*p++ = basis_64[(string[i] >> 2) & 0x3F];
*p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int) (string[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len)
{
*p++ = basis_64[(string[i] >> 2) & 0x3F];
if (i == (len - 1))
{
*p++ = basis_64[((string[i] & 0x3) << 4)];
*p++ = '=';
}
else
{
*p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
*p++ = '\0';
return encoded;
ExitProcessing:
return NULL;
return strdup("fuck");
}
/**
* @brief converts base64 contents to binary
@@ -1330,6 +1757,317 @@ void *mutils_decode_base64(unsigned char *src,unsigned long srcl,unsigned long *
return ret; /* return the string */
}
unsigned char mutils_hex_char_to_bin(char x)
{
if (x >= '0' && x <= '9')
return(x - '0');
x=toupper(x);
return((x - 'A') + 10);
}
/**
* convert a hex string to it's binary format.
* @param hex_string - The hex string to convert
* @param len - length of the hex string
* @param *olen - The length of the binary string - returns
*
* @return pointer to a unsigned char holding the binary version of the
* hex string. returns NULL on failure. The caller should check
* olen (> 0) before using the binary
*
* @note Memory is allocated for the retured unsigned char pointer
* The caller is responsible to free it
*
* The format of the hex string can be any of:
* 0xde:ad:be:ef:ca:fe
* de:ad:be:ef:ca:fe
* de-ad-be-ef-ca-fe
* 0xde-ad-be-ef-ca-fe
* de:ad-be_ef:ca:fe
*
* The converted binary value will be: de ad be ef ca fe
*
* It will only convert valid hex strings to binary, for example, if
* the string is like: de:gh:ad:ff:bb:kk:cc
* The binary value will contain: de ad ff bb cc
* Note, gh and kk are ignored
*/
unsigned char *mutils_hex_to_bin(char *hex_string,int len,int *olen)
{
int
j=0;
int
bin_len=0,
n=0,
i;
unsigned char
value,
*out,
space[4];
char
*cp=hex_string;
if (! hex_string || ! len)
return(NULL);
if ((*cp == '0') && ((*(cp + 1) == 'x') || (*(cp + 1) == 'X')))
{
cp += 2;
n=2;
}
/*
** allocate half of hex_string as the length of binary.
** we may be allocated more than needed as : - etc may be
** part of the hex string
*/
bin_len=(len >> 1);
if (bin_len <= 0)
return(NULL);
out=(unsigned char *) malloc(bin_len*sizeof(unsigned char));
memset(out,0,bin_len);
for (i=n; i < len; i += 2)
{
if (hex_string[i] == '\n' || hex_string[i] == '\r' ||
hex_string[i] == ' ' || hex_string[i] == '\t' ||
hex_string[i] == ':' ||
hex_string[i] == '-' ||
hex_string[i] == '_')
{
i--;
continue;
}
if (isxdigit(hex_string[i]) && isxdigit(hex_string[i+1]))
{
value=(mutils_hex_char_to_bin (hex_string[i]) << 4) & 0xf0;
value |= (mutils_hex_char_to_bin(hex_string[i+1]) & 0x0f);
out[j++]=value;
}
}
*olen=j;
return(out);
}
/**
* @brief convert binary to hex
* @param input - binary data
* @param len - length of input data
* @param output - NULL terminated string equivalent in hex
* @return length of output string (not including NULL) on success, -1
* on failure
*
* Note: *output points to a malloc'd space, caller is responsible to
* to free it
* adapted from net-snmp 5.0.6 code (tools.c)
*/
int mutils_binary_to_hex(unsigned char *input,int len,char **output)
{
int
olen;
char
*s,
*op;
unsigned char
*ip;
olen=(len * 2) + 1;
s=(char *) calloc(1,olen);
if (s == NULL)
return (-1);
op=s;
ip=input;
while ((ip - input) < len)
{
*op++ = MUTILS_VAL2_HEX((*ip >> 4) & 0xf);
*op++ = MUTILS_VAL2_HEX(*ip & 0xf);
ip++;
}
*op='\0';
*output=s;
return(olen);
}
/**
* @brief convert binary to hex
* @param in binary data
* @param in_len length of input in bytes
* @param out output buffer to hold the converted hex data. in/out. The buffer is
* NULL terminated.
* @param out_len bytes of memroy pre allocated in out. out_len must be
* greater than in_len*2
* @return length of converted hex buffer on success, -1 on failure
*
* Note: this function is similar to mutils_binary_to_hex(), only differece is
* that in this function, the caller passes the pre-allocated buffer.
*/
int mutils_binary_to_hex_buf(unsigned char *in,int in_len,char *out,int *out_len)
{
char
*op;
unsigned char
*ip;
op=out;
ip=in;
if (*out_len < (in_len * 2) + 1)
{
*out_len=(-1);
(void) fprintf(stderr,"%s (%d) - outbuf must have atlease %d bytes of space pre-allocated\n",
MUTILS_CFL,((in_len * 2) + 1));
return(-1);
}
*out_len=(in_len * 2);
while ((ip - in) < in_len)
{
*op++ = MUTILS_VAL2_HEX((*ip >> 4) & 0xf);
*op++ = MUTILS_VAL2_HEX(*ip & 0xf);
ip++;
}
*op='\0';
return(*out_len);
}
/*
** return MUTILS_TRUE if the file is binary. MUTILS_FALSE otherwise.
** return -1 on error
** The algorithm is adapted from Perl pp_fttext()
** 512 bytes of file is used.
**
** here is the algorithm (perldoc -I -B|more)
The "-T" and "-B" switches work as follows. The first block or
so of the file is examined for odd characters such as strange
control codes or characters with the high bit set. If too many
strange characters (>30%) are found, it's a "-B" file;
otherwise it's a "-T" file. Also, any file containing a zero
byte in the first block is considered a binary file
*/
int mutils_file_is_binary(const char *file)
{
struct stat
sbuf;
FILE
*fp = NULL;
char
*s,
buf[513];
size_t
len;
int
i,
sz,
n;
int
odd = 0;
float
x;
sz = sizeof(buf) - 1;
if (stat(file, &sbuf) != 0)
{
(void) fprintf(stderr,"Could not stat file %s\n",file);
return(-1);
}
len = sbuf.st_size;
if (len > 512)
{
len = 512;
}
fp = fopen(file, "rb");
if (fp == NULL)
{
(void) fprintf(stderr,"Error reading file: %s\n",file);
return(-1);
}
memset(buf, 0, sizeof(buf));
n = fread(buf, 1, len, fp);
if (n != len)
{
(void) fprintf(stderr,"read error\n");
return(-1);
}
s = buf;
if (len && len < sizeof(buf) && buf[len - 1] == 0x1a)
{
--len;
}
for (i=0; i < len; i++, s++)
{
if (!*s)
{
odd += len;
break;
}
else if (*s & 128)
{
if (UTF8_IS_START(*s))
{
int ulen = UTF8SKIP(*s);
if (ulen < len - i)
{
int
j;
for (j = 1; j < ulen; j++)
{
if (!UTF8_IS_CONTINUATION(s[j]))
{
goto NotUtf8;
}
}
--ulen;
s += ulen;
i += ulen;
continue;
}
}
NotUtf8:
odd++;
}
else
{
if (*s < 32 && *s != '\n' && *s != '\r' && *s != '\b' &&
*s != '\t' && *s != '\f' && *s != 27)
{
odd++;
}
}
}
x = ((odd * 1.0) / (len * 1.0));
if (x < 0.30)
{
return MUTILS_FALSE;
}
else
{
return MUTILS_TRUE;
}
ExitProcessing:
if (fp)
{
(void) fclose(fp);
}
return(-1);
}
#ifdef TEST
+162 -3
View File
@@ -33,7 +33,20 @@
#include <sys/stat.h>
#include <io.h>
#include <share.h>
#include <direct.h>
#include <Winsock2.h> /* for timeval */
#define ftruncate chsize
#ifdef getcwd
#undef getcwd
#endif
#define getcwd _getcwd
#ifdef snprintf
#undef snprintf
#endif
#define snprintf _snprintf
#endif
#if HAVE_SYS_PARAM_H
@@ -48,6 +61,8 @@
#include <unistd.h>
#endif
#include <stdarg.h>
#if HAVE_FCNTL_H
#ifndef O_RDONLY /* prevent multiple inclusion on lame systems (from
vile)*/
@@ -75,8 +90,62 @@ vile)*/
#endif
#endif
#define MUTILS_CFL __FILE__,__LINE__
#if APR_HAVE_LIMITS_H
#include <limits.h>
#else
#if APR_HAVE_SYS_SYSLIMITS_H
#include <sys/syslimits.h>
#endif
#endif
#if defined(PATH_MAX)
#define MUTILS_PATH_MAX PATH_MAX
#elif defined(_POSIX_PATH_MAX)
#define MUTILS_PATH_MAX _POSIX_PATH_MAX
#else
#define MUTILS_PATH_MAX 4098
#endif
#if !defined(O_BINARY)
#define O_BINARY 0x00
#endif
#define MUTILS_TRUE 1
#define MUTILS_FALSE 0
typedef struct _MutilsBlob
{
size_t
length;
unsigned char
*data;
size_t
offset,
size;
}MutilsBlob;
#ifdef WINNT
typedef struct _MutilsTime
{
FILETIME
absolute;
}MutilsTime;
#else
typedef struct _MutilsTime
{
unsigned int
secs,
nsecs;
}MutilsTime;
#endif /* WINNT */
#define MUTILS_CFL __FILE__,__LINE__
#define MCFL __FILE__,__LINE__
#define MJL __LINE__
#if __STDC__ || defined(sgi) || defined(_AIX)
#undef _Declare
@@ -88,7 +157,6 @@ vile)*/
#define MUTILS_MAX_TOKEN_LEN 1024
#define MUTILS_CHECK_MALLOC(p) \
do \
{ \
@@ -99,9 +167,42 @@ do \
}\
}while(0)
/* from net-snmp 5.0.6 tools.h */
#define MUTILS_FREE(s) if (s) { free((void *)s); s=NULL;}
#define MUTILS_TOUPPER(c) (c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c)
#define MUTILS_TOLOWER(c) (c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c)
#define MUTILS_VAL2_HEX(s) ( (s) + (((s) >= 10) ? ('a'-10) : '0') )
#define MUTILS_HEX2_VAL(s) \
((isalpha(s) ? (MUTILS_TOLOWER(s)-'a'+10) : (MUTILS_TOLOWER(s)-'0')) & 0xf)
#define MUTILS_MAX(a,b) ((a) > (b) ? (a) : (b))
#define MUTILS_MIN(a,b) ((a) > (b) ? (b) : (a))
/* from net-snmp 5.0.6 tools.h */
/* function prototypes */
typedef void (*mutils_error_func) (char *fmt,va_list args);
typedef void (*mutils_hexdump_func) (unsigned char *bytes,int bytes_len);
void mutils_error (char *fmt,...);
void mutils_info (char *fmt,...);
void mutils_warn (char *fmt,...);
void mutils_debug(char *fmt,...);
void mutils_set_debug(int debug);
void mutils_set_error_hook(mutils_error_func new_func);
void mutils_set_info_hook(mutils_error_func new_func);
void mutils_set_debug_hook(mutils_error_func new_func);
void mutils_set_warn_hook(mutils_error_func new_func);
void mutils_set_hexdump_hook(mutils_hexdump_func new_func);
void mutils_set_hexprint_hook(mutils_hexdump_func new_func);
void mutils_reset_error_hook(void);
void mutils_reset_info_hook(void);
void mutils_reset_warn_hook(void);
void mutils_reset_debug_hook(void);
void mutilsBase64Encode (FILE *ifp,FILE *ofp);
void mutilsGenerateMIMEBoundary(char *boundary,int len);
int mutilsParseURL (char *url,char *hostname,
@@ -127,8 +228,10 @@ char *mutilsStristr (char *s,char *t);
int mutilsIsinname (char *string,char *mask);
char *mutilsGetTime (void);
char mutilsChopNL (char *str);
int mutilsTmpFilename (char *filename);
/*int mutilsTmpFilename (char *filename);*/
char *mutilsBasename (char *path);
char *mutilsExtension (char *file_path);
char *mutilsExtensionLower (char *file_path);
int mutilsWhich (char *name);
void mutilsSetLock (int fd);
void mutilsDotLock (char *filepath,char *errbuf);
@@ -141,8 +244,64 @@ char *mutilsGetDirname (char *file);
char *mutilsSpacesToChar (char *str,int c);
char **mutilsTokenize(char *str,int delim,int *ntokens);
void mutilsFreeTokens(char **tokens,int ntokens);
int mutils_base64_encode_len(int len);
unsigned char *mutils_encode_base64(void *src,unsigned long srcl,unsigned long *len);
char *mutils_encode_base64_noformat(const char *src, int src_len);
void *mutils_decode_base64(unsigned char *src,unsigned long srcl,unsigned long *len);
int mutils_make_encrypted_key(const char *plain,unsigned char *cipher,int clen);
int mutils_decrypt_key(unsigned char *cipher,int clen,char *plain,int plain_buf_len);
char *mutils_decrypt_hex(char *hex,int hex_len,char *pbuf,int pbuf_len);
void mutils_hex_dump(FILE *fp,unsigned char *buf,int length);
void mutils_hex_print(FILE *fp,unsigned char *bytes,int len);
unsigned char *mutils_get_master_key24(void);
unsigned char *mutils_get_iv8(void);
unsigned char mutils_hex_char_to_bin(char x);
unsigned char *mutils_hex_to_bin(char *hex_string,int len,int *olen);
int mutils_binary_to_hex(unsigned char *input,int len,char **output);
int mutils_binary_to_hex_buf(unsigned char *in,int in_len,char *out,int *out_len);
void *mutils_acquire_memory(size_t size);
void mutils_liberate_memory(void **memory);
void mutils_reacquire_memory(void **memory,const size_t size);
void mutils_attach_blob(MutilsBlob *blob_info,void *blob,size_t length);
void mutils_rewind_blob(MutilsBlob *blob);
MutilsBlob *mutils_clone_blobinfo(MutilsBlob *blob_info);
MutilsBlob *mutils_allocate_blob(int data_len);
MutilsBlob *mutils_file_to_blob(char *filename);
MutilsBlob *mutils_data_to_blob(unsigned char *data,int data_len);
void mutils_detach_blob(MutilsBlob *blob_info);
void mutils_destroy_blob(MutilsBlob *blob);
void mutils_msb_order_long(char *p,const size_t length);
void mutils_msb_order_short(char *p,const size_t length);
int mutils_read_blob(MutilsBlob *blob_info,const size_t length,
void *data);
int mutils_read_blob_byte(MutilsBlob *blob);
unsigned long mutils_read_blob_lsb_long(MutilsBlob *blob_info);
unsigned short mutils_read_blob_lsb_short(MutilsBlob *blob);
unsigned long mutils_read_blob_msb_long(MutilsBlob *blob,int *err_no);
unsigned short mutils_read_blob_msb_short(MutilsBlob *blob,int *err_no);
char *mutils_read_blob_string(MutilsBlob *blob,char *string,int slen);
int mutils_size_blob(MutilsBlob *blob);
int mutils_tell_blob(MutilsBlob *blob);
int mutils_write_blob(MutilsBlob *blob,const size_t length,const void *data);
size_t mutils_write_blob_byte(MutilsBlob *blob_info,const long value);
int mutils_write_blob_lsb_long(MutilsBlob *blob,const unsigned long value);
int mutils_write_blob_lsb_short(MutilsBlob *blob,const unsigned long value);
int mutils_write_blob_msb_long(MutilsBlob *blob,const unsigned long value);
int mutils_write_blob_msb_short(MutilsBlob *blob,const unsigned long value);
size_t mutils_write_blob_string(MutilsBlob *blob_info,const char *string);
char *mutils_getcwd(char *buf,int buflen);
FILE *mutils_get_tempfileFP(char *tempfile_path,int buflen);
char *mutils_basename(const char *path);
int mutils_file_is_binary(const char *file);
/* time */
int mutils_time_now(MutilsTime *mt);
void mutils_time_fmt(MutilsTime *mt,char *buf,int bufsiz);
#endif /* MUTILS_H */
+2 -2
View File
@@ -348,7 +348,7 @@ void mutilsSafeStrcat(char *dst,char *src,int length,int ssc_size,
exit(0);
}
if (strlen(src) >= ssc_size - ssc_length)
if ((int) strlen(src) >= ssc_size - ssc_length)
{
/*
StringImage("buffer overflow detected! aborting");
@@ -506,5 +506,5 @@ char *mutilsStrLower(char *str)
*s=tolower(*s);
}
return (s);
return (str);
}
View File
View File
+2 -2
View File
@@ -4,12 +4,12 @@
# Aug-07-1998
#
CC= gcc
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_YP_GET_DEFAULT_DOMAIN=1 -DHAVE_LIBNSL=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENSSL=1
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_MALLOC_H=1 -DHAVE_UNISTD_H=1 -DHAVE_CTYPE_H=1 -DHAVE_STDINT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_FCNTL_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_LIMITS_H=1 -DHAVE_FLOCK=1 -DHAVE_SOCKET=1 -DHAVE_HTONL=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETHOSTBYADDR=1 -DHAVE_RES_SEARCH=1 -DHAVE_LIBRESOLV=1 -DHAVE_INET_ATON=1 -DHAVE_DN_SKIPNAME=1 -DHAVE_MKSTEMP=1 -DHAVE_GETADDRINFO=1
AR= ar cq
RANLIB= ranlib
LIBNAME= libsll.a
INCLUDES= -I. -I/usr/include/malloc
INCLUDES= -I.
# replace -O with -g in order to debug
View File
View File
Regular → Executable
+127 -15
View File
@@ -8,6 +8,7 @@
#include <math.h>
#include "mutils.h"
#include "msock.h"
#include "sll.h"
@@ -28,6 +29,7 @@
#endif /* HAVE_OPENSSL */
/*
** header for mailsend - a simple mail sender via SMTP
** $Id: mailsend.h,v 1.3 2002/06/22 21:17:29 muquit Exp $
@@ -39,27 +41,28 @@
#define MFL __FILE__,__LINE__
#define MAILSEND_VERSION "@(#) mailsend v1.15b5"
#define MAILSEND_VERSION "@(#) mailsend v1.20b2"
#define MAILSEND_PROG "mailsend"
#define MAILSEND_AUTHOR "muquit@muquit.com"
#define MAILSEND_URL "http://www.muquit.com/"
#define NO_SPAM_STATEMENT "GNU GPL. It is illegal to use this software for Spamming"
#define NO_SPAM_STATEMENT "BSD. It is illegal to use this software for Spamming"
#define MAILSEND_SMTP_PORT 587 // 25
#define MAILSEND_SMTP_PORT 25
#define MAILSEND_DEF_SUB ""
#define A_SPACE ' '
#define A_DASH '-'
#define EMPTY_OK 0x01
#define EMPTY_NOT_OK 0x02
#define ATTACHMENT_SEP ','
#define FILE_TYPE_DOS 0x00000001
#define FILE_TYPE_UNIX 0x00000002
#define FILE_TYPE_BINARY 0x00000004
#define DEFAULT_CONNECT_TIMEOUT 5 /* seconds */
#define DEFAULT_READ_TIMEOUT 5 /* seconds */
#ifdef EXTERN
#undef EXTERN
@@ -67,7 +70,7 @@
#ifndef __MAIN__
#define EXTERN extern
#else
#else
#define EXTERN
#endif /* __MAIN__ */
@@ -111,10 +114,45 @@ do \
}\
}while(0)
#define RETURN_IF_NOT_ZERO(rc) \
do \
{ \
if (rc != 0) \
{ \
return(rc); \
} \
}while(0)
#define CHECK_WRITE_STATUS(n) \
do \
{ \
if (n <= 0) \
{ \
goto ExitProcessing; \
} \
}while(0)
#define ERR_STR strerror(errno)
#define CONTENT_DISPOSITION_INLINE 0x01
#define CONTENT_DISPOSITION_ATTACHMENT 0x02
/* only suport base64 at this time */
/* as of Jul-01-2013 */
#define ENCODE_7BIT 0x01 /* default for text/plain */
#define ENCODE_8BIT 0x02
#define ENCODE_BASE64 0x03
#define ENCODE_QUOTED_PRINTABLE 0x04
#define ENCODE_NONE 0x05
#define DEFAULT_CHARSET "utf-8"
EXTERN int g_verbose;
EXTERN int g_connect_timeout;
EXTERN int g_read_timeout;
EXTERN int g_wait_for_cr;
EXTERN int g_do_ssl;
EXTERN int g_do_starttls;
EXTERN int g_quiet;
EXTERN int g_do_auth;
@@ -126,12 +164,25 @@ EXTERN char g_charset[33];
EXTERN char g_username[64];
EXTERN char g_userpass[64];
EXTERN char g_from_name[64];
EXTERN char g_content_transfer_encoding[32];
EXTERN FILE *g_log_fp;
EXTERN char g_log_file[MUTILS_PATH_MAX];
EXTERN int g_show_attachment_in_log;
EXTERN int g_use_protocol;
EXTERN char g_content_type[64];
EXTERN char g_attach_sep[4];
EXTERN char g_attach_name[64];
EXTERN char g_content_disposition[32];
EXTERN char g_content_id[64];
EXTERN char g_mime_type[64];
EXTERN int g_force;
typedef struct _Address
{
/*
** label holds strings like "To" "Cc" "Bcc".
** label holds strings like "To" "Cc" "Bcc".
** The address is the email address.
*/
@@ -144,11 +195,31 @@ typedef struct _Attachment
{
char
*file_path,
*file_name;
*file_name,
*attachment_name,
*content_id;
char
*oneline_msg;
char
*mime_type;
char
*content_disposition;
char
*content_transfer_encoding,
*charset;
int
attach_separator;
FILE
*fp_read;
char
mime_tmpfile[MUTILS_PATH_MAX];
}Attachment;
/* the mail sturct */
@@ -180,34 +251,58 @@ typedef struct _Mailsendrc
}Mailsendrc;
/* function prototypes */
char *xStrdup(char *string);
char *xStrdup(const char *string);
int addAddressToList(char *a,char *label);
TheMail *initTheMail(void);
Address *newAddress(void);
Sll *getAddressList(void);
void printAddressList(void);
void print_server_caps(void);
void print_one_lines(void);
char *check_server_cap(char *what);
int read_smtp_line();
void show_smtp_info(char *smtp_server,int port,char *domain);
int read_smtp_line(void);
int read_smtp_multi_lines(void);
int show_smtp_info(char *smtp_server,int port,char *domain);
int send_the_mail(char *from,char *to,char *cc,char *bcc,char *sub,
char *smtp_server,int smtp_port,char *helo_domain,
char *attach_file,char *txt_msg_file,char *the_msg,
int is_mime,char *rrr,char *rt,int add_dateh);
int is_mime,char *rrr,char *rt,int add_dateh,char* return_path_addr);
TheMail *newTheMail(void);
void errorMsg(char *format,...);
void showVerbose(char *format,...);
void print_info(char *format,...);
void write_log(char *format,...);
void open_log(const char *log_file);
void close_log(void);
void exit_ok(void);
void exit_error(void);
void log_info(const char *fmt, ...);
void log_debug(const char *fmt, ...);
void log_error(const char *fmt, ...);
void log_fatal(const char *fmt, ...);
int addAddressesFromFileToList(char *adress_list_file);
int validateMusts(char *from,char *to,char *smtp_server,
char *helo_domain);
char *askFor(char *buf,int buflen,char *label,int loop);
int isInConsole(int fd);
int add_one_line_to_list(char *line);
int add_msg_body_files_to_list(char *file_path);
int add_embed_image_to_attachment_list(const char *image_file);
int add_customer_header_to_list(char *line);
int add_attachment_to_list(char *file_path_mime);
int add_oneline_to_attachment_list(char *one_line_msg);
int add_msg_body_to_attachment_list(const char *msg_body_file);
int add_server_cap_to_list(char *capability);
Sll *get_attachment_list();
Sll *get_server_caps_list();
void print_attachemtn_list();
Sll *get_one_line_list(void);
Sll *get_custom_header_list(void);
Sll *get_attachment_list(void);
Sll *get_oneline_attachment_list(void);
Sll *get_msg_body_attachment_list(void);
Sll *get_embed_image_attachment_list(void);
Sll *get_server_caps_list(void);
Sll *get_msg_body_files_list(void);
void print_attachment_list(void);
void print_oneline_attachment_list(void);
char *fix_to(char *to);
int isInteractive(void);
int get_filepath_mimetype(char *str,char *filename,int fn_size,
@@ -219,8 +314,25 @@ int do_tls(int sfd);
void initialize_openssl(char *cipher);
char *encode_cram_md5(char *challenge,char *user,char *pass);
int guess_file_type(char *path,unsigned int *flag);
void generate_encrypted_password(const char *plaintext);
void print_copyright(void);
int get_encoding_type(const char *type);
int get_content_disposition(const char *disposition);
Attachment *allocate_attachment(void);
int write_to_socket(char *str);
int print_content_type_header(const char *boundary);
int send_attachment(Attachment *a, const char *boundary);
int process_attachments(const char *boundary);
int process_oneline_messages(const char *boundary);
int process_embeded_images(const char *boundary);
int encode2base64andwrite2socket(const char *str);
int include_msg_body(void);
int include_image(void);
void show_examples(void);
char *get_mime_type(char *path);
#ifdef HAVE_OPENSSL
void print_cert_info(SSL *ssl);
void show_mime_types(void);
#endif /* HAVE_OPENSSL */
#endif /* ! MAIL_SEND_H */
Regular → Executable
+687 -178
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+366 -51
View File
@@ -13,7 +13,12 @@
#include "mailsend.h"
static Sll
*one_line_head = NULL,
*custom_headers_head = NULL,
*attachment_head=NULL,
*oneline_attachment_head = NULL,
*msg_body_attachment_head = NULL,
*embed_image_attachment_head = NULL,
*server_caps=NULL,
*addr_head=NULL;
@@ -31,9 +36,21 @@ void print_server_caps(void)
}
}
void print_one_lines(void)
{
Sll
*l;
for (l = one_line_head; l; l = l->next)
{
(void) fprintf(stdout,"LINE: '%s'\n",(char *) l->data);
(void) fflush(stdout);
}
}
void printAddressList2(Sll *list)
{
/*
Sll
*l;
@@ -44,9 +61,37 @@ void printAddressList2(Sll *list)
{
addr=(Address *) l->data;
}
*/
}
void print_attachemtn_list()
void print_oneline_attachment_list(void)
{
Sll
*l;
Attachment
*a;
if (!g_verbose)
{
return;
}
for (l=oneline_attachment_head; l; l=l->next)
{
a=(Attachment *) l->data;
(void) fprintf(stderr,"Message: %s\n",a->oneline_msg);
(void) fprintf(stderr,"Mime type: %s\n",a->mime_type);
(void) fprintf(stderr,"Disposition: %s\n",a->content_disposition);
if (a->content_transfer_encoding)
(void) fprintf(stderr,"Encoding type: %s\n",a->content_transfer_encoding);
else
(void) fprintf(stderr,"Encoding type: none\n");
(void) fprintf(stderr,"\n");
}
}
void print_attachment_list(void)
{
Sll
*l;
@@ -57,13 +102,19 @@ void print_attachemtn_list()
for (l=attachment_head; l; l=l->next)
{
a=(Attachment *) l->data;
/*
(void) fprintf(stderr,"File path: %s\n",a->file_path);
(void) fprintf(stderr,"File name: %s\n",a->file_name);
if (a->attachment_name)
(void) fprintf(stderr,"Attachment name: %s\n",a->attachment_name);
(void) fprintf(stderr,"Mime type: %s\n",a->mime_type);
(void) fprintf(stderr,"Disposition: %s\n",a->content_disposition);
if (a->content_id)
(void) fprintf(stderr,"Content-ID: %s\n",a->content_id);
if (a->content_transfer_encoding)
(void) fprintf(stderr,"Encoding type: %s\n",a->content_transfer_encoding);
else
(void) fprintf(stderr,"Encoding type: none\n");
(void) fprintf(stderr,"\n");
*/
}
}
@@ -133,6 +184,56 @@ int add_server_cap_to_list(char *cap)
return(0);
}
/*
** Add each line entered with -H to list of lines
** they represent custom headers in the mail.
** For example X-Priority etc. can be added that way
*/
int add_customer_header_to_list(char *line)
{
Sll
*nl = NULL;
char
*l;
if (line == NULL || *line == '\0')
{
return (-1);
}
l = strdup(line);
CHECK_MALLOC(l);
nl = allocateNode((void *) l);
CHECK_MALLOC(nl);
appendNode(&custom_headers_head, &nl);
return(0);
}
/*
** Add each line entered with -M to a list of lines
** return 0 on success, -1 otherwise
*/
int add_one_line_to_list(char *line)
{
Sll
*nl = NULL;
char
*l;
if (line == NULL || *line == '\0')
{
return (-1);
}
l = strdup(line);
CHECK_MALLOC(l);
nl = allocateNode((void *) l);
CHECK_MALLOC(nl);
appendNode(&one_line_head, &nl);
return(0);
}
/**
@@ -141,6 +242,8 @@ int add_server_cap_to_list(char *cap)
int add_attachment_to_list(char *file_path_mime)
{
int
rc,
separator,
ntokens;
Sll
@@ -150,7 +253,7 @@ int add_attachment_to_list(char *file_path_mime)
**tokens=NULL,
*file_path=NULL,
*file_name=NULL,
*mime_type=NULL,
*mime_type,
*content_disposition="attachment";
Attachment
@@ -160,13 +263,17 @@ int add_attachment_to_list(char *file_path_mime)
return(-1);
/* Tokenize the string "file,mime_type,something" */
tokens=mutilsTokenize(file_path_mime,',',&ntokens);
separator = *g_attach_sep;
showVerbose("Separator: %c\n",separator);
tokens=mutilsTokenize(file_path_mime,separator,&ntokens);
if (tokens == NULL)
{
errorMsg("Could not parse attachment string: \"%s\"",file_path_mime);
exit(1);
exit_error();
}
showVerbose("ntokens: %d\n",ntokens);
/* get the file name out */
file_path=tokens[0];
if ((file_name=strrchr(file_path,'/')) ||
@@ -179,9 +286,7 @@ int add_attachment_to_list(char *file_path_mime)
file_name=file_path;
}
a=(Attachment *) malloc(sizeof(Attachment));
CHECK_MALLOC(a);
a = allocate_attachment();
a->file_path=xStrdup(file_path);
a->file_name=xStrdup(file_name);
@@ -190,9 +295,11 @@ int add_attachment_to_list(char *file_path_mime)
case 1: /* Only File_path/name given */
{
/*
mime_type="application/octet-stream";
a->mime_type=xStrdup(mime_type);
a->content_disposition=xStrdup("attachment");
*/
break;
}
@@ -200,75 +307,228 @@ int add_attachment_to_list(char *file_path_mime)
{
mime_type=tokens[1];
a->mime_type=xStrdup(mime_type);
a->content_disposition=xStrdup("attachment");
break;
}
case 3:
case 3: /* filepath/name, mime_type, disposition given */
case 4: /* filepath/name, mime_type, disposition, attchment name given */
case 5: /* content-id */
case 6: /* encoding type */
{
mime_type=tokens[1];
a->mime_type=xStrdup(mime_type);
content_disposition=tokens[2];
if (*content_disposition == 'a')
{
a->content_disposition=xStrdup("attachment");
}
else if (*content_disposition == 'i')
{
a->content_disposition=xStrdup("inline");
}
else
{
a->content_disposition=xStrdup("attachment");
}
if (ntokens == 4)
{
a->attachment_name = xStrdup(tokens[3]);
}
if (ntokens == 5)
{
a->attachment_name = xStrdup(tokens[3]);
if (strncmp(tokens[4],"none",4) != 0)
a->content_id = xStrdup(tokens[4]);
}
if (ntokens == 6)
{
a->attachment_name = xStrdup(tokens[3]);
if (strncmp(tokens[4],"none",4) != 0)
a->content_id = xStrdup(tokens[4]);
a->content_transfer_encoding = xStrdup(tokens[5]);
}
break;
}
default:
{
errorMsg("Invalid string specified with -a \"%s\"",file_path_mime);
exit(1);
exit_error();
break;
}
}
rc = mutils_file_is_binary(a->file_path);
if (rc == -1)
{
errorMsg("Could not determine file type of %s",a->file_path);
}
if (rc == MUTILS_TRUE)
{
mime_type = get_mime_type(a->file_path);
if (*g_mime_type != '\0')
{
if ((mutilsStrcasecmp(g_mime_type,"text/html") == 0) ||
(mutilsStrcasecmp(g_mime_type,"text/plain") == 0))
{
a->charset = xStrdup("none");
a->mime_type = xStrdup(mime_type);
a->content_transfer_encoding = xStrdup("base64");
}
}
}
if (a->mime_type == NULL)
{
if (*g_mime_type != '\0')
{
a->mime_type = xStrdup(g_mime_type);
}
else
{
a->mime_type = xStrdup(get_mime_type(a->file_path));
}
}
if (a->content_transfer_encoding == NULL)
{
if (*g_content_transfer_encoding == '\0')
{
a->content_transfer_encoding = xStrdup("base64");
}
}
if (a->content_id == NULL)
{
if (*g_content_id != '\0')
{
a->content_id = xStrdup(g_content_id);
}
}
if (a->attachment_name == NULL)
{
a->attachment_name = xStrdup(file_name);
}
na=allocateNode((void *) a);
CHECK_MALLOC(na);
appendNode(&attachment_head,&na);
/*
print_attachemtn_list();
*/
#if 0
if ((mime_type=strchr(file_path_mime,ATTACHMENT_SEP)))
{
*mime_type++='\0';
}
else
{
mime_type="application/octet-stream";
}
/* get the file name out */
if ((file_name=strrchr(file_path_mime,'/')) || (file_name=strrchr(file_path_mime,'\\')))
{
file_name++;
}
else
{
file_name=file_path_mime;
}
a=(Attachment *) malloc(sizeof(Attachment));
CHECK_MALLOC(a);
a->file_path=xStrdup(file_path_mime);
a->file_name=xStrdup(file_name);
a->mime_type=xStrdup(mime_type);
na=allocateNode((void *) a);
CHECK_MALLOC(na);
appendNode(&attachment_head,&na);
#endif /* 0 */
/*print_attachemtn_list();*/
return(0);
}
int add_embed_image_to_attachment_list(const char *image_file)
{
Sll
*na=NULL;
Attachment
*a=NULL;
if (image_file == NULL || *image_file == '\0')
{
return(-1);
}
a=allocate_attachment(); /* defaults will be set */
a->file_path = xStrdup(image_file);
if (a->charset)
{
(void) free((char *) a->charset);
a->charset = xStrdup("none");
}
if (a->mime_type == NULL)
{
if (*g_mime_type != '\0')
{
a->mime_type = xStrdup(g_mime_type);
}
else
{
a->mime_type = xStrdup(get_mime_type(a->file_path));
}
}
if (a->content_transfer_encoding == NULL)
{
if (*g_content_transfer_encoding == '\0')
{
a->content_transfer_encoding = xStrdup("base64");
}
}
na=allocateNode((void *) a);
CHECK_MALLOC(na);
appendNode(&embed_image_attachment_head,&na);
return(0);
}
int add_msg_body_to_attachment_list(const char *msg_body_file)
{
Sll
*na=NULL;
Attachment
*a=NULL;
if (msg_body_file == NULL || *msg_body_file == '\0')
{
return(-1);
}
a=allocate_attachment(); /* defaults will be set */
a->file_path = xStrdup(msg_body_file);
na=allocateNode((void *) a);
CHECK_MALLOC(na);
appendNode(&msg_body_attachment_head,&na);
return(0);
}
/*
** create a list of Attachment for one line messages
** it uses -mime-type and -enc-type, so these two flags
** must specified first before -M
*/
int add_oneline_to_attachment_list(char *oneline_msg)
{
Sll
*na=NULL;
Attachment
*a=NULL;
if (oneline_msg == NULL || *oneline_msg == '\0')
{
return(-1);
}
a=allocate_attachment(); /* defaults will be set */
a->oneline_msg=xStrdup(oneline_msg);
a->content_disposition=xStrdup("inline");
if (*g_mime_type == '\0')
{
a->mime_type = xStrdup("text/plain");
}
if (a->content_transfer_encoding == NULL)
{
a->content_transfer_encoding = xStrdup("none");
}
na=allocateNode((void *) a);
CHECK_MALLOC(na);
appendNode(&oneline_attachment_head,&na);
return(0);
}
@@ -421,7 +681,7 @@ int addAddressesFromFileToList(char *address_file)
if (addr == NULL)
{
errorMsg("addAddressToList: malloc problem for newAddress()");
return (-1);
goto ExitProcessing;
}
/* fill with data */
showVerbose("Label: %s\n",label);
@@ -434,7 +694,7 @@ int addAddressesFromFileToList(char *address_file)
{
errorMsg("addAddressToList: malloc problem with allocateNode()");
(void) free ((char *) addr);
return (-1);
goto ExitProcessing;
}
appendNode(&addr_head,&list);
}
@@ -443,6 +703,10 @@ int addAddressesFromFileToList(char *address_file)
(void) fclose(fp);
return (0);
ExitProcessing:
if (fp != (FILE *) NULL)
(void) fclose(fp);
return (-1);
}
@@ -451,15 +715,66 @@ Sll *getAddressList(void)
return (addr_head);
}
Sll *get_one_line_list(void)
{
return (one_line_head);
}
Sll *get_custom_header_list(void)
{
return (custom_headers_head);
}
Sll *get_attachment_list(void)
{
return(attachment_head);
}
Sll *get_oneline_attachment_list(void)
{
return(oneline_attachment_head);
}
Sll *get_server_cap_list(void)
{
return(server_caps);
}
Sll *get_msg_body_attachment_list(void)
{
return(msg_body_attachment_head);
}
Sll *get_embed_image_attachment_list(void)
{
return (embed_image_attachment_head);
}
Attachment *allocate_attachment(void)
{
Attachment
*a;
a = (Attachment *) malloc(sizeof(Attachment));
CHECK_MALLOC(a);
memset(a,0,sizeof(Attachment));
a->charset = xStrdup(g_charset); /* default is "utf-8" */
if (*g_mime_type != '\0')
{
a->mime_type = xStrdup(g_mime_type);
}
if (*g_content_transfer_encoding != '\0')
a->content_transfer_encoding = xStrdup(g_content_transfer_encoding);
a->attach_separator = *g_attach_sep;
a->content_disposition = xStrdup(g_content_disposition);
if (*g_attach_name != '\0')
{
a->attachment_name = xStrdup(g_attach_name);
}
return(a);
}
/* just a debug routine */
Regular → Executable
+944 -318
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+298 -18
View File
@@ -8,10 +8,22 @@
*/
#include "mailsend.h"
#include "copyright.h"
#define DAY_MIN (24 * HOUR_MIN) /* minutes in a day */
#define HOUR_MIN 60 /* minutes in an hour */
#define MIN_SEC 60 /* seconds in a minute */
static struct _MimeType
{
char
*ext,
*val;
} s_mime_type[] =
{
#include "mime_types.h"
};
/*
** returns a positive number if the file descriptor is connected to
@@ -42,10 +54,50 @@ int isInteractive(void)
return(0);
}
/*
** arg: type
** at this time valid types are: "base64", "none"
*/
int get_encoding_type(const char *type)
{
if (type == NULL || *type == '\0')
{
return ENCODE_BASE64;
}
if (strncmp("base64", type, 6) == 0)
{
return ENCODE_BASE64;
}
else if (strncmp("none", type, 4) == 0)
{
return ENCODE_NONE;
}
return ENCODE_BASE64;
}
int get_content_disposition(const char *disposition)
{
if (disposition == NULL || *disposition == '\0')
{
return CONTENT_DISPOSITION_ATTACHMENT;
}
if (strncmp("attachment", disposition, 10) == 0)
{
return CONTENT_DISPOSITION_ATTACHMENT;
}
else if (strncmp("inline", disposition, 6) == 0)
{
return CONTENT_DISPOSITION_INLINE;
}
return CONTENT_DISPOSITION_ATTACHMENT;
}
/*
** duplicate a string. exits on failure
*/
char *xStrdup (char *string)
char *xStrdup (const char *string)
{
char
*tmp;
@@ -59,13 +111,34 @@ char *xStrdup (char *string)
if (tmp == (char *) NULL)
{
(void) fprintf(stderr,"Error: mystrdup(): memory allocation problem\n");
exit(0);
exit_error();
}
/* it's safe to copy this way */
(void) strcpy(tmp, string);
return (tmp);
}
void log_info(const char *fmt, ...)
{
va_list
args;
va_start(args, fmt);
va_end(args);
}
void log_debug(const char *fmt, ...)
{
}
void log_error(const char *fmt, ...)
{
}
void log_fatal(const char *fmt, ...)
{
}
void errorMsg(char *format,...)
{
va_list
@@ -75,6 +148,21 @@ void errorMsg(char *format,...)
(void) fprintf (stderr,"Error: ");
vfprintf(stderr,format,args);
(void) fprintf(stderr,"\n");
(void) fflush(stderr);
if (g_log_fp != NULL)
{
MutilsTime
mt;
char
timebuf[64];
mutils_time_now(&mt);
mutils_time_fmt(&mt,timebuf,sizeof(timebuf));
(void) fprintf (g_log_fp,"%s: Error: ",timebuf);
vfprintf(g_log_fp,format,args);
(void) fprintf(g_log_fp,"\n");
(void) fflush(g_log_fp);
}
va_end(args);
}
@@ -82,15 +170,35 @@ void showVerbose(char *format,...)
{
va_list
args;
if (g_quiet)
return;
if (g_verbose == 1)
{
va_start(args,format);
vfprintf(stdout,format,args);
(void) fflush(stdout);
va_end(args);
if (isInConsole(_fileno(stdout)))
{
va_start(args,format);
vfprintf(stdout,format,args);
(void) fflush(stdout);
va_end(args);
}
if (g_log_fp != NULL)
{
MutilsTime
mt;
char
timebuf[64];
mutils_time_now(&mt);
mutils_time_fmt(&mt,timebuf,sizeof(timebuf));
(void) fprintf(g_log_fp,"%s: " ,timebuf);
va_start(args,format);
vfprintf(g_log_fp,format,args);
(void) fflush(g_log_fp);
va_end(args);
}
}
}
@@ -106,7 +214,50 @@ void print_info(char *format,...)
vfprintf(stdout,format,args);
(void) fflush(stdout);
va_end(args);
}
void write_log(char *format,...)
{
va_list
args;
MutilsTime
mt;
char
timebuf[64];
if (g_log_fp == NULL)
return;
mutils_time_now(&mt);
mutils_time_fmt(&mt,timebuf,sizeof(timebuf));
va_start(args,format);
(void) fprintf(g_log_fp,"%s: " ,timebuf);
vfprintf(g_log_fp,format,args);
(void) fflush(g_log_fp);
va_end(args);
}
void close_log(void)
{
if (g_log_fp != NULL)
{
(void) fclose(g_log_fp);
g_log_fp = NULL;
}
}
void exit_ok(void)
{
close_log();
exit(0);
}
void exit_error(void)
{
close_log();
exit(1);
}
@@ -188,6 +339,7 @@ int validateMusts(char *from,char *to,char *smtp_server,char *helo_domain)
char *askFor(char *buf,int buflen,char *label,int ask)
{
char *s;
if (label == NULL || *label == '\0')
return (NULL);
@@ -195,13 +347,13 @@ char *askFor(char *buf,int buflen,char *label,int ask)
again:
if (isInConsole(_fileno(stdin)))
{
(void) fprintf(stdout,label);
(void) fprintf(stdout,"%s",label);
(void) fflush(stdout);
(void) fflush(stderr);
}
(void) fgets(buf,buflen,stdin);
if (*buf == '\0' || *buf == '\n')
s = fgets(buf,buflen,stdin);
if (s == NULL || *buf == '\0' || *buf == '\n')
{
if (ask == EMPTY_NOT_OK)
goto again;
@@ -259,11 +411,13 @@ int get_filepath_mimetype(char *str,char *filepath,int fp_size,char *mype_type,i
{
int
separator,
rc=0;
char
*fp,
*mt;
if ((mt=strchr(str,ATTACHMENT_SEP)))
separator = *g_attach_sep;
if ((mt=strchr(str,separator)))
{
*mt++='\0';
}
@@ -272,11 +426,11 @@ int get_filepath_mimetype(char *str,char *filepath,int fp_size,char *mype_type,i
errorMsg("Could not determine mime-type from input: %s\n",str);
return(-1);
}
mutilsSafeStrcpy(mype_type,mt,mt_size);
mutilsSafeStrcpy(mype_type,mt,mt_size-1);
/* get the filepath out */
fp=str;
mutilsSafeStrcpy(filepath,fp,fp_size);
mutilsSafeStrcpy(filepath,fp,fp_size-1);
return(rc);
}
@@ -289,6 +443,7 @@ void initialize_openssl(char *cipher)
SSL_library_init();
SSL_load_error_strings();
RAND_seed(rnd_seed,sizeof(rnd_seed));
OpenSSL_add_all_algorithms();
ssl_ctx=SSL_CTX_new(SSLv23_client_method());
if (ssl_ctx == NULL)
{
@@ -403,11 +558,15 @@ int rfc822_date(time_t when,char *datebuf,int bufsiz)
/*
** return 0 on success, -1 on failure
** super simple naive funtion to detect if a file is
** binary or not.. it's just to prevent attaching binary file
** if no encoding type is specified. It's not a simple task
** to detect if a file is binary or not correctly.
*/
int guess_file_type(char *file,unsigned int *flag)
{
char
buf[BUFSIZ];
buf[513];
int
i,
@@ -474,6 +633,7 @@ ExitProcessing:
}
/*
static int unix2dos(FILE *ifp,FILE *ofp)
{
int
@@ -489,7 +649,7 @@ static int unix2dos(FILE *ifp,FILE *ofp)
return(-1);
#ifdef WINNT
_setmode(_fileno(ofp),_O_BINARY);
#endif /* WINNT */
#endif
while(!feof(ifp))
{
n=fread(buf,1,BUFSIZ,ifp);
@@ -513,7 +673,82 @@ static int unix2dos(FILE *ifp,FILE *ofp)
}
}
}
*/
void print_copyright(void)
{
char
**p;
for (p = mailsend_copyright; *p != NULL; p++)
{
(void) fprintf(stdout,"%s\n",*p);
}
(void) fflush(stdout);
}
/*
** Return the MIME type of the file
** Parameters:
** path - path of the file
** Return Values:
** mime type
** Side Effects:
** none
** Comments:
** If no extension is found, "text/plain" will be returned
** Development History:
*/
char *get_mime_type(char *path)
{
char
*npath = NULL,
*ext = NULL;
char
*text_plain = "text/plain";
int
i;
if (path == NULL || *path == '\0')
{
return(text_plain);
}
/* Issue #140. path was modified */
npath = xStrdup(path);
ext = mutilsExtensionLower(npath);
for (i=0; i < sizeof(s_mime_type)/sizeof(*s_mime_type); i++)
{
if (strcmp(s_mime_type[i].ext, ext) == 0)
{
if (npath != NULL)
{
(void) free((char *) npath);
}
return (s_mime_type[i].val);
}
}
if (npath != NULL)
{
(void) free((char *) npath);
}
return(text_plain);
}
void show_mime_types()
{
int
i;
for (i=0; i < sizeof(s_mime_type)/sizeof(*s_mime_type); i++)
{
(void) fprintf(stdout,"%s\t%s\n",
s_mime_type[i].val,
s_mime_type[i].ext);
}
}
#ifdef HAVE_OPENSSL
void print_cert_info(SSL *ssl)
@@ -576,8 +811,19 @@ char *encode_cram_md5(char *challenge,char *user,char *secret)
unsigned char
hmac_md5[16];
#ifdef LIBRESSL_VERSION_NUMBER
HMAC_CTX
ctx;
#else
#if OPENSSL_VERSION_NUMBER < 0x10100000L
HMAC_CTX
ctx;
#else
/* OpenSSL 1.1.x*/
HMAC_CTX
*ctx;
#endif
#endif
const EVP_MD
*md5=NULL;
@@ -591,9 +837,10 @@ char *encode_cram_md5(char *challenge,char *user,char *secret)
char
*b64;
/*
unsigned long
b64len=0;
*/
char
hex[33],
buf[BUFSIZ];
@@ -602,22 +849,41 @@ char *encode_cram_md5(char *challenge,char *user,char *secret)
secret == NULL || *secret == '\0')
return(NULL);
showVerbose("Server Challenge: %s\n",challenge);
OpenSSL_add_all_digests();
/* decode the challenge */
data=mutils_decode_base64(challenge,strlen(challenge),&data_len);
data=mutils_decode_base64((unsigned char *) challenge,strlen(challenge),&data_len);
if (data == NULL)
{
errorMsg("Could not base64 decode CRAM-MD5 challenge: %s",challenge);
return(NULL);
}
showVerbose("Challenge After decoding: %s\n",data);
/* take HMAC-MD5 of the challenge*/
#ifdef LIBRESSL_VERSION_NUMBER
md5=EVP_get_digestbyname("md5");
HMAC_CTX_init(&ctx);
HMAC_Init(&ctx,secret,strlen(secret),md5);
HMAC_Update(&ctx,data,data_len);
HMAC_Final(&ctx,hmac_md5,&hmac_len);
#else
#if OPENSSL_VERSION_NUMBER < 0x10100000L
md5=EVP_get_digestbyname("md5");
HMAC_CTX_init(&ctx);
HMAC_Init(&ctx,secret,strlen(secret),md5);
HMAC_Update(&ctx,data,data_len);
HMAC_Final(&ctx,hmac_md5,&hmac_len);
#else
/* OpenSSL 1.1.x */
ctx = HMAC_CTX_new();
HMAC_Init_ex(ctx,secret,strlen(secret),EVP_md5(),NULL);
HMAC_Update(ctx,data,data_len);
HMAC_Final(ctx,hmac_md5,&hmac_len);
#endif
#endif /* LIBRESSL_VERSION_NUMBER */
/* convert the digest to hex */
memset(hex,0,sizeof(hex));
@@ -625,22 +891,36 @@ char *encode_cram_md5(char *challenge,char *user,char *secret)
{
(void) sprintf(hex+2*i,"%02x",hmac_md5[i]);
}
showVerbose("HMAC-MD5 of challenge: %s\n",hex);
(void) snprintf(buf,sizeof(buf)-1,"%s %s",user,hex);
showVerbose("base64 encode: %s\n",buf);
showVerbose("Taking base64 of \"%s\"\n",buf);
/* base64 encode "user hex_digest" */
b64=mutils_encode_base64(buf,strlen(buf),&b64len);
#if 0
b64=mutils_encode_base64((unsigned char *) buf,strlen(buf),&b64len);
if (b64len <= 0)
return(NULL);
/* mutils_encode_base64 adds CRLF */
if (b64len > 2)
b64[b64len-2]='\0';
#endif
b64 = mutils_encode_base64_noformat(buf,strlen(buf));
if (b64 == NULL)
{
errorMsg("Could not base64 encode: %s",buf);
return (NULL);
}
showVerbose("base64: %s\n",b64);
return(b64);
}
#else
char *encode_cram_md5(char *challenge,char *user,char *secret)
{
errorMsg("Must be compiled with OpenSSL in order to get CRAM-MD5 support\n");
errorMsg("Must be compiled with OpenSSL in order to get CRAM-MD5 support\n");
return(NULL);
}
#endif /* HAVE_OPENSSL */