]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common: Remove ssl-proxy code
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 31 Oct 2017 23:51:14 +0000 (01:51 +0200)
committerTimo Sirainen <tss@dovecot.fi>
Mon, 6 Nov 2017 23:09:00 +0000 (01:09 +0200)
src/login-common/Makefile.am
src/login-common/ssl-proxy-gnutls.c [deleted file]
src/login-common/ssl-proxy-openssl.c [deleted file]
src/login-common/ssl-proxy.c [deleted file]
src/login-common/ssl-proxy.h [deleted file]

index 7340e6b3063e5bca363d0334249df6d986a61466..806ddd235a4343e9337d7b690d175674f7ff4fd4 100644 (file)
@@ -19,18 +19,7 @@ liblogin_la_SOURCES = \
        login-proxy-state.c \
        login-settings.c \
        main.c \
-       sasl-server.c \
-       ssl-proxy.c \
-       ssl-proxy-gnutls.c \
-       ssl-proxy-openssl.c
-
-if BUILD_OPENSSL
-openssl_obj = ../lib-ssl-iostream/iostream-openssl-common.lo
-endif
-
-liblogin_la_LIBADD = \
-       $(openssl_obj) \
-       $(SSL_LIBS)
+       sasl-server.c
 
 headers = \
        access-lookup.h \
@@ -39,8 +28,7 @@ headers = \
        login-proxy.h \
        login-proxy-state.h \
        login-settings.h \
-       sasl-server.h \
-       ssl-proxy.h
+       sasl-server.h
 
 pkginc_libdir=$(pkgincludedir)
 pkginc_lib_HEADERS = $(headers)
