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