From 182803926beef4cc2e0fe4928e61c8ce0d969f26 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Wed, 14 Oct 2015 23:19:10 +0300 Subject: [PATCH] conn: added new API xmpp_conn_set_flags() xmpp_conn_set_flags() and xmpp_conn_get_flags() unify interface of connection configuration. This interface allows compile-time check of supported features or even run-time check. Therefore, applications can be built with older libstrophe which doesn't support some optional flags. --- ChangeLog | 5 ++-- examples/basic.c | 26 ++++++++++------- src/auth.c | 13 ++++++++- src/common.h | 5 ++-- src/conn.c | 72 ++++++++++++++++++++++++++++++++++++++++++------ src/event.c | 4 +-- strophe.h | 7 ++++- 7 files changed, 105 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1426448..95bcf3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,10 @@ 0.8.9 - IPv6 support - - Old style SSL support + - Legacy SSL support - New API: - xmpp_uuid_gen() - - xmpp_conn_set_old_style_ssl() + - xmpp_conn_get_flags() + - xmpp_conn_set_flags() - xmpp_conn_is_secured() - Exposed private API: - xmpp_jid_new() diff --git a/examples/basic.c b/examples/basic.c index 8c0f3a4..652d860 100644 --- a/examples/basic.c +++ b/examples/basic.c @@ -42,16 +42,17 @@ int main(int argc, char **argv) xmpp_conn_t *conn; xmpp_log_t *log; char *jid, *pass, *host = NULL; + long flags = 0; int i; - int opt_disable_tls = 0; - int opt_old_ssl = 0; /* take a jid and password on the command line */ for (i = 1; i < argc; ++i) { if (strcmp(argv[i], "--disable-tls") == 0) - opt_disable_tls = 1; - else if (strcmp(argv[i], "--old-ssl") == 0) - opt_old_ssl = 1; + flags |= XMPP_CONN_FLAG_DISABLE_TLS; + else if (strcmp(argv[i], "--mandatory-tls") == 0) + flags |= XMPP_CONN_FLAG_MANDATORY_TLS; + else if (strcmp(argv[i], "--legacy-ssl") == 0) + flags |= XMPP_CONN_FLAG_LEGACY_SSL; else break; } @@ -59,7 +60,10 @@ int main(int argc, char **argv) fprintf(stderr, "Usage: basic [options] []\n\n" "Options:\n" " --disable-tls Disable TLS.\n" - " --old-ssl Use old style SSL.\n"); + " --mandatory-tls Deny plaintext connection.\n" + " --legacy-ssl Use old style SSL.\n\n" + "Note: --disable-tls conflicts with --mandatory-tls or " + "--legacy-ssl\n"); return 1; } @@ -68,6 +72,11 @@ int main(int argc, char **argv) if (i + 2 < argc) host = argv[i + 2]; + /* + * Note, this example doesn't handle errors. Applications should check + * return values of non-void functions. + */ + /* init library */ xmpp_initialize(); @@ -79,10 +88,7 @@ int main(int argc, char **argv) conn = xmpp_conn_new(ctx); /* configure connection properties (optional) */ - if (opt_disable_tls) - xmpp_conn_disable_tls(conn); - if (opt_old_ssl) - xmpp_conn_set_old_style_ssl(conn); + xmpp_conn_set_flags(conn, flags); /* setup authentication information */ xmpp_conn_set_jid(conn, jid); diff --git a/src/auth.c b/src/auth.c index 67d2bb1..ebf8973 100644 --- a/src/auth.c +++ b/src/auth.c @@ -592,7 +592,18 @@ static void _auth(xmpp_conn_t * const conn) /* TLS was tried, unset flag */ conn->tls_support = 0; - } else if (anonjid && conn->sasl_support & SASL_MASK_ANONYMOUS) { + /* _auth() will be called later */ + return; + } + + if (conn->tls_mandatory && !xmpp_conn_is_secured(conn)) { + xmpp_error(conn->ctx, "xmpp", "TLS is not supported, but set as" + "mandatory for this connection"); + conn_disconnect(conn); + return; + } + + if (anonjid && conn->sasl_support & SASL_MASK_ANONYMOUS) { /* some crap here */ auth = _make_sasl_auth(conn, "ANONYMOUS"); if (!auth) { diff --git a/src/common.h b/src/common.h index a1a3118..5cbe79a 100644 --- a/src/common.h +++ b/src/common.h @@ -137,7 +137,7 @@ struct _xmpp_handlist_t { enum { XMPP_PORT_CLIENT = 5222, - XMPP_PORT_CLIENT_OLD_SSL = 5223, + XMPP_PORT_CLIENT_LEGACY_SSL = 5223, XMPP_PORT_COMPONENT = 5347, }; @@ -157,7 +157,8 @@ struct _xmpp_conn_t { int tls_support; int tls_disabled; - int tls_is_old_ssl; + int tls_mandatory; + int tls_legacy_ssl; 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 3286ece..cd422c2 100644 --- a/src/conn.c +++ b/src/conn.c @@ -108,7 +108,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->tls_support = 0; conn->tls_disabled = 0; - conn->tls_is_old_ssl = 0; + conn->tls_mandatory = 0; + conn->tls_legacy_ssl = 0; conn->tls_failed = 0; conn->sasl_support = 0; conn->secured = 0; @@ -422,11 +423,11 @@ int xmpp_connect_client(xmpp_conn_t * const conn, prefdomain = conn->domain; port = altport ? altport : _conn_default_port(conn); } - if (conn->tls_is_old_ssl) { + if (conn->tls_legacy_ssl) { /* SSL tunneled connection on 5223 port is legacy and doesn't * have an SRV record. Force port 5223 here. */ - port = XMPP_PORT_CLIENT_OLD_SSL; + port = XMPP_PORT_CLIENT_LEGACY_SSL; } } if (prefdomain != NULL) { @@ -780,22 +781,75 @@ int conn_tls_start(xmpp_conn_t * const conn) return rc; } +/** Return applied flags for the connection. + * + * @param conn a Strophe connection object + * + * @return ORed connection flags that are applied for the connection. + */ +long xmpp_conn_get_flags(const xmpp_conn_t * const conn) +{ + long flags; + + 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; + + return flags; +} + +/** Set flags for the connection. + * This function applies set flags and resets unset ones. Default connection + * configuration is all flags unset. Flags can be applied only for a connection + * in disconnected state. + * All unsupported flags are ignored. If a flag is unset after successful set + * operation then the flag is not supported by current version. + * + * Supported flags are: + * + * - XMPP_CONN_FLAG_DISABLE_TLS + * - XMPP_CONN_FLAG_MANDATORY_TLS + * - XMPP_CONN_FLAG_LEGACY_SSL + * + * @param conn a Strophe connection object + * @param flags ORed connection flags + * + * @return 0 on success or -1 if flags can't be applied. + */ +int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags) +{ + if (conn->state != XMPP_STATE_DISCONNECTED) { + xmpp_error(conn->ctx, "conn", "Flags can be set only " + "for disconnected connection"); + return -1; + } + if (flags & XMPP_CONN_FLAG_DISABLE_TLS && + flags & (XMPP_CONN_FLAG_MANDATORY_TLS | XMPP_CONN_FLAG_LEGACY_SSL)) { + xmpp_error(conn->ctx, "conn", "Flags 0x%04lx conflict", flags); + return -1; + } + + 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; + + return 0; +} + /** Disable TLS for this connection, called by users of the library. * Occasionally a server will be misconfigured to send the starttls * feature, but will not support the handshake. * * @param conn a Strophe connection object + * + * @note this function is deprecated + * @see xmpp_conn_set_flags() */ void xmpp_conn_disable_tls(xmpp_conn_t * const conn) { conn->tls_disabled = 1; } -void xmpp_conn_set_old_style_ssl(xmpp_conn_t * const conn) -{ - conn->tls_is_old_ssl = 1; -} - /** Returns whether TLS session is established or not. */ int xmpp_conn_is_secured(xmpp_conn_t * const conn) { @@ -903,7 +957,7 @@ static int _conn_default_port(xmpp_conn_t * const conn) { switch (conn->type) { case XMPP_CLIENT: - return conn->tls_is_old_ssl ? XMPP_PORT_CLIENT_OLD_SSL : + return conn->tls_legacy_ssl ? XMPP_PORT_CLIENT_LEGACY_SSL : XMPP_PORT_CLIENT; case XMPP_COMPONENT: return XMPP_PORT_COMPONENT; diff --git a/src/event.c b/src/event.c index da04257..ee10fd6 100644 --- a/src/event.c +++ b/src/event.c @@ -269,8 +269,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) conn->state = XMPP_STATE_CONNECTED; xmpp_debug(ctx, "xmpp", "connection successful"); - if (conn->tls_is_old_ssl) { - xmpp_debug(ctx, "xmpp", "using old style SSL connection"); + if (conn->tls_legacy_ssl) { + xmpp_debug(ctx, "xmpp", "using legacy SSL connection"); ret = conn_tls_start(conn); if (ret != 0) { conn_disconnect(conn); diff --git a/strophe.h b/strophe.h index ebce46c..de62573 100644 --- a/strophe.h +++ b/strophe.h @@ -192,6 +192,10 @@ typedef enum { XMPP_SE_XML_NOT_WELL_FORMED } xmpp_error_type_t; +#define XMPP_CONN_FLAG_DISABLE_TLS 0x0001 +#define XMPP_CONN_FLAG_MANDATORY_TLS 0x0002 +#define XMPP_CONN_FLAG_LEGACY_SSL 0x0004 + typedef struct { xmpp_error_type_t type; char *text; @@ -208,6 +212,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx); xmpp_conn_t * xmpp_conn_clone(xmpp_conn_t * const conn); int xmpp_conn_release(xmpp_conn_t * const conn); +long xmpp_conn_get_flags(const xmpp_conn_t * const conn); +int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags); const char *xmpp_conn_get_jid(const xmpp_conn_t * const conn); const char *xmpp_conn_get_bound_jid(const xmpp_conn_t * const conn); void xmpp_conn_set_jid(xmpp_conn_t * const conn, const char * const jid); @@ -215,7 +221,6 @@ const char *xmpp_conn_get_pass(const xmpp_conn_t * const conn); void xmpp_conn_set_pass(xmpp_conn_t * const conn, const char * const pass); xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn); void xmpp_conn_disable_tls(xmpp_conn_t * const conn); -void xmpp_conn_set_old_style_ssl(xmpp_conn_t * const conn); int xmpp_conn_is_secured(xmpp_conn_t * const conn); int xmpp_connect_client(xmpp_conn_t * const conn,