When xmpp_vsnprintf() received count == 0 it still performs write to the
buffer. This leads to a write outside allocated memory, when
xmpp_stanza_to_text() parses a specific stanza. Because of error in
_render_update() writing exactly buflen+1 with xmpp_snprintf() is counted
as valid operation and next xmpp_snprintf will be performed to a buffer
with zero length. This leads to wrong rendering of 1024-length stanzas
and invalid write for specific larger stanzas:
==22436== Invalid write of size 1
==22436== at 0x4E4B3A1: xmpp_vsnprintf (snprintf.c:709)
==22436== by 0x4E4B479: xmpp_snprintf (snprintf.c:722)
==22436== by 0x4E4C011: _render_stanza_recursive (stanza.c:328)
==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384)
==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384)
==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384)
==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384)
==22436== by 0x4E4C3B3: _render_stanza_recursive (stanza.c:384)
==22436== by 0x4E4C4E5: xmpp_stanza_to_text (stanza.c:435)
==22436== by 0x4E407A8: _handle_stream_stanza (conn.c:1157)
==22436== by 0x4E4EF2B: _end_element (parser_expat.c:157)
==22436== by 0x571005A: doContent (in /usr/lib64/libexpat.so.1.6.2)
==22436== Address 0x63b95b0 is 0 bytes after a block of size 1,024 alloc'd
==22436== at 0x4C2BFE0: malloc (vg_replace_malloc.c:299)
==22436== by 0x4E41947: _malloc (ctx.c:116)
==22436== by 0x4E41A54: xmpp_alloc (ctx.c:204)
==22436== by 0x4E4C4A3: xmpp_stanza_to_text (stanza.c:428)
==22436== by 0x4E407A8: _handle_stream_stanza (conn.c:1157)
==22436== by 0x4E4EF2B: _end_element (parser_expat.c:157)
==22436== by 0x571005A: doContent (in /usr/lib64/libexpat.so.1.6.2)
==22436== by 0x57109FB: contentProcessor (in ...
==22436== by 0x5712A9F: XML_ParseBuffer (in ...
==22436== by 0x4E4F1E7: parser_feed (parser_expat.c:247)
==22436== by 0x4E42BBC: xmpp_run_once (event.c:284)
==22436== by 0x4E42D62: xmpp_run (event.c:336)
Fix xmpp_vsnprintf() and _render_update() behaviour.
Default opening tag doesn't allow to implement XEP-0174. In this case
client needs to send specific attributes. As solution user passes
attributes that are sent inside opening tag. Previous variant of this
function is renamed to xmpp_conn_open_stream_default().
The way to pass attributes is not the best one, but it's used to conform
existent interface of xmpp_stanza_get_attributes().
Remove "raw" suffix from functions that work with a raw connection.
Previously this was incremented, but not decremented. I've corrected
the code to decrement it. It doesn't appear to be used anywhere, but
it is helpful to implement xmpp_graceful_stop().
Leave default configuration. A particular server closes tcp connection
during negotiation otherwise.
tls_schannel is still broken and tls_read() fails with
SEC_E_UNSUPPORTED_FUNCTION error.
This function is similar to xmpp_connect_client(), but doesn't perform
authentication. Instead, it calls user's connection handler immediately
after establishing the connection. Hence, user can implement own
authendication or registration procedures.
Such a "raw" connection can be useful when user interaction is required
(e.g. Data Forms in XEP-0077, OAuth2).
* Removed dependency from internal headers in rand.h. xmpp_rand
interface can be public in the future;
* xmpp_rand functions accept xmpp_rand_t object instead of xmpp_ctx_t.
If interface function returns char* the result must be freed with
xmpp_free().
In case of const char* the result must not be changed by user. Also, the
result is valid only during stanza lifetime.
Store keepalive parameters in conn object. This allows call the function
with a disconnected conn. Also, the parameters are not cleared on
reconnect and applied once a socket is created.
If `id == NULL' there were two issues: use-after-free error or
logging wrong error description.
Also open stream handler was called even when error occured and
conn object was disconnected.
Disconnected xmpp_conn_t object can be connected again. The object
is reset before connection, but the next fields remain untoucned:
* all handlers
* flags
* jid and password
Main use-case of this change is reconnect when an error occurs.