Compare commits
8 Commits
control-au
...
0.13.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d59a9fe45 | ||
|
|
40f2452fb0 | ||
|
|
1cf09b1870 | ||
|
|
5edc480932 | ||
|
|
641211ecae | ||
|
|
d8fd6e6d14 | ||
|
|
9410530507 | ||
|
|
d6d71e97f8 |
18
ChangeLog
18
ChangeLog
@@ -1,3 +1,19 @@
|
|||||||
|
0.13.1
|
||||||
|
- Fix SCRAM-*-PLUS SASL mechanisms with OpenSSL and TLS < v1.3 (40f2452)
|
||||||
|
- Only signal "stream negotiation success" once (1cf09b1)
|
||||||
|
- Fix `sock_connect()` not looping over all DNS records returned if no `sockopt_cb` is set (5edc480)
|
||||||
|
- Replace usage of EBADFD, it's not in POSIX (#235)
|
||||||
|
|
||||||
|
0.13.0
|
||||||
|
- Fix connected/connecting signaling to user (#227)
|
||||||
|
- Fix wording of licensing terms (#225)
|
||||||
|
- Prepare for future changes in OpenSSL (#226)
|
||||||
|
- Improve Stream Management (#227) (#230)
|
||||||
|
- Add SCRAM-PLUS Variants (#228)
|
||||||
|
- Introduce XEP-0138 stream compression (#231)
|
||||||
|
- Deprecated the following API (#227):
|
||||||
|
- xmpp_conn_disable_tls() - replaced by a flag set by xmpp_conn_set_flags()
|
||||||
|
|
||||||
0.12.3
|
0.12.3
|
||||||
- Improve TCP-connection establishment (#221)
|
- Improve TCP-connection establishment (#221)
|
||||||
- Handle case where the server doesn't provide the `bind` feature (#224)
|
- Handle case where the server doesn't provide the `bind` feature (#224)
|
||||||
@@ -21,7 +37,7 @@
|
|||||||
- Fix some build steps when builddir != srcdir (#208)
|
- Fix some build steps when builddir != srcdir (#208)
|
||||||
- Allow the user to disable build of examples (#209)
|
- Allow the user to disable build of examples (#209)
|
||||||
- CI builds against OpenSSL 3 (#206)
|
- CI builds against OpenSSL 3 (#206)
|
||||||
- Change the call signature of the following API:
|
- Change the call signature of the following API (#208):
|
||||||
- xmpp_conn_set_client_cert() - the PKCS#12 file has now to be passed via the `cert`
|
- xmpp_conn_set_client_cert() - the PKCS#12 file has now to be passed via the `cert`
|
||||||
parameter. Originally it was via `key`. Currently both styles are supported,
|
parameter. Originally it was via `key`. Currently both styles are supported,
|
||||||
but in a future release only passing via `cert` will be accepted.
|
but in a future release only passing via `cert` will be accepted.
|
||||||
|
|||||||
2
Doxyfile
2
Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = Strophe
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.12
|
PROJECT_NUMBER = 0.13
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ or if you have everything configured properly:
|
|||||||
|
|
||||||
Then open `docs/html/index.html`.
|
Then open `docs/html/index.html`.
|
||||||
|
|
||||||
An online version of the documentation of the latest release is available on http://strophe.im/libstrophe/
|
An online version of the documentation of the latest release is available on https://strophe.im/libstrophe/
|
||||||
|
|
||||||
Releases
|
Releases
|
||||||
--------
|
--------
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
m4_define([v_maj], [0])
|
m4_define([v_maj], [0])
|
||||||
m4_define([v_min], [12])
|
m4_define([v_min], [13])
|
||||||
m4_define([v_patch], [3])
|
m4_define([v_patch], [1])
|
||||||
m4_define([project_version], [v_maj.v_min.v_patch])
|
m4_define([project_version], [v_maj.v_min.v_patch])
|
||||||
|
|
||||||
m4_define([lt_cur], m4_eval(v_maj + v_min))
|
m4_define([lt_cur], m4_eval(v_maj + v_min))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ includedir=@includedir@
|
|||||||
|
|
||||||
Name: libstrophe
|
Name: libstrophe
|
||||||
Description: A simple, lightweight C library for writing XMPP clients
|
Description: A simple, lightweight C library for writing XMPP clients
|
||||||
URL: http://strophe.im/libstrophe/
|
URL: https://strophe.im/libstrophe/
|
||||||
Version: @VERSION@
|
Version: @VERSION@
|
||||||
Requires:
|
Requires:
|
||||||
Requires.private: @PC_REQUIRES@
|
Requires.private: @PC_REQUIRES@
|
||||||
|
|||||||
154
src/auth.c
154
src/auth.c
@@ -799,9 +799,7 @@ static void _auth(xmpp_conn_t *conn)
|
|||||||
conn->ctx, "auth",
|
conn->ctx, "auth",
|
||||||
"Password hasn't been set, and SASL ANONYMOUS unsupported.");
|
"Password hasn't been set, and SASL ANONYMOUS unsupported.");
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
} else if ((conn->sasl_support & SASL_MASK_SCRAM_PLUS) ||
|
} else if (conn->sasl_support & SASL_MASK_SCRAM) {
|
||||||
((conn->sasl_support & SASL_MASK_SCRAM_WEAK) &&
|
|
||||||
!conn->only_strong_auth)) {
|
|
||||||
size_t n;
|
size_t n;
|
||||||
scram_ctx = strophe_alloc(conn->ctx, sizeof(*scram_ctx));
|
scram_ctx = strophe_alloc(conn->ctx, sizeof(*scram_ctx));
|
||||||
memset(scram_ctx, 0, sizeof(*scram_ctx));
|
memset(scram_ctx, 0, sizeof(*scram_ctx));
|
||||||
@@ -859,8 +857,7 @@ static void _auth(xmpp_conn_t *conn)
|
|||||||
|
|
||||||
/* SASL algorithm was tried, unset flag */
|
/* SASL algorithm was tried, unset flag */
|
||||||
conn->sasl_support &= ~scram_ctx->alg->mask;
|
conn->sasl_support &= ~scram_ctx->alg->mask;
|
||||||
} else if ((conn->sasl_support & SASL_MASK_DIGESTMD5) &&
|
} else if (conn->sasl_support & SASL_MASK_DIGESTMD5) {
|
||||||
conn->weak_auth_enabled) {
|
|
||||||
auth = _make_sasl_auth(conn, "DIGEST-MD5");
|
auth = _make_sasl_auth(conn, "DIGEST-MD5");
|
||||||
if (!auth) {
|
if (!auth) {
|
||||||
disconnect_mem_error(conn);
|
disconnect_mem_error(conn);
|
||||||
@@ -874,8 +871,7 @@ static void _auth(xmpp_conn_t *conn)
|
|||||||
|
|
||||||
/* SASL DIGEST-MD5 was tried, unset flag */
|
/* SASL DIGEST-MD5 was tried, unset flag */
|
||||||
conn->sasl_support &= ~SASL_MASK_DIGESTMD5;
|
conn->sasl_support &= ~SASL_MASK_DIGESTMD5;
|
||||||
} else if ((conn->sasl_support & SASL_MASK_PLAIN) &&
|
} else if (conn->sasl_support & SASL_MASK_PLAIN) {
|
||||||
conn->weak_auth_enabled) {
|
|
||||||
auth = _make_sasl_auth(conn, "PLAIN");
|
auth = _make_sasl_auth(conn, "PLAIN");
|
||||||
if (!auth) {
|
if (!auth) {
|
||||||
disconnect_mem_error(conn);
|
disconnect_mem_error(conn);
|
||||||
@@ -1099,21 +1095,19 @@ static int _handle_features_compress(xmpp_conn_t *conn,
|
|||||||
static int
|
static int
|
||||||
_handle_features_sasl(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
_handle_features_sasl(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *bind, *session, *opt;
|
xmpp_stanza_t *bind, *session;
|
||||||
xmpp_stanza_t *resume;
|
xmpp_stanza_t *resume;
|
||||||
const char *ns;
|
|
||||||
char h[11];
|
char h[11];
|
||||||
|
|
||||||
UNUSED(userdata);
|
UNUSED(userdata);
|
||||||
|
|
||||||
/* remove missing features handler */
|
/* Remove missing features handler */
|
||||||
xmpp_timed_handler_delete(conn, _handle_missing_features_sasl);
|
xmpp_timed_handler_delete(conn, _handle_missing_features_sasl);
|
||||||
|
|
||||||
/* check whether resource binding is required */
|
/* Check whether resource binding is required */
|
||||||
bind = xmpp_stanza_get_child_by_name(stanza, "bind");
|
bind = xmpp_stanza_get_child_by_name_and_ns(stanza, "bind", XMPP_NS_BIND);
|
||||||
if (bind) {
|
if (bind) {
|
||||||
ns = xmpp_stanza_get_ns(bind);
|
conn->bind_required = 1;
|
||||||
conn->bind_required = ns != NULL && strcmp(ns, XMPP_NS_BIND) == 0;
|
|
||||||
bind = xmpp_stanza_copy(bind);
|
bind = xmpp_stanza_copy(bind);
|
||||||
if (!bind) {
|
if (!bind) {
|
||||||
disconnect_mem_error(conn);
|
disconnect_mem_error(conn);
|
||||||
@@ -1123,25 +1117,31 @@ _handle_features_sasl(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
|||||||
conn->bind_required = 0;
|
conn->bind_required = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether session establishment is required */
|
/* Check whether session establishment is required.
|
||||||
session = xmpp_stanza_get_child_by_name(stanza, "session");
|
*
|
||||||
|
* The mechanism is deprecated, but we still support it.
|
||||||
|
*
|
||||||
|
* RFC3921 contains Ch. 3 "Session Establishment".
|
||||||
|
*
|
||||||
|
* RFC6121 removes this and explains in Ch. 1.4:
|
||||||
|
* "Interoperability Note: [...] Implementation and deployment experience
|
||||||
|
* has shown that this additional step is unnecessary. [...]" */
|
||||||
|
session = xmpp_stanza_get_child_by_name_and_ns(stanza, "session",
|
||||||
|
XMPP_NS_SESSION);
|
||||||
if (session) {
|
if (session) {
|
||||||
ns = xmpp_stanza_get_ns(session);
|
conn->session_required =
|
||||||
opt = xmpp_stanza_get_child_by_name(session, "optional");
|
xmpp_stanza_get_child_by_name(session, "optional") == NULL;
|
||||||
if (!opt)
|
|
||||||
conn->session_required =
|
|
||||||
ns != NULL && strcmp(ns, XMPP_NS_SESSION) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check stream-management support */
|
||||||
if (xmpp_stanza_get_child_by_name_and_ns(stanza, "sm", XMPP_NS_SM)) {
|
if (xmpp_stanza_get_child_by_name_and_ns(stanza, "sm", XMPP_NS_SM)) {
|
||||||
/* stream management supported */
|
|
||||||
conn->sm_state->sm_support = 1;
|
conn->sm_state->sm_support = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we are expecting either <bind/> and <session/> since this is a
|
/* We are expecting either <bind/> and optionally <session/> since this is a
|
||||||
XMPP style connection or we <resume/> the previous session */
|
XMPP style connection or we <resume/> the previous session */
|
||||||
|
|
||||||
/* check whether we can <resume/> the previous session */
|
/* Check whether we can <resume/> the previous session */
|
||||||
if (!conn->sm_disable && conn->sm_state->can_resume &&
|
if (!conn->sm_disable && conn->sm_state->can_resume &&
|
||||||
conn->sm_state->previd && conn->sm_state->bound_jid) {
|
conn->sm_state->previd && conn->sm_state->bound_jid) {
|
||||||
resume = xmpp_stanza_new(conn->ctx);
|
resume = xmpp_stanza_new(conn->ctx);
|
||||||
@@ -1188,11 +1188,57 @@ static int _handle_missing_features_sasl(xmpp_conn_t *conn, void *userdata)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _session_start(xmpp_conn_t *conn)
|
||||||
|
{
|
||||||
|
xmpp_stanza_t *session;
|
||||||
|
xmpp_stanza_t *iq = xmpp_iq_new(conn->ctx, "set", "_xmpp_session1");
|
||||||
|
if (!iq) {
|
||||||
|
disconnect_mem_error(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session = xmpp_stanza_new(conn->ctx);
|
||||||
|
if (!session) {
|
||||||
|
xmpp_stanza_release(iq);
|
||||||
|
disconnect_mem_error(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup response handlers */
|
||||||
|
handler_add_id(conn, _handle_session, "_xmpp_session1", NULL);
|
||||||
|
handler_add_timed(conn, _handle_missing_session, SESSION_TIMEOUT, NULL);
|
||||||
|
|
||||||
|
xmpp_stanza_set_name(session, "session");
|
||||||
|
xmpp_stanza_set_ns(session, XMPP_NS_SESSION);
|
||||||
|
|
||||||
|
xmpp_stanza_add_child_ex(iq, session, 0);
|
||||||
|
|
||||||
|
/* send session establishment request */
|
||||||
|
send_stanza(conn, iq, XMPP_QUEUE_STROPHE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _sm_enable(xmpp_conn_t *conn)
|
||||||
|
{
|
||||||
|
xmpp_stanza_t *enable = xmpp_stanza_new(conn->ctx);
|
||||||
|
if (!enable) {
|
||||||
|
disconnect_mem_error(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xmpp_stanza_set_name(enable, "enable");
|
||||||
|
xmpp_stanza_set_ns(enable, XMPP_NS_SM);
|
||||||
|
if (!conn->sm_state->dont_request_resume)
|
||||||
|
xmpp_stanza_set_attribute(enable, "resume", "true");
|
||||||
|
handler_add(conn, _handle_sm, XMPP_NS_SM, NULL, NULL, NULL);
|
||||||
|
send_stanza(conn, enable, XMPP_QUEUE_SM_STROPHE);
|
||||||
|
conn->sm_state->sm_sent_nr = 0;
|
||||||
|
conn->sm_state->sm_enabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_handle_bind(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
_handle_bind(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||||
{
|
{
|
||||||
const char *type;
|
const char *type;
|
||||||
xmpp_stanza_t *iq, *session, *binding, *jid_stanza, *enable = NULL;
|
xmpp_stanza_t *binding, *jid_stanza;
|
||||||
|
|
||||||
UNUSED(userdata);
|
UNUSED(userdata);
|
||||||
|
|
||||||
@@ -1215,58 +1261,19 @@ _handle_bind(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send enable directly after the bind request */
|
|
||||||
if (conn->sm_state->sm_support && !conn->sm_disable) {
|
|
||||||
enable = xmpp_stanza_new(conn->ctx);
|
|
||||||
if (!enable) {
|
|
||||||
disconnect_mem_error(conn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
xmpp_stanza_set_name(enable, "enable");
|
|
||||||
xmpp_stanza_set_ns(enable, XMPP_NS_SM);
|
|
||||||
if (!conn->sm_state->dont_request_resume)
|
|
||||||
xmpp_stanza_set_attribute(enable, "resume", "true");
|
|
||||||
handler_add(conn, _handle_sm, XMPP_NS_SM, NULL, NULL, NULL);
|
|
||||||
send_stanza(conn, enable, XMPP_QUEUE_SM_STROPHE);
|
|
||||||
conn->sm_state->sm_sent_nr = 0;
|
|
||||||
conn->sm_state->sm_enabled = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* establish a session if required */
|
/* establish a session if required */
|
||||||
if (conn->session_required) {
|
if (conn->session_required) {
|
||||||
/* setup response handlers */
|
_session_start(conn);
|
||||||
handler_add_id(conn, _handle_session, "_xmpp_session1", NULL);
|
}
|
||||||
handler_add_timed(conn, _handle_missing_session, SESSION_TIMEOUT,
|
/* send enable directly after the bind request */
|
||||||
NULL);
|
else if (conn->sm_state->sm_support && !conn->sm_disable) {
|
||||||
|
_sm_enable(conn);
|
||||||
/* send session request */
|
|
||||||
iq = xmpp_iq_new(conn->ctx, "set", "_xmpp_session1");
|
|
||||||
if (!iq) {
|
|
||||||
disconnect_mem_error(conn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
session = xmpp_stanza_new(conn->ctx);
|
|
||||||
if (!session) {
|
|
||||||
xmpp_stanza_release(iq);
|
|
||||||
disconnect_mem_error(conn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmpp_stanza_set_name(session, "session");
|
|
||||||
xmpp_stanza_set_ns(session, XMPP_NS_SESSION);
|
|
||||||
|
|
||||||
xmpp_stanza_add_child_ex(iq, session, 0);
|
|
||||||
|
|
||||||
/* send session establishment request */
|
|
||||||
send_stanza(conn, iq, XMPP_QUEUE_STROPHE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if there's no xmpp session required and we didn't try to enable
|
/* if there's no xmpp session required and we didn't try to enable
|
||||||
* stream-management, we're done here and the stream-negotiation was
|
* stream-management, we're done here and the stream-negotiation was
|
||||||
* successful
|
* successful
|
||||||
*/
|
*/
|
||||||
if (!conn->session_required && !enable) {
|
else {
|
||||||
_stream_negotiation_success(conn);
|
_stream_negotiation_success(conn);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1303,8 +1310,11 @@ _handle_session(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
|||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
} else if (type && strcmp(type, "result") == 0) {
|
} else if (type && strcmp(type, "result") == 0) {
|
||||||
strophe_debug(conn->ctx, "xmpp", "Session establishment successful.");
|
strophe_debug(conn->ctx, "xmpp", "Session establishment successful.");
|
||||||
|
if (conn->sm_state->sm_support && !conn->sm_disable) {
|
||||||
_stream_negotiation_success(conn);
|
_sm_enable(conn);
|
||||||
|
} else {
|
||||||
|
_stream_negotiation_success(conn);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
strophe_error(conn->ctx, "xmpp",
|
strophe_error(conn->ctx, "xmpp",
|
||||||
"Server sent malformed session reply.");
|
"Server sent malformed session reply.");
|
||||||
|
|||||||
@@ -259,8 +259,6 @@ struct _xmpp_conn_t {
|
|||||||
int sasl_support; /* if true, field is a bitfield of supported
|
int sasl_support; /* if true, field is a bitfield of supported
|
||||||
mechanisms */
|
mechanisms */
|
||||||
int auth_legacy_enabled;
|
int auth_legacy_enabled;
|
||||||
int weak_auth_enabled;
|
|
||||||
int only_strong_auth;
|
|
||||||
int secured; /* set when stream is secured with TLS */
|
int secured; /* set when stream is secured with TLS */
|
||||||
xmpp_certfail_handler certfail_handler;
|
xmpp_certfail_handler certfail_handler;
|
||||||
xmpp_password_callback password_callback;
|
xmpp_password_callback password_callback;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ static int _conn_decompress(struct xmpp_compression *comp,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strophe_error(comp->conn->ctx, "zlib", "inflate error %d", ret);
|
strophe_error(comp->conn->ctx, "zlib", "inflate error %d", ret);
|
||||||
comp->conn->error = EBADFD;
|
comp->conn->error = ret;
|
||||||
conn_disconnect(comp->conn);
|
conn_disconnect(comp->conn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ _compression_write(xmpp_conn_t *conn, const void *buff, size_t len, int flush)
|
|||||||
}
|
}
|
||||||
if (ret != Z_OK) {
|
if (ret != Z_OK) {
|
||||||
strophe_error(conn->ctx, "zlib", "deflate error %d", ret);
|
strophe_error(conn->ctx, "zlib", "deflate error %d", ret);
|
||||||
conn->error = EBADFD;
|
conn->error = ret;
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -227,22 +227,22 @@ int compression_init(xmpp_conn_t *conn)
|
|||||||
|
|
||||||
comp->compression.stream.next_out = comp->compression.buffer;
|
comp->compression.stream.next_out = comp->compression.buffer;
|
||||||
comp->compression.stream.avail_out = STROPHE_COMPRESSION_BUFFER_SIZE;
|
comp->compression.stream.avail_out = STROPHE_COMPRESSION_BUFFER_SIZE;
|
||||||
int err = deflateInit(&comp->compression.stream, Z_DEFAULT_COMPRESSION);
|
int ret = deflateInit(&comp->compression.stream, Z_DEFAULT_COMPRESSION);
|
||||||
if (err != Z_OK) {
|
if (ret != Z_OK) {
|
||||||
strophe_free_and_null(conn->ctx, comp->compression.buffer);
|
strophe_free_and_null(conn->ctx, comp->compression.buffer);
|
||||||
conn->error = EBADFD;
|
conn->error = ret;
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
return err;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
_init_zlib_compression(conn->ctx, &comp->decompression);
|
_init_zlib_compression(conn->ctx, &comp->decompression);
|
||||||
|
|
||||||
err = inflateInit(&comp->decompression.stream);
|
ret = inflateInit(&comp->decompression.stream);
|
||||||
if (err != Z_OK) {
|
if (ret != Z_OK) {
|
||||||
strophe_free_and_null(conn->ctx, comp->decompression.buffer);
|
strophe_free_and_null(conn->ctx, comp->decompression.buffer);
|
||||||
conn->error = EBADFD;
|
conn->error = ret;
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
return err;
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/conn.c
23
src/conn.c
@@ -1133,8 +1133,6 @@ long xmpp_conn_get_flags(const xmpp_conn_t *conn)
|
|||||||
XMPP_CONN_FLAG_DISABLE_SM * conn->sm_disable |
|
XMPP_CONN_FLAG_DISABLE_SM * conn->sm_disable |
|
||||||
XMPP_CONN_FLAG_ENABLE_COMPRESSION * conn->compression.allowed |
|
XMPP_CONN_FLAG_ENABLE_COMPRESSION * conn->compression.allowed |
|
||||||
XMPP_CONN_FLAG_COMPRESSION_DONT_RESET * conn->compression.dont_reset |
|
XMPP_CONN_FLAG_COMPRESSION_DONT_RESET * conn->compression.dont_reset |
|
||||||
XMPP_CONN_FLAG_WEAK_AUTH * conn->weak_auth_enabled |
|
|
||||||
XMPP_CONN_FLAG_STRONG_AUTH * conn->only_strong_auth |
|
|
||||||
XMPP_CONN_FLAG_LEGACY_AUTH * conn->auth_legacy_enabled;
|
XMPP_CONN_FLAG_LEGACY_AUTH * conn->auth_legacy_enabled;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
@@ -1149,14 +1147,14 @@ long xmpp_conn_get_flags(const xmpp_conn_t *conn)
|
|||||||
*
|
*
|
||||||
* Supported flags are:
|
* Supported flags are:
|
||||||
*
|
*
|
||||||
* - XMPP_CONN_FLAG_DISABLE_TLS
|
* - \ref XMPP_CONN_FLAG_DISABLE_TLS
|
||||||
* - XMPP_CONN_FLAG_MANDATORY_TLS
|
* - \ref XMPP_CONN_FLAG_MANDATORY_TLS
|
||||||
* - XMPP_CONN_FLAG_LEGACY_SSL
|
* - \ref XMPP_CONN_FLAG_LEGACY_SSL
|
||||||
* - XMPP_CONN_FLAG_TRUST_TLS
|
* - \ref XMPP_CONN_FLAG_TRUST_TLS
|
||||||
* - XMPP_CONN_FLAG_LEGACY_AUTH
|
* - \ref XMPP_CONN_FLAG_LEGACY_AUTH
|
||||||
* - XMPP_CONN_FLAG_DISABLE_SM
|
* - \ref XMPP_CONN_FLAG_DISABLE_SM
|
||||||
* - XMPP_CONN_FLAG_ENABLE_COMPRESSION
|
* - \ref XMPP_CONN_FLAG_ENABLE_COMPRESSION
|
||||||
* - XMPP_CONN_FLAG_COMPRESSION_DONT_RESET
|
* - \ref XMPP_CONN_FLAG_COMPRESSION_DONT_RESET
|
||||||
*
|
*
|
||||||
* @param conn a Strophe connection object
|
* @param conn a Strophe connection object
|
||||||
* @param flags ORed connection flags
|
* @param flags ORed connection flags
|
||||||
@@ -1190,14 +1188,11 @@ int xmpp_conn_set_flags(xmpp_conn_t *conn, long flags)
|
|||||||
(flags & XMPP_CONN_FLAG_ENABLE_COMPRESSION) ? 1 : 0;
|
(flags & XMPP_CONN_FLAG_ENABLE_COMPRESSION) ? 1 : 0;
|
||||||
conn->compression.dont_reset =
|
conn->compression.dont_reset =
|
||||||
(flags & XMPP_CONN_FLAG_COMPRESSION_DONT_RESET) ? 1 : 0;
|
(flags & XMPP_CONN_FLAG_COMPRESSION_DONT_RESET) ? 1 : 0;
|
||||||
conn->weak_auth_enabled = (flags & XMPP_CONN_FLAG_WEAK_AUTH) ? 1 : 0;
|
|
||||||
conn->only_strong_auth = (flags & XMPP_CONN_FLAG_STRONG_AUTH) ? 1 : 0;
|
|
||||||
flags &= ~(XMPP_CONN_FLAG_DISABLE_TLS | XMPP_CONN_FLAG_MANDATORY_TLS |
|
flags &= ~(XMPP_CONN_FLAG_DISABLE_TLS | XMPP_CONN_FLAG_MANDATORY_TLS |
|
||||||
XMPP_CONN_FLAG_LEGACY_SSL | XMPP_CONN_FLAG_TRUST_TLS |
|
XMPP_CONN_FLAG_LEGACY_SSL | XMPP_CONN_FLAG_TRUST_TLS |
|
||||||
XMPP_CONN_FLAG_LEGACY_AUTH | XMPP_CONN_FLAG_DISABLE_SM |
|
XMPP_CONN_FLAG_LEGACY_AUTH | XMPP_CONN_FLAG_DISABLE_SM |
|
||||||
XMPP_CONN_FLAG_ENABLE_COMPRESSION |
|
XMPP_CONN_FLAG_ENABLE_COMPRESSION |
|
||||||
XMPP_CONN_FLAG_COMPRESSION_DONT_RESET |
|
XMPP_CONN_FLAG_COMPRESSION_DONT_RESET);
|
||||||
XMPP_CONN_FLAG_WEAK_AUTH | XMPP_CONN_FLAG_STRONG_AUTH);
|
|
||||||
if (flags) {
|
if (flags) {
|
||||||
strophe_error(conn->ctx, "conn", "Flags 0x%04lx unknown", flags);
|
strophe_error(conn->ctx, "conn", "Flags 0x%04lx unknown", flags);
|
||||||
return XMPP_EINVOP;
|
return XMPP_EINVOP;
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ sock_t sock_connect(xmpp_sock_t *xsock)
|
|||||||
{
|
{
|
||||||
struct addrinfo *ainfo;
|
struct addrinfo *ainfo;
|
||||||
sock_t sock;
|
sock_t sock;
|
||||||
int rc = 0;
|
int rc;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -228,6 +228,7 @@ sock_t sock_connect(xmpp_sock_t *xsock)
|
|||||||
|
|
||||||
sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
|
sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
|
||||||
if (sock != INVALID_SOCKET) {
|
if (sock != INVALID_SOCKET) {
|
||||||
|
rc = 0;
|
||||||
if (xsock->conn->sockopt_cb) {
|
if (xsock->conn->sockopt_cb) {
|
||||||
/* Don't allow user to overwrite sockfd value. */
|
/* Don't allow user to overwrite sockfd value. */
|
||||||
sock_t sock_copy = sock;
|
sock_t sock_copy = sock;
|
||||||
|
|||||||
@@ -750,8 +750,9 @@ int tls_init_channel_binding(tls_t *tls,
|
|||||||
{
|
{
|
||||||
const char *label = NULL;
|
const char *label = NULL;
|
||||||
size_t labellen = 0;
|
size_t labellen = 0;
|
||||||
|
int ssl_version = SSL_version(tls->ssl);
|
||||||
|
|
||||||
switch (SSL_version(tls->ssl)) {
|
switch (ssl_version) {
|
||||||
case SSL3_VERSION:
|
case SSL3_VERSION:
|
||||||
*binding_prefix = "tls-unique";
|
*binding_prefix = "tls-unique";
|
||||||
*binding_prefix_len = strlen("tls-unique");
|
*binding_prefix_len = strlen("tls-unique");
|
||||||
@@ -774,7 +775,7 @@ int tls_init_channel_binding(tls_t *tls,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
strophe_error(tls->ctx, "tls", "Unsupported TLS Version: %s",
|
strophe_error(tls->ctx, "tls", "Unsupported TLS/SSL Version: %s",
|
||||||
SSL_get_version(tls->ssl));
|
SSL_get_version(tls->ssl));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -785,11 +786,28 @@ int tls_init_channel_binding(tls_t *tls,
|
|||||||
if (!tls->channel_binding_data)
|
if (!tls->channel_binding_data)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (SSL_export_keying_material(tls->ssl, tls->channel_binding_data,
|
if (ssl_version <= TLS1_2_VERSION) {
|
||||||
tls->channel_binding_size, label, labellen,
|
size_t len;
|
||||||
NULL, 0, 0) != 1) {
|
if (SSL_session_reused(tls->ssl)) {
|
||||||
strophe_error(tls->ctx, "tls", "Could not get channel binding data");
|
len = SSL_get_peer_finished(tls->ssl, tls->channel_binding_data,
|
||||||
return -1;
|
tls->channel_binding_size);
|
||||||
|
} else {
|
||||||
|
len = SSL_get_finished(tls->ssl, tls->channel_binding_data,
|
||||||
|
tls->channel_binding_size);
|
||||||
|
}
|
||||||
|
if (len != tls->channel_binding_size) {
|
||||||
|
strophe_error(tls->ctx, "tls",
|
||||||
|
"Got channel binding data of wrong size %zu", len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (SSL_export_keying_material(tls->ssl, tls->channel_binding_data,
|
||||||
|
tls->channel_binding_size, label,
|
||||||
|
labellen, NULL, 0, 0) != 1) {
|
||||||
|
strophe_error(tls->ctx, "tls",
|
||||||
|
"Could not get channel binding data");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
17
strophe.h
17
strophe.h
@@ -208,14 +208,6 @@ typedef struct _xmpp_sm_t xmpp_sm_state_t;
|
|||||||
* Only enable this flag if you know what you're doing.
|
* Only enable this flag if you know what you're doing.
|
||||||
*/
|
*/
|
||||||
#define XMPP_CONN_FLAG_COMPRESSION_DONT_RESET (1UL << 7)
|
#define XMPP_CONN_FLAG_COMPRESSION_DONT_RESET (1UL << 7)
|
||||||
/** @def XMPP_CONN_FLAG_WEAK_AUTH
|
|
||||||
* Allow weak authentication methods (DIGEST-MD5 and PLAIN).
|
|
||||||
*/
|
|
||||||
#define XMPP_CONN_FLAG_WEAK_AUTH (1UL << 8)
|
|
||||||
/** @def XMPP_CONN_FLAG_STRONG_AUTH
|
|
||||||
* Only allow strong authentication methods (Only the SCRAM-*-PLUS variants).
|
|
||||||
*/
|
|
||||||
#define XMPP_CONN_FLAG_STRONG_AUTH (1UL << 9)
|
|
||||||
|
|
||||||
/* connect callback */
|
/* connect callback */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -715,11 +707,18 @@ void xmpp_rand_bytes(xmpp_rand_t *rand, unsigned char *output, size_t len);
|
|||||||
*/
|
*/
|
||||||
void xmpp_rand_nonce(xmpp_rand_t *rand, char *output, size_t len);
|
void xmpp_rand_nonce(xmpp_rand_t *rand, char *output, size_t len);
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Formerly "private but exported" functions made public for now to announce
|
* Formerly "private but exported" functions made public for now to announce
|
||||||
* deprecation */
|
* deprecation */
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XMPP_DEPRECATED(x) macro to show a compiler warning for deprecated API
|
||||||
|
* functions
|
||||||
|
*
|
||||||
|
* @param x The function that can be used as a replacement or 'internal' if
|
||||||
|
* there is no replacement
|
||||||
|
*/
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if (__GNUC__ * 100 + __GNUC_MINOR__ >= 405)
|
#if (__GNUC__ * 100 + __GNUC_MINOR__ >= 405)
|
||||||
#define XMPP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x)))
|
#define XMPP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x)))
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ static void test_stanza_error(xmpp_ctx_t *ctx)
|
|||||||
xmpp_stanza_reply_error(stanza, "cancel", "service-unavailable", NULL);
|
xmpp_stanza_reply_error(stanza, "cancel", "service-unavailable", NULL);
|
||||||
assert(error != NULL);
|
assert(error != NULL);
|
||||||
mood = xmpp_stanza_new_from_string(ctx, str_mood);
|
mood = xmpp_stanza_new_from_string(ctx, str_mood);
|
||||||
assert(stanza != NULL);
|
assert(mood != NULL);
|
||||||
|
|
||||||
assert(xmpp_stanza_get_to(error) != NULL);
|
assert(xmpp_stanza_get_to(error) != NULL);
|
||||||
COMPARE("romeo@montague.lit/home", xmpp_stanza_get_to(error));
|
COMPARE("romeo@montague.lit/home", xmpp_stanza_get_to(error));
|
||||||
|
|||||||
Reference in New Issue
Block a user