]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/sendmail/src/sfsasl.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / sendmail / src / sfsasl.c
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 */