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