xref: /freebsd/contrib/sendmail/src/sfsasl.c (revision d9a42747950146bf03cda7f6e25d219253f8a57a)
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>
12 SM_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 */
28 struct sasl_obj
29 {
30 	SM_FILE_T *fp;
31 	sasl_conn_t *conn;
32 };
33 
34 struct 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 
54 static int sasl_getinfo __P((SM_FILE_T *, int, void *));
55 
56 static int
57 sasl_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 
98 static int sasl_open __P((SM_FILE_T *, const void *, int, const void *));
99 
100 /* ARGSUSED2 */
101 static int
102 sasl_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 
146 static int sasl_close __P((SM_FILE_T *));
147 
148 static int
149 sasl_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 */
164 extern 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 **	Results:
176 **		-1 on error
177 **		otherwise the number of bytes read
178 */
179 
180 static ssize_t sasl_read __P((SM_FILE_T *, char *, size_t));
181 
182 static ssize_t
183 sasl_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 
275 static ssize_t sasl_write __P((SM_FILE_T *, const char *, size_t));
276 
277 static ssize_t
278 sasl_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 
362 int
363 sfdcsasl(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 */
419 struct tls_obj
420 {
421 	SM_FILE_T *fp;
422 	SSL *con;
423 };
424 
425 struct 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 
445 static int tls_getinfo __P((SM_FILE_T *, int, void *));
446 
447 /* ARGSUSED2 */
448 static int
449 tls_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 
486 static int tls_open __P((SM_FILE_T *, const void *, int, const void *));
487 
488 /* ARGSUSED2 */
489 static int
490 tls_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 
532 static int tls_close __P((SM_FILE_T *));
533 
534 static int
535 tls_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 **	Results:
565 **		>0 on success
566 **		0 on timeout
567 **		<0 on error
568 */
569 
570 int
571 tls_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 **	Results:
680 **		previous read timeout
681 **	This is a hack: there is no way to pass it in
682 */
683 
684 static int tls_rd_tmo = -1;
685 
686 int
687 set_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 **	Results:
706 **		-1 on error
707 **		otherwise the number of bytes read
708 */
709 
710 static ssize_t tls_read __P((SM_FILE_T *, char *, size_t));
711 
712 static ssize_t
713 tls_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 
836 static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t));
837 
838 static ssize_t
839 tls_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 
946 int
947 sfdctls(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