xref: /freebsd/contrib/sendmail/src/sfsasl.c (revision 119b75925c562202145d7bac7b676b98029c6cb9)
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 /* ! 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 negotiation 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 			errno = 0;
332 			/* XXX result == 0? */
333 			ret = sm_io_write(so->fp, SM_TIME_DEFAULT,
334 					  &outbuf[total], outlen);
335 			if (ret <= 0)
336 				return ret;
337 			outlen -= ret;
338 			total += ret;
339 		}
340 # if SASL < 20000
341 		SASL_DEALLOC(outbuf);
342 # endif /* SASL < 20000 */
343 	}
344 	return size;
345 }
346 
347 /*
348 **  SFDCSASL -- create sasl file type and open in and out file pointers
349 **	       for sendmail to read from and write to.
350 **
351 **	Parameters:
352 **		fin -- the sm_io file encrypted data to be read from
353 **		fout -- the sm_io file encrypted data to be written to
354 **		conn -- the sasl connection pointer
355 **		tmo -- timeout
356 **
357 **	Returns:
358 **		-1 on error
359 **		0 on success
360 **
361 **	Side effects:
362 **		The arguments "fin" and "fout" are replaced with the new
363 **		SM_FILE_T pointers.
364 */
365 
366 int
367 sfdcsasl(fin, fout, conn, tmo)
368 	SM_FILE_T **fin;
369 	SM_FILE_T **fout;
370 	sasl_conn_t *conn;
371 	int tmo;
372 {
373 	SM_FILE_T *newin, *newout;
374 	SM_FILE_T  SM_IO_SET_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
375 		sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
376 		SM_TIME_DEFAULT);
377 	struct sasl_info info;
378 
379 	if (conn == NULL)
380 	{
381 		/* no need to do anything */
382 		return 0;
383 	}
384 
385 	SM_IO_INIT_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
386 		sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
387 		SM_TIME_DEFAULT);
388 	info.fp = *fin;
389 	info.conn = conn;
390 	newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
391 			SM_IO_RDONLY_B, NULL);
392 
393 	if (newin == NULL)
394 		return -1;
395 
396 	info.fp = *fout;
397 	info.conn = conn;
398 	newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
399 			SM_IO_WRONLY_B, NULL);
400 
401 	if (newout == NULL)
402 	{
403 		(void) sm_io_close(newin, SM_TIME_DEFAULT);
404 		return -1;
405 	}
406 	sm_io_automode(newin, newout);
407 
408 	sm_io_setinfo(*fin, SM_IO_WHAT_TIMEOUT, &tmo);
409 	sm_io_setinfo(*fout, SM_IO_WHAT_TIMEOUT, &tmo);
410 
411 	*fin = newin;
412 	*fout = newout;
413 	return 0;
414 }
415 #endif /* SASL */
416 
417 #if STARTTLS
418 # include "sfsasl.h"
419 # include <openssl/err.h>
420 
421 /* Structure used by the "tls" file type */
422 struct tls_obj
423 {
424 	SM_FILE_T *fp;
425 	SSL *con;
426 };
427 
428 struct tls_info
429 {
430 	SM_FILE_T *fp;
431 	SSL *con;
432 };
433 
434 /*
435 **  TLS_GETINFO - returns requested information about a "tls" file
436 **		 descriptor.
437 **
438 **	Parameters:
439 **		fp -- the file descriptor
440 **		what -- the type of information requested
441 **		valp -- the thang to return the information in (unused)
442 **
443 **	Returns:
444 **		-1 for unknown requests
445 **		>=0 on success with valp filled in (if possible).
446 */
447 
448 static int tls_getinfo __P((SM_FILE_T *, int, void *));
449 
450 /* ARGSUSED2 */
451 static int
452 tls_getinfo(fp, what, valp)
453 	SM_FILE_T *fp;
454 	int what;
455 	void *valp;
456 {
457 	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
458 
459 	switch (what)
460 	{
461 	  case SM_IO_WHAT_FD:
462 		if (so->fp == NULL)
463 			return -1;
464 		return so->fp->f_file; /* for stdio fileno() compatability */
465 
466 	  case SM_IO_IS_READABLE:
467 		return SSL_pending(so->con) > 0;
468 
469 	  default:
470 		return -1;
471 	}
472 }
473 
474 /*
475 **  TLS_OPEN -- creates the tls specific information for opening a
476 **	       file of the tls type.
477 **
478 **	Parameters:
479 **		fp -- the file pointer associated with the new open
480 **		info -- the sm_io file pointer holding the open and the
481 **			TLS encryption connection to be read from or written to
482 **		flags -- ignored
483 **		rpool -- ignored
484 **
485 **	Returns:
486 **		0 on success
487 */
488 
489 static int tls_open __P((SM_FILE_T *, const void *, int, const void *));
490 
491 /* ARGSUSED2 */
492 static int
493 tls_open(fp, info, flags, rpool)
494 	SM_FILE_T *fp;
495 	const void *info;
496 	int flags;
497 	const void *rpool;
498 {
499 	struct tls_obj *so;
500 	struct tls_info *ti = (struct tls_info *) info;
501 
502 	so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj));
503 	if (so == NULL)
504 	{
505 		errno = ENOMEM;
506 		return -1;
507 	}
508 	so->fp = ti->fp;
509 	so->con = ti->con;
510 
511 	/*
512 	**  We try to get the "raw" file descriptor that TLS uses to
513 	**  do the actual read/write with. This is to allow us control
514 	**  over the file descriptor being a blocking or non-blocking type.
515 	**  Under the covers TLS handles the change and this allows us
516 	**  to do timeouts with sm_io.
517 	*/
518 
519 	fp->f_file = sm_io_getinfo(so->fp, SM_IO_WHAT_FD, NULL);
520 	(void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
521 	fp->f_cookie = so;
522 	return 0;
523 }
524 
525 /*
526 **  TLS_CLOSE -- close the tls specific parts of the tls file pointer
527 **
528 **	Parameters:
529 **		fp -- the file pointer to close
530 **
531 **	Returns:
532 **		0 on success
533 */
534 
535 static int tls_close __P((SM_FILE_T *));
536 
537 static int
538 tls_close(fp)
539 	SM_FILE_T *fp;
540 {
541 	struct tls_obj *so;
542 
543 	so = (struct tls_obj *) fp->f_cookie;
544 	if (so == NULL)
545 		return 0;
546 	if (so->fp != NULL)
547 	{
548 		sm_io_close(so->fp, SM_TIME_DEFAULT);
549 		so->fp = NULL;
550 	}
551 	sm_free(so);
552 	so = NULL;
553 	return 0;
554 }
555 
556 /* maximum number of retries for TLS related I/O due to handshakes */
557 # define MAX_TLS_IOS	4
558 
559 /*
560 **  TLS_RETRY -- check whether a failed SSL operation can be retried
561 **
562 **	Parameters:
563 **		ssl -- TLS structure
564 **		rfd -- read fd
565 **		wfd -- write fd
566 **		tlsstart -- start time of TLS operation
567 **		timeout -- timeout for TLS operation
568 **		err -- SSL error
569 **		where -- description of operation
570 **
571 **	Results:
572 **		>0 on success
573 **		0 on timeout
574 **		<0 on error
575 */
576 
577 int
578 tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
579 	SSL *ssl;
580 	int rfd;
581 	int wfd;
582 	time_t tlsstart;
583 	int timeout;
584 	int err;
585 	const char *where;
586 {
587 	int ret;
588 	time_t left;
589 	time_t now = curtime();
590 	struct timeval tv;
591 
592 	ret = -1;
593 
594 	/*
595 	**  For SSL_ERROR_WANT_{READ,WRITE}:
596 	**  There is not a complete SSL record available yet
597 	**  or there is only a partial SSL record removed from
598 	**  the network (socket) buffer into the SSL buffer.
599 	**  The SSL_connect will only succeed when a full
600 	**  SSL record is available (assuming a "real" error
601 	**  doesn't happen). To handle when a "real" error
602 	**  does happen the select is set for exceptions too.
603 	**  The connection may be re-negotiated during this time
604 	**  so both read and write "want errors" need to be handled.
605 	**  A select() exception loops back so that a proper SSL
606 	**  error message can be gotten.
607 	*/
608 
609 	left = timeout - (now - tlsstart);
610 	if (left <= 0)
611 		return 0;	/* timeout */
612 	tv.tv_sec = left;
613 	tv.tv_usec = 0;
614 
615 	if (LogLevel > 14)
616 	{
617 		sm_syslog(LOG_INFO, NOQID,
618 			  "STARTTLS=%s, info: fds=%d/%d, err=%d",
619 			  where, rfd, wfd, err);
620 	}
621 
622 	if ((err == SSL_ERROR_WANT_READ && !SM_FD_OK_SELECT(rfd)) ||
623 	    (err == SSL_ERROR_WANT_WRITE && !SM_FD_OK_SELECT(wfd)))
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 **		previous read timeout
689 **	This is a hack: there is no way to pass it in
690 */
691 
692 static int tls_rd_tmo = -1;
693 
694 int
695 set_tls_rd_tmo(rd_tmo)
696 	int rd_tmo;
697 {
698 	int old_rd_tmo;
699 
700 	old_rd_tmo = tls_rd_tmo;
701 	tls_rd_tmo = rd_tmo;
702 	return old_rd_tmo;
703 }
704 
705 /*
706 **  TLS_READ -- read secured information for the caller
707 **
708 **	Parameters:
709 **		fp -- the file pointer
710 **		buf -- the location to place the data
711 **		size -- the number of bytes to read from connection
712 **
713 **	Results:
714 **		-1 on error
715 **		otherwise the number of bytes read
716 */
717 
718 static ssize_t tls_read __P((SM_FILE_T *, char *, size_t));
719 
720 static ssize_t
721 tls_read(fp, buf, size)
722 	SM_FILE_T *fp;
723 	char *buf;
724 	size_t size;
725 {
726 	int r, rfd, wfd, try, ssl_err;
727 	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
728 	time_t tlsstart;
729 	char *err;
730 
731 	try = 99;
732 	err = NULL;
733 	tlsstart = curtime();
734 
735   retry:
736 	r = SSL_read(so->con, (char *) buf, size);
737 
738 	if (r > 0)
739 		return r;
740 
741 	err = NULL;
742 	switch (ssl_err = SSL_get_error(so->con, r))
743 	{
744 	  case SSL_ERROR_NONE:
745 	  case SSL_ERROR_ZERO_RETURN:
746 		break;
747 	  case SSL_ERROR_WANT_WRITE:
748 		err = "read W BLOCK";
749 		/* FALLTHROUGH */
750 	  case SSL_ERROR_WANT_READ:
751 		if (err == NULL)
752 			err = "read R BLOCK";
753 		rfd = SSL_get_rfd(so->con);
754 		wfd = SSL_get_wfd(so->con);
755 		try = tls_retry(so->con, rfd, wfd, tlsstart,
756 				(tls_rd_tmo < 0) ? TimeOuts.to_datablock
757 						 : tls_rd_tmo,
758 				ssl_err, "read");
759 		if (try > 0)
760 			goto retry;
761 		errno = SM_ERR_TIMEOUT;
762 		break;
763 
764 	  case SSL_ERROR_WANT_X509_LOOKUP:
765 		err = "write X BLOCK";
766 		break;
767 	  case SSL_ERROR_SYSCALL:
768 		if (r == 0 && errno == 0) /* out of protocol EOF found */
769 			break;
770 		err = "syscall error";
771 /*
772 		get_last_socket_error());
773 */
774 		break;
775 	  case SSL_ERROR_SSL:
776 #if DEAL_WITH_ERROR_SSL
777 		if (r == 0 && errno == 0) /* out of protocol EOF found */
778 			break;
779 #endif /* DEAL_WITH_ERROR_SSL */
780 		err = "generic SSL error";
781 
782 		if (LogLevel > 9)
783 		{
784 			int pri;
785 
786 			if (errno == EAGAIN && try > 0)
787 				pri = LOG_DEBUG;
788 			else
789 				pri = LOG_WARNING;
790 			tlslogerr(pri, "read");
791 		}
792 
793 #if DEAL_WITH_ERROR_SSL
794 		/* avoid repeated calls? */
795 		if (r == 0)
796 			r = -1;
797 #endif /* DEAL_WITH_ERROR_SSL */
798 		break;
799 	}
800 	if (err != NULL)
801 	{
802 		int save_errno;
803 
804 		save_errno = (errno == 0) ? EIO : errno;
805 		if (try == 0 && save_errno == SM_ERR_TIMEOUT)
806 		{
807 			if (LogLevel > 7)
808 				sm_syslog(LOG_WARNING, NOQID,
809 					  "STARTTLS: read error=timeout");
810 		}
811 		else if (LogLevel > 8)
812 		{
813 			int pri;
814 
815 			if (save_errno == EAGAIN && try > 0)
816 				pri = LOG_DEBUG;
817 			else
818 				pri = LOG_WARNING;
819 			sm_syslog(pri, NOQID,
820 				  "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
821 				  err, r, errno,
822 				  ERR_error_string(ERR_get_error(), NULL), try,
823 				  ssl_err);
824 		}
825 		else if (LogLevel > 7)
826 			sm_syslog(LOG_WARNING, NOQID,
827 				  "STARTTLS: read error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
828 				  err, r, errno, try, ssl_err);
829 		errno = save_errno;
830 	}
831 	return r;
832 }
833 
834 /*
835 **  TLS_WRITE -- write information out through secure connection
836 **
837 **	Parameters:
838 **		fp -- the file pointer
839 **		buf -- holds the data to be securely written
840 **		size -- the number of bytes to write
841 **
842 **	Returns:
843 **		-1 on error
844 **		otherwise number of bytes written
845 */
846 
847 static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t));
848 
849 static ssize_t
850 tls_write(fp, buf, size)
851 	SM_FILE_T *fp;
852 	const char *buf;
853 	size_t size;
854 {
855 	int r, rfd, wfd, try, ssl_err;
856 	struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
857 	time_t tlsstart;
858 	char *err;
859 
860 	try = 99;
861 	err = NULL;
862 	tlsstart = curtime();
863 
864   retry:
865 	r = SSL_write(so->con, (char *) buf, size);
866 
867 	if (r > 0)
868 		return r;
869 	err = NULL;
870 	switch (ssl_err = SSL_get_error(so->con, r))
871 	{
872 	  case SSL_ERROR_NONE:
873 	  case SSL_ERROR_ZERO_RETURN:
874 		break;
875 	  case SSL_ERROR_WANT_WRITE:
876 		err = "read W BLOCK";
877 		/* FALLTHROUGH */
878 	  case SSL_ERROR_WANT_READ:
879 		if (err == NULL)
880 			err = "read R BLOCK";
881 		rfd = SSL_get_rfd(so->con);
882 		wfd = SSL_get_wfd(so->con);
883 		try = tls_retry(so->con, rfd, wfd, tlsstart,
884 				DATA_PROGRESS_TIMEOUT, ssl_err, "write");
885 		if (try > 0)
886 			goto retry;
887 		errno = SM_ERR_TIMEOUT;
888 		break;
889 	  case SSL_ERROR_WANT_X509_LOOKUP:
890 		err = "write X BLOCK";
891 		break;
892 	  case SSL_ERROR_SYSCALL:
893 		if (r == 0 && errno == 0) /* out of protocol EOF found */
894 			break;
895 		err = "syscall error";
896 /*
897 		get_last_socket_error());
898 */
899 		break;
900 	  case SSL_ERROR_SSL:
901 		err = "generic SSL error";
902 /*
903 		ERR_GET_REASON(ERR_peek_error()));
904 */
905 		if (LogLevel > 9)
906 			tlslogerr(LOG_WARNING, "write");
907 
908 #if DEAL_WITH_ERROR_SSL
909 		/* avoid repeated calls? */
910 		if (r == 0)
911 			r = -1;
912 #endif /* DEAL_WITH_ERROR_SSL */
913 		break;
914 	}
915 	if (err != NULL)
916 	{
917 		int save_errno;
918 
919 		save_errno = (errno == 0) ? EIO : errno;
920 		if (try == 0 && save_errno == SM_ERR_TIMEOUT)
921 		{
922 			if (LogLevel > 7)
923 				sm_syslog(LOG_WARNING, NOQID,
924 					  "STARTTLS: write error=timeout");
925 		}
926 		else if (LogLevel > 8)
927 			sm_syslog(LOG_WARNING, NOQID,
928 				  "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
929 				  err, r, errno,
930 				  ERR_error_string(ERR_get_error(), NULL), try,
931 				  ssl_err);
932 		else if (LogLevel > 7)
933 			sm_syslog(LOG_WARNING, NOQID,
934 				  "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
935 				  err, r, errno, try, ssl_err);
936 		errno = save_errno;
937 	}
938 	return r;
939 }
940 
941 /*
942 **  SFDCTLS -- create tls file type and open in and out file pointers
943 **	      for sendmail to read from and write to.
944 **
945 **	Parameters:
946 **		fin -- data input source being replaced
947 **		fout -- data output source being replaced
948 **		con -- the tls connection pointer
949 **
950 **	Returns:
951 **		-1 on error
952 **		0 on success
953 **
954 **	Side effects:
955 **		The arguments "fin" and "fout" are replaced with the new
956 **		SM_FILE_T pointers.
957 **		The original "fin" and "fout" are preserved in the tls file
958 **		type but are not actually used because of the design of TLS.
959 */
960 
961 int
962 sfdctls(fin, fout, con)
963 	SM_FILE_T **fin;
964 	SM_FILE_T **fout;
965 	SSL *con;
966 {
967 	SM_FILE_T *tlsin, *tlsout;
968 	SM_FILE_T SM_IO_SET_TYPE(tls_vector, "tls", tls_open, tls_close,
969 		tls_read, tls_write, NULL, tls_getinfo, NULL,
970 		SM_TIME_FOREVER);
971 	struct tls_info info;
972 
973 	SM_ASSERT(con != NULL);
974 
975 	SM_IO_INIT_TYPE(tls_vector, "tls", tls_open, tls_close,
976 		tls_read, tls_write, NULL, tls_getinfo, NULL,
977 		SM_TIME_FOREVER);
978 	info.fp = *fin;
979 	info.con = con;
980 	tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY_B,
981 			   NULL);
982 	if (tlsin == NULL)
983 		return -1;
984 
985 	info.fp = *fout;
986 	tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY_B,
987 			    NULL);
988 	if (tlsout == NULL)
989 	{
990 		(void) sm_io_close(tlsin, SM_TIME_DEFAULT);
991 		return -1;
992 	}
993 	sm_io_automode(tlsin, tlsout);
994 
995 	*fin = tlsin;
996 	*fout = tlsout;
997 	return 0;
998 }
999 #endif /* STARTTLS */
1000