106f25ae9SGregory Neil Shapiro /* 28774250cSGregory Neil Shapiro * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. 306f25ae9SGregory Neil Shapiro * All rights reserved. 406f25ae9SGregory Neil Shapiro * 506f25ae9SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set 606f25ae9SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of 706f25ae9SGregory Neil Shapiro * the sendmail distribution. 806f25ae9SGregory Neil Shapiro * 906f25ae9SGregory Neil Shapiro */ 1006f25ae9SGregory Neil Shapiro 1106f25ae9SGregory Neil Shapiro #ifndef lint 1213058a91SGregory Neil Shapiro static char id[] = "@(#)$Id: sfsasl.c,v 8.17.4.15 2001/07/11 17:37:07 gshapiro Exp $"; 1306f25ae9SGregory Neil Shapiro #endif /* ! lint */ 1406f25ae9SGregory Neil Shapiro 1506f25ae9SGregory Neil Shapiro #if SFIO 1606f25ae9SGregory Neil Shapiro # include <sfio/stdio.h> 1706f25ae9SGregory Neil Shapiro #endif /* SFIO */ 1806f25ae9SGregory Neil Shapiro 1906f25ae9SGregory Neil Shapiro #include <stdlib.h> 2006f25ae9SGregory Neil Shapiro #include <sendmail.h> 2106f25ae9SGregory Neil Shapiro 2206f25ae9SGregory Neil Shapiro #if SASL && SFIO 2306f25ae9SGregory Neil Shapiro /* 2406f25ae9SGregory Neil Shapiro ** SASL 2506f25ae9SGregory Neil Shapiro */ 2606f25ae9SGregory Neil Shapiro 2706f25ae9SGregory Neil Shapiro # include <sasl.h> 2806f25ae9SGregory Neil Shapiro # include "sfsasl.h" 2906f25ae9SGregory Neil Shapiro 30193538b7SGregory Neil Shapiro /* how to deallocate a buffer allocated by SASL */ 318774250cSGregory Neil Shapiro # define SASL_DEALLOC(b) sm_free(b) 32193538b7SGregory Neil Shapiro 3306f25ae9SGregory Neil Shapiro static ssize_t 3406f25ae9SGregory Neil Shapiro sasl_read(f, buf, size, disc) 3506f25ae9SGregory Neil Shapiro Sfio_t *f; 3606f25ae9SGregory Neil Shapiro Void_t *buf; 3706f25ae9SGregory Neil Shapiro size_t size; 3806f25ae9SGregory Neil Shapiro Sfdisc_t *disc; 3906f25ae9SGregory Neil Shapiro { 4006f25ae9SGregory Neil Shapiro int len, result; 41193538b7SGregory Neil Shapiro static char *outbuf = NULL; 42193538b7SGregory Neil Shapiro static unsigned int outlen = 0; 43193538b7SGregory Neil Shapiro static unsigned int offset = 0; 4406f25ae9SGregory Neil Shapiro Sasldisc_t *sd = (Sasldisc_t *) disc; 4506f25ae9SGregory Neil Shapiro 46193538b7SGregory Neil Shapiro /* 47193538b7SGregory Neil Shapiro ** sasl_decode() may require more data than a single read() returns. 48193538b7SGregory Neil Shapiro ** Hence we have to put a loop around the decoding. 49193538b7SGregory Neil Shapiro ** This also requires that we may have to split up the returned 50193538b7SGregory Neil Shapiro ** data since it might be larger than the allowed size. 51193538b7SGregory Neil Shapiro ** Therefore we use a static pointer and return portions of it 52193538b7SGregory Neil Shapiro ** if necessary. 53193538b7SGregory Neil Shapiro */ 5406f25ae9SGregory Neil Shapiro 55193538b7SGregory Neil Shapiro while (outbuf == NULL && outlen == 0) 56193538b7SGregory Neil Shapiro { 57193538b7SGregory Neil Shapiro len = sfrd(f, buf, size, disc); 5806f25ae9SGregory Neil Shapiro if (len <= 0) 5906f25ae9SGregory Neil Shapiro return len; 6006f25ae9SGregory Neil Shapiro result = sasl_decode(sd->conn, buf, len, &outbuf, &outlen); 6106f25ae9SGregory Neil Shapiro if (result != SASL_OK) 6206f25ae9SGregory Neil Shapiro { 63193538b7SGregory Neil Shapiro outbuf = NULL; 64193538b7SGregory Neil Shapiro offset = 0; 65193538b7SGregory Neil Shapiro outlen = 0; 6606f25ae9SGregory Neil Shapiro return -1; 6706f25ae9SGregory Neil Shapiro } 68193538b7SGregory Neil Shapiro } 6906f25ae9SGregory Neil Shapiro 7006f25ae9SGregory Neil Shapiro if (outbuf != NULL) 7106f25ae9SGregory Neil Shapiro { 72193538b7SGregory Neil Shapiro if (outlen - offset > size) 73193538b7SGregory Neil Shapiro { 74193538b7SGregory Neil Shapiro /* return another part of the buffer */ 75193538b7SGregory Neil Shapiro (void) memcpy(buf, outbuf + offset, (size_t) size); 76193538b7SGregory Neil Shapiro offset += size; 77193538b7SGregory Neil Shapiro result = size; 7806f25ae9SGregory Neil Shapiro } 79193538b7SGregory Neil Shapiro else 80193538b7SGregory Neil Shapiro { 81193538b7SGregory Neil Shapiro /* return the rest of the buffer */ 82193538b7SGregory Neil Shapiro result = outlen - offset; 83193538b7SGregory Neil Shapiro (void) memcpy(buf, outbuf + offset, (size_t) result); 84193538b7SGregory Neil Shapiro SASL_DEALLOC(outbuf); 85193538b7SGregory Neil Shapiro outbuf = NULL; 86193538b7SGregory Neil Shapiro offset = 0; 87193538b7SGregory Neil Shapiro outlen = 0; 88193538b7SGregory Neil Shapiro } 89193538b7SGregory Neil Shapiro } 90193538b7SGregory Neil Shapiro else 91193538b7SGregory Neil Shapiro { 92193538b7SGregory Neil Shapiro /* be paranoid: outbuf == NULL but outlen != 0 */ 93193538b7SGregory Neil Shapiro syserr("!sasl_read failure: outbuf == NULL but outlen != 0"); 94193538b7SGregory Neil Shapiro } 95193538b7SGregory Neil Shapiro return result; 9606f25ae9SGregory Neil Shapiro } 9706f25ae9SGregory Neil Shapiro 9806f25ae9SGregory Neil Shapiro static ssize_t 9906f25ae9SGregory Neil Shapiro sasl_write(f, buf, size, disc) 10006f25ae9SGregory Neil Shapiro Sfio_t *f; 10106f25ae9SGregory Neil Shapiro const Void_t *buf; 10206f25ae9SGregory Neil Shapiro size_t size; 10306f25ae9SGregory Neil Shapiro Sfdisc_t *disc; 10406f25ae9SGregory Neil Shapiro { 10506f25ae9SGregory Neil Shapiro int result; 10606f25ae9SGregory Neil Shapiro char *outbuf; 10706f25ae9SGregory Neil Shapiro unsigned int outlen; 10806f25ae9SGregory Neil Shapiro Sasldisc_t *sd = (Sasldisc_t *) disc; 10906f25ae9SGregory Neil Shapiro 11006f25ae9SGregory Neil Shapiro result = sasl_encode(sd->conn, buf, size, &outbuf, &outlen); 11106f25ae9SGregory Neil Shapiro 11206f25ae9SGregory Neil Shapiro if (result != SASL_OK) 11306f25ae9SGregory Neil Shapiro return -1; 11406f25ae9SGregory Neil Shapiro 11506f25ae9SGregory Neil Shapiro if (outbuf != NULL) 11606f25ae9SGregory Neil Shapiro { 11706f25ae9SGregory Neil Shapiro sfwr(f, outbuf, outlen, disc); 118193538b7SGregory Neil Shapiro SASL_DEALLOC(outbuf); 11906f25ae9SGregory Neil Shapiro } 12006f25ae9SGregory Neil Shapiro return size; 12106f25ae9SGregory Neil Shapiro } 12206f25ae9SGregory Neil Shapiro 12306f25ae9SGregory Neil Shapiro int 12406f25ae9SGregory Neil Shapiro sfdcsasl(fin, fout, conn) 12506f25ae9SGregory Neil Shapiro Sfio_t *fin; 12606f25ae9SGregory Neil Shapiro Sfio_t *fout; 12706f25ae9SGregory Neil Shapiro sasl_conn_t *conn; 12806f25ae9SGregory Neil Shapiro { 12906f25ae9SGregory Neil Shapiro Sasldisc_t *saslin, *saslout; 13006f25ae9SGregory Neil Shapiro 13106f25ae9SGregory Neil Shapiro if (conn == NULL) 13206f25ae9SGregory Neil Shapiro { 13306f25ae9SGregory Neil Shapiro /* no need to do anything */ 13406f25ae9SGregory Neil Shapiro return 0; 13506f25ae9SGregory Neil Shapiro } 13606f25ae9SGregory Neil Shapiro 1378774250cSGregory Neil Shapiro saslin = (Sasldisc_t *) xalloc(sizeof(Sasldisc_t)); 1388774250cSGregory Neil Shapiro saslout = (Sasldisc_t *) xalloc(sizeof(Sasldisc_t)); 13906f25ae9SGregory Neil Shapiro saslin->disc.readf = sasl_read; 14006f25ae9SGregory Neil Shapiro saslin->disc.writef = sasl_write; 14106f25ae9SGregory Neil Shapiro saslin->disc.seekf = NULL; 14206f25ae9SGregory Neil Shapiro saslin->disc.exceptf = NULL; 14306f25ae9SGregory Neil Shapiro 14406f25ae9SGregory Neil Shapiro saslout->disc.readf = sasl_read; 14506f25ae9SGregory Neil Shapiro saslout->disc.writef = sasl_write; 14606f25ae9SGregory Neil Shapiro saslout->disc.seekf = NULL; 14706f25ae9SGregory Neil Shapiro saslout->disc.exceptf = NULL; 14806f25ae9SGregory Neil Shapiro 14906f25ae9SGregory Neil Shapiro saslin->conn = conn; 15006f25ae9SGregory Neil Shapiro saslout->conn = conn; 15106f25ae9SGregory Neil Shapiro 15206f25ae9SGregory Neil Shapiro if (sfdisc(fin, (Sfdisc_t *) saslin) != (Sfdisc_t *) saslin || 15306f25ae9SGregory Neil Shapiro sfdisc(fout, (Sfdisc_t *) saslout) != (Sfdisc_t *) saslout) 15406f25ae9SGregory Neil Shapiro { 1558774250cSGregory Neil Shapiro sm_free(saslin); 1568774250cSGregory Neil Shapiro sm_free(saslout); 15706f25ae9SGregory Neil Shapiro return -1; 15806f25ae9SGregory Neil Shapiro } 15906f25ae9SGregory Neil Shapiro return 0; 16006f25ae9SGregory Neil Shapiro } 16106f25ae9SGregory Neil Shapiro #endif /* SASL && SFIO */ 16206f25ae9SGregory Neil Shapiro 16306f25ae9SGregory Neil Shapiro #if STARTTLS && (SFIO || _FFR_TLS_TOREK) 16406f25ae9SGregory Neil Shapiro /* 16506f25ae9SGregory Neil Shapiro ** STARTTLS 16606f25ae9SGregory Neil Shapiro */ 16706f25ae9SGregory Neil Shapiro 16806f25ae9SGregory Neil Shapiro # include "sfsasl.h" 16906f25ae9SGregory Neil Shapiro # include <openssl/err.h> 17006f25ae9SGregory Neil Shapiro 17106f25ae9SGregory Neil Shapiro # if SFIO 17213058a91SGregory Neil Shapiro static ssize_t 17306f25ae9SGregory Neil Shapiro tls_read(f, buf, size, disc) 17406f25ae9SGregory Neil Shapiro Sfio_t *f; 17506f25ae9SGregory Neil Shapiro Void_t *buf; 17606f25ae9SGregory Neil Shapiro size_t size; 17706f25ae9SGregory Neil Shapiro Sfdisc_t *disc; 17806f25ae9SGregory Neil Shapiro # else /* SFIO */ 17913058a91SGregory Neil Shapiro static int 18006f25ae9SGregory Neil Shapiro tls_read(disc, buf, size) 18106f25ae9SGregory Neil Shapiro void *disc; 18213058a91SGregory Neil Shapiro char *buf; 18313058a91SGregory Neil Shapiro int size; 18406f25ae9SGregory Neil Shapiro # endif /* SFIO */ 18506f25ae9SGregory Neil Shapiro { 18606f25ae9SGregory Neil Shapiro int r; 18706f25ae9SGregory Neil Shapiro Tlsdisc_t *sd; 18806f25ae9SGregory Neil Shapiro 18906f25ae9SGregory Neil Shapiro /* Cast back to correct type */ 19006f25ae9SGregory Neil Shapiro sd = (Tlsdisc_t *) disc; 19106f25ae9SGregory Neil Shapiro 19206f25ae9SGregory Neil Shapiro r = SSL_read(sd->con, (char *) buf, size); 19306f25ae9SGregory Neil Shapiro if (r < 0 && LogLevel > 7) 19406f25ae9SGregory Neil Shapiro { 19506f25ae9SGregory Neil Shapiro char *err; 19606f25ae9SGregory Neil Shapiro 19706f25ae9SGregory Neil Shapiro err = NULL; 19806f25ae9SGregory Neil Shapiro switch (SSL_get_error(sd->con, r)) 19906f25ae9SGregory Neil Shapiro { 20006f25ae9SGregory Neil Shapiro case SSL_ERROR_NONE: 20106f25ae9SGregory Neil Shapiro break; 20206f25ae9SGregory Neil Shapiro case SSL_ERROR_WANT_WRITE: 20306f25ae9SGregory Neil Shapiro err = "write W BLOCK"; 20406f25ae9SGregory Neil Shapiro break; 20506f25ae9SGregory Neil Shapiro case SSL_ERROR_WANT_READ: 20606f25ae9SGregory Neil Shapiro err = "write R BLOCK"; 20706f25ae9SGregory Neil Shapiro break; 20806f25ae9SGregory Neil Shapiro case SSL_ERROR_WANT_X509_LOOKUP: 20906f25ae9SGregory Neil Shapiro err = "write X BLOCK"; 21006f25ae9SGregory Neil Shapiro break; 21106f25ae9SGregory Neil Shapiro case SSL_ERROR_ZERO_RETURN: 21206f25ae9SGregory Neil Shapiro break; 21306f25ae9SGregory Neil Shapiro case SSL_ERROR_SYSCALL: 21406f25ae9SGregory Neil Shapiro err = "syscall error"; 21506f25ae9SGregory Neil Shapiro /* 21606f25ae9SGregory Neil Shapiro get_last_socket_error()); 21706f25ae9SGregory Neil Shapiro */ 21806f25ae9SGregory Neil Shapiro break; 21906f25ae9SGregory Neil Shapiro case SSL_ERROR_SSL: 22006f25ae9SGregory Neil Shapiro err = "generic SSL error"; 22106f25ae9SGregory Neil Shapiro break; 22206f25ae9SGregory Neil Shapiro } 22306f25ae9SGregory Neil Shapiro if (err != NULL) 22406f25ae9SGregory Neil Shapiro sm_syslog(LOG_WARNING, NOQID, "TLS: read error: %s", 22506f25ae9SGregory Neil Shapiro err); 22606f25ae9SGregory Neil Shapiro } 22706f25ae9SGregory Neil Shapiro return r; 22806f25ae9SGregory Neil Shapiro } 22906f25ae9SGregory Neil Shapiro 23006f25ae9SGregory Neil Shapiro # if SFIO 23113058a91SGregory Neil Shapiro static ssize_t 23206f25ae9SGregory Neil Shapiro tls_write(f, buf, size, disc) 23306f25ae9SGregory Neil Shapiro Sfio_t *f; 23406f25ae9SGregory Neil Shapiro const Void_t *buf; 23506f25ae9SGregory Neil Shapiro size_t size; 23606f25ae9SGregory Neil Shapiro Sfdisc_t *disc; 23706f25ae9SGregory Neil Shapiro # else /* SFIO */ 23813058a91SGregory Neil Shapiro static int 23906f25ae9SGregory Neil Shapiro tls_write(disc, buf, size) 24006f25ae9SGregory Neil Shapiro void *disc; 24113058a91SGregory Neil Shapiro const char *buf; 24213058a91SGregory Neil Shapiro int size; 24306f25ae9SGregory Neil Shapiro # endif /* SFIO */ 24406f25ae9SGregory Neil Shapiro { 24506f25ae9SGregory Neil Shapiro int r; 24606f25ae9SGregory Neil Shapiro Tlsdisc_t *sd; 24706f25ae9SGregory Neil Shapiro 24806f25ae9SGregory Neil Shapiro /* Cast back to correct type */ 24906f25ae9SGregory Neil Shapiro sd = (Tlsdisc_t *) disc; 25006f25ae9SGregory Neil Shapiro 25106f25ae9SGregory Neil Shapiro r = SSL_write(sd->con, (char *)buf, size); 25206f25ae9SGregory Neil Shapiro if (r < 0 && LogLevel > 7) 25306f25ae9SGregory Neil Shapiro { 25406f25ae9SGregory Neil Shapiro char *err; 25506f25ae9SGregory Neil Shapiro 25606f25ae9SGregory Neil Shapiro err = NULL; 25706f25ae9SGregory Neil Shapiro switch (SSL_get_error(sd->con, r)) 25806f25ae9SGregory Neil Shapiro { 25906f25ae9SGregory Neil Shapiro case SSL_ERROR_NONE: 26006f25ae9SGregory Neil Shapiro break; 26106f25ae9SGregory Neil Shapiro case SSL_ERROR_WANT_WRITE: 26206f25ae9SGregory Neil Shapiro err = "write W BLOCK"; 26306f25ae9SGregory Neil Shapiro break; 26406f25ae9SGregory Neil Shapiro case SSL_ERROR_WANT_READ: 26506f25ae9SGregory Neil Shapiro err = "write R BLOCK"; 26606f25ae9SGregory Neil Shapiro break; 26706f25ae9SGregory Neil Shapiro case SSL_ERROR_WANT_X509_LOOKUP: 26806f25ae9SGregory Neil Shapiro err = "write X BLOCK"; 26906f25ae9SGregory Neil Shapiro break; 27006f25ae9SGregory Neil Shapiro case SSL_ERROR_ZERO_RETURN: 27106f25ae9SGregory Neil Shapiro break; 27206f25ae9SGregory Neil Shapiro case SSL_ERROR_SYSCALL: 27306f25ae9SGregory Neil Shapiro err = "syscall error"; 27406f25ae9SGregory Neil Shapiro /* 27506f25ae9SGregory Neil Shapiro get_last_socket_error()); 27606f25ae9SGregory Neil Shapiro */ 27706f25ae9SGregory Neil Shapiro break; 27806f25ae9SGregory Neil Shapiro case SSL_ERROR_SSL: 27906f25ae9SGregory Neil Shapiro err = "generic SSL error"; 28006f25ae9SGregory Neil Shapiro /* 28106f25ae9SGregory Neil Shapiro ERR_GET_REASON(ERR_peek_error())); 28206f25ae9SGregory Neil Shapiro */ 28306f25ae9SGregory Neil Shapiro break; 28406f25ae9SGregory Neil Shapiro } 28506f25ae9SGregory Neil Shapiro if (err != NULL) 28606f25ae9SGregory Neil Shapiro sm_syslog(LOG_WARNING, NOQID, "TLS: write error: %s", 28706f25ae9SGregory Neil Shapiro err); 28806f25ae9SGregory Neil Shapiro } 28906f25ae9SGregory Neil Shapiro return r; 29006f25ae9SGregory Neil Shapiro } 29106f25ae9SGregory Neil Shapiro 29206f25ae9SGregory Neil Shapiro # if !SFIO 29306f25ae9SGregory Neil Shapiro static int 29406f25ae9SGregory Neil Shapiro tls_close(cookie) 29506f25ae9SGregory Neil Shapiro void *cookie; 29606f25ae9SGregory Neil Shapiro { 29706f25ae9SGregory Neil Shapiro int retval = 0; 29806f25ae9SGregory Neil Shapiro Tlsdisc_t *tc; 29906f25ae9SGregory Neil Shapiro 30006f25ae9SGregory Neil Shapiro /* Cast back to correct type */ 30106f25ae9SGregory Neil Shapiro tc = (Tlsdisc_t *)cookie; 30206f25ae9SGregory Neil Shapiro 30306f25ae9SGregory Neil Shapiro if (tc->fp != NULL) 30406f25ae9SGregory Neil Shapiro { 30506f25ae9SGregory Neil Shapiro retval = fclose(tc->fp); 30606f25ae9SGregory Neil Shapiro tc->fp = NULL; 30706f25ae9SGregory Neil Shapiro } 30806f25ae9SGregory Neil Shapiro 3098774250cSGregory Neil Shapiro sm_free(tc); 31006f25ae9SGregory Neil Shapiro return retval; 31106f25ae9SGregory Neil Shapiro } 31206f25ae9SGregory Neil Shapiro # endif /* !SFIO */ 31306f25ae9SGregory Neil Shapiro 31406f25ae9SGregory Neil Shapiro int 31506f25ae9SGregory Neil Shapiro sfdctls(fin, fout, con) 31606f25ae9SGregory Neil Shapiro # if SFIO 31706f25ae9SGregory Neil Shapiro Sfio_t *fin; 31806f25ae9SGregory Neil Shapiro Sfio_t *fout; 31906f25ae9SGregory Neil Shapiro # else /* SFIO */ 32006f25ae9SGregory Neil Shapiro FILE **fin; 32106f25ae9SGregory Neil Shapiro FILE **fout; 32206f25ae9SGregory Neil Shapiro # endif /* SFIO */ 32306f25ae9SGregory Neil Shapiro SSL *con; 32406f25ae9SGregory Neil Shapiro { 32506f25ae9SGregory Neil Shapiro Tlsdisc_t *tlsin, *tlsout; 32606f25ae9SGregory Neil Shapiro # if !SFIO 32706f25ae9SGregory Neil Shapiro FILE *fp; 32842e5d165SGregory Neil Shapiro # else /* !SFIO */ 32942e5d165SGregory Neil Shapiro int rfd, wfd; 33006f25ae9SGregory Neil Shapiro # endif /* !SFIO */ 33106f25ae9SGregory Neil Shapiro 33206f25ae9SGregory Neil Shapiro if (con == NULL) 33306f25ae9SGregory Neil Shapiro return 0; 33406f25ae9SGregory Neil Shapiro 3358774250cSGregory Neil Shapiro tlsin = (Tlsdisc_t *) xalloc(sizeof(Tlsdisc_t)); 3368774250cSGregory Neil Shapiro tlsout = (Tlsdisc_t *) xalloc(sizeof(Tlsdisc_t)); 33706f25ae9SGregory Neil Shapiro # if SFIO 33806f25ae9SGregory Neil Shapiro tlsin->disc.readf = tls_read; 33906f25ae9SGregory Neil Shapiro tlsin->disc.writef = tls_write; 34006f25ae9SGregory Neil Shapiro tlsin->disc.seekf = NULL; 34106f25ae9SGregory Neil Shapiro tlsin->disc.exceptf = NULL; 34206f25ae9SGregory Neil Shapiro tlsin->con = con; 34306f25ae9SGregory Neil Shapiro 34406f25ae9SGregory Neil Shapiro tlsout->disc.readf = tls_read; 34506f25ae9SGregory Neil Shapiro tlsout->disc.writef = tls_write; 34606f25ae9SGregory Neil Shapiro tlsout->disc.seekf = NULL; 34706f25ae9SGregory Neil Shapiro tlsout->disc.exceptf = NULL; 34806f25ae9SGregory Neil Shapiro tlsout->con = con; 34906f25ae9SGregory Neil Shapiro 35042e5d165SGregory Neil Shapiro rfd = fileno(fin); 35142e5d165SGregory Neil Shapiro wfd = fileno(fout); 35242e5d165SGregory Neil Shapiro if (rfd < 0 || wfd < 0 || 35342e5d165SGregory Neil Shapiro SSL_set_rfd(con, rfd) <= 0 || SSL_set_wfd(con, wfd) <= 0) 35442e5d165SGregory Neil Shapiro { 3558774250cSGregory Neil Shapiro sm_free(tlsin); 3568774250cSGregory Neil Shapiro sm_free(tlsout); 35742e5d165SGregory Neil Shapiro return -1; 35842e5d165SGregory Neil Shapiro } 35906f25ae9SGregory Neil Shapiro if (sfdisc(fin, (Sfdisc_t *) tlsin) != (Sfdisc_t *) tlsin || 36006f25ae9SGregory Neil Shapiro sfdisc(fout, (Sfdisc_t *) tlsout) != (Sfdisc_t *) tlsout) 36106f25ae9SGregory Neil Shapiro { 3628774250cSGregory Neil Shapiro sm_free(tlsin); 3638774250cSGregory Neil Shapiro sm_free(tlsout); 36406f25ae9SGregory Neil Shapiro return -1; 36506f25ae9SGregory Neil Shapiro } 36606f25ae9SGregory Neil Shapiro # else /* SFIO */ 36706f25ae9SGregory Neil Shapiro tlsin->fp = *fin; 36806f25ae9SGregory Neil Shapiro tlsin->con = con; 36906f25ae9SGregory Neil Shapiro fp = funopen(tlsin, tls_read, tls_write, NULL, tls_close); 37006f25ae9SGregory Neil Shapiro if (fp == NULL) 37106f25ae9SGregory Neil Shapiro { 3728774250cSGregory Neil Shapiro sm_free(tlsin); 37306f25ae9SGregory Neil Shapiro return -1; 37406f25ae9SGregory Neil Shapiro } 37506f25ae9SGregory Neil Shapiro *fin = fp; 37606f25ae9SGregory Neil Shapiro 37706f25ae9SGregory Neil Shapiro tlsout->fp = *fout; 37806f25ae9SGregory Neil Shapiro tlsout->con = con; 37906f25ae9SGregory Neil Shapiro fp = funopen(tlsout, tls_read, tls_write, NULL, tls_close); 38006f25ae9SGregory Neil Shapiro if (fp == NULL) 38106f25ae9SGregory Neil Shapiro { 38206f25ae9SGregory Neil Shapiro FILE *save; 38306f25ae9SGregory Neil Shapiro 38406f25ae9SGregory Neil Shapiro /* Hack: Don't close underlying fp */ 38506f25ae9SGregory Neil Shapiro save = tlsin->fp; 38606f25ae9SGregory Neil Shapiro tlsin->fp = NULL; 38706f25ae9SGregory Neil Shapiro fclose(*fin); 38806f25ae9SGregory Neil Shapiro *fin = save; 3898774250cSGregory Neil Shapiro sm_free(tlsout); 39006f25ae9SGregory Neil Shapiro return -1; 39106f25ae9SGregory Neil Shapiro } 39206f25ae9SGregory Neil Shapiro *fout = fp; 39306f25ae9SGregory Neil Shapiro SSL_set_rfd(con, fileno(tlsin->fp)); 39406f25ae9SGregory Neil Shapiro SSL_set_wfd(con, fileno(tlsout->fp)); 39506f25ae9SGregory Neil Shapiro # endif /* SFIO */ 39606f25ae9SGregory Neil Shapiro return 0; 39706f25ae9SGregory Neil Shapiro } 39806f25ae9SGregory Neil Shapiro #endif /* STARTTLS && (SFIO || _FFR_TLS_TOREK) */ 399