diff --git a/src/login-common/ssl-proxy-gnutls.c b/src/login-common/ssl-proxy-gnutls.c
deleted file mode 100644 (file)
index 1d85ed2..0000000
+++ /dev/null
@@ -1,543 +0,0 @@
-/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
-
-#include "login-common.h"
-#include "ioloop.h"
-#include "net.h"
-#include "hash.h"
-#include "ssl-proxy.h"
-
-#ifdef HAVE_GNUTLS
-
-#error broken currently
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <gcrypt.h>
-#include <gnutls/gnutls.h>
-
-struct ssl_proxy {
-       int refcount;
-
-       gnutls_session session;
-       struct ip_addr ip;
-
-       int fd_ssl, fd_plain;
-       struct io *io_ssl, *io_plain;
-       int io_ssl_dir;
-
-       unsigned char outbuf_plain[1024];
-       unsigned int outbuf_pos_plain;
-
-       size_t send_left_ssl, send_left_plain;
-};
-
-const int protocol_priority[] =
-       { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
-const int kx_priority[] =
-       { GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, 0 };
-const int cipher_priority[] =
-       { GNUTLS_CIPHER_RIJNDAEL_CBC, GNUTLS_CIPHER_3DES_CBC,
-         GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_CIPHER_ARCFOUR_40, 0 };
-const int comp_priority[] =
-       { GNUTLS_COMP_LZO, GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
-const int mac_priority[] =
-       { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
-const int cert_type_priority[] =
-       { GNUTLS_CRT_X509, 0 };
-
-static struct hash_table *ssl_proxies;
-static gnutls_certificate_credentials x509_cred;
-static gnutls_dh_params dh_params;
-static gnutls_rsa_params rsa_params;
-
-static void ssl_input(struct ssl_proxy *proxy);
-static void plain_input(struct ssl_proxy *proxy);
-static bool ssl_proxy_destroy(struct ssl_proxy *proxy);
-
-static const char *get_alert_text(struct ssl_proxy *proxy)
-{
-       return gnutls_alert_get_name(gnutls_alert_get(proxy->session));
-}
-
-static int handle_ssl_error(struct ssl_proxy *proxy, int error)
-{
-       if (!gnutls_error_is_fatal(error)) {
-               if (!verbose_ssl)
-                       return 0;
-
-               if (error == GNUTLS_E_WARNING_ALERT_RECEIVED) {
-                       i_warning("Received SSL warning alert: %s [%s]",
-                                 get_alert_text(proxy),
-                                 net_ip2addr(&proxy->ip));
-               } else {
-                       i_warning("Non-fatal SSL error: %s: %s",
-                                 get_alert_text(proxy),
-                                 net_ip2addr(&proxy->ip));
-               }
-               return 0;
-       }
-
-       if (verbose_ssl) {
-               /* fatal error occurred */
-               if (error == GNUTLS_E_FATAL_ALERT_RECEIVED) {
-                       i_warning("Received SSL fatal alert: %s [%s]",
-                                 get_alert_text(proxy),
-                                 net_ip2addr(&proxy->ip));
-               } else {
-                       i_warning("Error reading from SSL client: %s [%s]",
-                                 gnutls_strerror(error),
-                                 net_ip2addr(&proxy->ip));
-               }
-       }
-
-        gnutls_alert_send_appropriate(proxy->session, error);
-       ssl_proxy_destroy(proxy);
-       return -1;
-}
-
-static int proxy_recv_ssl(struct ssl_proxy *proxy, void *data, size_t size)
-{
-       int rcvd;
-
-       rcvd = gnutls_record_recv(proxy->session, data, size);
-       if (rcvd > 0)
-               return rcvd;
-
-       if (rcvd == 0 || rcvd == GNUTLS_E_UNEXPECTED_PACKET_LENGTH) {
-               /* disconnected, either by nicely telling us that we'll
-                  close the connection, or by simply killing the
-                  connection which gives us the packet length error. */
-               ssl_proxy_destroy(proxy);
-               return -1;
-       }
-
-       return handle_ssl_error(proxy, rcvd);
-}
-
-static int proxy_send_ssl(struct ssl_proxy *proxy,
-                         const void *data, size_t size)
-{
-       int sent;
-
-       sent = gnutls_record_send(proxy->session, data, size);
-       if (sent >= 0)
-               return sent;
-
-       if (sent == GNUTLS_E_PUSH_ERROR || sent == GNUTLS_E_INVALID_SESSION) {
-               /* don't warn about errors related to unexpected
-                  disconnection */
-               ssl_proxy_destroy(proxy);
-               return -1;
-       }
-
-       return handle_ssl_error(proxy, sent);
-}
-
-static int ssl_proxy_destroy(struct ssl_proxy *proxy)
-{
-       if (--proxy->refcount > 0)
-               return TRUE;
-
-       hash_table_remove(ssl_proxies, proxy);
-
-       gnutls_deinit(proxy->session);
-
-       if (proxy->io_ssl != NULL)
-               io_remove(proxy->io_ssl);
-       if (proxy->io_plain != NULL)
-               io_remove(proxy->io_plain);
-
-       net_disconnect(proxy->fd_ssl);
-       net_disconnect(proxy->fd_plain);
-
-       i_free(proxy);
-
-       main_unref();
-       return FALSE;
-}
-
-static void ssl_output(struct ssl_proxy *proxy)
-{
-       int sent;
-
-       sent = net_transmit(proxy->fd_plain,
-                           proxy->outbuf_plain + proxy->outbuf_pos_plain,
-                           proxy->send_left_plain);
-       if (sent < 0) {
-               /* disconnected */
-               ssl_proxy_destroy(proxy);
-               return;
-       }
-
-       proxy->send_left_plain -= sent;
-       proxy->outbuf_pos_plain += sent;
-
-       if (proxy->send_left_plain > 0)
-               return;
-
-       /* everything is sent, start reading again */
-       io_remove(proxy->io_ssl);
-       proxy->io_ssl = io_add(proxy->fd_ssl, IO_READ, ssl_input, proxy);
-}
-
-static void ssl_input(struct ssl_proxy *proxy)
-{
-       int rcvd, sent;
-
-       rcvd = proxy_recv_ssl(proxy, proxy->outbuf_plain,
-                             sizeof(proxy->outbuf_plain));
-       if (rcvd <= 0)
-               return;
-
-       sent = net_transmit(proxy->fd_plain, proxy->outbuf_plain, (size_t)rcvd);
-       if (sent == rcvd)
-               return;
-
-       if (sent < 0) {
-               /* disconnected */
-               ssl_proxy_destroy(proxy);
-               return;
-       }
-
-       /* everything wasn't sent - don't read anything until we've
-          sent it all */
-        proxy->outbuf_pos_plain = 0;
-       proxy->send_left_plain = rcvd - sent;
-
-       io_remove(proxy->io_ssl);
-       proxy->io_ssl = io_add(proxy->fd_ssl, IO_WRITE, ssl_output, proxy);
-}
-
-static void plain_output(struct ssl_proxy *proxy)
-{
-       int sent;
-
-       sent = proxy_send_ssl(proxy, NULL, proxy->send_left_ssl);
-       if (sent <= 0)
-               return;
-
-       proxy->send_left_ssl -= sent;
-       if (proxy->send_left_ssl > 0)
-               return;
-
-       /* everything is sent, start reading again */
-       io_remove(proxy->io_plain);
-       proxy->io_plain = io_add(proxy->fd_plain, IO_READ, plain_input, proxy);
-}
-
-static void plain_input(struct ssl_proxy *proxy)
-{
-       char buf[1024];
-       ssize_t rcvd, sent;
-
-       rcvd = net_receive(proxy->fd_plain, buf, sizeof(buf));
-       if (rcvd < 0) {
-               /* disconnected */
-               gnutls_bye(proxy->session, 1);
-               ssl_proxy_destroy(proxy);
-               return;
-       }
-
-       sent = proxy_send_ssl(proxy, buf, (size_t)rcvd);
-       if (sent < 0 || sent == rcvd)
-               return;
-
-       /* everything wasn't sent - don't read anything until we've
-          sent it all */
-       proxy->send_left_ssl = rcvd - sent;
-
-       io_remove(proxy->io_plain);
-       proxy->io_plain = io_add(proxy->fd_ssl, IO_WRITE, plain_output, proxy);
-}
-
-static void ssl_handshake(struct ssl_proxy *proxy)
-{
-       int ret, dir;
-
-        ret = gnutls_handshake(proxy->session);
-       if (ret >= 0) {
-               /* handshake done, now we can start reading */
-               if (proxy->io_ssl != NULL)
-                       io_remove(proxy->io_ssl);
-
-               proxy->io_plain = io_add(proxy->fd_plain, IO_READ,
-                                        plain_input, proxy);
-               proxy->io_ssl = io_add(proxy->fd_ssl, IO_READ,
-                                      ssl_input, proxy);
-               return;
-       }
-
-       if (handle_ssl_error(proxy, ret) < 0)
-               return;
-
-       /* i/o interrupted */
-       dir = gnutls_record_get_direction(proxy->session) == 0 ?
-               IO_READ : IO_WRITE;
-       if (proxy->io_ssl_dir != dir) {
-               if (proxy->io_ssl != NULL)
-                       io_remove(proxy->io_ssl);
-               proxy->io_ssl = io_add(proxy->fd_ssl, dir,
-                                      ssl_handshake, proxy);
-               proxy->io_ssl_dir = dir;
-       }
-}
-
-static gnutls_session initialize_state(void)
-{
-       gnutls_session session;
-
-       gnutls_init(&session, GNUTLS_SERVER);
-
-       gnutls_protocol_set_priority(session, protocol_priority);
-       gnutls_cipher_set_priority(session, cipher_priority);
-       gnutls_compression_set_priority(session, comp_priority);
-       gnutls_kx_set_priority(session, kx_priority);
-       gnutls_mac_set_priority(session, mac_priority);
-       gnutls_certificate_type_set_priority(session, cert_type_priority);
-
-       gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
-       return session;
-}
-
-int ssl_proxy_new(int fd, struct ip_addr *ip)
-{
-        struct ssl_proxy *proxy;
-       gnutls_session session;
-       int sfd[2];
-
-       if (!ssl_initialized) {
-               i_error("SSL support not enabled in configuration");
-               return -1;
-       }
-
-       session = initialize_state();
-       gnutls_transport_set_ptr(session, fd);
-
-       if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) == -1) {
-               i_error("socketpair() failed: %m");
-               gnutls_deinit(session);
-               return -1;
-       }
-
-       net_set_nonblock(sfd[0], TRUE);
-       net_set_nonblock(sfd[1], TRUE);
-       net_set_nonblock(fd, TRUE);
-
-       proxy = i_new(struct ssl_proxy, 1);
-       proxy->refcount = 1;
-       proxy->session = session;
-       proxy->fd_ssl = fd;
-       proxy->fd_plain = sfd[0];
-       proxy->ip = *ip;
-
-       hash_table_insert(ssl_proxies, proxy, proxy);
-
-       proxy->refcount++;
-       ssl_handshake(proxy);
-       if (!ssl_proxy_destroy(proxy)) {
-               /* handshake failed. return the disconnected socket anyway
-                  so the caller doesn't try to use the old closed fd */
-               return sfd[1];
-       }
-
-        main_ref();
-       return sfd[1];
-}
-
-static void read_next_field(int fd, gnutls_datum *datum,
-                           const char *fname, const char *field_name)
-{
-        ssize_t ret;
-
-       /* get size */
-       ret = read(fd, &datum->size, sizeof(datum->size));
-       if (ret < 0)
-               i_fatal("read() failed for %s: %m", fname);
-
-       if (ret != sizeof(datum->size)) {
-               i_unlink(fname);
-               i_fatal("Corrupted SSL parameter file %s: File too small",
-                       fname);
-       }
-
-       if (datum->size > 10240) {
-               i_unlink(fname);
-               i_fatal("Corrupted SSL parameter file %s: "
-                       "Field '%s' too large (%u)",
-                       fname, field_name, datum->size);
-       }
-
-       /* read the actual data */
-       datum->data = t_malloc(datum->size);
-       ret = read(fd, datum->data, datum->size);
-       if (ret < 0)
-               i_fatal("read() failed for %s: %m", fname);
-
-       if ((size_t)ret != datum->size) {
-               i_unlink(fname);
-               i_fatal("Corrupted SSL parameter file %s: "
-                       "Field '%s' not fully in file (%u < %u)",
-                       fname, field_name, datum->size - ret, datum->size);
-       }
-}
-
-static void read_dh_parameters(int fd, const char *fname)
-{
-       gnutls_datum dbits, prime, generator;
-       int ret, bits;
-
-       if ((ret = gnutls_dh_params_init(&dh_params)) < 0) {
-               i_fatal("gnutls_dh_params_init() failed: %s",
-                       gnutls_strerror(ret));
-       }
-
-       /* read until bits field is 0 */
-       for (;;) {
-               read_next_field(fd, &dbits, fname, "DH bits");
-
-               if (dbits.size != sizeof(int)) {
-                       i_unlink(fname);
-                       i_fatal("Corrupted SSL parameter file %s: "
-                               "Field 'DH bits' has invalid size %u",
-                               fname, dbits.size);
-               }
-
-               bits = *((int *) dbits.data);
-               if (bits == 0)
-                       break;
-
-               read_next_field(fd, &prime, fname, "DH prime");
-               read_next_field(fd, &generator, fname, "DH generator");
-
-               ret = gnutls_dh_params_set(dh_params, prime, generator, bits);
-               if (ret < 0) {
-                       i_fatal("gnutls_dh_params_set() failed: %s",
-                               gnutls_strerror(ret));
-               }
-       }
-}
-
-static void read_rsa_parameters(int fd, const char *fname)
-{
-       gnutls_datum m, e, d, p, q, u;
-       int ret;
-
-       read_next_field(fd, &m, fname, "RSA m");
-       read_next_field(fd, &e, fname, "RSA e");
-       read_next_field(fd, &d, fname, "RSA d");
-       read_next_field(fd, &p, fname, "RSA p");
-       read_next_field(fd, &q, fname, "RSA q");
-       read_next_field(fd, &u, fname, "RSA u");
-
-       if ((ret = gnutls_rsa_params_init(&rsa_params)) < 0) {
-               i_fatal("gnutls_rsa_params_init() failed: %s",
-                       gnutls_strerror(ret));
-       }
-
-       /* only 512bit is allowed */
-       ret = gnutls_rsa_params_set(rsa_params, m, e, d, p, q, u, 512);
-       if (ret < 0) {
-               i_fatal("gnutls_rsa_params_set() failed: %s",
-                       gnutls_strerror(ret));
-       }
-}
-
-static void read_parameters(const char *fname)
-{
-       int fd;
-
-       /* we'll wait until parameter file exists */
-       for (;;) {
-               fd = open(fname, O_RDONLY);
-               if (fd != -1)
-                       break;
-
-               if (errno != ENOENT)
-                       i_fatal("Can't open SSL parameter file %s: %m", fname);
-
-               sleep(1);
-       }
-
-       read_dh_parameters(fd, fname);
-       read_rsa_parameters(fd, fname);
-
-       i_close_fd(&fd);
-}
-
-static void gcrypt_log_handler(void *context ATTR_UNUSED, int level,
-                              const char *fmt, va_list args)
-{
-       if (level != GCRY_LOG_FATAL)
-               return;
-
-       T_BEGIN {
-               i_error("gcrypt fatal: %s", t_strdup_vprintf(fmt, args));
-       } T_END;
-}
-
-void ssl_proxy_init(void)
-{
-       const char *certfile, *keyfile, *paramfile;
-       unsigned char buf[4];
-       int ret;
-
-       certfile = getenv("SSL_CERT_FILE");
-       keyfile = getenv("SSL_KEY_FILE");
-       paramfile = getenv("SSL_PARAM_FILE");
-
-       if (certfile == NULL || keyfile == NULL || paramfile == NULL) {
-               /* SSL support is disabled */
-               return;
-       }
-
-       if ((ret = gnutls_global_init() < 0)) {
-               i_fatal("gnu_tls_global_init() failed: %s",
-                       gnutls_strerror(ret));
-       }
-
-       /* gcrypt initialization - set log handler and make sure randomizer
-          opens /dev/urandom now instead of after we've chrooted */
-       gcry_set_log_handler(gcrypt_log_handler, NULL);
-       gcry_randomize(buf, sizeof(buf), GCRY_STRONG_RANDOM);
-
-       read_parameters(paramfile);
-
-       if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
-               i_fatal("gnutls_certificate_allocate_credentials() failed: %s",
-                       gnutls_strerror(ret));
-       }
-
-       ret = gnutls_certificate_set_x509_key_file(x509_cred, certfile, keyfile,
-                                                  GNUTLS_X509_FMT_PEM);
-       if (ret < 0) {
-               i_fatal("Can't load certificate files %s and %s: %s",
-                       certfile, keyfile, gnutls_strerror(ret));
-       }
-
-        gnutls_certificate_set_dh_params(x509_cred, dh_params);
-        gnutls_certificate_set_rsa_export_params(x509_cred, rsa_params);
-
-       ssl_proxies = hash_table_create(default_pool, 0, NULL, NULL);
-       ssl_initialized = TRUE;
-}
-
-void ssl_proxy_deinit(void)
-{
-       struct hash_iterate_context *iter;
-       void *key, *value;
-
-       if (!ssl_initialized)
-               return;
-
-       iter = hash_table_iterate_init(ssl_proxies);
-       while (hash_table_iterate(iter, &key, &value))
-               ssl_proxy_destroy(value);
-       hash_table_iterate_deinit(iter);
-       hash_table_destroy(ssl_proxies);
-
-       gnutls_certificate_free_credentials(x509_cred);
-       gnutls_global_deinit();
-}
-
-#endif
diff --git a/src/login-common/ssl-proxy-openssl.c b/src/login-common/ssl-proxy-openssl.c
deleted file mode 100644 (file)
index b2432d9..0000000
+++ /dev/null
@@ -1,1391 +0,0 @@
-/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
-
-#include "login-common.h"
-#include "array.h"
-#include "ioloop.h"
-#include "net.h"
-#include "ostream.h"
-#include "read-full.h"
-#include "safe-memset.h"
-#include "hash.h"
-#include "llist.h"
-#include "master-interface.h"
-#include "master-service-ssl-settings.h"
-#include "client-common.h"
-#include "ssl-proxy.h"
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_OPENSSL
-
-#include "iostream-openssl.h"
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-
-#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L
-#  define HAVE_ECDH
-#endif
-
-#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME /* FIXME: this may be unnecessary.. */
-#  undef HAVE_SSL_GET_SERVERNAME
-#endif
-
-enum ssl_io_action {
-       SSL_ADD_INPUT,
-       SSL_REMOVE_INPUT,
-       SSL_ADD_OUTPUT,
-       SSL_REMOVE_OUTPUT
-};
-
-struct ssl_proxy {
-       int refcount;
-       struct ssl_proxy *prev, *next;
-
-       SSL *ssl;
-       struct client *client;
-       struct ip_addr ip;
-       const struct login_settings *login_set;
-       const struct master_service_ssl_settings *ssl_set;
-       pool_t set_pool;
-
-       int fd_ssl, fd_plain;
-       struct io *io_ssl_read, *io_ssl_write, *io_plain_read, *io_plain_write;
-
-       unsigned char plainout_buf[1024];
-       unsigned int plainout_size;
-
-       unsigned char sslout_buf[1024];
-       unsigned int sslout_size;
-
-       ssl_handshake_callback_t *handshake_callback;
-       void *handshake_context;
-
-       const char *cert_error;
-       char *last_error;
-       bool handshaked:1;
-       bool destroyed:1;
-       bool cert_received:1;
-       bool cert_broken:1;
-       bool client_proxy:1;
-       bool flushing:1;
-       bool failed:1;
-};
-
-struct ssl_parameters {
-       DH *dh_default;
-};
-
-struct ssl_server_cert {
-       const char *cert;
-       const char *key;
-};
-
-struct ssl_server_context {
-       SSL_CTX *ctx;
-       pool_t pool;
-
-       struct ssl_server_cert pri, alt;
-
-       const char *ca;
-       const char *dh;
-       const char *cipher_list;
-       const char *curve_list;
-       const char *protocols;
-       bool verify_client_cert;
-       bool prefer_server_ciphers;
-       bool compression;
-       bool tickets;
-};
-
-static int extdata_index;
-static HASH_TABLE(struct ssl_server_context *,
-                 struct ssl_server_context *) ssl_servers;
-static SSL_CTX *ssl_client_ctx;
-static unsigned int ssl_proxy_count;
-static struct ssl_proxy *ssl_proxies;
-static struct ssl_parameters ssl_params;
-static int ssl_username_nid;
-static ENGINE *ssl_engine;
-
-static void plain_read(struct ssl_proxy *proxy);
-static void ssl_read(struct ssl_proxy *proxy);
-static void ssl_write(struct ssl_proxy *proxy);
-static void ssl_step(struct ssl_proxy *proxy);
-static void ssl_proxy_unref(struct ssl_proxy *proxy);
-
-static struct ssl_server_context *
-ssl_server_context_init(const struct login_settings *login_set,
-                       const struct master_service_ssl_settings *ssl_set);
-static void ssl_server_context_deinit(struct ssl_server_context **_ctx);
-
-static void ssl_proxy_ctx_set_crypto_params(SSL_CTX *ssl_ctx,
-                                            const struct master_service_ssl_settings *set);
-#if defined(HAVE_ECDH) && !defined(SSL_CTRL_SET_ECDH_AUTO)
-static int ssl_proxy_ctx_get_pkey_ec_curve_name(const struct master_service_ssl_settings *set);
-#endif
-
-static void ssl_proxy_destroy_failed(struct ssl_proxy *proxy)
-{
-       proxy->failed = TRUE;
-       ssl_proxy_destroy(proxy);
-}
-
-static unsigned int ssl_server_context_hash(const struct ssl_server_context *ctx)
-{
-       unsigned int n, i, g, h = 0;
-       const char *cert[] = { ctx->pri.cert, ctx->alt.cert };
-
-       /* checking for different certs is typically good enough,
-          and it should be enough to check only the first few bytes. */
-       for(n=0;n<N_ELEMENTS(cert);n++) {
-               if (cert[n] == NULL) continue;
-               for (i = 0; i < 16 && cert[n][i] != '\0'; i++) {
-                       h = (h << 4) + cert[n][i];
-                       if ((g = h & 0xf0000000UL) != 0) {
-                               h = h ^ (g >> 24);
-                               h = h ^ g;
-                       }
-               }
-       }
-       return h;
-}
-
-static int ssl_server_context_cmp(const struct ssl_server_context *ctx1,
-                                 const struct ssl_server_context *ctx2)
-{
-       if (((ctx1->pri.cert != ctx2->pri.cert) &&
-            (ctx1->pri.cert == NULL || ctx2->pri.cert == NULL)) ||
-           ((ctx1->alt.cert != ctx2->alt.cert) &&
-            (ctx1->alt.cert == NULL || ctx2->alt.cert == NULL)))
-               return 1;
-       if (ctx1->pri.cert != NULL && strcmp(ctx1->pri.cert, ctx2->pri.cert) != 0)
-               return 1;
-       if (ctx1->pri.key != NULL && strcmp(ctx1->pri.key, ctx2->pri.key) != 0)
-               return 1;
-       if (ctx1->alt.cert != NULL && strcmp(ctx1->alt.cert, ctx2->alt.cert) != 0)
-               return 1;
-       if (ctx1->alt.key != NULL && strcmp(ctx1->alt.key, ctx2->alt.key) != 0)
-               return 1;
-       if (null_strcmp(ctx1->ca, ctx2->ca) != 0)
-               return 1;
-       if (null_strcmp(ctx1->cipher_list, ctx2->cipher_list) != 0)
-               return 1;
-       if (null_strcmp(ctx1->curve_list, ctx2->curve_list) != 0)
-               return 1;
-       if (null_strcmp(ctx1->protocols, ctx2->protocols) != 0)
-               return 1;
-
-       return ctx1->verify_client_cert == ctx2->verify_client_cert ? 0 : 1;
-}
-
-static void ssl_free_parameters(struct ssl_parameters *params)
-{
-       if (params->dh_default != NULL) {
-               DH_free(params->dh_default);
-                params->dh_default = NULL;
-       }
-}
-
-static void ssl_set_io(struct ssl_proxy *proxy, enum ssl_io_action action)
-{
-       switch (action) {
-       case SSL_ADD_INPUT:
-               if (proxy->io_ssl_read != NULL)
-                       break;
-               proxy->io_ssl_read = io_add(proxy->fd_ssl, IO_READ,
-                                           ssl_step, proxy);
-               break;
-       case SSL_REMOVE_INPUT:
-               io_remove(&proxy->io_ssl_read);
-               break;
-       case SSL_ADD_OUTPUT:
-               if (proxy->io_ssl_write != NULL)
-                       break;
-               proxy->io_ssl_write = io_add(proxy->fd_ssl, IO_WRITE,
-                                            ssl_step, proxy);
-               break;
-       case SSL_REMOVE_OUTPUT:
-               io_remove(&proxy->io_ssl_write);
-               break;
-       }
-}
-
-static void plain_block_input(struct ssl_proxy *proxy, bool block)
-{
-       if (block) {
-               io_remove(&proxy->io_plain_read);
-       } else {
-               if (proxy->io_plain_read == NULL) {
-                       proxy->io_plain_read = io_add(proxy->fd_plain, IO_READ,
-                                                     plain_read, proxy);
-               }
-       }
-}
-
-static void plain_read(struct ssl_proxy *proxy)
-{
-       ssize_t ret;
-       bool corked = FALSE;
-
-       if (proxy->sslout_size == sizeof(proxy->sslout_buf)) {
-               /* buffer full, block input until it's written */
-               plain_block_input(proxy, TRUE);
-               return;
-       }
-
-       proxy->refcount++;
-
-       while (proxy->sslout_size < sizeof(proxy->sslout_buf) &&
-              !proxy->destroyed) {
-               ret = net_receive(proxy->fd_plain,
-                                 proxy->sslout_buf + proxy->sslout_size,
-                                 sizeof(proxy->sslout_buf) -
-                                 proxy->sslout_size);
-               if (ret <= 0) {
-                       if (ret < 0)
-                               ssl_proxy_destroy(proxy);
-                       break;
-               } else {
-                       proxy->sslout_size += ret;
-                       if (!corked) {
-                               if (net_set_cork(proxy->fd_ssl, TRUE) == 0)
-                                       corked = TRUE;
-                       }
-                       ssl_write(proxy);
-               }
-       }
-
-       if (corked)
-               (void)net_set_cork(proxy->fd_ssl, FALSE);
-
-       ssl_proxy_unref(proxy);
-}
-
-static void plain_write(struct ssl_proxy *proxy)
-{
-       ssize_t ret;
-
-       proxy->refcount++;
-
-       ret = net_transmit(proxy->fd_plain, proxy->plainout_buf,
-                          proxy->plainout_size);
-       if (ret < 0)
-               ssl_proxy_destroy(proxy);
-       else {
-               proxy->plainout_size -= ret;
-               memmove(proxy->plainout_buf, proxy->plainout_buf + ret,
-                       proxy->plainout_size);
-
-               if (proxy->plainout_size > 0) {
-                       if (proxy->io_plain_write == NULL) {
-                               proxy->io_plain_write =
-                                       io_add(proxy->fd_plain, IO_WRITE,
-                                              plain_write, proxy);
-                       }
-               } else {
-                       io_remove(&proxy->io_plain_write);
-               }
-
-               ssl_set_io(proxy, SSL_ADD_INPUT);
-               if (SSL_pending(proxy->ssl) > 0)
-                       ssl_read(proxy);
-       }
-
-       ssl_proxy_unref(proxy);
-}
-
-static void ssl_handle_error(struct ssl_proxy *proxy, int ret,
-                            const char *func_name)
-{
-       const char *errstr = NULL;
-       int err;
-
-       proxy->refcount++;
-
-       i_free_and_null(proxy->last_error);
-       err = SSL_get_error(proxy->ssl, ret);
-
-       switch (err) {
-       case SSL_ERROR_WANT_READ:
-               ssl_set_io(proxy, SSL_ADD_INPUT);
-               break;
-       case SSL_ERROR_WANT_WRITE:
-               ssl_set_io(proxy, SSL_ADD_OUTPUT);
-               break;
-       case SSL_ERROR_SYSCALL:
-               /* eat up the error queue */
-               if (ERR_peek_error() != 0)
-                       errstr = openssl_iostream_error();
-               else if (ret != 0)
-                       errstr = strerror(errno);
-               else {
-                       /* EOF. */
-                       errstr = "Disconnected";
-                       break;
-               }
-               errstr = t_strdup_printf("%s syscall failed: %s",
-                                        func_name, errstr);
-               break;
-       case SSL_ERROR_ZERO_RETURN:
-               /* clean connection closing */
-               ssl_proxy_destroy(proxy);
-               break;
-       case SSL_ERROR_SSL:
-               if (ERR_GET_REASON(ERR_peek_error()) == ERR_R_MALLOC_FAILURE) {
-                       i_error("OpenSSL malloc() failed. "
-                               "You may need to increase service %s { vsz_limit }",
-                               login_binary->process_name);
-               }
-               errstr = t_strdup_printf("%s failed: %s",
-                                        func_name, openssl_iostream_error());
-               break;
-       default:
-               errstr = t_strdup_printf("%s failed: unknown failure %d (%s)",
-                                        func_name, err, openssl_iostream_error());
-               break;
-       }
-
-       if (errstr != NULL) {
-               if (proxy->ssl_set->verbose_ssl)
-                       i_debug("SSL error: %s", errstr);
-               proxy->last_error = i_strdup(errstr);
-               ssl_proxy_destroy_failed(proxy);
-       }
-       ssl_proxy_unref(proxy);
-}
-
-static void ssl_handshake(struct ssl_proxy *proxy)
-{
-       int ret;
-
-       if (proxy->client_proxy) {
-               ret = SSL_connect(proxy->ssl);
-               if (ret != 1) {
-                       ssl_handle_error(proxy, ret, "SSL_connect()");
-                       return;
-               }
-       } else {
-               ret = SSL_accept(proxy->ssl);
-               if (ret != 1) {
-                       ssl_handle_error(proxy, ret, "SSL_accept()");
-                       return;
-               }
-       }
-       i_free_and_null(proxy->last_error);
-       proxy->handshaked = TRUE;
-
-       ssl_set_io(proxy, SSL_ADD_INPUT);
-       plain_block_input(proxy, FALSE);
-
-       if (proxy->handshake_callback != NULL) {
-               if (proxy->handshake_callback(proxy->handshake_context) < 0)
-                       ssl_proxy_destroy_failed(proxy);
-       }
-}
-
-static void ssl_read(struct ssl_proxy *proxy)
-{
-       int ret;
-
-       while (proxy->plainout_size < sizeof(proxy->plainout_buf) &&
-              !proxy->destroyed) {
-               ret = SSL_read(proxy->ssl,
-                              proxy->plainout_buf + proxy->plainout_size,
-                              sizeof(proxy->plainout_buf) -
-                              proxy->plainout_size);
-               if (ret <= 0) {
-                       ssl_handle_error(proxy, ret, "SSL_read()");
-                       break;
-               } else {
-                       i_free_and_null(proxy->last_error);
-                       proxy->plainout_size += ret;
-                       plain_write(proxy);
-               }
-       }
-}
-
-static void ssl_write(struct ssl_proxy *proxy)
-{
-       int ret;
-
-       ret = SSL_write(proxy->ssl, proxy->sslout_buf, proxy->sslout_size);
-       if (ret <= 0)
-               ssl_handle_error(proxy, ret, "SSL_write()");
-       else {
-               i_free_and_null(proxy->last_error);
-               proxy->sslout_size -= ret;
-               memmove(proxy->sslout_buf, proxy->sslout_buf + ret,
-                       proxy->sslout_size);
-
-               ssl_set_io(proxy, proxy->sslout_size > 0 ?
-                          SSL_ADD_OUTPUT : SSL_REMOVE_OUTPUT);
-               plain_block_input(proxy, FALSE);
-       }
-}
-
-static void ssl_step(struct ssl_proxy *proxy)
-{
-       proxy->refcount++;
-
-       if (!proxy->handshaked) {
-               ssl_set_io(proxy, SSL_REMOVE_OUTPUT);
-               ssl_handshake(proxy);
-       }
-
-       if (proxy->handshaked) {
-               if (proxy->plainout_size == sizeof(proxy->plainout_buf))
-                       ssl_set_io(proxy, SSL_REMOVE_INPUT);
-               else
-                       ssl_read(proxy);
-
-               if (proxy->sslout_size == 0)
-                       ssl_set_io(proxy, SSL_REMOVE_OUTPUT);
-               else {
-                       (void)net_set_cork(proxy->fd_ssl, TRUE);
-                       ssl_write(proxy);
-                       (void)net_set_cork(proxy->fd_ssl, FALSE);
-               }
-       }
-
-       ssl_proxy_unref(proxy);
-}
-
-static int
-ssl_proxy_alloc_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip,
-                      pool_t set_pool, const struct login_settings *login_set,
-                      const struct master_service_ssl_settings *ssl_set,
-                      struct ssl_proxy **proxy_r)
-{
-       struct ssl_proxy *proxy;
-       SSL *ssl;
-       int sfd[2];
-
-       i_assert(fd != -1);
-
-       *proxy_r = NULL;
-
-       if (!ssl_initialized) {
-               i_error("SSL support not enabled in configuration");
-               return -1;
-       }
-
-       
-
-       ssl = SSL_new(ssl_ctx);
-       if (ssl == NULL) {
-               i_error("SSL_new() failed: %s", openssl_iostream_error());
-               return -1;
-       }
-
-       if (SSL_set_fd(ssl, fd) != 1) {
-               i_error("SSL_set_fd() failed: %s", openssl_iostream_error());
-               SSL_free(ssl);
-               return -1;
-       }
-
-       if (socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) < 0) {
-               i_error("socketpair() failed: %m");
-               SSL_free(ssl);
-               return -1;
-       }
-
-       net_set_nonblock(sfd[0], TRUE);
-       net_set_nonblock(sfd[1], TRUE);
-       net_set_nonblock(fd, TRUE);
-
-       proxy = i_new(struct ssl_proxy, 1);
-       proxy->refcount = 2;
-       proxy->ssl = ssl;
-       proxy->login_set = login_set;
-       proxy->ssl_set = ssl_set;
-       proxy->fd_ssl = fd;
-       proxy->fd_plain = sfd[0];
-       proxy->ip = *ip;
-       proxy->set_pool = set_pool;
-       pool_ref(set_pool);
-       SSL_set_ex_data(ssl, extdata_index, proxy);
-
-       ssl_proxy_count++;
-       DLLIST_PREPEND(&ssl_proxies, proxy);
-
-       *proxy_r = proxy;
-       return sfd[1];
-}
-
-static struct ssl_server_context *
-ssl_server_context_get(const struct login_settings *login_set,
-                      const struct master_service_ssl_settings *set)
-{
-       struct ssl_server_context *ctx, lookup_ctx;
-
-       i_zero(&lookup_ctx);
-       lookup_ctx.pri.cert = set->ssl_cert;
-       lookup_ctx.pri.key = set->ssl_key;
-       lookup_ctx.alt.cert = set->ssl_alt_cert;
-       lookup_ctx.alt.key = set->ssl_alt_key;
-       lookup_ctx.ca = set->ssl_ca;
-       lookup_ctx.cipher_list = set->ssl_cipher_list;
-       lookup_ctx.curve_list = set->ssl_curve_list;
-       lookup_ctx.protocols = set->ssl_protocols;
-       lookup_ctx.verify_client_cert = set->ssl_verify_client_cert ||
-               login_set->auth_ssl_require_client_cert ||
-               login_set->auth_ssl_username_from_cert;
-       lookup_ctx.prefer_server_ciphers = set->ssl_prefer_server_ciphers;
-       lookup_ctx.compression = set->parsed_opts.compression;
-       lookup_ctx.tickets = set->parsed_opts.tickets;
-
-       ctx = hash_table_lookup(ssl_servers, &lookup_ctx);
-       if (ctx == NULL)
-               ctx = ssl_server_context_init(login_set, set);
-       return ctx;
-}
-
-int ssl_proxy_alloc(int fd, const struct ip_addr *ip, pool_t set_pool,
-                   const struct login_settings *login_set,
-                   const struct master_service_ssl_settings *ssl_set,
-                   struct ssl_proxy **proxy_r)
-{
-       struct ssl_server_context *ctx;
-
-       ctx = ssl_server_context_get(login_set, ssl_set);
-       return ssl_proxy_alloc_common(ctx->ctx, fd, ip,
-                                     set_pool, login_set, ssl_set, proxy_r);
-}
-
-int ssl_proxy_client_alloc(int fd, struct ip_addr *ip, pool_t set_pool,
-                          const struct login_settings *login_set,
-                          const struct master_service_ssl_settings *ssl_set,
-                          ssl_handshake_callback_t *callback, void *context,
-                          struct ssl_proxy **proxy_r)
-{
-       int ret;
-
-       ret = ssl_proxy_alloc_common(ssl_client_ctx, fd, ip,
-                                    set_pool, login_set, ssl_set, proxy_r);
-       if (ret < 0)
-               return -1;
-
-       (*proxy_r)->handshake_callback = callback;
-       (*proxy_r)->handshake_context = context;
-       (*proxy_r)->client_proxy = TRUE;
-       return ret;
-}
-
-void ssl_proxy_start(struct ssl_proxy *proxy)
-{
-       ssl_step(proxy);
-}
-
-void ssl_proxy_set_client(struct ssl_proxy *proxy, struct client *client)
-{
-       i_assert(proxy->client == NULL);
-
-       client_ref(client);
-       proxy->client = client;
-}
-
-bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy)
-{
-       return proxy->cert_received && !proxy->cert_broken;
-}
-
-bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy)
-{
-       return proxy->cert_received && proxy->cert_broken;
-}
-
-int ssl_proxy_cert_match_name(struct ssl_proxy *proxy, const char *verify_name)
-{
-       const char *reason;
-
-       return openssl_cert_match_name(proxy->ssl, verify_name, &reason) ? 0 : -1;
-}
-
-const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy)
-{
-       X509 *x509;
-       char *name;
-       int len;
-
-       if (!ssl_proxy_has_valid_client_cert(proxy))
-               return NULL;
-
-       x509 = SSL_get_peer_certificate(proxy->ssl);
-       if (x509 == NULL)
-               return NULL; /* we should have had it.. */
-
-       len = X509_NAME_get_text_by_NID(X509_get_subject_name(x509),
-                                       ssl_username_nid, NULL, 0);
-       if (len < 0)
-               name = "";
-       else {
-               name = t_malloc0(len + 1);
-               if (X509_NAME_get_text_by_NID(X509_get_subject_name(x509),
-                                       ssl_username_nid, name, len + 1) < 0)
-                       name = "";
-               else if (strlen(name) != (size_t)len) {
-                       /* NUL characters in name. Someone's trying to fake
-                          being another user? Don't allow it. */
-                       name = "";
-               }
-       }
-       X509_free(x509);
-       
-       return *name == '\0' ? NULL : name;
-}
-
-bool ssl_proxy_is_handshaked(const struct ssl_proxy *proxy)
-{
-       return proxy->handshaked;
-}
-
-const char *ssl_proxy_get_last_error(const struct ssl_proxy *proxy)
-{
-       return proxy->last_error;
-}
-
-const char *ssl_proxy_get_security_string(struct ssl_proxy *proxy)
-{
-       const SSL_CIPHER *cipher;
-       int bits, alg_bits;
-       const char *comp_str;
-
-       if (!proxy->handshaked)
-               return "";
-
-       cipher = SSL_get_current_cipher(proxy->ssl);
-       bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
-       comp_str = ssl_proxy_get_compression(proxy);
-       comp_str = comp_str == NULL ? "" : t_strconcat(" ", comp_str, NULL);
-       return t_strdup_printf("%s with cipher %s (%d/%d bits)%s",
-                              SSL_get_version(proxy->ssl),
-                              SSL_CIPHER_get_name(cipher),
-                              bits, alg_bits, comp_str);
-}
-
-const char *ssl_proxy_get_compression(struct ssl_proxy *proxy ATTR_UNUSED)
-{
-#if defined(HAVE_SSL_COMPRESSION) && !defined(OPENSSL_NO_COMP)
-       const COMP_METHOD *comp;
-
-       comp = SSL_get_current_compression(proxy->ssl);
-       return comp == NULL ? NULL : SSL_COMP_get_name(comp);
-#else
-       return NULL;
-#endif
-}
-
-const char *ssl_proxy_get_cert_error(struct ssl_proxy *proxy)
-{
-       return proxy->cert_error != NULL ? proxy->cert_error :
-               "(Unknown error)";
-}
-
-void ssl_proxy_free(struct ssl_proxy **_proxy)
-{
-       struct ssl_proxy *proxy = *_proxy;
-
-       *_proxy = NULL;
-       ssl_proxy_unref(proxy);
-}
-
-static void ssl_proxy_unref(struct ssl_proxy *proxy)
-{
-       if (--proxy->refcount > 0)
-               return;
-       i_assert(proxy->refcount == 0);
-
-       SSL_free(proxy->ssl);
-
-       pool_unref(&proxy->set_pool);
-       i_free(proxy->last_error);
-       i_free(proxy);
-}
-
-static void ssl_proxy_flush(struct ssl_proxy *proxy)
-{
-       /* this is pretty kludgy. mainly this is just for flushing the final
-          LOGOUT command output. */
-       plain_read(proxy);
-       ssl_step(proxy);
-}
-
-void ssl_proxy_destroy(struct ssl_proxy *proxy)
-{
-       if (proxy->destroyed || proxy->flushing)
-               return;
-       proxy->flushing = TRUE;
-       if (!proxy->failed && proxy->handshaked)
-               ssl_proxy_flush(proxy);
-       proxy->destroyed = TRUE;
-
-       ssl_proxy_count--;
-       DLLIST_REMOVE(&ssl_proxies, proxy);
-
-       io_remove(&proxy->io_ssl_read);
-       io_remove(&proxy->io_ssl_write);
-       io_remove(&proxy->io_plain_read);
-       io_remove(&proxy->io_plain_write);
-
-       if (SSL_shutdown(proxy->ssl) != 1) {
-               /* if bidirectional shutdown fails we need to clear
-                  the error queue. */
-               openssl_iostream_clear_errors();
-       }
-
-       net_disconnect(proxy->fd_ssl);
-       net_disconnect(proxy->fd_plain);
-
-       if (proxy->client != NULL)
-               client_unref(&proxy->client);
-       ssl_proxy_unref(proxy);
-}
-
-static RSA *ssl_gen_rsa_key(SSL *ssl ATTR_UNUSED,
-                           int is_export ATTR_UNUSED, int keylength)
-{
-       RSA *rsa = RSA_new();
-       BIGNUM *e = BN_new();
-       BN_set_word(e, RSA_F4);
-       RSA_generate_key_ex(rsa, keylength, e, NULL);
-       BN_free(e);
-       return rsa;
-}
-
-static void ssl_info_callback(const SSL *ssl, int where, int ret)
-{
-       struct ssl_proxy *proxy;
-
-       proxy = SSL_get_ex_data(ssl, extdata_index);
-
-       if (!proxy->ssl_set->verbose_ssl)
-               return;
-
-       if ((where & SSL_CB_ALERT) != 0) {
-               switch (ret & 0xff) {
-               case SSL_AD_CLOSE_NOTIFY:
-                       i_debug("SSL alert: %s [%s]",
-                               SSL_alert_desc_string_long(ret),
-                               net_ip2addr(&proxy->ip));
-                       break;
-               default:
-                       i_warning("SSL alert: where=0x%x, ret=%d: %s %s [%s]",
-                                 where, ret, SSL_alert_type_string_long(ret),
-                                 SSL_alert_desc_string_long(ret),
-                                 net_ip2addr(&proxy->ip));
-                       break;
-               }
-       } else if (ret == 0) {
-               i_warning("SSL failed: where=0x%x: %s [%s]",
-                         where, SSL_state_string_long(ssl),
-                         net_ip2addr(&proxy->ip));
-       } else {
-               i_debug("SSL: where=0x%x, ret=%d: %s [%s]",
-                       where, ret, SSL_state_string_long(ssl),
-                       net_ip2addr(&proxy->ip));
-       }
-}
-
-static int ssl_verify_client_cert(int preverify_ok, X509_STORE_CTX *ctx)
-{
-       SSL *ssl;
-        struct ssl_proxy *proxy;
-       int ctxerr;
-       char buf[1024];
-       X509_NAME *subject;
-
-       ssl = X509_STORE_CTX_get_ex_data(ctx,
-                                        SSL_get_ex_data_X509_STORE_CTX_idx());
-       proxy = SSL_get_ex_data(ssl, extdata_index);
-       proxy->cert_received = TRUE;
-       ctxerr = X509_STORE_CTX_get_error(ctx);
-
-       if (proxy->client_proxy && !proxy->login_set->ssl_require_crl &&
-           (ctxerr == X509_V_ERR_UNABLE_TO_GET_CRL ||
-            ctxerr == X509_V_ERR_CRL_HAS_EXPIRED)) {
-               /* no CRL given with the CA list. don't worry about it. */
-               preverify_ok = 1;
-       }
-       if (preverify_ok == 0)
-               proxy->cert_broken = TRUE;
-
-       subject = X509_get_subject_name(X509_STORE_CTX_get_current_cert(ctx));
-       (void)X509_NAME_oneline(subject, buf, sizeof(buf));
-       buf[sizeof(buf)-1] = '\0'; /* just in case.. */
-
-       ctxerr = X509_STORE_CTX_get_error(ctx);
-
-       if (proxy->cert_error == NULL) {
-               proxy->cert_error = p_strdup_printf(proxy->client->pool, "%s: %s",
-                       X509_verify_cert_error_string(ctxerr), buf);
-       }
-
-       if (proxy->ssl_set->verbose_ssl ||
-           (proxy->login_set->auth_verbose && preverify_ok == 0)) {
-               if (preverify_ok != 0) {
-                       client_log(proxy->client, t_strdup_printf(
-                               "Valid certificate: %s", buf));
-               } else {
-                       client_log(proxy->client, t_strdup_printf(
-                               "Invalid certificate: %s: %s",
-                               X509_verify_cert_error_string(ctxerr), buf));
-               }
-       }
-
-       /* Return success anyway, because if ssl_require_client_cert=no we
-          could still allow authentication. */
-       return 1;
-}
-
-static int
-pem_password_callback(char *buf, int size, int rwflag ATTR_UNUSED,
-                     void *userdata)
-{
-       if (userdata == NULL) {
-               i_error("SSL private key file is password protected, "
-                       "but password isn't given");
-               return 0;
-       }
-
-       if (i_strocpy(buf, userdata, size) < 0)
-               return 0;
-       return strlen(buf);
-}
-
-unsigned int ssl_proxy_get_count(void)
-{
-       return ssl_proxy_count;
-}
-
-static void load_ca(X509_STORE *store, const char *ca,
-                   STACK_OF(X509_NAME) **xnames_r)
-{
-       /* mostly just copy&pasted from X509_load_cert_crl_file() */
-       STACK_OF(X509_INFO) *inf;
-       X509_INFO *itmp;
-       X509_NAME *xname;
-       BIO *bio;
-       int i;
-
-       bio = BIO_new_mem_buf(t_strdup_noconst(ca), strlen(ca));
-       if (bio == NULL)
-               i_fatal("BIO_new_mem_buf() failed");
-       inf = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
-       if (inf == NULL)
-               i_fatal("Couldn't parse ssl_ca: %s", openssl_iostream_error());
-       BIO_free(bio);
-
-       if (xnames_r != NULL) {
-               *xnames_r = sk_X509_NAME_new_null();
-               if (*xnames_r == NULL)
-                       i_fatal_status(FATAL_OUTOFMEM, "sk_X509_NAME_new_null() failed");
-       }
-       for(i = 0; i < sk_X509_INFO_num(inf); i++) {
-               itmp = sk_X509_INFO_value(inf, i);
-               if(itmp->x509 != NULL) {
-                       X509_STORE_add_cert(store, itmp->x509);
-                       xname = X509_get_subject_name(itmp->x509);
-                       if (xname != NULL && xnames_r != NULL) {
-                               xname = X509_NAME_dup(xname);
-                               if (xname == NULL)
-                                       i_fatal_status(FATAL_OUTOFMEM, "X509_NAME_dup() failed");
-                               sk_X509_NAME_push(*xnames_r, xname);
-                       }
-               }
-               if(itmp->crl != NULL)
-                       X509_STORE_add_crl(store, itmp->crl);
-       }
-       sk_X509_INFO_pop_free(inf, X509_INFO_free);
-}
-
-static STACK_OF(X509_NAME) *
-ssl_proxy_ctx_init(SSL_CTX *ssl_ctx, const struct master_service_ssl_settings *set,
-                  bool load_xnames)
-{
-       X509_STORE *store;
-       STACK_OF(X509_NAME) *xnames = NULL;
-       /* enable all SSL workarounds, except empty fragments as it
-          makes SSL more vulnerable against attacks */
-       long ssl_ops = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
-
-#ifdef SSL_OP_NO_COMPRESSION
-       if (!set->parsed_opts.compression)
-               ssl_ops |= SSL_OP_NO_COMPRESSION;
-#endif
-#ifdef SSL_OP_NO_TICKET
-       if (!set->parsed_opts.tickets)
-               ssl_ops |= SSL_OP_NO_TICKET;
-#endif
-       SSL_CTX_set_options(ssl_ctx, ssl_ops);
-
-#ifdef SSL_MODE_RELEASE_BUFFERS
-       SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
-#endif
-
-       if (*set->ssl_ca != '\0') {
-               /* set trusted CA certs */
-               store = SSL_CTX_get_cert_store(ssl_ctx);
-               load_ca(store, set->ssl_ca, load_xnames ? &xnames : NULL);
-       }
-       ssl_proxy_ctx_set_crypto_params(ssl_ctx, set);
-       SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback);
-       return xnames;
-}
-
-static void
-ssl_proxy_ctx_set_crypto_params(SSL_CTX *ssl_ctx,
-       const struct master_service_ssl_settings *set ATTR_UNUSED)
-{
-#if defined(HAVE_ECDH) && !defined(SSL_CTRL_SET_ECDH_AUTO)
-       EC_KEY *ecdh;
-       int nid;
-       const char *curve_name;
-#endif
-       if (SSL_CTX_need_tmp_RSA(ssl_ctx) != 0)
-               SSL_CTX_set_tmp_rsa_callback(ssl_ctx, ssl_gen_rsa_key);
-#ifdef HAVE_ECDH
-       /* In the non-recommended situation where ECDH cipher suites are being
-          used instead of ECDHE, do not reuse the same ECDH key pair for
-          different sessions. This option improves forward secrecy. */
-       SSL_CTX_set_options(ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
-#ifdef SSL_CTRL_SET_ECDH_AUTO
-       /* OpenSSL >= 1.0.2 automatically handles ECDH temporary key parameter
-          selection. */
-       SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
-#else
-       /* For OpenSSL < 1.0.2, ECDH temporary key parameter selection must be
-          performed manually. Attempt to select the same curve as that used
-          in the server's private EC key file. Otherwise fall back to the
-          NIST P-384 (secp384r1) curve to be compliant with RFC 6460 when
-          AES-256 TLS cipher suites are in use. This fall back option does
-          however make Dovecot non-compliant with RFC 6460 which requires
-          curve NIST P-256 (prime256v1) be used when AES-128 TLS cipher
-          suites are in use. At least the non-compliance is in the form of
-          providing too much security rather than too little. */
-       nid = ssl_proxy_ctx_get_pkey_ec_curve_name(set);
-       ecdh = EC_KEY_new_by_curve_name(nid);
-       if (ecdh == NULL) {
-               /* Fall back option */
-               nid = NID_secp384r1;
-               ecdh = EC_KEY_new_by_curve_name(nid);
-       }
-       if ((curve_name = OBJ_nid2sn(nid)) != NULL && set->verbose_ssl)
-               i_debug("SSL: elliptic curve %s will be used for ECDH and"
-                       " ECDHE key exchanges", curve_name);
-       if (ecdh != NULL) {
-               SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
-               EC_KEY_free(ecdh);
-       }
-#endif
-#endif
-}
-
-static void
-ssl_proxy_ctx_verify_client(SSL_CTX *ssl_ctx, STACK_OF(X509_NAME) *ca_names)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
-       X509_STORE *store;
-
-       store = SSL_CTX_get_cert_store(ssl_ctx);
-       X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK |
-                            X509_V_FLAG_CRL_CHECK_ALL);
-#endif
-       SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
-                          ssl_verify_client_cert);
-       /* set list of CA names that are sent to client */
-       SSL_CTX_set_client_CA_list(ssl_ctx, ca_names);
-}
-
-static EVP_PKEY * ATTR_NULL(2)
-ssl_proxy_load_key(const char *key, const char *password)
-{
-       EVP_PKEY *pkey;
-       BIO *bio;
-       char *dup_password;
-
-       bio = BIO_new_mem_buf(t_strdup_noconst(key), strlen(key));
-       if (bio == NULL)
-               i_fatal("BIO_new_mem_buf() failed");
-
-       dup_password = t_strdup_noconst(password);
-       pkey = PEM_read_bio_PrivateKey(bio, NULL, pem_password_callback,
-                                      dup_password);
-       if (pkey == NULL) {
-               i_fatal("Couldn't parse private ssl_key: %s",
-                       openssl_iostream_key_load_error());
-       }
-       BIO_free(bio);
-       return pkey;
-}
-
-static DH *
-ssl_proxy_load_dh(const char *dhparam)
-{
-       DH *dh;
-       BIO *bio;
-
-       bio = BIO_new_mem_buf(t_strdup_noconst(dhparam), strlen(dhparam));
-       if (bio == NULL)
-               i_fatal("BIO_new_mem_buf() failed");
-       dh = NULL;
-       dh = PEM_read_bio_DHparams(bio, &dh, NULL, NULL);
-       if (dh == NULL)
-               i_fatal("Couldn't parse DH parameters: %s",
-                       openssl_iostream_key_load_error());
-       BIO_free(bio);
-       return dh;
-}
-
-static void
-ssl_proxy_ctx_use_key(SSL_CTX *ctx,
-                     const struct master_service_ssl_settings *set)
-{
-       EVP_PKEY *pkey;
-       const char *password;
-
-       password = *set->ssl_key_password != '\0' ? set->ssl_key_password :
-               getenv(MASTER_SSL_KEY_PASSWORD_ENV);
-       if (*set->ssl_key != '\0') {
-               pkey = ssl_proxy_load_key(set->ssl_key, password);
-               if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1)
-                       i_fatal("Can't load private ssl_key: %s", openssl_iostream_key_load_error());
-               EVP_PKEY_free(pkey);
-       }
-       if (*set->ssl_alt_key != '\0') {
-               pkey = ssl_proxy_load_key(set->ssl_alt_key, password);
-               if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1)
-                       i_fatal("Can't load private ssl_alt_key: %s", openssl_iostream_key_load_error());
-               EVP_PKEY_free(pkey);
-       }
-}
-
-static void
-ssl_proxy_ctx_use_dh(SSL_CTX *ctx,
-                    const struct master_service_ssl_settings *set)
-{
-       DH *dh;
-
-       dh = ssl_proxy_load_dh(set->ssl_dh);
-       if (SSL_CTX_set_tmp_dh(ctx, dh) != 1)
-               i_fatal("Can't load DH parameters: %s", openssl_iostream_key_load_error());
-       DH_free(dh);
-}
-
-#if defined(HAVE_ECDH) && !defined(SSL_CTRL_SET_ECDH_AUTO)
-static int
-ssl_proxy_ctx_get_pkey_ec_curve_name(const struct master_service_ssl_settings *set)
-{
-       int nid = 0;
-       EVP_PKEY *pkey;
-       const char *password;
-       EC_KEY *eckey;
-       const EC_GROUP *ecgrp;
-
-       password = *set->ssl_key_password != '\0' ? set->ssl_key_password :
-               getenv(MASTER_SSL_KEY_PASSWORD_ENV);
-       pkey = ssl_proxy_load_key(set->ssl_key, password);
-       if (pkey != NULL &&
-           (eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL &&
-           (ecgrp = EC_KEY_get0_group(eckey)) != NULL)
-               nid = EC_GROUP_get_curve_name(ecgrp);
-       else {
-               /* clear errors added by the above calls */
-               openssl_iostream_clear_errors();
-       }
-       EVP_PKEY_free(pkey);
-       return nid;
-}
-#endif
-
-static int
-ssl_proxy_ctx_use_certificate_chain(SSL_CTX *ctx, const char *cert)
-{
-       /* mostly just copy&pasted from SSL_CTX_use_certificate_chain_file() */
-       BIO *in;
-       X509 *x;
-       int ret = 0;
-
-       in = BIO_new_mem_buf(t_strdup_noconst(cert), strlen(cert));
-       if (in == NULL)
-               i_fatal("BIO_new_mem_buf() failed");
-
-       x = PEM_read_bio_X509(in, NULL, NULL, NULL);
-       if (x == NULL)
-               goto end;
-
-       ret = SSL_CTX_use_certificate(ctx, x);
-#if 0
-       /* This is in OpenSSL code, but it seems to cause failures.. */
-       if (ERR_peek_error() != 0)
-               ret = 0;
-#endif
-
-       if (ret != 0) {
-               /* If we could set up our certificate, now proceed to
-                * the CA certificates.
-                */
-               X509 *ca;
-               int r;
-               unsigned long err;
-               
-               while ((ca = PEM_read_bio_X509(in,NULL,NULL,NULL)) != NULL) {
-                       r = SSL_CTX_add_extra_chain_cert(ctx, ca);
-                       if (r == 0) {
-                               X509_free(ca);
-                               ret = 0;
-                               goto end;
-                       }
-               }
-               /* When the while loop ends, it's usually just EOF. */
-               err = ERR_peek_last_error();
-               if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
-                       ERR_clear_error();
-               else 
-                       ret = 0; /* some real error */
-               }
-
-end:
-       if (x != NULL) X509_free(x);
-       BIO_free(in);
-       return ret;
-}
-
-#ifdef HAVE_SSL_GET_SERVERNAME
-static void ssl_servername_callback(SSL *ssl, int *al ATTR_UNUSED,
-                                   void *context ATTR_UNUSED)
-{
-       struct ssl_server_context *ctx;
-       struct ssl_proxy *proxy;
-       struct client *client;
-       const char *host;
-       void **other_sets;
-
-       proxy = SSL_get_ex_data(ssl, extdata_index);
-       host = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
-
-       client = proxy->client;
-       if (!client->ssl_servername_settings_read) {
-               client->ssl_servername_settings_read = TRUE;
-               client->set = login_settings_read(client->pool,
-                                                 &client->local_ip,
-                                                 &client->ip, host,
-                                                 &client->ssl_set,
-                                                 &other_sets);
-       }
-       client->local_name = p_strdup(client->pool, host);
-       ctx = ssl_server_context_get(client->set, client->ssl_set);
-       SSL_set_SSL_CTX(ssl, ctx->ctx);
-}
-#endif
-
-static struct ssl_server_context *
-ssl_server_context_init(const struct login_settings *login_set,
-                       const struct master_service_ssl_settings *ssl_set)
-{
-       struct ssl_server_context *ctx;
-       SSL_CTX *ssl_ctx;
-       pool_t pool;
-       STACK_OF(X509_NAME) *xnames;
-
-       pool = pool_alloconly_create("ssl server context", 4096);
-       ctx = p_new(pool, struct ssl_server_context, 1);
-       ctx->pool = pool;
-       ctx->pri.cert = p_strdup(pool, ssl_set->ssl_cert);
-       ctx->pri.key = p_strdup(pool, ssl_set->ssl_key);
-       ctx->alt.cert = p_strdup(pool, ssl_set->ssl_alt_cert);
-       ctx->alt.key = p_strdup(pool, ssl_set->ssl_alt_key);
-       ctx->ca = p_strdup(pool, ssl_set->ssl_ca);
-       ctx->dh = p_strdup(pool, ssl_set->ssl_dh);
-       ctx->cipher_list = p_strdup(pool, ssl_set->ssl_cipher_list);
-       ctx->curve_list = p_strdup(pool, ssl_set->ssl_curve_list);
-       ctx->protocols = p_strdup(pool, ssl_set->ssl_protocols);
-       ctx->verify_client_cert = ssl_set->ssl_verify_client_cert ||
-               login_set->auth_ssl_require_client_cert ||
-               login_set->auth_ssl_username_from_cert;
-       ctx->prefer_server_ciphers = ssl_set->ssl_prefer_server_ciphers;
-       ctx->compression = ssl_set->parsed_opts.compression;
-       ctx->tickets = ssl_set->parsed_opts.tickets;
-
-       ctx->ctx = ssl_ctx = SSL_CTX_new(SSLv23_server_method());
-       if (ssl_ctx == NULL)
-               i_fatal("SSL_CTX_new() failed");
-       xnames = ssl_proxy_ctx_init(ssl_ctx, ssl_set, ctx->verify_client_cert);
-
-       if (SSL_CTX_set_cipher_list(ssl_ctx, ctx->cipher_list) != 1) {
-               i_fatal("Can't set cipher list to '%s': %s",
-                       ctx->cipher_list, openssl_iostream_error());
-       }
-       if (ctx->prefer_server_ciphers)
-               SSL_CTX_set_options(ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
-       SSL_CTX_set_options(ssl_ctx, openssl_get_protocol_options(ctx->protocols));
-
-#ifdef HAVE_SSL_CTX_SET1_CURVES_LIST
-       if (ctx->curve_list != NULL && strlen(ctx->curve_list) > 0 &&
-                       SSL_CTX_set1_curves_list(ssl_ctx, ctx->curve_list) != 1) {
-               i_fatal("Failed to set curve list to '%s'", ctx->curve_list);
-       }
-#endif
-
-       if (ctx->pri.cert != NULL && *ctx->pri.cert != '\0' &&
-           ssl_proxy_ctx_use_certificate_chain(ctx->ctx, ctx->pri.cert) != 1) {
-               i_fatal("Can't load ssl_cert: %s",
-                       openssl_iostream_use_certificate_error(ctx->pri.cert, "ssl_cert"));
-       }
-       if (ctx->alt.cert != NULL && *ctx->alt.cert != '\0' &&
-           ssl_proxy_ctx_use_certificate_chain(ctx->ctx, ctx->alt.cert) != 1) {
-               i_fatal("Can't load ssl_alt_cert: %s",
-                       openssl_iostream_use_certificate_error(ctx->alt.cert, "ssl_cert"));
-       }
-
-#ifdef HAVE_SSL_GET_SERVERNAME
-       if (SSL_CTX_set_tlsext_servername_callback(ctx->ctx,
-                                                  ssl_servername_callback) != 1) {
-               if (ssl_set->verbose_ssl)
-                       i_debug("OpenSSL library doesn't support SNI");
-       }
-#endif
-
-       ssl_proxy_ctx_use_key(ctx->ctx, ssl_set);
-       ssl_proxy_ctx_use_dh(ctx->ctx, ssl_set);
-
-       if (ctx->verify_client_cert)
-               ssl_proxy_ctx_verify_client(ctx->ctx, xnames);
-
-       i_assert(hash_table_lookup(ssl_servers, ctx) == NULL);
-       hash_table_insert(ssl_servers, ctx, ctx);
-       return ctx;
-}
-
-static void ssl_server_context_deinit(struct ssl_server_context **_ctx)
-{
-       struct ssl_server_context *ctx = *_ctx;
-
-       SSL_CTX_free(ctx->ctx);
-       pool_unref(&ctx->pool);
-}
-
-static void
-ssl_proxy_client_ctx_set_client_cert(SSL_CTX *ctx,
-                                    const struct login_settings *set)
-{
-       EVP_PKEY *pkey;
-
-       if (*set->ssl_client_cert == '\0')
-               return;
-
-       if (ssl_proxy_ctx_use_certificate_chain(ctx, set->ssl_client_cert) != 1) {
-               i_fatal("Can't load ssl_client_cert: %s",
-                       openssl_iostream_use_certificate_error(
-                               set->ssl_client_cert, "ssl_client_cert"));
-       }
-
-       pkey = ssl_proxy_load_key(set->ssl_client_key, NULL);
-       if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) {
-               i_fatal("Can't load private ssl_client_key: %s",
-                       openssl_iostream_key_load_error());
-       }
-       EVP_PKEY_free(pkey);
-}
-
-static void
-ssl_proxy_init_client(const struct login_settings *login_set,
-                     const struct master_service_ssl_settings *ssl_set)
-{
-       STACK_OF(X509_NAME) *xnames;
-
-       if ((ssl_client_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
-               i_fatal("SSL_CTX_new() failed");
-       xnames = ssl_proxy_ctx_init(ssl_client_ctx, ssl_set, TRUE);
-       ssl_proxy_ctx_verify_client(ssl_client_ctx, xnames);
-
-       ssl_proxy_client_ctx_set_client_cert(ssl_client_ctx, login_set);
-}
-
-void ssl_proxy_init(void)
-{
-       const struct login_settings *login_set = global_login_settings;
-       const struct master_service_ssl_settings *ssl_set = global_ssl_settings;
-       static char dovecot[] = "dovecot";
-       unsigned char buf;
-
-       if (strcmp(ssl_set->ssl, "no") == 0)
-               return;
-
-       SSL_library_init();
-       SSL_load_error_strings();
-       OpenSSL_add_all_algorithms();
-
-       if (*ssl_set->ssl_crypto_device != '\0') {
-               ENGINE_load_builtin_engines();
-               ssl_engine = ENGINE_by_id(ssl_set->ssl_crypto_device);
-               if (ssl_engine == NULL) {
-                       i_fatal("Unknown ssl_crypto_device: %s",
-                               ssl_set->ssl_crypto_device);
-               }
-               ENGINE_init(ssl_engine);
-               ENGINE_set_default_RSA(ssl_engine);
-               ENGINE_set_default_DSA(ssl_engine);
-               ENGINE_set_default_ciphers(ssl_engine);
-       }
-
-       extdata_index = SSL_get_ex_new_index(0, dovecot, NULL, NULL, NULL);
-
-       hash_table_create(&ssl_servers, default_pool, 0,
-                         ssl_server_context_hash, ssl_server_context_cmp);
-       (void)ssl_server_context_init(login_set, ssl_set);
-
-       ssl_proxy_init_client(login_set, ssl_set);
-       ssl_username_nid = OBJ_txt2nid(ssl_set->ssl_cert_username_field);
-       if (ssl_username_nid == NID_undef) {
-               i_fatal("Invalid ssl_cert_username_field: %s",
-                       ssl_set->ssl_cert_username_field);
-       }
-
-       /* PRNG initialization might want to use /dev/urandom, make sure it
-          does it before chrooting. We might not have enough entropy at
-          the first try, so this function may fail. It's still been
-          initialized though. */
-       (void)RAND_bytes(&buf, 1);
-
-       i_zero(&ssl_params);
-
-       ssl_proxy_count = 0;
-        ssl_proxies = NULL;
-       ssl_initialized = TRUE;
-}
-
-void ssl_proxy_deinit(void)
-{
-       struct hash_iterate_context *iter;
-       struct ssl_server_context *ctx;
-
-       if (!ssl_initialized)
-               return;
-
-       while (ssl_proxies != NULL)
-               ssl_proxy_destroy(ssl_proxies);
-
-       iter = hash_table_iterate_init(ssl_servers);
-       while (hash_table_iterate(iter, ssl_servers, &ctx, &ctx))
-               ssl_server_context_deinit(&ctx);
-       hash_table_iterate_deinit(&iter);
-       hash_table_destroy(&ssl_servers);
-
-       ssl_free_parameters(&ssl_params);
-       SSL_CTX_free(ssl_client_ctx);
-       if (ssl_engine != NULL) {
-               ENGINE_finish(ssl_engine);
-               ENGINE_cleanup();
-       }
-       EVP_cleanup();
-       ERR_free_strings();
-}
-
-#endif
diff --git a/src/login-common/ssl-proxy.c b/src/login-common/ssl-proxy.c
deleted file mode 100644 (file)
index c55c74b..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "ssl-proxy.h"
-
-bool ssl_initialized = FALSE;
-
-#ifndef HAVE_SSL
-
-/* no SSL support */
-
-int ssl_proxy_alloc(int fd ATTR_UNUSED, const struct ip_addr *ip ATTR_UNUSED,
-                   pool_t set_pool ATTR_UNUSED,
-                   const struct login_settings *login_set ATTR_UNUSED,
-                   const struct master_service_ssl_settings *ssl_set ATTR_UNUSED,
-                   struct ssl_proxy **proxy_r ATTR_UNUSED)
-{
-       i_error("Dovecot wasn't built with SSL support");
-       return -1;
-}
-
-int ssl_proxy_client_alloc(int fd ATTR_UNUSED, struct ip_addr *ip ATTR_UNUSED,
-                          pool_t set_pool ATTR_UNUSED,
-                          const struct login_settings *login_set ATTR_UNUSED,
-                          const struct master_service_ssl_settings *ssl_set ATTR_UNUSED,
-                          ssl_handshake_callback_t *callback ATTR_UNUSED,
-                          void *context ATTR_UNUSED,
-                          struct ssl_proxy **proxy_r ATTR_UNUSED)
-{
-       i_error("Dovecot wasn't built with SSL support");
-       return -1;
-}
-
-void ssl_proxy_start(struct ssl_proxy *proxy ATTR_UNUSED)
-{
-}
-
-void ssl_proxy_set_client(struct ssl_proxy *proxy ATTR_UNUSED,
-                         struct client *client ATTR_UNUSED)
-{
-}
-
-bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return FALSE;
-}
-
-bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return FALSE;
-}
-
-int ssl_proxy_cert_match_name(struct ssl_proxy *proxy ATTR_UNUSED,
-                             const char *verify_name ATTR_UNUSED)
-{
-       return -1;
-}
-
-const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return NULL;
-}
-
-bool ssl_proxy_is_handshaked(const struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return FALSE;
-}
-
-const char *ssl_proxy_get_last_error(const struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return NULL;
-}
-
-const char *ssl_proxy_get_security_string(struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return "";
-}
-
-const char *ssl_proxy_get_compression(struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return NULL;
-}
-
-const char *ssl_proxy_get_cert_error(struct ssl_proxy *proxy ATTR_UNUSED)
-{
-       return "";
-}
-
-void ssl_proxy_destroy(struct ssl_proxy *proxy ATTR_UNUSED) {}
-
-void ssl_proxy_free(struct ssl_proxy **proxy ATTR_UNUSED) {}
-
-unsigned int ssl_proxy_get_count(void)
-{
-       return 0;
-}
-
-void ssl_proxy_init(void) {}
-void ssl_proxy_deinit(void) {}
-
-#endif
diff --git a/src/login-common/ssl-proxy.h b/src/login-common/ssl-proxy.h
deleted file mode 100644 (file)
index 2cb79cb..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SSL_PROXY_H
-#define SSL_PROXY_H
-
-struct ip_addr;
-struct ssl_proxy;
-struct master_service_ssl_settings;
-struct login_settings;
-struct client;
-
-extern bool ssl_initialized;
-
-typedef int ssl_handshake_callback_t(void *context);
-
-/* establish SSL connection with the given fd, returns a new fd which you
-   must use from now on, or -1 if error occurred. Unless -1 is returned,
-   the given fd must be simply forgotten. */
-int ssl_proxy_alloc(int fd, const struct ip_addr *ip, pool_t set_pool,
-                   const struct login_settings *login_set,
-                   const struct master_service_ssl_settings *ssl_set,
-                   struct ssl_proxy **proxy_r);
-int ssl_proxy_client_alloc(int fd, struct ip_addr *ip, pool_t set_pool,
-                          const struct login_settings *login_set,
-                          const struct master_service_ssl_settings *ssl_set,
-                          ssl_handshake_callback_t *callback, void *context,
-                          struct ssl_proxy **proxy_r);
-void ssl_proxy_start(struct ssl_proxy *proxy);
-void ssl_proxy_set_client(struct ssl_proxy *proxy, struct client *client);
-bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy) ATTR_PURE;
-bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy);
-int ssl_proxy_cert_match_name(struct ssl_proxy *proxy, const char *verify_name);
-const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy);
-bool ssl_proxy_is_handshaked(const struct ssl_proxy *proxy) ATTR_PURE;
-const char *ssl_proxy_get_last_error(const struct ssl_proxy *proxy) ATTR_PURE;
-const char *ssl_proxy_get_security_string(struct ssl_proxy *proxy);
-const char *ssl_proxy_get_compression(struct ssl_proxy *proxy);
-const char *ssl_proxy_get_cert_error(struct ssl_proxy *proxy);
-void ssl_proxy_destroy(struct ssl_proxy *proxy);
-void ssl_proxy_free(struct ssl_proxy **proxy);
-
-/* Return number of active SSL proxies */
-unsigned int ssl_proxy_get_count(void) ATTR_PURE;
-
-void ssl_proxy_init(void);
-void ssl_proxy_deinit(void);
-
-#endif