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
|
0.8.9
|
||||||
- IPv6 support
|
- IPv6 support
|
||||||
|
- Old style SSL support
|
||||||
- New API xmpp_uuid_gen()
|
- New API xmpp_uuid_gen()
|
||||||
|
|
||||||
0.8.8
|
0.8.8
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <strophe.h>
|
#include <strophe.h>
|
||||||
|
|
||||||
@@ -36,20 +37,32 @@ int main(int argc, char **argv)
|
|||||||
xmpp_ctx_t *ctx;
|
xmpp_ctx_t *ctx;
|
||||||
xmpp_conn_t *conn;
|
xmpp_conn_t *conn;
|
||||||
xmpp_log_t *log;
|
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 */
|
/* take a jid and password on the command line */
|
||||||
if (argc < 3 || argc > 4) {
|
for (i = 1; i < argc; ++i) {
|
||||||
fprintf(stderr, "Usage: basic <jid> <pass> [<host>]\n\n");
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
jid = argv[1];
|
jid = argv[i];
|
||||||
pass = argv[2];
|
pass = argv[i + 1];
|
||||||
host = NULL;
|
if (i + 2 < argc)
|
||||||
|
host = argv[i + 2];
|
||||||
if (argc == 4)
|
|
||||||
host = argv[3];
|
|
||||||
|
|
||||||
/* init library */
|
/* init library */
|
||||||
xmpp_initialize();
|
xmpp_initialize();
|
||||||
@@ -61,6 +74,12 @@ int main(int argc, char **argv)
|
|||||||
/* create a connection */
|
/* create a connection */
|
||||||
conn = xmpp_conn_new(ctx);
|
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 */
|
/* setup authentication information */
|
||||||
xmpp_conn_set_jid(conn, jid);
|
xmpp_conn_set_jid(conn, jid);
|
||||||
xmpp_conn_set_pass(conn, pass);
|
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)
|
void * const userdata)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
name = xmpp_stanza_get_name(stanza);
|
name = xmpp_stanza_get_name(stanza);
|
||||||
xmpp_debug(conn->ctx, "xmpp",
|
xmpp_debug(conn->ctx, "xmpp", "handle proceedtls called for %s", name);
|
||||||
"handle proceedtls called for %s", name);
|
|
||||||
|
|
||||||
if (strcmp(name, "proceed") == 0) {
|
if (strcmp(name, "proceed") == 0) {
|
||||||
xmpp_debug(conn->ctx, "xmpp", "proceeding with TLS");
|
xmpp_debug(conn->ctx, "xmpp", "proceeding with TLS");
|
||||||
|
|
||||||
conn->tls = tls_new(conn->ctx, conn->sock);
|
if (conn_tls_start(conn) == 0) {
|
||||||
|
conn_open_stream(conn);
|
||||||
if (!tls_start(conn->tls))
|
} else {
|
||||||
{
|
/* failed tls spoils the connection, so disconnect */
|
||||||
xmpp_debug(conn->ctx, "xmpp", "Couldn't start TLS! error %d", tls_error(conn->tls));
|
xmpp_disconnect(conn);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -146,6 +146,12 @@ struct _xmpp_handlist_t {
|
|||||||
#define SASL_MASK_ANONYMOUS 0x04
|
#define SASL_MASK_ANONYMOUS 0x04
|
||||||
#define SASL_MASK_SCRAMSHA1 0x08
|
#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);
|
typedef void (*xmpp_open_handler)(xmpp_conn_t * const conn);
|
||||||
|
|
||||||
struct _xmpp_conn_t {
|
struct _xmpp_conn_t {
|
||||||
@@ -162,6 +168,7 @@ struct _xmpp_conn_t {
|
|||||||
|
|
||||||
int tls_support;
|
int tls_support;
|
||||||
int tls_disabled;
|
int tls_disabled;
|
||||||
|
int tls_is_old_ssl;
|
||||||
int tls_failed; /* set when tls fails, so we don't try again */
|
int tls_failed; /* set when tls fails, so we don't try again */
|
||||||
int sasl_support; /* if true, field is a bitfield of supported
|
int sasl_support; /* if true, field is a bitfield of supported
|
||||||
mechanisms */
|
mechanisms */
|
||||||
@@ -215,6 +222,7 @@ struct _xmpp_conn_t {
|
|||||||
void conn_disconnect(xmpp_conn_t * const conn);
|
void conn_disconnect(xmpp_conn_t * const conn);
|
||||||
void conn_disconnect_clean(xmpp_conn_t * const conn);
|
void conn_disconnect_clean(xmpp_conn_t * const conn);
|
||||||
void conn_open_stream(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_prepare_reset(xmpp_conn_t * const conn, xmpp_open_handler handler);
|
||||||
void conn_parser_reset(xmpp_conn_t * const conn);
|
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
|
/** @defgroup Connections Connection management
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ static void _handle_stream_end(char *name,
|
|||||||
void * const userdata);
|
void * const userdata);
|
||||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
||||||
void * const userdata);
|
void * const userdata);
|
||||||
|
static int _conn_default_port(xmpp_conn_t * const conn);
|
||||||
|
|
||||||
/** Create a new Strophe connection object.
|
/** 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_support = 0;
|
||||||
conn->tls_disabled = 0;
|
conn->tls_disabled = 0;
|
||||||
|
conn->tls_is_old_ssl = 0;
|
||||||
conn->tls_failed = 0;
|
conn->tls_failed = 0;
|
||||||
conn->sasl_support = 0;
|
conn->sasl_support = 0;
|
||||||
conn->secured = 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
|
* @param altdomain a string with domain to use if SRV lookup fails. If this
|
||||||
* is NULL, the domain from the JID will be used.
|
* is NULL, the domain from the JID will be used.
|
||||||
* @param altport an integer port number to use if SRV lookup fails. If this
|
* @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
|
* @param callback a xmpp_conn_handler callback function that will receive
|
||||||
* notifications of connection status
|
* notifications of connection status
|
||||||
* @param userdata an opaque data pointer that will be passed to the callback
|
* @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,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata)
|
void * const userdata)
|
||||||
{
|
{
|
||||||
char connectdomain[2048];
|
char domain[2048];
|
||||||
int connectport;
|
int port;
|
||||||
const char * domain;
|
const char *prefdomain = NULL;
|
||||||
|
int found;
|
||||||
|
|
||||||
conn->type = XMPP_CLIENT;
|
conn->type = XMPP_CLIENT;
|
||||||
|
|
||||||
conn->domain = xmpp_jid_domain(conn->ctx, conn->jid);
|
conn->domain = xmpp_jid_domain(conn->ctx, conn->jid);
|
||||||
if (!conn->domain) return -1;
|
if (!conn->domain) return -1;
|
||||||
|
|
||||||
if (altdomain) {
|
if (altdomain != NULL) {
|
||||||
xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain.");
|
xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain.");
|
||||||
strcpy(connectdomain, altdomain);
|
prefdomain = altdomain;
|
||||||
connectport = altport ? altport : 5222;
|
port = altport ? altport : _conn_default_port(conn);
|
||||||
} else if (!sock_srv_lookup("xmpp-client", "tcp", conn->domain,
|
} else {
|
||||||
connectdomain, 2048, &connectport)) {
|
found = sock_srv_lookup("xmpp-client", "tcp", conn->domain,
|
||||||
xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed.");
|
domain, sizeof(domain), &port);
|
||||||
if (!altdomain)
|
if (!found) {
|
||||||
domain = conn->domain;
|
xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed, "
|
||||||
else
|
"connecting via domain.");
|
||||||
domain = altdomain;
|
prefdomain = conn->domain;
|
||||||
xmpp_debug(conn->ctx, "xmpp", "Using alternate domain %s, port %d",
|
port = altport ? altport : _conn_default_port(conn);
|
||||||
altdomain, altport);
|
}
|
||||||
strcpy(connectdomain, domain);
|
if (conn->tls_is_old_ssl) {
|
||||||
connectport = altport ? altport : 5222;
|
/* 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",
|
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;
|
if (conn->sock == -1) return -1;
|
||||||
|
|
||||||
/* setup handler */
|
/* setup handler */
|
||||||
@@ -433,7 +445,7 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
|||||||
|
|
||||||
conn->state = XMPP_STATE_CONNECTING;
|
conn->state = XMPP_STATE_CONNECTING;
|
||||||
conn->timeout_stamp = time_stamp();
|
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;
|
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;
|
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);
|
xmpp_debug(conn->ctx, "xmpp", "Connecting via %s", server);
|
||||||
conn->sock = sock_connect(server, connectport);
|
conn->sock = sock_connect(server, connectport);
|
||||||
@@ -730,6 +742,36 @@ void conn_open_stream(xmpp_conn_t * const conn)
|
|||||||
XMPP_NS_STREAMS);
|
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.
|
/** Disable TLS for this connection, called by users of the library.
|
||||||
* Occasionally a server will be misconfigured to send the starttls
|
* Occasionally a server will be misconfigured to send the starttls
|
||||||
* feature, but wil not support the handshake.
|
* 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;
|
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)
|
static void _log_open_tag(xmpp_conn_t *conn, char **attrs)
|
||||||
{
|
{
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
@@ -837,3 +884,16 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
|||||||
|
|
||||||
handler_fire_stanza(conn, 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 */
|
/* connection complete */
|
||||||
|
|
||||||
/* check for error */
|
/* check for error */
|
||||||
if (sock_connect_error(conn->sock) != 0) {
|
ret = sock_connect_error(conn->sock);
|
||||||
|
if (ret != 0) {
|
||||||
/* connection failed */
|
/* connection failed */
|
||||||
xmpp_debug(ctx, "xmpp", "connection failed");
|
xmpp_debug(ctx, "xmpp", "connection failed, error %d", ret);
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -268,7 +269,15 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
conn->state = XMPP_STATE_CONNECTED;
|
conn->state = XMPP_STATE_CONNECTED;
|
||||||
xmpp_debug(ctx, "xmpp", "connection successful");
|
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 */
|
/* send stream init */
|
||||||
conn_open_stream(conn);
|
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);
|
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);
|
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_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,
|
int xmpp_connect_client(xmpp_conn_t * const conn,
|
||||||
const char * const altdomain,
|
const char * const altdomain,
|
||||||
|
|||||||
Reference in New Issue
Block a user