1 /*
2 * Copyright (c) 1999-2006, 2008 Proofpoint, Inc. and its suppliers.
3 * All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11 #include <sm/gen.h>
12 SM_RCSID("@(#)$Id: sfsasl.c,v 8.121 2013-11-22 20:51:56 ca Exp $")
13 #include <stdlib.h>
14 #include <sendmail.h>
15 #include <sm/time.h>
16 #include <sm/fdset.h>
17 #include <errno.h>
18
19 /* allow to disable error handling code just in case... */
20 #ifndef DEAL_WITH_ERROR_SSL
21 # define DEAL_WITH_ERROR_SSL 1
22 #endif
23
24 #if SASL
25 # include "sfsasl.h"
26
27 /* Structure used by the "sasl" file type */
28 struct sasl_obj
29 {
30 SM_FILE_T *fp;
31 sasl_conn_t *conn;
32 };
33
34 struct sasl_info
35 {
36 SM_FILE_T *fp;
37 sasl_conn_t *conn;
38 };
39
40 /*
41 ** SASL_GETINFO - returns requested information about a "sasl" file
42 ** descriptor.
43 **
44 ** Parameters:
45 ** fp -- the file descriptor
46 ** what -- the type of information requested
47 ** valp -- the thang to return the information in
48 **
49 ** Returns:
50 ** -1 for unknown requests
51 ** >=0 on success with valp filled in (if possible).
52 */
53
54 static int sasl_getinfo __P((SM_FILE_T *, int, void *));
55
56 static int
sasl_getinfo(fp,what,valp)57 sasl_getinfo(fp, what, valp)
58 SM_FILE_T *fp;
59 int what;
60 void *valp;
61 {
62 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
63
64 switch (what)
65 {
66 case SM_IO_WHAT_FD:
67 if (so->fp == NULL)
68 return -1;
69 return so->fp->f_file; /* for stdio fileno() compatibility */
70
71 case SM_IO_IS_READABLE:
72 if (so->fp == NULL)
73 return 0;
74
75 /* get info from underlying file */
76 return sm_io_getinfo(so->fp, what, valp);
77
78 default:
79 return -1;
80 }
81 }
82
83 /*
84 ** SASL_OPEN -- creates the sasl specific information for opening a
85 ** file of the sasl type.
86 **
87 ** Parameters:
88 ** fp -- the file pointer associated with the new open
89 ** info -- contains the sasl connection information pointer and
90 ** the original SM_FILE_T that holds the open
91 ** flags -- ignored
92 ** rpool -- ignored
93 **
94 ** Returns:
95 ** 0 on success
96 */
97
98 static int sasl_open __P((SM_FILE_T *, const void *, int, const void *));
99
100 /* ARGSUSED2 */
101 static int
sasl_open(fp,info,flags,rpool)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
sasl_close(fp)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
sasl_read(fp,buf,size)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
197 static char *outbuf = NULL;
198 # endif
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
218 while (outbuf == NULL && outlen == 0)
219 # endif
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
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
sasl_write(fp,buf,size)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
291 char *outbuf;
292 # endif
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 subtracts 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
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
sfdcsasl(fin,fout,conn,tmo)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 <tls.h>
420 # include <openssl/err.h>
421
422 /* Structure used by the "tls" file type */
423 struct tls_obj
424 {
425 SM_FILE_T *fp;
426 SSL *con;
427 };
428
429 struct tls_info
430 {
431 SM_FILE_T *fp;
432 SSL *con;
433 };
434
435 /*
436 ** TLS_GETINFO - returns requested information about a "tls" file
437 ** descriptor.
438 **
439 ** Parameters:
440 ** fp -- the file descriptor
441 ** what -- the type of information requested
442 ** valp -- the thang to return the information in (unused)
443 **
444 ** Returns:
445 ** -1 for unknown requests
446 ** >=0 on success with valp filled in (if possible).
447 */
448
449 static int tls_getinfo __P((SM_FILE_T *, int, void *));
450
451 /* ARGSUSED2 */
452 static int
tls_getinfo(fp,what,valp)453 tls_getinfo(fp, what, valp)
454 SM_FILE_T *fp;
455 int what;
456 void *valp;
457 {
458 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
459
460 switch (what)
461 {
462 case SM_IO_WHAT_FD:
463 if (so->fp == NULL)
464 return -1;
465 return so->fp->f_file; /* for stdio fileno() compatibility */
466
467 case SM_IO_IS_READABLE:
468 return SSL_pending(so->con) > 0;
469
470 default:
471 return -1;
472 }
473 }
474
475 /*
476 ** TLS_OPEN -- creates the tls specific information for opening a
477 ** file of the tls type.
478 **
479 ** Parameters:
480 ** fp -- the file pointer associated with the new open
481 ** info -- the sm_io file pointer holding the open and the
482 ** TLS encryption connection to be read from or written to
483 ** flags -- ignored
484 ** rpool -- ignored
485 **
486 ** Returns:
487 ** 0 on success
488 */
489
490 static int tls_open __P((SM_FILE_T *, const void *, int, const void *));
491
492 /* ARGSUSED2 */
493 static int
tls_open(fp,info,flags,rpool)494 tls_open(fp, info, flags, rpool)
495 SM_FILE_T *fp;
496 const void *info;
497 int flags;
498 const void *rpool;
499 {
500 struct tls_obj *so;
501 struct tls_info *ti = (struct tls_info *) info;
502
503 so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj));
504 if (so == NULL)
505 {
506 errno = ENOMEM;
507 return -1;
508 }
509 so->fp = ti->fp;
510 so->con = ti->con;
511
512 /*
513 ** We try to get the "raw" file descriptor that TLS uses to
514 ** do the actual read/write with. This is to allow us control
515 ** over the file descriptor being a blocking or non-blocking type.
516 ** Under the covers TLS handles the change and this allows us
517 ** to do timeouts with sm_io.
518 */
519
520 fp->f_file = sm_io_getinfo(so->fp, SM_IO_WHAT_FD, NULL);
521 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
522 fp->f_cookie = so;
523 return 0;
524 }
525
526 /*
527 ** TLS_CLOSE -- close the tls specific parts of the tls file pointer
528 **
529 ** Parameters:
530 ** fp -- the file pointer to close
531 **
532 ** Returns:
533 ** 0 on success
534 */
535
536 static int tls_close __P((SM_FILE_T *));
537
538 static int
tls_close(fp)539 tls_close(fp)
540 SM_FILE_T *fp;
541 {
542 struct tls_obj *so;
543
544 so = (struct tls_obj *) fp->f_cookie;
545 if (so == NULL)
546 return 0;
547 if (so->fp != NULL)
548 {
549 sm_io_close(so->fp, SM_TIME_DEFAULT);
550 so->fp = NULL;
551 }
552 sm_free(so);
553 so = NULL;
554 return 0;
555 }
556
557 /* maximum number of retries for TLS related I/O due to handshakes */
558 # define MAX_TLS_IOS 4
559
560 /*
561 ** TLS_RETRY -- check whether a failed SSL operation can be retried
562 **
563 ** Parameters:
564 ** ssl -- TLS structure
565 ** rfd -- read fd
566 ** wfd -- write fd
567 ** tlsstart -- start time of TLS operation
568 ** timeout -- timeout for TLS operation
569 ** err -- SSL error
570 ** where -- description of operation
571 **
572 ** Results:
573 ** >0 on success
574 ** 0 on timeout
575 ** <0 on error
576 */
577
578 int
tls_retry(ssl,rfd,wfd,tlsstart,timeout,err,where)579 tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
580 SSL *ssl;
581 int rfd;
582 int wfd;
583 time_t tlsstart;
584 int timeout;
585 int err;
586 const char *where;
587 {
588 int ret;
589 time_t left;
590 time_t now = curtime();
591 struct timeval tv;
592
593 ret = -1;
594
595 /*
596 ** For SSL_ERROR_WANT_{READ,WRITE}:
597 ** There is not a complete SSL record available yet
598 ** or there is only a partial SSL record removed from
599 ** the network (socket) buffer into the SSL buffer.
600 ** The SSL_connect will only succeed when a full
601 ** SSL record is available (assuming a "real" error
602 ** doesn't happen). To handle when a "real" error
603 ** does happen the select is set for exceptions too.
604 ** The connection may be re-negotiated during this time
605 ** so both read and write "want errors" need to be handled.
606 ** A select() exception loops back so that a proper SSL
607 ** error message can be gotten.
608 */
609
610 left = timeout - (now - tlsstart);
611 if (left <= 0)
612 return 0; /* timeout */
613 tv.tv_sec = left;
614 tv.tv_usec = 0;
615
616 if (LogLevel > 14)
617 {
618 sm_syslog(LOG_INFO, NOQID,
619 "STARTTLS=%s, info: fds=%d/%d, err=%d",
620 where, rfd, wfd, err);
621 }
622
623 if ((err == SSL_ERROR_WANT_READ && !SM_FD_OK_SELECT(rfd)) ||
624 (err == SSL_ERROR_WANT_WRITE && !SM_FD_OK_SELECT(wfd)))
625 {
626 if (LogLevel > 5)
627 {
628 sm_syslog(LOG_ERR, NOQID,
629 "STARTTLS=%s, error: fd %d/%d too large",
630 where, rfd, wfd);
631 tlslogerr(LOG_WARNING, 8, 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
678 # define SM_ERR_TIMEOUT EIO
679 #endif
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
set_tls_rd_tmo(rd_tmo)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
tls_read(fp,buf,size)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 break;
772 case SSL_ERROR_SSL:
773 #if DEAL_WITH_ERROR_SSL
774 if (r == 0 && errno == 0) /* out of protocol EOF found */
775 break;
776 #endif
777 err = "generic SSL error";
778
779 if (LogLevel > 9)
780 {
781 int pri;
782
783 if (errno == EAGAIN && try > 0)
784 pri = LOG_DEBUG;
785 else
786 pri = LOG_WARNING;
787 tlslogerr(pri, 9, "read");
788 }
789
790 #if DEAL_WITH_ERROR_SSL
791 /* avoid repeated calls? */
792 if (r == 0)
793 r = -1;
794 #endif
795 break;
796 }
797 if (err != NULL)
798 {
799 int save_errno;
800
801 save_errno = (errno == 0) ? EIO : errno;
802 if (try == 0 && save_errno == SM_ERR_TIMEOUT)
803 {
804 if (LogLevel > 7)
805 sm_syslog(LOG_WARNING, NOQID,
806 "STARTTLS: read error=timeout");
807 }
808 else if (LogLevel > 8)
809 {
810 int pri;
811
812 if (save_errno == EAGAIN && try > 0)
813 pri = LOG_DEBUG;
814 else
815 pri = LOG_WARNING;
816 sm_syslog(pri, NOQID,
817 "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
818 err, r, errno,
819 ERR_error_string(ERR_get_error(), NULL), try,
820 ssl_err);
821 }
822 else if (LogLevel > 7)
823 sm_syslog(LOG_WARNING, NOQID,
824 "STARTTLS: read error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
825 err, r, errno, try, ssl_err);
826 errno = save_errno;
827 }
828 return r;
829 }
830
831 /*
832 ** TLS_WRITE -- write information out through secure connection
833 **
834 ** Parameters:
835 ** fp -- the file pointer
836 ** buf -- holds the data to be securely written
837 ** size -- the number of bytes to write
838 **
839 ** Returns:
840 ** -1 on error
841 ** otherwise number of bytes written
842 */
843
844 static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t));
845
846 static ssize_t
tls_write(fp,buf,size)847 tls_write(fp, buf, size)
848 SM_FILE_T *fp;
849 const char *buf;
850 size_t size;
851 {
852 int r, rfd, wfd, try, ssl_err;
853 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
854 time_t tlsstart;
855 char *err;
856
857 try = 99;
858 err = NULL;
859 tlsstart = curtime();
860
861 retry:
862 r = SSL_write(so->con, (char *) buf, size);
863
864 if (r > 0)
865 return r;
866 err = NULL;
867 switch (ssl_err = SSL_get_error(so->con, r))
868 {
869 case SSL_ERROR_NONE:
870 case SSL_ERROR_ZERO_RETURN:
871 break;
872 case SSL_ERROR_WANT_WRITE:
873 err = "read W BLOCK";
874 /* FALLTHROUGH */
875 case SSL_ERROR_WANT_READ:
876 if (err == NULL)
877 err = "read R BLOCK";
878 rfd = SSL_get_rfd(so->con);
879 wfd = SSL_get_wfd(so->con);
880 try = tls_retry(so->con, rfd, wfd, tlsstart,
881 DATA_PROGRESS_TIMEOUT, ssl_err, "write");
882 if (try > 0)
883 goto retry;
884 errno = SM_ERR_TIMEOUT;
885 break;
886 case SSL_ERROR_WANT_X509_LOOKUP:
887 err = "write X BLOCK";
888 break;
889 case SSL_ERROR_SYSCALL:
890 if (r == 0 && errno == 0) /* out of protocol EOF found */
891 break;
892 err = "syscall error";
893 break;
894 case SSL_ERROR_SSL:
895 err = "generic SSL error";
896 /*
897 ERR_GET_REASON(ERR_peek_error()));
898 */
899 tlslogerr(LOG_WARNING, 9, "write");
900
901 #if DEAL_WITH_ERROR_SSL
902 /* avoid repeated calls? */
903 if (r == 0)
904 r = -1;
905 #endif
906 break;
907 }
908 if (err != NULL)
909 {
910 int save_errno;
911
912 save_errno = (errno == 0) ? EIO : errno;
913 if (try == 0 && save_errno == SM_ERR_TIMEOUT)
914 {
915 if (LogLevel > 7)
916 sm_syslog(LOG_WARNING, NOQID,
917 "STARTTLS: write error=timeout");
918 }
919 else if (LogLevel > 8)
920 sm_syslog(LOG_WARNING, NOQID,
921 "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
922 err, r, errno,
923 ERR_error_string(ERR_get_error(), NULL), try,
924 ssl_err);
925 else if (LogLevel > 7)
926 sm_syslog(LOG_WARNING, NOQID,
927 "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
928 err, r, errno, try, ssl_err);
929 errno = save_errno;
930 }
931 return r;
932 }
933
934 /*
935 ** SFDCTLS -- create tls file type and open in and out file pointers
936 ** for sendmail to read from and write to.
937 **
938 ** Parameters:
939 ** fin -- data input source being replaced
940 ** fout -- data output source being replaced
941 ** con -- the tls connection pointer
942 **
943 ** Returns:
944 ** -1 on error
945 ** 0 on success
946 **
947 ** Side effects:
948 ** The arguments "fin" and "fout" are replaced with the new
949 ** SM_FILE_T pointers.
950 ** The original "fin" and "fout" are preserved in the tls file
951 ** type but are not actually used because of the design of TLS.
952 */
953
954 int
sfdctls(fin,fout,con)955 sfdctls(fin, fout, con)
956 SM_FILE_T **fin;
957 SM_FILE_T **fout;
958 SSL *con;
959 {
960 SM_FILE_T *tlsin, *tlsout;
961 SM_FILE_T SM_IO_SET_TYPE(tls_vector, "tls", tls_open, tls_close,
962 tls_read, tls_write, NULL, tls_getinfo, NULL,
963 SM_TIME_FOREVER);
964 struct tls_info info;
965
966 SM_ASSERT(con != NULL);
967
968 SM_IO_INIT_TYPE(tls_vector, "tls", tls_open, tls_close,
969 tls_read, tls_write, NULL, tls_getinfo, NULL,
970 SM_TIME_FOREVER);
971 info.fp = *fin;
972 info.con = con;
973 tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY_B,
974 NULL);
975 if (tlsin == NULL)
976 return -1;
977
978 info.fp = *fout;
979 tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY_B,
980 NULL);
981 if (tlsout == NULL)
982 {
983 (void) sm_io_close(tlsin, SM_TIME_DEFAULT);
984 return -1;
985 }
986 sm_io_automode(tlsin, tlsout);
987
988 *fin = tlsin;
989 *fout = tlsout;
990 return 0;
991 }
992 #endif /* STARTTLS */
993