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