conn: implemented old-style SSL connection
Added new API xmpp_conn_set_old_style_ssl(). This function forces using of old-style SSL connection.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
0.8.9
|
||||
- IPv6 support
|
||||
- Old style SSL support
|
||||
- New API xmpp_uuid_gen()
|
||||
|
||||
0.8.8
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <strophe.h>
|
||||
|
||||
@@ -36,20 +37,32 @@ int main(int argc, char **argv)
|
||||
xmpp_ctx_t *ctx;
|
||||
xmpp_conn_t *conn;
|
||||
xmpp_log_t *log;
|
||||
char *jid, *pass, *host;
|
||||
char *jid, *pass, *host = NULL;
|
||||
int i;
|
||||
int opt_disable_tls = 0;
|
||||
int opt_old_ssl = 0;
|
||||
|
||||
/* take a jid and password on the command line */
|
||||
if (argc < 3 || argc > 4) {
|
||||
fprintf(stderr, "Usage: basic <jid> <pass> [<host>]\n\n");
|
||||
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;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ((argc - i) < 2 || (argc - i) > 3) {
|
||||
fprintf(stderr, "Usage: basic [options] <jid> <pass> [<host>]\n\n"
|
||||
"Options:\n"
|
||||
" --disable-tls Disable TLS.\n"
|
||||
" --old-ssl Use old style SSL.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
jid = argv[1];
|
||||
pass = argv[2];
|
||||
host = NULL;
|
||||
|
||||
if (argc == 4)
|
||||
host = argv[3];
|
||||
jid = argv[i];
|
||||
pass = argv[i + 1];
|
||||
if (i + 2 < argc)
|
||||
host = argv[i + 2];
|
||||
|
||||
/* init library */
|
||||
xmpp_initialize();
|
||||
@@ -61,6 +74,12 @@ int main(int argc, char **argv)
|
||||
/* create a connection */
|
||||
conn = xmpp_conn_new(ctx);
|
||||
|
||||
/* configure connection properties */
|
||||
if (opt_disable_tls)
|
||||
xmpp_conn_disable_tls(conn);
|
||||
if (opt_old_ssl)
|
||||
xmpp_conn_set_old_style_ssl(conn);
|
||||
|
||||
/* setup authentication information */
|
||||
xmpp_conn_set_jid(conn, jid);
|
||||
xmpp_conn_set_pass(conn, pass);
|
||||
|
||||
29
src/auth.c
29
src/auth.c
@@ -280,32 +280,19 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn,
|
||||
void * const userdata)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = xmpp_stanza_get_name(stanza);
|
||||
xmpp_debug(conn->ctx, "xmpp",
|
||||
"handle proceedtls called for %s", name);
|
||||
xmpp_debug(conn->ctx, "xmpp", "handle proceedtls called for %s", name);
|
||||
|
||||
if (strcmp(name, "proceed") == 0) {
|
||||
xmpp_debug(conn->ctx, "xmpp", "proceeding with TLS");
|
||||
|
||||
conn->tls = tls_new(conn->ctx, conn->sock);
|
||||
|
||||
if (!tls_start(conn->tls))
|
||||
{
|
||||
xmpp_debug(conn->ctx, "xmpp", "Couldn't start TLS! error %d", tls_error(conn->tls));
|
||||
tls_free(conn->tls);
|
||||
conn->tls = NULL;
|
||||
conn->tls_failed = 1;
|
||||
|
||||
/* failed tls spoils the connection, so disconnect */
|
||||
xmpp_disconnect(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
conn->secured = 1;
|
||||
conn_prepare_reset(conn, auth_handle_open);
|
||||
|
||||
conn_open_stream(conn);
|
||||
}
|
||||
if (conn_tls_start(conn) == 0) {
|
||||
conn_open_stream(conn);
|
||||
} else {
|
||||
/* failed tls spoils the connection, so disconnect */
|
||||
xmpp_disconnect(conn);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -146,6 +146,12 @@ struct _xmpp_handlist_t {
|
||||
#define SASL_MASK_ANONYMOUS 0x04
|
||||
#define SASL_MASK_SCRAMSHA1 0x08
|
||||
|
||||
enum {
|
||||
XMPP_PORT_CLIENT = 5222,
|
||||
XMPP_PORT_CLIENT_OLD_SSL = 5223,
|
||||
XMPP_PORT_COMPONENT = 5347,
|
||||
};
|
||||
|
||||
typedef void (*xmpp_open_handler)(xmpp_conn_t * const conn);
|
||||
|
||||
struct _xmpp_conn_t {
|
||||
@@ -162,6 +168,7 @@ struct _xmpp_conn_t {
|
||||
|
||||
int tls_support;
|
||||
int tls_disabled;
|
||||
int tls_is_old_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 */
|
||||
@@ -215,6 +222,7 @@ struct _xmpp_conn_t {
|
||||
void conn_disconnect(xmpp_conn_t * const conn);
|
||||
void conn_disconnect_clean(xmpp_conn_t * const conn);
|
||||
void conn_open_stream(xmpp_conn_t * const conn);
|
||||
int conn_tls_start(xmpp_conn_t * const conn);
|
||||
void conn_prepare_reset(xmpp_conn_t * const conn, xmpp_open_handler handler);
|
||||
void conn_parser_reset(xmpp_conn_t * const conn);
|
||||
|
||||
|
||||
104
src/conn.c
104
src/conn.c
@@ -16,6 +16,7 @@
|
||||
/** @defgroup Connections Connection management
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -55,6 +56,7 @@ static void _handle_stream_end(char *name,
|
||||
void * const userdata);
|
||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
||||
void * const userdata);
|
||||
static int _conn_default_port(xmpp_conn_t * const conn);
|
||||
|
||||
/** Create a new Strophe connection object.
|
||||
*
|
||||
@@ -106,6 +108,7 @@ 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_failed = 0;
|
||||
conn->sasl_support = 0;
|
||||
conn->secured = 0;
|
||||
@@ -377,7 +380,7 @@ xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn)
|
||||
* @param altdomain a string with domain to use if SRV lookup fails. If this
|
||||
* is NULL, the domain from the JID will be used.
|
||||
* @param altport an integer port number to use if SRV lookup fails. If this
|
||||
* is 0, the default port (5222) will be assumed.
|
||||
* is 0, the default port will be assumed.
|
||||
* @param callback a xmpp_conn_handler callback function that will receive
|
||||
* notifications of connection status
|
||||
* @param userdata an opaque data pointer that will be passed to the callback
|
||||
@@ -392,34 +395,43 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
||||
xmpp_conn_handler callback,
|
||||
void * const userdata)
|
||||
{
|
||||
char connectdomain[2048];
|
||||
int connectport;
|
||||
const char * domain;
|
||||
char domain[2048];
|
||||
int port;
|
||||
const char *prefdomain = NULL;
|
||||
int found;
|
||||
|
||||
conn->type = XMPP_CLIENT;
|
||||
|
||||
conn->domain = xmpp_jid_domain(conn->ctx, conn->jid);
|
||||
if (!conn->domain) return -1;
|
||||
|
||||
if (altdomain) {
|
||||
if (altdomain != NULL) {
|
||||
xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain.");
|
||||
strcpy(connectdomain, altdomain);
|
||||
connectport = altport ? altport : 5222;
|
||||
} else if (!sock_srv_lookup("xmpp-client", "tcp", conn->domain,
|
||||
connectdomain, 2048, &connectport)) {
|
||||
xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed.");
|
||||
if (!altdomain)
|
||||
domain = conn->domain;
|
||||
else
|
||||
domain = altdomain;
|
||||
xmpp_debug(conn->ctx, "xmpp", "Using alternate domain %s, port %d",
|
||||
altdomain, altport);
|
||||
strcpy(connectdomain, domain);
|
||||
connectport = altport ? altport : 5222;
|
||||
prefdomain = altdomain;
|
||||
port = altport ? altport : _conn_default_port(conn);
|
||||
} else {
|
||||
found = sock_srv_lookup("xmpp-client", "tcp", conn->domain,
|
||||
domain, sizeof(domain), &port);
|
||||
if (!found) {
|
||||
xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed, "
|
||||
"connecting via domain.");
|
||||
prefdomain = conn->domain;
|
||||
port = altport ? altport : _conn_default_port(conn);
|
||||
}
|
||||
if (conn->tls_is_old_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;
|
||||
}
|
||||
}
|
||||
conn->sock = sock_connect(connectdomain, connectport);
|
||||
if (prefdomain != NULL) {
|
||||
strncpy(domain, prefdomain, sizeof(domain));
|
||||
domain[sizeof(domain) - 1] = '\0';
|
||||
}
|
||||
conn->sock = sock_connect(domain, port);
|
||||
xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%d returned %d",
|
||||
connectdomain, connectport, conn->sock);
|
||||
domain, port, conn->sock);
|
||||
if (conn->sock == -1) return -1;
|
||||
|
||||
/* setup handler */
|
||||
@@ -433,7 +445,7 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
||||
|
||||
conn->state = XMPP_STATE_CONNECTING;
|
||||
conn->timeout_stamp = time_stamp();
|
||||
xmpp_debug(conn->ctx, "xmpp", "attempting to connect to %s", connectdomain);
|
||||
xmpp_debug(conn->ctx, "xmpp", "attempting to connect to %s", domain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -476,7 +488,7 @@ int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
|
||||
if (!(server && conn->jid && conn->pass)) return -1;
|
||||
|
||||
|
||||
connectport = port ? port : 5347;
|
||||
connectport = port ? port : _conn_default_port(conn);
|
||||
|
||||
xmpp_debug(conn->ctx, "xmpp", "Connecting via %s", server);
|
||||
conn->sock = sock_connect(server, connectport);
|
||||
@@ -730,6 +742,36 @@ void conn_open_stream(xmpp_conn_t * const conn)
|
||||
XMPP_NS_STREAMS);
|
||||
}
|
||||
|
||||
int conn_tls_start(xmpp_conn_t * const conn)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (conn->tls_disabled) {
|
||||
conn->tls = NULL;
|
||||
rc = -ENOSYS;
|
||||
} else {
|
||||
conn->tls = tls_new(conn->ctx, conn->sock);
|
||||
rc = conn->tls == NULL ? -ENOMEM : 0;
|
||||
}
|
||||
|
||||
if (conn->tls != NULL) {
|
||||
if (tls_start(conn->tls)) {
|
||||
conn->secured = 1;
|
||||
conn_prepare_reset(conn, auth_handle_open);
|
||||
} else {
|
||||
rc = tls_error(conn->tls);
|
||||
conn->error = rc;
|
||||
tls_free(conn->tls);
|
||||
conn->tls = NULL;
|
||||
conn->tls_failed = 1;
|
||||
}
|
||||
}
|
||||
if (rc != 0)
|
||||
xmpp_debug(conn->ctx, "conn", "Couldn't start TLS! error %d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** Disable TLS for this connection, called by users of the library.
|
||||
* Occasionally a server will be misconfigured to send the starttls
|
||||
* feature, but wil not support the handshake.
|
||||
@@ -741,6 +783,11 @@ 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;
|
||||
}
|
||||
|
||||
static void _log_open_tag(xmpp_conn_t *conn, char **attrs)
|
||||
{
|
||||
char buf[4096];
|
||||
@@ -837,3 +884,16 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
||||
|
||||
handler_fire_stanza(conn, stanza);
|
||||
}
|
||||
|
||||
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 :
|
||||
XMPP_PORT_CLIENT;
|
||||
case XMPP_COMPONENT:
|
||||
return XMPP_PORT_COMPONENT;
|
||||
default:
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
15
src/event.c
15
src/event.c
@@ -258,9 +258,10 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
||||
/* connection complete */
|
||||
|
||||
/* check for error */
|
||||
if (sock_connect_error(conn->sock) != 0) {
|
||||
ret = sock_connect_error(conn->sock);
|
||||
if (ret != 0) {
|
||||
/* connection failed */
|
||||
xmpp_debug(ctx, "xmpp", "connection failed");
|
||||
xmpp_debug(ctx, "xmpp", "connection failed, error %d", ret);
|
||||
conn_disconnect(conn);
|
||||
break;
|
||||
}
|
||||
@@ -268,7 +269,15 @@ 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");
|
||||
ret = conn_tls_start(conn);
|
||||
if (ret != 0) {
|
||||
conn_disconnect(conn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* send stream init */
|
||||
conn_open_stream(conn);
|
||||
}
|
||||
|
||||
@@ -215,6 +215,7 @@ 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_connect_client(xmpp_conn_t * const conn,
|
||||
const char * const altdomain,
|
||||
|
||||
Reference in New Issue
Block a user