source: trunk/third/sendmail/sendmail/sfsasl.c @ 22421

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