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