From 9269d6b0d560d864b484ab4ee18dbe69e67f9065 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 4 Jul 2017 17:20:33 +0300 Subject: [PATCH] conn: add flag XMPP_CONN_FLAG_TRUST_TLS TLS modules accept invalid server's certificates when the flag is set. --- src/common.h | 1 + src/conn.c | 9 +++++++-- src/tls_openssl.c | 8 ++++++-- strophe.h | 4 ++++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/common.h b/src/common.h index 1290d72..f1356b0 100644 --- a/src/common.h +++ b/src/common.h @@ -168,6 +168,7 @@ struct _xmpp_conn_t { int tls_disabled; int tls_mandatory; int tls_legacy_ssl; + int tls_trust; int tls_failed; /* set when tls fails, so we don't try again */ int sasl_support; /* if true, field is a bitfield of supported mechanisms */ diff --git a/src/conn.c b/src/conn.c index bea84eb..86307ba 100644 --- a/src/conn.c +++ b/src/conn.c @@ -128,6 +128,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->tls_disabled = 0; conn->tls_mandatory = 0; conn->tls_legacy_ssl = 0; + conn->tls_trust = 0; conn->tls_failed = 0; conn->sasl_support = 0; conn->secured = 0; @@ -911,7 +912,8 @@ long xmpp_conn_get_flags(const xmpp_conn_t * const conn) flags = XMPP_CONN_FLAG_DISABLE_TLS * conn->tls_disabled | XMPP_CONN_FLAG_MANDATORY_TLS * conn->tls_mandatory | - XMPP_CONN_FLAG_LEGACY_SSL * conn->tls_legacy_ssl; + XMPP_CONN_FLAG_LEGACY_SSL * conn->tls_legacy_ssl | + XMPP_CONN_FLAG_TRUST_TLS * conn->tls_trust; return flags; } @@ -928,6 +930,7 @@ long xmpp_conn_get_flags(const xmpp_conn_t * const conn) * - XMPP_CONN_FLAG_DISABLE_TLS * - XMPP_CONN_FLAG_MANDATORY_TLS * - XMPP_CONN_FLAG_LEGACY_SSL + * - XMPP_CONN_FLAG_TRUST_TLS * * @param conn a Strophe connection object * @param flags ORed connection flags @@ -944,7 +947,8 @@ int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags) return XMPP_EINVOP; } if (flags & XMPP_CONN_FLAG_DISABLE_TLS && - flags & (XMPP_CONN_FLAG_MANDATORY_TLS | XMPP_CONN_FLAG_LEGACY_SSL)) { + flags & (XMPP_CONN_FLAG_MANDATORY_TLS | XMPP_CONN_FLAG_LEGACY_SSL | + XMPP_CONN_FLAG_TRUST_TLS)) { xmpp_error(conn->ctx, "conn", "Flags 0x%04lx conflict", flags); return XMPP_EINVOP; } @@ -952,6 +956,7 @@ int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags) conn->tls_disabled = (flags & XMPP_CONN_FLAG_DISABLE_TLS) ? 1 : 0; conn->tls_mandatory = (flags & XMPP_CONN_FLAG_MANDATORY_TLS) ? 1 : 0; conn->tls_legacy_ssl = (flags & XMPP_CONN_FLAG_LEGACY_SSL) ? 1 : 0; + conn->tls_trust = (flags & XMPP_CONN_FLAG_TRUST_TLS) ? 1 : 0; return 0; } diff --git a/src/tls_openssl.c b/src/tls_openssl.c index 7e52c6f..f320908 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -75,6 +75,7 @@ int tls_error(tls_t *tls) tls_t *tls_new(xmpp_conn_t *conn) { tls_t *tls = xmpp_alloc(conn->ctx, sizeof(*tls)); + int mode; if (tls) { int ret; @@ -86,7 +87,8 @@ tls_t *tls_new(xmpp_conn_t *conn) if (tls->ssl_ctx == NULL) goto err; - SSL_CTX_set_options(tls->ssl_ctx, SSL_OP_ALL); /* Enable bug workarounds. */ + /* Enable bug workarounds. */ + SSL_CTX_set_options(tls->ssl_ctx, SSL_OP_ALL); /* Disable insecure SSL/TLS versions. */ SSL_CTX_set_options(tls->ssl_ctx, SSL_OP_NO_SSLv2); /* DROWN */ @@ -101,7 +103,9 @@ tls_t *tls_new(xmpp_conn_t *conn) if (tls->ssl == NULL) goto err_free_ctx; - SSL_set_verify(tls->ssl, SSL_VERIFY_PEER, 0); + /* Trust server's certificate when user sets the flag explicitly. */ + mode = conn->tls_trust ? SSL_VERIFY_NONE : SSL_VERIFY_PEER; + SSL_set_verify(tls->ssl, mode, 0); #if OPENSSL_VERSION_NUMBER >= 0x10002000L /* Hostname verification is supported in OpenSSL 1.0.2 and newer. */ X509_VERIFY_PARAM *param = SSL_get0_param(tls->ssl); diff --git a/strophe.h b/strophe.h index 2f78629..a99d7c6 100644 --- a/strophe.h +++ b/strophe.h @@ -166,6 +166,10 @@ typedef struct _xmpp_stanza_t xmpp_stanza_t; #define XMPP_CONN_FLAG_DISABLE_TLS (1UL << 0) #define XMPP_CONN_FLAG_MANDATORY_TLS (1UL << 1) #define XMPP_CONN_FLAG_LEGACY_SSL (1UL << 2) +/** @def XMPP_CONN_FLAG_TRUST_TLS + * Trust server's certificate even if it is invalid. + */ +#define XMPP_CONN_FLAG_TRUST_TLS (1UL << 3) /* connect callback */ typedef enum {