1/*
2 * Copyright (c) 1999-2006, 2008 Proofpoint, Inc. and its suppliers.
3 *	All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11#include <sm/gen.h>
12SM_RCSID("@(#)$Id: sfsasl.c,v 8.121 2013-11-22 20:51:56 ca Exp $")
13#include <stdlib.h>
14#include <sendmail.h>
15#include <sm/time.h>
16#include <sm/fdset.h>
17#include <errno.h>
18
19/* allow to disable error handling code just in case... */
20#ifndef DEAL_WITH_ERROR_SSL
21# define DEAL_WITH_ERROR_SSL	1
22#endif
23
24#if SASL
25# include "sfsasl.h"
26
27/* Structure used by the "sasl" file type */
28struct sasl_obj
29{
30	SM_FILE_T *fp;
31	sasl_conn_t *conn;
32};
33
34struct sasl_info
35{
36	SM_FILE_T *fp;
37	sasl_conn_t *conn;
38};
39
40/*
41**  SASL_GETINFO - returns requested information about a "sasl" file
42**		  descriptor.
43**
44**	Parameters:
45**		fp -- the file descriptor
46**		what -- the type of information requested
47**		valp -- the thang to return the information in
48**
49**	Returns:
50**		-1 for unknown requests
51**		>=0 on success with valp filled in (if possible).
52*/
53
54static int sasl_getinfo __P((SM_FILE_T *, int, void *));
55
56static int
57sasl_getinfo(fp, what, valp)
58	SM_FILE_T *fp;
59	int what;
60	void *valp;
61{
62	struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
63
64	switch (what)
65	{
66	  case SM_IO_WHAT_FD:
67		if (so->fp == NULL)
68			return -1;
69		return so->fp->f_file; /* for stdio fileno() compatibility */
70
71	  case SM_IO_IS_READABLE:
72		if (so->fp == NULL)
73			return 0;
74
75		/* get info from underlying file */
76		return sm_io_getinfo(so->fp, what, valp);
77
78	  default:
79		return -1;
80	}
81}
82
83/*
84**  SASL_OPEN -- creates the sasl specific information for opening a
85**		file of the sasl type.
86**
87**	Parameters:
88**		fp -- the file pointer associated with the new open
89**		info -- contains the sasl connection information pointer and
90**			the original SM_FILE_T that holds the open
91**		flags -- ignored
92**		rpool -- ignored
93**
94**	Returns:
95**		0 on success
96*/
97
98static int sasl_open __P((SM_FILE_T *, const void *, int, const void *));
99
100/* ARGSUSED2 */
101static int
102sasl_open(fp, info, flags, rpool)
103	SM_FILE_T *fp;
104	const void *info;
105	int flags;
106	const void *rpool;
107{
108	struct sasl_obj *so;
109	struct sasl_info *si = (struct sasl_info *) info;
110
111	so = (struct sasl_obj *) sm_malloc(sizeof(struct sasl_obj));
112	if (so == NULL)
113	{
114		errno = ENOMEM;
115		return -1;
116	}
117	so->fp = si->fp;
118	so->conn = si->conn;
119
120	/*
121	**  The underlying 'fp' is set to SM_IO_NOW so that the entire
122	**  encoded string is written in one chunk. Otherwise there is
123	**  the possibility that it may appear illegal, bogus or
124	**  mangled to the other side of the connection.
125	**  We will read or write through 'fp' since it is the opaque
126	**  connection for the communications. We need to treat it this
127	**  way in case the encoded string is to be sent down a TLS
128	**  connection rather than, say, sm_io's stdio.
129	*/
130
131	(void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
132	fp->f_cookie = so;
133	return 0;
134}
135
136/*
137**  SASL_CLOSE -- close the sasl specific parts of the sasl file pointer
138**
139**	Parameters:
140**		fp -- the file pointer to close
141**
142**	Returns:
143**		0 on success
144*/
145
146static int sasl_close __P((SM_FILE_T *));
147
148static int
149sasl_close(fp)
150	SM_FILE_T *fp;
151{
152	struct sasl_obj *so;
153
154	so = (struct sasl_obj *) fp->f_cookie;
155	if (so == NULL)
156		return 0;
157	SM_CLOSE_FP(so->fp);
158	sm_free(so);
159	so = NULL;
160	return 0;
161}
162
163/* how to deallocate a buffer allocated by SASL */
164extern void	sm_sasl_free __P((void *));
165#  define SASL_DEALLOC(b)	sm_sasl_free(b)
166
167/*
168**  SASL_READ -- read encrypted information and decrypt it for the caller
169**
170**	Parameters:
171**		fp -- the file pointer
172**		buf -- the location to place the decrypted information
173**		size -- the number of bytes to read after decryption
174**
175**	Returns:
176**		-1 on error
177**		otherwise the number of bytes read
178*/
179
180static ssize_t sasl_read __P((SM_FILE_T *, char *, size_t));
181
182static ssize_t
183sasl_read(fp, buf, size)
184	SM_FILE_T *fp;
185	char *buf;
186	size_t size;
187{
188	int result;
189	ssize_t len;
190# if SASL >= 20000
191	static const char *outbuf = NULL;
192# else
193	static char *outbuf = NULL;
194# endif
195	static unsigned int outlen = 0;
196	static unsigned int offset = 0;
197	struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
198
199	/*
200	**  sasl_decode() may require more data than a single read() returns.
201	**  Hence we have to put a loop around the decoding.
202	**  This also requires that we may have to split up the returned
203	**  data since it might be larger than the allowed size.
204	**  Therefore we use a static pointer and return portions of it
205	**  if necessary.
206	**  XXX Note: This function is not thread-safe nor can it be used
207	**  on more than one file. A correct implementation would store
208	**  this data in fp->f_cookie.
209	*/
210
211# if SASL >= 20000
212	while (outlen == 0)
213# else
214	while (outbuf == NULL && outlen == 0)
215# endif
216	{
217		len = sm_io_read(so->fp, SM_TIME_DEFAULT, buf, size);
218		if (len <= 0)
219			return len;
220		result = sasl_decode(so->conn, buf,
221				     (unsigned int) len, &outbuf, &outlen);
222		if (result != SASL_OK)
223		{
224			if (LogLevel > 7)
225				sm_syslog(LOG_WARNING, NOQID,
226					"AUTH: sasl_decode error=%d", result);
227			outbuf = NULL;
228			offset = 0;
229			outlen = 0;
230			return -1;
231		}
232	}
233
234	if (outbuf == NULL)
235	{
236		/* be paranoid: outbuf == NULL but outlen != 0 */
237		syserr("@sasl_read failure: outbuf == NULL but outlen != 0");
238		/* NOTREACHED */
239	}
240	if (outlen - offset > size)
241	{
242		/* return another part of the buffer */
243		(void) memcpy(buf, outbuf + offset, size);
244		offset += size;
245		len = size;
246	}
247	else
248	{
249		/* return the rest of the buffer */
250		len = outlen - offset;
251		(void) memcpy(buf, outbuf + offset, (size_t) len);
252# if SASL < 20000
253		SASL_DEALLOC(outbuf);
254# endif
255		outbuf = NULL;
256		offset = 0;
257		outlen = 0;
258	}
259	return len;
260}
261
262/*
263**  SASL_WRITE -- write information out after encrypting it
264**
265**	Parameters:
266**		fp -- the file pointer
267**		buf -- holds the data to be encrypted and written
268**		size -- the number of bytes to have encrypted and written
269**
270**	Returns:
271**		-1 on error
272**		otherwise number of bytes written
273*/
274
275static ssize_t sasl_write __P((SM_FILE_T *, const char *, size_t));
276
277static ssize_t
278sasl_write(fp, buf, size)
279	SM_FILE_T *fp;
280	const char *buf;
281	size_t size;
282{
283	int result;
284# if SASL >= 20000
285	const char *outbuf;
286# else
287	char *outbuf;
288# endif
289	unsigned int outlen, *maxencode;
290	size_t ret = 0, total = 0;
291	struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
292
293	/*
294	**  Fetch the maximum input buffer size for sasl_encode().
295	**  This can be less than the size set in attemptauth()
296	**  due to a negotiation with the other side, e.g.,
297	**  Cyrus IMAP lmtp program sets maxbuf=4096,
298	**  digestmd5 subtracts 25 and hence we'll get 4071
299	**  instead of 8192 (MAXOUTLEN).
300	**  Hack (for now): simply reduce the size, callers are (must be)
301	**  able to deal with that and invoke sasl_write() again with
302	**  the rest of the data.
303	**  Note: it would be better to store this value in the context
304	**  after the negotiation.
305	*/
306
307	result = sasl_getprop(so->conn, SASL_MAXOUTBUF,
308				(const void **) &maxencode);
309	if (result == SASL_OK && size > *maxencode && *maxencode > 0)
310		size = *maxencode;
311
312	result = sasl_encode(so->conn, buf,
313			     (unsigned int) size, &outbuf, &outlen);
314
315	if (result != SASL_OK)
316	{
317		if (LogLevel > 7)
318			sm_syslog(LOG_WARNING, NOQID,
319				"AUTH: sasl_encode error=%d", result);
320		return -1;
321	}
322
323	if (outbuf != NULL)
324	{
325		while (outlen > 0)
326		{
327			errno = 0;
328			/* XXX result == 0? */
329			ret = sm_io_write(so->fp, SM_TIME_DEFAULT,
330					  &outbuf[total], outlen);
331			if (ret <= 0)
332				return ret;
333			outlen -= ret;
334			total += ret;
335		}
336# if SASL < 20000
337		SASL_DEALLOC(outbuf);
338# endif
339	}
340	return size;
341}
342
343/*
344**  SFDCSASL -- create sasl file type and open in and out file pointers
345**	       for sendmail to read from and write to.
346**
347**	Parameters:
348**		fin -- the sm_io file encrypted data to be read from
349**		fout -- the sm_io file encrypted data to be written to
350**		conn -- the sasl connection pointer
351**		tmo -- timeout
352**
353**	Returns:
354**		-1 on error
355**		0 on success
356**
357**	Side effects:
358**		The arguments "fin" and "fout" are replaced with the new
359**		SM_FILE_T pointers.
360*/
361
362int
363sfdcsasl(fin, fout, conn, tmo)
364	SM_FILE_T **fin;
365	SM_FILE_T **fout;
366	sasl_conn_t *conn;
367	int tmo;
368{
369	SM_FILE_T *newin, *newout;
370	SM_FILE_T  SM_IO_SET_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
371		sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
372		SM_TIME_DEFAULT);
373	struct sasl_info info;
374
375	if (conn == NULL)
376	{
377		/* no need to do anything */
378		return 0;
379	}
380
381	SM_IO_INIT_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
382		sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
383		SM_TIME_DEFAULT);
384	info.fp = *fin;
385	info.conn = conn;
386	newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
387			SM_IO_RDONLY_B, NULL);
388
389	if (newin == NULL)
390		return -1;
391
392	info.fp = *fout;
393	info.conn = conn;
394	newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
395			SM_IO_WRONLY_B, NULL);
396
397	if (newout == NULL)
398	{
399		(void) sm_io_close(newin, SM_TIME_DEFAULT);
400		return -1;
401	}
402	sm_io_automode(newin, newout);
403
404	sm_io_setinfo(*fin, SM_IO_WHAT_TIMEOUT, &tmo);
405	sm_io_setinfo(*fout, SM_IO_WHAT_TIMEOUT, &tmo);
406
407	*fin = newin;
408	*fout = newout;
409	return 0;
410}
411#endif /* SASL */
412
413#if STARTTLS
414# include "sfsasl.h"
415# include <tls.h>
416# include <openssl/err.h>
417
418/* Structure used by the "tls" file type */
419struct tls_obj
420{
421	SM_FILE_T *fp;
422	SSL *con;
423};
424
425struct tls_info
426{
427	SM_FILE_T *fp;
428	SSL *con;
429};
430
431/*
432**  TLS_GETINFO - returns requested information about a "tls" file
433**		 descriptor.
434**
435**	Parameters:
436**		fp -- the file descriptor
437**		what -- the type of information requested
438**		valp -- the thang to return the information in (unused)
439**
440**	Returns:
441**		-1 for unknown requests
442**		>=0 on success with valp filled in (if possible).
443*/
444
445static int tls_getinfo __P((SM_FILE_T *, int, void *));
446
447/* ARGSUSED2 */
448static int
449tls_getinfo(fp, what, valp)
450	SM_FILE_T *fp;
451	int what;
452	void *valp;
453{
454	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
455
456	switch (what)
457	{
458	  case SM_IO_WHAT_FD:
459		if (so->fp == NULL)
460			return -1;
461		return so->fp->f_file; /* for stdio fileno() compatibility */
462
463	  case SM_IO_IS_READABLE:
464		return SSL_pending(so->con) > 0;
465
466	  default:
467		return -1;
468	}
469}
470
471/*
472**  TLS_OPEN -- creates the tls specific information for opening a
473**	       file of the tls type.
474**
475**	Parameters:
476**		fp -- the file pointer associated with the new open
477**		info -- the sm_io file pointer holding the open and the
478**			TLS encryption connection to be read from or written to
479**		flags -- ignored
480**		rpool -- ignored
481**
482**	Returns:
483**		0 on success
484*/
485
486static int tls_open __P((SM_FILE_T *, const void *, int, const void *));
487
488/* ARGSUSED2 */
489static int
490tls_open(fp, info, flags, rpool)
491	SM_FILE_T *fp;
492	const void *info;
493	int flags;
494	const void *rpool;
495{
496	struct tls_obj *so;
497	struct tls_info *ti = (struct tls_info *) info;
498
499	so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj));
500	if (so == NULL)
501	{
502		errno = ENOMEM;
503		return -1;
504	}
505	so->fp = ti->fp;
506	so->con = ti->con;
507
508	/*
509	**  We try to get the "raw" file descriptor that TLS uses to
510	**  do the actual read/write with. This is to allow us control
511	**  over the file descriptor being a blocking or non-blocking type.
512	**  Under the covers TLS handles the change and this allows us
513	**  to do timeouts with sm_io.
514	*/
515
516	fp->f_file = sm_io_getinfo(so->fp, SM_IO_WHAT_FD, NULL);
517	(void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
518	fp->f_cookie = so;
519	return 0;
520}
521
522/*
523**  TLS_CLOSE -- close the tls specific parts of the tls file pointer
524**
525**	Parameters:
526**		fp -- the file pointer to close
527**
528**	Returns:
529**		0 on success
530*/
531
532static int tls_close __P((SM_FILE_T *));
533
534static int
535tls_close(fp)
536	SM_FILE_T *fp;
537{
538	struct tls_obj *so;
539
540	so = (struct tls_obj *) fp->f_cookie;
541	if (so == NULL)
542		return 0;
543	SM_CLOSE_FP(so->fp);
544	sm_free(so);
545	so = NULL;
546	return 0;
547}
548
549/* maximum number of retries for TLS related I/O due to handshakes */
550# define MAX_TLS_IOS	4
551
552/*
553**  TLS_RETRY -- check whether a failed SSL operation can be retried
554**
555**	Parameters:
556**		ssl -- TLS structure
557**		rfd -- read fd
558**		wfd -- write fd
559**		tlsstart -- start time of TLS operation
560**		timeout -- timeout for TLS operation
561**		err -- SSL error
562**		where -- description of operation
563**
564**	Returns:
565**		>0 on success
566**		0 on timeout
567**		<0 on error
568*/
569
570int
571tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
572	SSL *ssl;
573	int rfd;
574	int wfd;
575	time_t tlsstart;
576	int timeout;
577	int err;
578	const char *where;
579{
580	int ret;
581	time_t left;
582	time_t now = curtime();
583	struct timeval tv;
584
585	ret = -1;
586
587	/*
588	**  For SSL_ERROR_WANT_{READ,WRITE}:
589	**  There is not a complete SSL record available yet
590	**  or there is only a partial SSL record removed from
591	**  the network (socket) buffer into the SSL buffer.
592	**  The SSL_connect will only succeed when a full
593	**  SSL record is available (assuming a "real" error
594	**  doesn't happen). To handle when a "real" error
595	**  does happen the select is set for exceptions too.
596	**  The connection may be re-negotiated during this time
597	**  so both read and write "want errors" need to be handled.
598	**  A select() exception loops back so that a proper SSL
599	**  error message can be gotten.
600	*/
601
602	left = timeout - (now - tlsstart);
603	if (left <= 0)
604		return 0;	/* timeout */
605	tv.tv_sec = left;
606	tv.tv_usec = 0;
607
608	if (LogLevel > 14)
609	{
610		sm_syslog(LOG_INFO, NOQID,
611			  "STARTTLS=%s, info: fds=%d/%d, err=%d",
612			  where, rfd, wfd, err);
613	}
614
615	if ((err == SSL_ERROR_WANT_READ && !SM_FD_OK_SELECT(rfd)) ||
616	    (err == SSL_ERROR_WANT_WRITE && !SM_FD_OK_SELECT(wfd)))
617	{
618		if (LogLevel > 5)
619		{
620			sm_syslog(LOG_ERR, NOQID,
621				  "STARTTLS=%s, error: fd %d/%d too large",
622				  where, rfd, wfd);
623			tlslogerr(LOG_WARNING, 8, where);
624		}
625		errno = EINVAL;
626	}
627	else if (err == SSL_ERROR_WANT_READ)
628	{
629		fd_set ssl_maskr, ssl_maskx;
630		int save_errno = errno;
631
632		FD_ZERO(&ssl_maskr);
633		FD_SET(rfd, &ssl_maskr);
634		FD_ZERO(&ssl_maskx);
635		FD_SET(rfd, &ssl_maskx);
636		do
637		{
638			ret = select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx,
639					&tv);
640		} while (ret < 0 && errno == EINTR);
641		if (ret < 0 && errno > 0)
642			ret = -errno;
643		errno = save_errno;
644	}
645	else if (err == SSL_ERROR_WANT_WRITE)
646	{
647		fd_set ssl_maskw, ssl_maskx;
648		int save_errno = errno;
649
650		FD_ZERO(&ssl_maskw);
651		FD_SET(wfd, &ssl_maskw);
652		FD_ZERO(&ssl_maskx);
653		FD_SET(rfd, &ssl_maskx);
654		do
655		{
656			ret = select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx,
657					&tv);
658		} while (ret < 0 && errno == EINTR);
659		if (ret < 0 && errno > 0)
660			ret = -errno;
661		errno = save_errno;
662	}
663	return ret;
664}
665
666/* errno to force refill() etc to stop (see IS_IO_ERROR()) */
667# ifdef ETIMEDOUT
668#  define SM_ERR_TIMEOUT	ETIMEDOUT
669# else
670#  define SM_ERR_TIMEOUT	EIO
671# endif
672
673/*
674**  SET_TLS_RD_TMO -- read secured information for the caller
675**
676**	Parameters:
677**		rd_tmo -- read timeout
678**
679**	Returns:
680**		previous read timeout
681**	This is a hack: there is no way to pass it in
682*/
683
684static int tls_rd_tmo = -1;
685
686int
687set_tls_rd_tmo(rd_tmo)
688	int rd_tmo;
689{
690	int old_rd_tmo;
691
692	old_rd_tmo = tls_rd_tmo;
693	tls_rd_tmo = rd_tmo;
694	return old_rd_tmo;
695}
696
697/*
698**  TLS_READ -- read secured information for the caller
699**
700**	Parameters:
701**		fp -- the file pointer
702**		buf -- the location to place the data
703**		size -- the number of bytes to read from connection
704**
705**	Returns:
706**		-1 on error
707**		otherwise the number of bytes read
708*/
709
710static ssize_t tls_read __P((SM_FILE_T *, char *, size_t));
711
712static ssize_t
713tls_read(fp, buf, size)
714	SM_FILE_T *fp;
715	char *buf;
716	size_t size;
717{
718	int r, rfd, wfd, try, ssl_err;
719	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
720	time_t tlsstart;
721	char *err;
722
723	try = 99;
724	err = NULL;
725	tlsstart = curtime();
726
727  retry:
728	r = SSL_read(so->con, (char *) buf, size);
729
730	if (r > 0)
731		return r;
732
733	err = NULL;
734	switch (ssl_err = SSL_get_error(so->con, r))
735	{
736	  case SSL_ERROR_NONE:
737	  case SSL_ERROR_ZERO_RETURN:
738		break;
739	  case SSL_ERROR_WANT_WRITE:
740		err = "read W BLOCK";
741		/* FALLTHROUGH */
742	  case SSL_ERROR_WANT_READ:
743		if (err == NULL)
744			err = "read R BLOCK";
745		rfd = SSL_get_rfd(so->con);
746		wfd = SSL_get_wfd(so->con);
747		try = tls_retry(so->con, rfd, wfd, tlsstart,
748				(tls_rd_tmo < 0) ? TimeOuts.to_datablock
749						 : tls_rd_tmo,
750				ssl_err, "read");
751		if (try > 0)
752			goto retry;
753		errno = SM_ERR_TIMEOUT;
754		break;
755
756	  case SSL_ERROR_WANT_X509_LOOKUP:
757		err = "write X BLOCK";
758		break;
759	  case SSL_ERROR_SYSCALL:
760		if (r == 0 && errno == 0) /* out of protocol EOF found */
761			break;
762		err = "syscall error";
763		break;
764	  case SSL_ERROR_SSL:
765# if DEAL_WITH_ERROR_SSL
766		if (r == 0 && errno == 0) /* out of protocol EOF found */
767			break;
768# endif
769		err = "generic SSL error";
770
771		if (LogLevel > 9)
772		{
773			int pri;
774
775			if (errno == EAGAIN && try > 0)
776				pri = LOG_DEBUG;
777			else
778				pri = LOG_WARNING;
779			tlslogerr(pri, 9, "read");
780		}
781
782# if DEAL_WITH_ERROR_SSL
783		/* avoid repeated calls? */
784		if (r == 0)
785			r = -1;
786# endif
787		break;
788	}
789	if (err != NULL)
790	{
791		int save_errno;
792
793		save_errno = (errno == 0) ? EIO : errno;
794		if (try == 0 && save_errno == SM_ERR_TIMEOUT)
795		{
796			if (LogLevel > 7)
797				sm_syslog(LOG_WARNING, NOQID,
798					  "STARTTLS: read error=timeout");
799		}
800		else if (LogLevel > 8)
801		{
802			int pri;
803
804			if (save_errno == EAGAIN && try > 0)
805				pri = LOG_DEBUG;
806			else
807				pri = LOG_WARNING;
808			sm_syslog(pri, NOQID,
809				  "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
810				  err, r, errno,
811				  ERR_error_string(ERR_get_error(), NULL), try,
812				  ssl_err);
813		}
814		else if (LogLevel > 7)
815			sm_syslog(LOG_WARNING, NOQID,
816				  "STARTTLS: read error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
817				  err, r, errno, try, ssl_err);
818		errno = save_errno;
819	}
820	return r;
821}
822
823/*
824**  TLS_WRITE -- write information out through secure connection
825**
826**	Parameters:
827**		fp -- the file pointer
828**		buf -- holds the data to be securely written
829**		size -- the number of bytes to write
830**
831**	Returns:
832**		-1 on error
833**		otherwise number of bytes written
834*/
835
836static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t));
837
838static ssize_t
839tls_write(fp, buf, size)
840	SM_FILE_T *fp;
841	const char *buf;
842	size_t size;
843{
844	int r, rfd, wfd, try, ssl_err;
845	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
846	time_t tlsstart;
847	char *err;
848
849	try = 99;
850	err = NULL;
851	tlsstart = curtime();
852
853  retry:
854	r = SSL_write(so->con, (char *) buf, size);
855
856	if (r > 0)
857		return r;
858	err = NULL;
859	switch (ssl_err = SSL_get_error(so->con, r))
860	{
861	  case SSL_ERROR_NONE:
862	  case SSL_ERROR_ZERO_RETURN:
863		break;
864	  case SSL_ERROR_WANT_WRITE:
865		err = "read W BLOCK";
866		/* FALLTHROUGH */
867	  case SSL_ERROR_WANT_READ:
868		if (err == NULL)
869			err = "read R BLOCK";
870		rfd = SSL_get_rfd(so->con);
871		wfd = SSL_get_wfd(so->con);
872		try = tls_retry(so->con, rfd, wfd, tlsstart,
873				DATA_PROGRESS_TIMEOUT, ssl_err, "write");
874		if (try > 0)
875			goto retry;
876		errno = SM_ERR_TIMEOUT;
877		break;
878	  case SSL_ERROR_WANT_X509_LOOKUP:
879		err = "write X BLOCK";
880		break;
881	  case SSL_ERROR_SYSCALL:
882		if (r == 0 && errno == 0) /* out of protocol EOF found */
883			break;
884		err = "syscall error";
885		break;
886	  case SSL_ERROR_SSL:
887		err = "generic SSL error";
888/*
889		ERR_GET_REASON(ERR_peek_error()));
890*/
891		tlslogerr(LOG_WARNING, 9, "write");
892
893# if DEAL_WITH_ERROR_SSL
894		/* avoid repeated calls? */
895		if (r == 0)
896			r = -1;
897# endif
898		break;
899	}
900	if (err != NULL)
901	{
902		int save_errno;
903
904		save_errno = (errno == 0) ? EIO : errno;
905		if (try == 0 && save_errno == SM_ERR_TIMEOUT)
906		{
907			if (LogLevel > 7)
908				sm_syslog(LOG_WARNING, NOQID,
909					  "STARTTLS: write error=timeout");
910		}
911		else if (LogLevel > 8)
912			sm_syslog(LOG_WARNING, NOQID,
913				  "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
914				  err, r, errno,
915				  ERR_error_string(ERR_get_error(), NULL), try,
916				  ssl_err);
917		else if (LogLevel > 7)
918			sm_syslog(LOG_WARNING, NOQID,
919				  "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
920				  err, r, errno, try, ssl_err);
921		errno = save_errno;
922	}
923	return r;
924}
925
926/*
927**  SFDCTLS -- create tls file type and open in and out file pointers
928**	      for sendmail to read from and write to.
929**
930**	Parameters:
931**		fin -- data input source being replaced
932**		fout -- data output source being replaced
933**		con -- the tls connection pointer
934**
935**	Returns:
936**		-1 on error
937**		0 on success
938**
939**	Side effects:
940**		The arguments "fin" and "fout" are replaced with the new
941**		SM_FILE_T pointers.
942**		The original "fin" and "fout" are preserved in the tls file
943**		type but are not actually used because of the design of TLS.
944*/
945
946int
947sfdctls(fin, fout, con)
948	SM_FILE_T **fin;
949	SM_FILE_T **fout;
950	SSL *con;
951{
952	SM_FILE_T *tlsin, *tlsout;
953	SM_FILE_T SM_IO_SET_TYPE(tls_vector, "tls", tls_open, tls_close,
954		tls_read, tls_write, NULL, tls_getinfo, NULL,
955		SM_TIME_FOREVER);
956	struct tls_info info;
957
958	SM_ASSERT(con != NULL);
959
960	SM_IO_INIT_TYPE(tls_vector, "tls", tls_open, tls_close,
961		tls_read, tls_write, NULL, tls_getinfo, NULL,
962		SM_TIME_FOREVER);
963	info.fp = *fin;
964	info.con = con;
965	tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY_B,
966			   NULL);
967	if (tlsin == NULL)
968		return -1;
969
970	info.fp = *fout;
971	tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY_B,
972			    NULL);
973	if (tlsout == NULL)
974	{
975		(void) sm_io_close(tlsin, SM_TIME_DEFAULT);
976		return -1;
977	}
978	sm_io_automode(tlsin, tlsout);
979
980	*fin = tlsin;
981	*fout = tlsout;
982	return 0;
983}
984#endif /* STARTTLS */
985