Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f915d7515 | ||
|
|
e25ca7719f | ||
|
|
2bf5cc0e41 | ||
|
|
30f3cc9263 | ||
|
|
e120109644 | ||
|
|
b4f13205d8 | ||
|
|
4797522d88 | ||
|
|
5ee06776ee | ||
|
|
c40b4c12c1 | ||
|
|
d8329960c5 | ||
|
|
94ece33f16 | ||
|
|
b179c2d277 | ||
|
|
ab568a2666 | ||
|
|
c10c930e8f | ||
|
|
6ddf424192 | ||
|
|
6aff44184e | ||
|
|
9cc9ea86bb | ||
|
|
13a0bc463c | ||
|
|
8ff510a3af | ||
|
|
633d1e9b52 | ||
|
|
a13ba65cfb | ||
|
|
0e6b0ef84d | ||
|
|
9a86efabe5 |
@@ -1,11 +1,11 @@
|
||||
language: c
|
||||
install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y install libtool pkg-config libexpat1-dev libxml2-dev libssl-dev check
|
||||
- sudo apt-get -y install libtool pkg-config libexpat1-dev libxml2-dev libssl-dev
|
||||
before_script:
|
||||
- ./bootstrap.sh
|
||||
script:
|
||||
- ./configure ${CONFIGURE_OPT} && make && make check-TESTS
|
||||
- ./configure ${CONFIGURE_OPT} CFLAGS="-Werror" && make && make check
|
||||
env:
|
||||
- CONFIGURE_OPT="--without-libxml2"
|
||||
- CONFIGURE_OPT="--with-libxml2"
|
||||
|
||||
11
ChangeLog
11
ChangeLog
@@ -1,3 +1,12 @@
|
||||
0.9.3
|
||||
- PLAIN mechanism is used only when no other mechanisms are supported
|
||||
- Legacy authentication is disabled by default, can be enabled with
|
||||
connection flag XMPP_CONN_FLAG_LEGACY_AUTH
|
||||
- Session is not established if it is optional
|
||||
- Fixed a bug causing a reused connection not to cleanup properly
|
||||
- Improved debug logging in OpenSSL module
|
||||
- Few memory leaks fixed
|
||||
|
||||
0.9.2
|
||||
- OpenSSL tls module verifies certificate by default. Set flag
|
||||
XMPP_CONN_FLAG_TRUST_TLS to ignore result of the verification
|
||||
@@ -12,6 +21,8 @@
|
||||
second in order to reduce CPU consumption
|
||||
- Reduced memory usage in expat module
|
||||
- New functions:
|
||||
- xmpp_error_new()
|
||||
- xmpp_send_error()
|
||||
- xmpp_ctx_set_timeout()
|
||||
- xmpp_sha1_digest()
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
AM_CFLAGS = -g -Wall
|
||||
|
||||
PARSER_CFLAGS=@PARSER_CFLAGS@
|
||||
PARSER_LIBS=@PARSER_LIBS@
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
AC_INIT([libstrophe], [0.9.2], [jack@metajack.im])
|
||||
AC_INIT([libstrophe], [0.9.3], [jack@metajack.im])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
LT_INIT([dlopen])
|
||||
|
||||
@@ -62,7 +62,7 @@ include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libexpat
|
||||
LOCAL_CFLAGS := -DHAVE_MEMMOVE
|
||||
LOCAL_CFLAGS := -DHAVE_MEMMOVE -DXML_DEV_URANDOM
|
||||
#LOCAL_C_INCLUDES := \
|
||||
# $(LOCAL_PATH)/expat
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
APP_ABI := armeabi armeabi-v7a mips x86
|
||||
APP_ABI := armeabi-v7a arm64-v8a
|
||||
APP_PLATFORM := android-19
|
||||
|
||||
259
src/auth.c
259
src/auth.c
@@ -61,6 +61,7 @@
|
||||
#endif
|
||||
|
||||
static void _auth(xmpp_conn_t * const conn);
|
||||
static void _auth_legacy(xmpp_conn_t *conn);
|
||||
static void _handle_open_sasl(xmpp_conn_t * const conn);
|
||||
static void _handle_open_tls(xmpp_conn_t * const conn);
|
||||
|
||||
@@ -69,11 +70,6 @@ static int _handle_component_hs_response(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza,
|
||||
void * const userdata);
|
||||
|
||||
static int _handle_missing_legacy(xmpp_conn_t * const conn,
|
||||
void * const userdata);
|
||||
static int _handle_legacy(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza,
|
||||
void * const userdata);
|
||||
static int _handle_features_sasl(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza,
|
||||
void * const userdata);
|
||||
@@ -219,6 +215,7 @@ static int _handle_features(xmpp_conn_t * const conn,
|
||||
void * const userdata)
|
||||
{
|
||||
xmpp_stanza_t *child, *mech;
|
||||
const char *ns;
|
||||
char *text;
|
||||
|
||||
/* remove the handler that detects missing stream:features */
|
||||
@@ -228,8 +225,10 @@ static int _handle_features(xmpp_conn_t * const conn,
|
||||
if (!conn->secured) {
|
||||
if (!conn->tls_disabled) {
|
||||
child = xmpp_stanza_get_child_by_name(stanza, "starttls");
|
||||
if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_TLS) == 0))
|
||||
conn->tls_support = 1;
|
||||
if (child) {
|
||||
ns = xmpp_stanza_get_ns(child);
|
||||
conn->tls_support = ns != NULL && strcmp(ns, XMPP_NS_TLS) == 0;
|
||||
}
|
||||
} else {
|
||||
conn->tls_support = 0;
|
||||
}
|
||||
@@ -237,11 +236,15 @@ static int _handle_features(xmpp_conn_t * const conn,
|
||||
|
||||
/* check for SASL */
|
||||
child = xmpp_stanza_get_child_by_name(stanza, "mechanisms");
|
||||
if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_SASL) == 0)) {
|
||||
ns = child ? xmpp_stanza_get_ns(child) : NULL;
|
||||
if (child && ns && strcmp(ns, XMPP_NS_SASL) == 0) {
|
||||
for (mech = xmpp_stanza_get_children(child); mech;
|
||||
mech = xmpp_stanza_get_next(mech)) {
|
||||
if (xmpp_stanza_get_name(mech) && strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) {
|
||||
text = xmpp_stanza_get_text(mech);
|
||||
if (text == NULL)
|
||||
continue;
|
||||
|
||||
if (strcasecmp(text, "PLAIN") == 0)
|
||||
conn->sasl_support |= SASL_MASK_PLAIN;
|
||||
else if (strcasecmp(text, "DIGEST-MD5") == 0)
|
||||
@@ -256,6 +259,10 @@ static int _handle_features(xmpp_conn_t * const conn,
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable PLAIN when other secure mechanisms are supported */
|
||||
if (conn->sasl_support & ~(SASL_MASK_PLAIN | SASL_MASK_ANONYMOUS))
|
||||
conn->sasl_support &= ~SASL_MASK_PLAIN;
|
||||
|
||||
_auth(conn);
|
||||
|
||||
return 0;
|
||||
@@ -550,9 +557,11 @@ static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t * const conn,
|
||||
*/
|
||||
static void _auth(xmpp_conn_t * const conn)
|
||||
{
|
||||
xmpp_stanza_t *auth, *authdata, *query, *child, *iq;
|
||||
char *str, *authid;
|
||||
xmpp_stanza_t *auth;
|
||||
xmpp_stanza_t *authdata;
|
||||
char *authid;
|
||||
char *scram_init;
|
||||
char *str;
|
||||
int anonjid;
|
||||
|
||||
/* if there is no node in conn->jid, we assume anonymous connect */
|
||||
@@ -719,105 +728,12 @@ static void _auth(xmpp_conn_t * const conn)
|
||||
|
||||
/* SASL PLAIN was tried */
|
||||
conn->sasl_support &= ~SASL_MASK_PLAIN;
|
||||
} else if (conn->type == XMPP_CLIENT) {
|
||||
/* legacy client authentication */
|
||||
|
||||
iq = xmpp_iq_new(conn->ctx, "set", "_xmpp_auth1");
|
||||
if (!iq) {
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
query = xmpp_stanza_new(conn->ctx);
|
||||
if (!query) {
|
||||
xmpp_stanza_release(iq);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_set_name(query, "query");
|
||||
xmpp_stanza_set_ns(query, XMPP_NS_AUTH);
|
||||
xmpp_stanza_add_child(iq, query);
|
||||
xmpp_stanza_release(query);
|
||||
|
||||
child = xmpp_stanza_new(conn->ctx);
|
||||
if (!child) {
|
||||
xmpp_stanza_release(iq);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_set_name(child, "username");
|
||||
xmpp_stanza_add_child(query, child);
|
||||
xmpp_stanza_release(child);
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata) {
|
||||
xmpp_stanza_release(iq);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
str = xmpp_jid_node(conn->ctx, conn->jid);
|
||||
xmpp_stanza_set_text(authdata, str);
|
||||
xmpp_free(conn->ctx, str);
|
||||
xmpp_stanza_add_child(child, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
child = xmpp_stanza_new(conn->ctx);
|
||||
if (!child) {
|
||||
xmpp_stanza_release(iq);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_set_name(child, "password");
|
||||
xmpp_stanza_add_child(query, child);
|
||||
xmpp_stanza_release(child);
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata) {
|
||||
xmpp_stanza_release(iq);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_set_text(authdata, conn->pass);
|
||||
xmpp_stanza_add_child(child, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
child = xmpp_stanza_new(conn->ctx);
|
||||
if (!child) {
|
||||
xmpp_stanza_release(iq);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_set_name(child, "resource");
|
||||
xmpp_stanza_add_child(query, child);
|
||||
xmpp_stanza_release(child);
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata) {
|
||||
xmpp_stanza_release(iq);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
str = xmpp_jid_resource(conn->ctx, conn->jid);
|
||||
if (str) {
|
||||
xmpp_stanza_set_text(authdata, str);
|
||||
xmpp_free(conn->ctx, str);
|
||||
} else {
|
||||
xmpp_stanza_release(authdata);
|
||||
xmpp_stanza_release(iq);
|
||||
xmpp_error(conn->ctx, "auth",
|
||||
"Cannot authenticate without resource");
|
||||
xmpp_disconnect(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_add_child(child, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL);
|
||||
handler_add_timed(conn, _handle_missing_legacy,
|
||||
LEGACY_TIMEOUT, NULL);
|
||||
|
||||
xmpp_send(conn, iq);
|
||||
xmpp_stanza_release(iq);
|
||||
} else if (conn->type == XMPP_CLIENT && conn->auth_legacy_enabled) {
|
||||
/* legacy client authentication */
|
||||
_auth_legacy(conn);
|
||||
} else {
|
||||
xmpp_error(conn->ctx, "auth", "Cannot authenticate with known methods");
|
||||
xmpp_disconnect(conn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,7 +787,8 @@ static int _handle_features_sasl(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
{
|
||||
xmpp_stanza_t *bind, *session, *iq, *res, *text;
|
||||
xmpp_stanza_t *bind, *session, *iq, *res, *text, *opt;
|
||||
const char *ns;
|
||||
char *resource;
|
||||
|
||||
/* remove missing features handler */
|
||||
@@ -880,16 +797,21 @@ static int _handle_features_sasl(xmpp_conn_t * const conn,
|
||||
/* we are expecting <bind/> and <session/> since this is a
|
||||
XMPP style connection */
|
||||
|
||||
/* check whether resource binding is required */
|
||||
bind = xmpp_stanza_get_child_by_name(stanza, "bind");
|
||||
if (bind && strcmp(xmpp_stanza_get_ns(bind), XMPP_NS_BIND) == 0) {
|
||||
/* resource binding is required */
|
||||
conn->bind_required = 1;
|
||||
if (bind) {
|
||||
ns = xmpp_stanza_get_ns(bind);
|
||||
conn->bind_required = ns != NULL && strcmp(ns, XMPP_NS_BIND) == 0;
|
||||
}
|
||||
|
||||
/* check whether session establishment is required */
|
||||
session = xmpp_stanza_get_child_by_name(stanza, "session");
|
||||
if (session && strcmp(xmpp_stanza_get_ns(session), XMPP_NS_SESSION) == 0) {
|
||||
/* session establishment required */
|
||||
conn->session_required = 1;
|
||||
if (session) {
|
||||
ns = xmpp_stanza_get_ns(session);
|
||||
opt = xmpp_stanza_get_child_by_name(session, "optional");
|
||||
if (!opt)
|
||||
conn->session_required = ns != NULL &&
|
||||
strcmp(ns, XMPP_NS_SESSION) == 0;
|
||||
}
|
||||
|
||||
/* if bind is required, go ahead and start it */
|
||||
@@ -1092,6 +1014,15 @@ static int _handle_missing_session(xmpp_conn_t * const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_missing_legacy(xmpp_conn_t * const conn,
|
||||
void * const userdata)
|
||||
{
|
||||
xmpp_error(conn->ctx, "xmpp", "Server did not reply to legacy "\
|
||||
"authentication request.");
|
||||
xmpp_disconnect(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_legacy(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza,
|
||||
void * const userdata)
|
||||
@@ -1128,13 +1059,97 @@ static int _handle_legacy(xmpp_conn_t * const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_missing_legacy(xmpp_conn_t * const conn,
|
||||
void * const userdata)
|
||||
static void _auth_legacy(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_error(conn->ctx, "xmpp", "Server did not reply to legacy "\
|
||||
"authentication request.");
|
||||
xmpp_disconnect(conn);
|
||||
return 0;
|
||||
xmpp_stanza_t *iq;
|
||||
xmpp_stanza_t *authdata;
|
||||
xmpp_stanza_t *query;
|
||||
xmpp_stanza_t *child;
|
||||
char *str;
|
||||
|
||||
xmpp_debug(conn->ctx, "auth", "Legacy authentication request");
|
||||
|
||||
iq = xmpp_iq_new(conn->ctx, "set", "_xmpp_auth1");
|
||||
if (!iq)
|
||||
goto err;
|
||||
|
||||
query = xmpp_stanza_new(conn->ctx);
|
||||
if (!query)
|
||||
goto err_free;
|
||||
xmpp_stanza_set_name(query, "query");
|
||||
xmpp_stanza_set_ns(query, XMPP_NS_AUTH);
|
||||
xmpp_stanza_add_child(iq, query);
|
||||
xmpp_stanza_release(query);
|
||||
|
||||
child = xmpp_stanza_new(conn->ctx);
|
||||
if (!child)
|
||||
goto err_free;
|
||||
xmpp_stanza_set_name(child, "username");
|
||||
xmpp_stanza_add_child(query, child);
|
||||
xmpp_stanza_release(child);
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata)
|
||||
goto err_free;
|
||||
str = xmpp_jid_node(conn->ctx, conn->jid);
|
||||
if (!str) {
|
||||
xmpp_stanza_release(authdata);
|
||||
goto err_free;
|
||||
}
|
||||
xmpp_stanza_set_text(authdata, str);
|
||||
xmpp_free(conn->ctx, str);
|
||||
xmpp_stanza_add_child(child, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
child = xmpp_stanza_new(conn->ctx);
|
||||
if (!child)
|
||||
goto err_free;
|
||||
xmpp_stanza_set_name(child, "password");
|
||||
xmpp_stanza_add_child(query, child);
|
||||
xmpp_stanza_release(child);
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata)
|
||||
goto err_free;
|
||||
xmpp_stanza_set_text(authdata, conn->pass);
|
||||
xmpp_stanza_add_child(child, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
child = xmpp_stanza_new(conn->ctx);
|
||||
if (!child)
|
||||
goto err_free;
|
||||
xmpp_stanza_set_name(child, "resource");
|
||||
xmpp_stanza_add_child(query, child);
|
||||
xmpp_stanza_release(child);
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata)
|
||||
goto err_free;
|
||||
str = xmpp_jid_resource(conn->ctx, conn->jid);
|
||||
if (str) {
|
||||
xmpp_stanza_set_text(authdata, str);
|
||||
xmpp_free(conn->ctx, str);
|
||||
} else {
|
||||
xmpp_stanza_release(authdata);
|
||||
xmpp_stanza_release(iq);
|
||||
xmpp_error(conn->ctx, "auth", "Cannot authenticate without resource");
|
||||
xmpp_disconnect(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_add_child(child, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL);
|
||||
handler_add_timed(conn, _handle_missing_legacy, LEGACY_TIMEOUT, NULL);
|
||||
|
||||
xmpp_send(conn, iq);
|
||||
xmpp_stanza_release(iq);
|
||||
return;
|
||||
|
||||
err_free:
|
||||
xmpp_stanza_release(iq);
|
||||
err:
|
||||
disconnect_mem_error(conn);
|
||||
}
|
||||
|
||||
void auth_handle_component_open(xmpp_conn_t * const conn)
|
||||
|
||||
@@ -172,6 +172,7 @@ struct _xmpp_conn_t {
|
||||
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 */
|
||||
int auth_legacy_enabled;
|
||||
int secured; /* set when stream is secured with TLS */
|
||||
|
||||
/* if server returns <bind/> or <session/> we must do them */
|
||||
|
||||
19
src/conn.c
19
src/conn.c
@@ -140,6 +140,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
|
||||
conn->tls_trust = 0;
|
||||
conn->tls_failed = 0;
|
||||
conn->sasl_support = 0;
|
||||
conn->auth_legacy_enabled = 0;
|
||||
conn->secured = 0;
|
||||
|
||||
conn->bind_required = 0;
|
||||
@@ -713,7 +714,7 @@ void conn_parser_reset(xmpp_conn_t * const conn)
|
||||
/** Initiate termination of the connection to the XMPP server.
|
||||
* This function starts the disconnection sequence by sending
|
||||
* </stream:stream> to the XMPP server. This function will do nothing
|
||||
* if the connection state is CONNECTING or CONNECTED.
|
||||
* if the connection state is different from CONNECTING or CONNECTED.
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*
|
||||
@@ -755,10 +756,10 @@ void xmpp_send_raw_string(xmpp_conn_t * const conn,
|
||||
char *bigbuf;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = xmpp_vsnprintf(buf, 1024, fmt, ap);
|
||||
len = xmpp_vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len >= 1024) {
|
||||
if (len >= sizeof(buf)) {
|
||||
/* we need more space for this data, so we allocate a big
|
||||
* enough buffer and print to that */
|
||||
len++; /* account for trailing \0 */
|
||||
@@ -779,7 +780,6 @@ void xmpp_send_raw_string(xmpp_conn_t * const conn,
|
||||
xmpp_free(conn->ctx, bigbuf);
|
||||
} else {
|
||||
xmpp_debug(conn->ctx, "conn", "SENT: %s", buf);
|
||||
|
||||
xmpp_send_raw(conn, buf, len);
|
||||
}
|
||||
}
|
||||
@@ -844,10 +844,9 @@ void xmpp_send(xmpp_conn_t * const conn,
|
||||
{
|
||||
char *buf;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
if (conn->state == XMPP_STATE_CONNECTED) {
|
||||
if ((ret = xmpp_stanza_to_text(stanza, &buf, &len)) == 0) {
|
||||
if (xmpp_stanza_to_text(stanza, &buf, &len) == 0) {
|
||||
xmpp_send_raw(conn, buf, len);
|
||||
xmpp_debug(conn->ctx, "conn", "SENT: %s", buf);
|
||||
xmpp_free(conn->ctx, buf);
|
||||
@@ -922,7 +921,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_TRUST_TLS * conn->tls_trust;
|
||||
XMPP_CONN_FLAG_TRUST_TLS * conn->tls_trust |
|
||||
XMPP_CONN_FLAG_LEGACY_AUTH * conn->auth_legacy_enabled;;
|
||||
|
||||
return flags;
|
||||
}
|
||||
@@ -940,6 +940,7 @@ long xmpp_conn_get_flags(const xmpp_conn_t * const conn)
|
||||
* - XMPP_CONN_FLAG_MANDATORY_TLS
|
||||
* - XMPP_CONN_FLAG_LEGACY_SSL
|
||||
* - XMPP_CONN_FLAG_TRUST_TLS
|
||||
* - XMPP_CONN_FLAG_LEGACY_AUTH
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
* @param flags ORed connection flags
|
||||
@@ -966,6 +967,7 @@ int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags)
|
||||
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;
|
||||
conn->auth_legacy_enabled = (flags & XMPP_CONN_FLAG_LEGACY_AUTH) ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1211,6 +1213,9 @@ static void _conn_reset(xmpp_conn_t * const conn)
|
||||
xmpp_free(ctx, tsq->data);
|
||||
xmpp_free(ctx, tsq);
|
||||
}
|
||||
conn->send_queue_head = NULL;
|
||||
conn->send_queue_tail = NULL;
|
||||
conn->send_queue_len = 0;
|
||||
|
||||
if (conn->stream_error) {
|
||||
xmpp_stanza_release(conn->stream_error->stanza);
|
||||
|
||||
@@ -163,6 +163,8 @@ int hash_add(hash_t *table, const char * const key, void *data)
|
||||
entry->next = table->entries[table_index];
|
||||
table->entries[table_index] = entry;
|
||||
table->num_keys++;
|
||||
} else {
|
||||
if (table->free) table->free(ctx, entry->value);
|
||||
}
|
||||
|
||||
entry->value = data;
|
||||
|
||||
@@ -137,7 +137,7 @@ static void _start_element(void *userdata,
|
||||
if (parser->depth == 0) {
|
||||
/* notify the owner */
|
||||
if (parser->startcb)
|
||||
parser->startcb((char *)name, (char **)attrs,
|
||||
parser->startcb(name, (char **)attrs,
|
||||
parser->userdata);
|
||||
} else {
|
||||
/* build stanzas at depth 1 */
|
||||
|
||||
@@ -127,9 +127,11 @@ static void Hash_DRBG_Instantiate(Hash_DRBG_CTX *ctx,
|
||||
|
||||
assert(entropy_input_len <= ENTROPY_MAX);
|
||||
assert(nonce_len <= NONCE_MAX);
|
||||
assert(nonce != NULL || nonce_len == 0);
|
||||
|
||||
memcpy(seed_material, entropy_input, entropy_input_len);
|
||||
memcpy(seed_material + entropy_input_len, nonce, nonce_len);
|
||||
if (nonce != NULL)
|
||||
memcpy(seed_material + entropy_input_len, nonce, nonce_len);
|
||||
Hash_df(seed_material, entropy_input_len + nonce_len, seed, seedlen);
|
||||
seed0[0] = 0;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ xmpp_rand_t *xmpp_rand_new(xmpp_ctx_t *ctx);
|
||||
*/
|
||||
void xmpp_rand_free(xmpp_ctx_t *ctx, xmpp_rand_t *rand);
|
||||
|
||||
/** Generate random integer
|
||||
/** Generate random integer.
|
||||
* Analogue of rand(3).
|
||||
*
|
||||
* @ingroup Random
|
||||
|
||||
30
src/stanza.c
30
src/stanza.c
@@ -344,10 +344,16 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
||||
}
|
||||
tmp = _escape_xml(stanza->ctx,
|
||||
(char *)hash_get(stanza->attributes, key));
|
||||
if (tmp == NULL) return XMPP_EMEM;
|
||||
if (tmp == NULL) {
|
||||
hash_iter_release(iter);
|
||||
return XMPP_EMEM;
|
||||
}
|
||||
ret = xmpp_snprintf(ptr, left, " %s=\"%s\"", key, tmp);
|
||||
xmpp_free(stanza->ctx, tmp);
|
||||
if (ret < 0) return XMPP_EMEM;
|
||||
if (ret < 0) {
|
||||
hash_iter_release(iter);
|
||||
return XMPP_EMEM;
|
||||
}
|
||||
_render_update(&written, buflen, ret, &left, &ptr);
|
||||
}
|
||||
hash_iter_release(iter);
|
||||
@@ -421,7 +427,12 @@ int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
||||
}
|
||||
|
||||
ret = _render_stanza_recursive(stanza, buffer, length);
|
||||
if (ret < 0) return ret;
|
||||
if (ret < 0) {
|
||||
xmpp_free(stanza->ctx, buffer);
|
||||
*buf = NULL;
|
||||
*buflen = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((size_t)ret > length - 1) {
|
||||
tmp = xmpp_realloc(stanza->ctx, buffer, ret + 1);
|
||||
@@ -435,7 +446,12 @@ int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
||||
buffer = tmp;
|
||||
|
||||
ret = _render_stanza_recursive(stanza, buffer, length);
|
||||
if ((size_t)ret > length - 1) return XMPP_EMEM;
|
||||
if ((size_t)ret > length - 1) {
|
||||
xmpp_free(stanza->ctx, buffer);
|
||||
*buf = NULL;
|
||||
*buflen = 0;
|
||||
return XMPP_EMEM;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[length - 1] = 0;
|
||||
@@ -573,7 +589,6 @@ int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza,
|
||||
|
||||
val = xmpp_strdup(stanza->ctx, value);
|
||||
if (!val) {
|
||||
hash_release(stanza->attributes);
|
||||
return XMPP_EMEM;
|
||||
}
|
||||
|
||||
@@ -809,10 +824,11 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t * const stanza,
|
||||
const char * const ns)
|
||||
{
|
||||
xmpp_stanza_t *child;
|
||||
const char *child_ns;
|
||||
|
||||
for (child = stanza->children; child; child = child->next) {
|
||||
if (xmpp_stanza_get_ns(child) &&
|
||||
strcmp(ns, xmpp_stanza_get_ns(child)) == 0)
|
||||
child_ns = xmpp_stanza_get_ns(child);
|
||||
if (child_ns && strcmp(ns, child_ns) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ enum {
|
||||
static void _tls_sock_wait(tls_t *tls, int error);
|
||||
static void _tls_set_error(tls_t *tls, int error);
|
||||
static void _tls_log_error(xmpp_ctx_t *ctx);
|
||||
static void _tls_dump_cert_info(tls_t *tls);
|
||||
|
||||
void tls_initialize(void)
|
||||
{
|
||||
@@ -188,6 +189,7 @@ int tls_start(tls_t *tls)
|
||||
x509_res = SSL_get_verify_result(tls->ssl);
|
||||
xmpp_debug(tls->ctx, "tls", "Certificate verification %s",
|
||||
x509_res == X509_V_OK ? "passed" : "FAILED");
|
||||
_tls_dump_cert_info(tls);
|
||||
|
||||
_tls_set_error(tls, error);
|
||||
return ret <= 0 ? 0 : 1;
|
||||
@@ -199,6 +201,11 @@ int tls_stop(tls_t *tls)
|
||||
int error;
|
||||
int ret;
|
||||
|
||||
/* According to OpenSSL.org, we must not call SSL_shutdown(3)
|
||||
if a previous fatal error has occurred on a connection. */
|
||||
if (tls->lasterror == SSL_ERROR_SYSCALL || tls->lasterror == SSL_ERROR_SSL)
|
||||
return 1;
|
||||
|
||||
while (1) {
|
||||
++retries;
|
||||
ret = SSL_shutdown(tls->ssl);
|
||||
@@ -307,3 +314,26 @@ static void _tls_log_error(xmpp_ctx_t *ctx)
|
||||
}
|
||||
} while (e != 0);
|
||||
}
|
||||
|
||||
static void _tls_dump_cert_info(tls_t *tls)
|
||||
{
|
||||
X509 *cert;
|
||||
char *name;
|
||||
|
||||
cert = SSL_get_peer_certificate(tls->ssl);
|
||||
if (cert == NULL)
|
||||
xmpp_debug(tls->ctx, "tls", "Certificate was not presented by peer");
|
||||
else {
|
||||
name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
|
||||
if (name != NULL) {
|
||||
xmpp_debug(tls->ctx, "tls", "Subject=%s", name);
|
||||
OPENSSL_free(name);
|
||||
}
|
||||
name = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
|
||||
if (name != NULL) {
|
||||
xmpp_debug(tls->ctx, "tls", "Issuer=%s", name);
|
||||
OPENSSL_free(name);
|
||||
}
|
||||
X509_free(cert);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,10 @@ typedef struct _xmpp_stanza_t xmpp_stanza_t;
|
||||
* Trust server's certificate even if it is invalid.
|
||||
*/
|
||||
#define XMPP_CONN_FLAG_TRUST_TLS (1UL << 3)
|
||||
/** @def XMPP_CONN_FLAG_LEGACY_AUTH
|
||||
* Enable legacy authentication support.
|
||||
*/
|
||||
#define XMPP_CONN_FLAG_LEGACY_AUTH (1UL << 4)
|
||||
|
||||
/* connect callback */
|
||||
typedef enum {
|
||||
|
||||
@@ -16,18 +16,19 @@
|
||||
#include "strophe.h"
|
||||
#include "common.h"
|
||||
#include "hash.h"
|
||||
#include "test.h"
|
||||
|
||||
#define TABLESIZE 100
|
||||
#define TESTSIZE 500
|
||||
|
||||
/* static test data */
|
||||
const int nkeys = 5;
|
||||
const char *keys[] = {
|
||||
"foo", "bar", "baz", "quux", "xyzzy"
|
||||
};
|
||||
const char *values[] = {
|
||||
"wuzzle", "mug", "canonical", "rosebud", "lottery"
|
||||
};
|
||||
const int nkeys = ARRAY_SIZE(keys);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@@ -58,7 +59,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* allocate a hash table */
|
||||
table = hash_new(ctx, TABLESIZE, NULL);
|
||||
table = hash_new(ctx, TABLESIZE, xmpp_free);
|
||||
if (table == NULL) {
|
||||
/* table allocation failed! */
|
||||
return 1;
|
||||
@@ -66,7 +67,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* test insertion */
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
err = hash_add(table, keys[i], (void*)values[i]);
|
||||
err = hash_add(table, keys[i], xmpp_strdup(ctx, values[i]));
|
||||
if (err) return err;
|
||||
}
|
||||
|
||||
@@ -78,7 +79,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* test replacing old values */
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
err = hash_add(table, keys[0], (void*)values[i]);
|
||||
err = hash_add(table, keys[0], xmpp_strdup(ctx, values[i]));
|
||||
if (err) return err;
|
||||
if (hash_num_keys(table) != nkeys) return 1;
|
||||
result = hash_get(table, keys[0]);
|
||||
@@ -86,7 +87,7 @@ int main(int argc, char **argv)
|
||||
if (strcmp(result, values[i]) != 0) return 1;
|
||||
}
|
||||
/* restore value for the 1st key */
|
||||
hash_add(table, keys[0], (void*)values[0]);
|
||||
hash_add(table, keys[0], xmpp_strdup(ctx, values[0]));
|
||||
|
||||
/* test cloning */
|
||||
clone = hash_clone(table);
|
||||
|
||||
Reference in New Issue
Block a user