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