LIBDOVECOT_STORAGE_LAST='$(top_builddir)/src/lib-storage/list/libstorage_list.la $(top_builddir)/src/lib-storage/index/libstorage_index.la $(top_builddir)/src/lib-storage/libstorage.la $(top_builddir)/src/lib-index/libindex.la'
LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la'
LIBDOVECOT_STORAGE="$LIBDOVECOT_STORAGE_FIRST $LINKED_STORAGE_LIBS $LIBDOVECOT_STORAGE_LAST"
- LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la'
+ LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la'
LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la'
fi
LIBDOVECOT_SQL='$(top_builddir)/src/lib-sql/libsql.la'
return asn1_string_to_c(str);
}
-int ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io,
- const char *verify_name)
+int openssl_cert_match_name(SSL *ssl, const char *verify_name)
{
X509 *cert;
STACK_OF(GENERAL_NAME) *gnames;
bool dns_names = FALSE;
unsigned int i, count;
- if (!ssl_iostream_has_valid_client_cert(ssl_io))
- return -1;
-
- cert = SSL_get_peer_certificate(ssl_io->ssl);
+ cert = SSL_get_peer_certificate(ssl);
i_assert(cert != NULL);
/* verify against SubjectAltNames */
return strcmp(get_cname(cert), verify_name) == 0 ? 0 : -1;
}
+int ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io,
+ const char *verify_name)
+{
+ if (!ssl_iostream_has_valid_client_cert(ssl_io))
+ return -1;
+
+ return openssl_cert_match_name(ssl_io->ssl, verify_name);
+}
+
int ssl_iostream_handshake(struct ssl_iostream *ssl_io)
{
int ret;
int ssl_iostream_load_key(const struct ssl_iostream_settings *set,
const char *key_source, EVP_PKEY **pkey_r);
const char *ssl_iostream_get_use_certificate_error(const char *cert);
+int openssl_cert_match_name(SSL *ssl, const char *verify_name);
/* Sync plain_input/plain_output streams with BIOs. Returns TRUE if at least
one byte was read/written. */
-I$(top_srcdir)/src/lib-auth \
-I$(top_srcdir)/src/lib-dns \
-I$(top_srcdir)/src/lib-master \
+ -I$(top_srcdir)/src/lib-ssl-iostream \
-DPKG_STATEDIR=\""$(statedir)"\"
liblogin_la_SOURCES = \
pkglib_LTLIBRARIES = libdovecot-login.la
libdovecot_login_la_SOURCES =
-libdovecot_login_la_LIBADD = liblogin.la ../lib-dovecot/libdovecot.la
+libdovecot_login_la_LIBADD = liblogin.la ../lib-ssl-iostream/libssl_iostream.la ../lib-dovecot/libdovecot.la
libdovecot_login_la_DEPENDENCIES = liblogin.la
libdovecot_login_la_LDFLAGS = -export-dynamic
{
struct login_proxy *proxy = context;
- if ((proxy->ssl_flags & PROXY_SSL_FLAG_ANY_CERT) != 0 ||
- ssl_proxy_has_valid_client_cert(proxy->ssl_server_proxy))
+ if ((proxy->ssl_flags & PROXY_SSL_FLAG_ANY_CERT) != 0)
return 0;
- if (!ssl_proxy_has_broken_client_cert(proxy->ssl_server_proxy)) {
+ if (ssl_proxy_has_broken_client_cert(proxy->ssl_server_proxy)) {
+ client_log_err(proxy->client, t_strdup_printf(
+ "proxy: Received invalid SSL certificate from %s:%u",
+ proxy->host, proxy->port));
+ } else if (!ssl_proxy_has_valid_client_cert(proxy->ssl_server_proxy)) {
client_log_err(proxy->client, t_strdup_printf(
"proxy: SSL certificate not received from %s:%u",
proxy->host, proxy->port));
- } else {
+ } else if (ssl_proxy_cert_match_name(proxy->ssl_server_proxy,
+ proxy->host) < 0) {
client_log_err(proxy->client, t_strdup_printf(
- "proxy: Received invalid SSL certificate from %s:%u",
+ "proxy: hostname doesn't match SSL certificate at %s:%u",
proxy->host, proxy->port));
+ } else {
+ return 0;
}
proxy->disconnecting = TRUE;
return -1;
#ifdef HAVE_OPENSSL
+#include "iostream-openssl.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
return proxy->cert_received && proxy->cert_broken;
}
+int ssl_proxy_cert_match_name(struct ssl_proxy *proxy, const char *verify_name)
+{
+ return openssl_cert_match_name(proxy->ssl, verify_name);
+}
+
const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy)
{
X509 *x509;
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;
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;