chiark / gitweb /
REORG Delete everything that's not innduct or build system or changed for innduct
[innduct.git] / nnrpd / tls.c
diff --git a/nnrpd/tls.c b/nnrpd/tls.c
deleted file mode 100644 (file)
index cfc8f03..0000000
+++ /dev/null
@@ -1,713 +0,0 @@
-/* tls.c --- TLSv1 functions
-   Copyright (C) 2000 Kenichi Okada <okada@opaopa.org>
-
-   Author: Kenichi Okada <okada@opaopa.org>
-   Created: 2000-02-22
-
-   Keywords: TLS, OpenSSL
-
-   Commentary:
-
-   [RFC 2246] "The TLS Protocol Version 1.0"
-        by Christopher Allen <callen@certicom.com> and
-        Tim Dierks <tdierks@certicom.com> (1999/01)
-
-   [RFC 2595] "Using TLS with IMAP, POP3 and ACAP"
-        by Chris Newman <chris.newman@innosoft.com> (1999/06)
-
-*/
-
-#include <sys/types.h>
-#include "config.h"
-#include "nnrpd.h"
-
-#ifdef HAVE_SSL
-
-/* System library. */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-#endif
-
-/* outside the ifdef so `make depend` works even ifndef HAVE_SSL */
-#include "tls.h"
-#include "sasl_config.h"
-
-#ifdef HAVE_SSL
-
-/* We must keep some of the info available */
-static const char hexcodes[] = "0123456789ABCDEF";
-
-static bool tls_initialized = false;
-
-static int verify_depth;
-static int verify_error = X509_V_OK;
-static int do_dump = 0;
-static SSL_CTX *CTX = NULL;
-SSL *tls_conn = NULL;
-
-#define CCERT_BUFSIZ 256
-
-int     tls_serverengine = 0;
-int     tls_serveractive = 0;  /* available or not */
-char   *tls_peer_subject = NULL;
-char   *tls_peer_issuer = NULL;
-char   *tls_peer_fingerprint = NULL;
-
-int     tls_clientactive = 0;  /* available or not */
-char   *tls_peer_CN = NULL;
-char   *tls_issuer_CN = NULL;
-
-const char   *tls_protocol = NULL;
-const char   *tls_cipher_name = NULL;
-int    tls_cipher_usebits = 0;
-int    tls_cipher_algbits = 0;
-
-
-int tls_loglevel = 0;
-
-
-/* taken from OpenSSL apps/s_cb.c 
- * tim - this seems to just be giving logging messages
- */
-
-static void apps_ssl_info_callback(SSL * s, int where, int ret)
-{
-    const char  *str;
-    int         w;
-
-    if (tls_loglevel==0) return;
-
-    w = where & ~SSL_ST_MASK;
-
-    if (w & SSL_ST_CONNECT)
-       str = "SSL_connect";
-    else if (w & SSL_ST_ACCEPT)
-       str = "SSL_accept";
-    else
-       str = "undefined";
-
-    if (where & SSL_CB_LOOP) {
-       if (tls_serverengine && (tls_loglevel >= 2))
-           Printf("%s:%s", str, SSL_state_string_long(s));
-    } else if (where & SSL_CB_ALERT) {
-       str = (where & SSL_CB_READ) ? "read" : "write";
-       if ((tls_serverengine && (tls_loglevel >= 2)) ||
-           ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY))
-         Printf("SSL3 alert %s:%s:%s", str,
-                SSL_alert_type_string_long(ret),
-                SSL_alert_desc_string_long(ret));
-    } else if (where & SSL_CB_EXIT) {
-       if (ret == 0)
-           Printf("%s:failed in %s",
-                    str, SSL_state_string_long(s));
-       else if (ret < 0) {
-           Printf("%s:error in %s",
-                    str, SSL_state_string_long(s));
-       }
-    }
-}
-
-
-/*
- *     Hardcoded DH parameter files, from OpenSSL.
- *     For information on how these files were generated, see
- *     "Assigned Number for SKIP Protocols" 
- *     (http://www.skip-vpn.org/spec/numbers.html.
- */
-static const char file_dh512[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
-XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
------END DH PARAMETERS-----\n";
-
-static const char file_dh1024[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
-jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
-ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
------END DH PARAMETERS-----\n";
-
-static const char file_dh2048[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
-89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
-T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
-zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
-Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
-CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
------END DH PARAMETERS-----\n";
-
-static const char file_dh4096[] =
-"-----BEGIN DH PARAMETERS-----\n\
-MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
-l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
-Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
-Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
-VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
-alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
-sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
-ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
-OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
-AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
-KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
------END DH PARAMETERS-----\n";
-
-/*
- *     Load hardcoded DH parameters.
- */
-static DH *
-load_dh_buffer (const char *buffer, size_t len)
-{
-       BIO *bio;
-       DH *dh = NULL;
-
-       bio = BIO_new_mem_buf((char *) buffer, len);
-       if (bio == NULL)
-               return NULL;
-       dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
-/*     if (dh == NULL) log error */
-       BIO_free(bio);
-
-       return dh;
-}
-
-/*
- *     Generate empheral DH key.  Because this can take a long
- *     time to compute, we use precomputed parameters of the
- *     common key sizes.
- *
- *     These values can be static (once loaded or computed) since
- *     the OpenSSL library can effectively generate random keys
- *     from the information provided.
- *
- *     EDH keying is slightly less efficient than static RSA keying,
- *     but it offers Perfect Forward Secrecy (PFS).
- *
- *     FIXME: support user-specified files, to eliminate risk of
- *     "small group" attacks.
- */
-static DH *tmp_dh_cb(SSL *s UNUSED, int export UNUSED, int keylength)
-{
-       DH *r = NULL;
-       static DH *dh = NULL;
-       static DH *dh512 = NULL;
-       static DH *dh1024 = NULL;
-       static DH *dh2048 = NULL;
-       static DH *dh4096 = NULL;
-
-       switch (keylength)
-       {
-       case 512:
-               if (dh512 == NULL)
-                       dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
-               r = dh512;
-               break;
-       case 1024:
-               if (dh1024 == NULL)
-                       dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
-               r = dh1024;
-               break;
-       case 2048:
-               if (dh2048 == NULL)
-                       dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
-               r = dh2048;
-               break;
-       case 4096:
-               if (dh4096 == NULL)
-                       dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
-               r = dh4096;
-               break;
-       default:
-               /* we should check current keylength vs. requested keylength */
-               /* also, this is an extremely expensive operation! */
-               dh = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
-               r = dh;
-       }
-
-       return r;
-}
-
-/* taken from OpenSSL apps/s_cb.c */
-
-static int verify_callback(int ok, X509_STORE_CTX * ctx)
-{
-    char    buf[256];
-    X509   *err_cert;
-    int     err;
-    int     depth;
-
-    syslog(L_NOTICE,"Doing a peer verify");
-
-    err_cert = X509_STORE_CTX_get_current_cert(ctx);
-    err = X509_STORE_CTX_get_error(ctx);
-    depth = X509_STORE_CTX_get_error_depth(ctx);
-
-    X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
-    if ((tls_serveractive) && (tls_loglevel >= 1))
-      Printf("Peer cert verify depth=%d %s", depth, buf);
-    if (ok==0)
-    {
-      syslog(L_NOTICE, "verify error:num=%d:%s", err,
-            X509_verify_cert_error_string(err));
-      
-       if (verify_depth >= depth) {
-           ok = 1;
-           verify_error = X509_V_OK;
-       } else {
-           ok = 0;
-           verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
-       }
-    }
-    switch (ctx->error) {
-    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
-       X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
-       syslog(L_NOTICE, "issuer= %s", buf);
-       break;
-    case X509_V_ERR_CERT_NOT_YET_VALID:
-    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
-       syslog(L_NOTICE, "cert not yet valid");
-       break;
-    case X509_V_ERR_CERT_HAS_EXPIRED:
-    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
-       syslog(L_NOTICE, "cert has expired");
-       break;
-    }
-    if ((tls_serveractive) && (tls_loglevel >= 1))
-      Printf("verify return:%d", ok);
-
-    return (ok);
-}
-
-
-/*
- * taken from OpenSSL crypto/bio/b_dump.c, modified to save a lot of strcpy
- * and strcat by Matti Aarnio.
- */
-
-#define TRUNCATE
-#define DUMP_WIDTH     16
-
-static int tls_dump(const char *s, int len)
-{
-    int     ret = 0;
-    char    buf[160 + 1];
-    char    *ss;
-    int     i;
-    int     j;
-    int     rows;
-    int     trunc;
-    unsigned char ch;
-
-    trunc = 0;
-
-
-#ifdef TRUNCATE
-    for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
-       trunc++;
-#endif
-
-    rows = (len / DUMP_WIDTH);
-    if ((rows * DUMP_WIDTH) < len)
-       rows++;
-
-    for (i = 0; i < rows; i++) {
-       buf[0] = '\0';                          /* start with empty string */
-       ss = buf;
-
-       sprintf(ss, "%04x ", i * DUMP_WIDTH);
-       ss += strlen(ss);
-       for (j = 0; j < DUMP_WIDTH; j++) {
-           if (((i * DUMP_WIDTH) + j) >= len) {
-               strcpy(ss, "   ");
-           } else {
-               ch = ((unsigned char) *((const char *)(s) + i * DUMP_WIDTH + j))
-                   & 0xff;
-               sprintf(ss, "%02x%c", ch, j == 7 ? '|' : ' ');
-               ss += 3;
-           }
-       }
-       ss += strlen(ss);
-       *ss+= ' ';
-       for (j = 0; j < DUMP_WIDTH; j++) {
-           if (((i * DUMP_WIDTH) + j) >= len)
-               break;
-           ch = ((unsigned char) *((const char *)(s) + i * DUMP_WIDTH + j))
-               & 0xff;
-           *ss+= (((ch >= ' ') && (ch <= '~')) ? ch : '.');
-           if (j == 7) *ss+= ' ';
-       }
-       *ss = 0;
-       /* 
-        * if this is the last call then update the ddt_dump thing so that
-         * we will move the selection point in the debug window
-         */    
-       if (tls_loglevel>0)
-         Printf("%s", buf);
-       ret += strlen(buf);
-    }
-#ifdef TRUNCATE
-    if (trunc > 0) {
-       snprintf(buf, sizeof(buf), "%04x - <SPACES/NULS>\n", len+ trunc);
-       if (tls_loglevel>0)
-         Printf("%s", buf);
-       ret += strlen(buf);
-    }
-#endif
-    return (ret);
-}
-
- /*
-  * Set up the cert things on the server side. We do need both the
-  * private key (in key_file) and the cert (in cert_file).
-  * Both files may be identical.
-  *
-  * This function is taken from OpenSSL apps/s_cb.c
-  */
-
-static int set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
-{
-    struct stat buf;
-
-    if (cert_file != NULL) {
-       if (SSL_CTX_use_certificate_file(ctx, cert_file,
-                                        SSL_FILETYPE_PEM) <= 0) {
-           syslog(L_ERROR, "unable to get certificate from '%s'", cert_file);
-           return (0);
-       }
-       if (key_file == NULL)
-           key_file = cert_file;
-
-       /* check ownership and permissions of key file */
-       if (lstat(key_file, &buf) == -1) {
-           syslog(L_ERROR, "unable to stat private key '%s'", key_file);
-           return (0);
-       }
-       if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) != 0 ||
-           buf.st_uid != getuid()) {
-           syslog(L_ERROR, "bad ownership or permissions on private key"
-                   " '%s': private key must be mode 600 and owned by "
-                   NEWSUSER, cert_file);
-           return (0);
-       }
-
-       if (SSL_CTX_use_PrivateKey_file(ctx, key_file,
-                                       SSL_FILETYPE_PEM) <= 0) {
-           syslog(L_ERROR, "unable to get private key from '%s'", key_file);
-           return (0);
-       }
-       /* Now we know that a key and cert have been set against
-         * the SSL context */
-       if (!SSL_CTX_check_private_key(ctx)) {
-           syslog(L_ERROR, "Private key does not match the certificate public key");
-           return (0);
-       }
-    }
-    return (1);
-}
-
-
-
- /*
-  * This is the setup routine for the SSL server. As smtpd might be called
-  * more than once, we only want to do the initialization one time.
-  *
-  * The skeleton of this function is taken from OpenSSL apps/s_server.c.
-
-  * returns -1 on error
-  */
-
-int tls_init_serverengine(int verifydepth,
-                         int askcert,
-                         int requirecert,
-                         char *tls_CAfile,
-                         char *tls_CApath,
-                         char *tls_cert_file,
-                         char *tls_key_file
-                         )
-{
-    int     off = 0;
-    int     verify_flags = SSL_VERIFY_NONE;
-    char   *CApath;
-    char   *CAfile;
-    char   *s_cert_file;
-    char   *s_key_file;
-    struct stat buf;
-
-    if (tls_serverengine)
-      return (0);                              /* already running */
-
-    if (tls_loglevel >= 2)
-      Printf("starting TLS engine");
-
-    SSL_load_error_strings();
-    SSLeay_add_ssl_algorithms();
-
-    CTX = SSL_CTX_new(SSLv23_server_method());
-    if (CTX == NULL) {
-      return (-1);
-    };
-
-    off |= SSL_OP_ALL;         /* Work around all known bugs */
-    SSL_CTX_set_options(CTX, off);
-    SSL_CTX_set_info_callback(CTX, apps_ssl_info_callback);
-    SSL_CTX_sess_set_cache_size(CTX, 128);
-
-    if (strlen(tls_CAfile) == 0)
-      CAfile = NULL;
-    else
-      CAfile = tls_CAfile;
-    if (strlen(tls_CApath) == 0)
-      CApath = NULL;
-    else
-      CApath = tls_CApath;
-
-    if ((!SSL_CTX_load_verify_locations(CTX, CAfile, CApath)) ||
-       (!SSL_CTX_set_default_verify_paths(CTX))) {
-      if (tls_loglevel >= 2)
-       Printf("TLS engine: cannot load CA data\n");
-      return (-1);
-    }
-    
-    if (strlen(tls_cert_file) == 0)
-      s_cert_file = NULL;
-    else
-      s_cert_file = tls_cert_file;
-    if (strlen(tls_key_file) == 0)
-      s_key_file = NULL;
-    else
-      s_key_file = tls_key_file;
-    
-    if (!set_cert_stuff(CTX, s_cert_file, s_key_file)) {
-      if (tls_loglevel >= 2)
-       Printf("TLS engine: cannot load cert/key data\n");
-      return (-1);
-    }
-
-    /* load some randomization data from /dev/urandom, if it exists */
-    /* FIXME: should also check for ".rand" file, update it on exit */
-    if (stat("/dev/urandom", &buf) == 0)
-      RAND_load_file("/dev/urandom", 16 * 1024);
-
-    SSL_CTX_set_tmp_dh_callback(CTX, tmp_dh_cb);
-    SSL_CTX_set_options(CTX, SSL_OP_SINGLE_DH_USE);
-
-    verify_depth = verifydepth;
-    if (askcert!=0)
-       verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
-    if (requirecert)
-       verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
-           | SSL_VERIFY_CLIENT_ONCE;
-    SSL_CTX_set_verify(CTX, verify_flags, verify_callback);
-
-    SSL_CTX_set_client_CA_list(CTX, SSL_load_client_CA_file(CAfile));
-
-    tls_serverengine = 1;
-    return (0);
-}
-
-
-/*
-**  The function called by nnrpd to initialize the TLS support.  Calls
-**  tls_init_server_engine and checks the result.  On any sort of failure,
-**  nnrpd will exit.
-*/
-void
-tls_init(void)
-{
-    int ssl_result;
-
-    if (tls_initialized)
-        return;
-    sasl_config_read();
-    ssl_result = tls_init_serverengine(5,        /* depth to verify */
-                                      0,        /* can client auth? */
-                                      0,        /* required client to auth? */
-                                      (char *)sasl_config_getstring("tls_ca_file", ""),
-                                      (char *)sasl_config_getstring("tls_ca_path", ""),
-                                      (char *)sasl_config_getstring("tls_cert_file", ""),
-                                      (char *)sasl_config_getstring("tls_key_file", ""));
-    if (ssl_result == -1) {
-        Reply("%d Error initializing TLS\r\n", NNTP_STARTTLS_BAD_VAL);
-        syslog(L_ERROR, "error initializing TLS: "
-               "[CA_file: %s] [CA_path: %s] [cert_file: %s] [key_file: %s]",
-               sasl_config_getstring("tls_ca_file", ""),
-               sasl_config_getstring("tls_ca_path", ""),
-               sasl_config_getstring("tls_cert_file", ""),
-               sasl_config_getstring("tls_key_file", ""));
-        ExitWithStats(1, false);
-    }
-    tls_initialized = true;
-}
-
-
-/* taken from OpenSSL apps/s_cb.c */
-
-static long bio_dump_cb(BIO * bio, int cmd, const char *argp, int argi,
-                       long argl UNUSED, long ret)
-{
-    if (!do_dump)
-       return (ret);
-
-    if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
-       Printf("read from %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int) argp,
-                argi, ret, (unsigned int) ret);
-       tls_dump(argp, (int) ret);
-       return (ret);
-    } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
-       Printf("write to %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int)argp,
-                argi, ret, (unsigned int) ret);
-       tls_dump(argp, (int) ret);
-    }
-    return (ret);
-}
-
- /*
-  * This is the actual startup routine for the connection. We expect
-  * that the buffers are flushed and the "220 Ready to start TLS" was
-  * send to the client, so that we can immediately can start the TLS
-  * handshake process.
-  *
-  * layerbits and authid are filled in on sucess. authid is only
-  * filled in if the client authenticated
-  * 
-  */
-int tls_start_servertls(int readfd, int writefd)
-{
-    int     sts;
-    int     keepalive;
-    SSL_SESSION *session;
-    SSL_CIPHER *cipher;
-
-    if (!tls_serverengine)
-    {          
-      /* should never happen */
-      syslog(L_ERROR, "tls_engine not running");
-      return (-1);
-    }
-    if (tls_loglevel >= 1)
-       Printf("setting up TLS connection");
-
-    if (tls_conn == NULL)
-    {
-       tls_conn = (SSL *) SSL_new(CTX);
-    }
-    if (tls_conn == NULL)
-    {
-       return (-1);
-    }
-    SSL_clear(tls_conn);
-
-#if    defined(SOL_SOCKET) && defined(SO_KEEPALIVE)
-    /* Set KEEPALIVE to catch broken socket connections. */
-    keepalive = 1;
-    if (setsockopt(readfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0)
-        syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", readfd);
-    if (setsockopt(writefd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0)
-        syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", writefd);
-#endif /* SOL_SOCKET && SO_KEEPALIVE */
-    
-    /* set the file descriptors for SSL to use */
-    if (SSL_set_rfd(tls_conn, readfd)==0)
-    {
-      return (-1);
-    }
-
-    if (SSL_set_wfd(tls_conn, writefd)==0)
-    {
-      return (-1);
-    }
-    
-    /*
-     * This is the actual handshake routine. It will do all the negotiations
-     * and will check the client cert etc.
-     */
-    SSL_set_accept_state(tls_conn);
-
-    /*
-     * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called?
-     * Well there is a BIO below the SSL routines that is automatically
-     * created for us, so we can use it for debugging purposes.
-     */
-    if (tls_loglevel >= 3)
-       BIO_set_callback(SSL_get_rbio(tls_conn), bio_dump_cb);
-
-    /* Dump the negotiation for loglevels 3 and 4*/
-    if (tls_loglevel >= 3)
-       do_dump = 1;
-
-      if ((sts = SSL_accept(tls_conn)) <= 0) { /* xxx <= 0 */
-       session = SSL_get_session(tls_conn);
-
-       if (session) {
-         SSL_CTX_remove_session(CTX, session);
-       }
-       if (tls_conn)
-         SSL_free(tls_conn);
-       tls_conn = NULL;
-       return (-1);
-      }
-      /* Only loglevel==4 dumps everything */
-      if (tls_loglevel < 4)
-       do_dump = 0;
-
-    tls_protocol = SSL_get_version(tls_conn);
-    cipher = SSL_get_current_cipher(tls_conn);
-
-    tls_cipher_name = SSL_CIPHER_get_name(cipher);
-    tls_cipher_usebits = SSL_CIPHER_get_bits(cipher,
-                                                &tls_cipher_algbits);
-    tls_serveractive = 1;
-
-    syslog(L_NOTICE, "starttls: %s with cipher %s (%d/%d bits) no authentication", tls_protocol, tls_cipher_name,
-          tls_cipher_usebits, tls_cipher_algbits);
-
-    return (0);
-}
-
-ssize_t
-SSL_writev (ssl, vector, count)
-     SSL *ssl;
-     const struct iovec *vector;
-     int count;
-{
-  static char *buffer = NULL;
-  static size_t allocsize = 0;
-  char *bp;
-  size_t bytes, to_copy;
-  int i;
-  /* Find the total number of bytes to be written.  */
-  bytes = 0;
-  for (i = 0; i < count; ++i)
-    bytes += vector[i].iov_len;
-  /* Allocate a buffer to hold the data.  */
-  if (NULL == buffer) {
-    buffer = (char *) xmalloc(bytes);
-    allocsize = bytes;
-  } else if (bytes > allocsize) {
-    buffer = (char *) xrealloc (buffer, bytes);
-    allocsize = bytes;
-  }
-  /* Copy the data into BUFFER.  */
-  to_copy = bytes;
-  bp = buffer;
-  for (i = 0; i < count; ++i)
-    {
-#define min(a, b)       ((a) > (b) ? (b) : (a))
-      size_t copy = min (vector[i].iov_len, to_copy);
-      memcpy (bp, vector[i].iov_base, copy);
-      bp += copy;
-      to_copy -= copy;
-      if (to_copy == 0)
-        break;
-    }
-  return SSL_write (ssl, buffer, bytes);
-}
-
-
-#endif /* HAVE_SSL */