Introduce a `conn_interface` to simplify the decision logic which API
we must call.
This also fixes some bugs of the previous commit.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
* Delay the notification of the library user that the connection was
successful, until SM is reported by the server as enabled.
* Clear the SM queue in case resumption failed.
* Improve some debug statements & comments.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Instead of setting each element individually to 0 or NULL, use memset.
This also fixes the missing initialization of `conn->sm_disable`.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
In case a connection is established, but the stream negotiation has not
completed yet, a user may think that they can start sending data,
but this is not the case.
All of the following quotes originate in RFC6120.
As of Ch. 8:
> After a client and a server (or two servers) have completed stream
> negotiation, either party can send XML stanzas.
As of Ch. 7.3.1:
> The parties to a stream MUST consider resource binding as
> mandatory-to-negotiate.
As of Ch. 6.3.1:
> The parties to a stream MUST consider SASL as mandatory-to-negotiate.
As of Ch. 4.3.5:
> The initiating entity MUST NOT attempt to send XML stanzas to entities
> other than itself (i.e., the client's connected resource or any other
> authenticated resource of the client's account) or the server to which
> it is connected until stream negotiation has been completed.
> Even if the initiating entity does attempt to do so, the receiving
> entity MUST NOT accept such stanzas and MUST close the stream with a
> <not-authorized/> stream error [...]
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
* Be more verbose in which argument is `should` and which is `is`.
* Fix the order in the `ENSURE_EQ()` macro.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Before this change we couldn't differentiate between this instance
and the one further down in the code.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
... also make it possible to pre-define `STROPHE_MESSAGE_BUFFER_SIZE` in
a custom build if someone doesn't want such a huge stack buffer.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
While the struct is still public in all versions of OpenSSL and its
forks, this may well change in the future. Prepare for that case and
use the X509_ALGOR_get0() accessor which has been available with this
signature since OpenSSL 1.1.
It has been pointed out that the wording of the license of this library is
not entirely clear.
The term "dual licensing" usually refers to a licence choice of two
licenses "LICENSE1 _or_ LICENSE2.
Instead the license of this library claimed "LICENSE1 _and_ LICENSE2".
After an internal discussion with @metajack and @pasis it was made clear
that the initial idea was to dual license the library in the usual way.
This was also made clear by jack on the ML in the past [0].
As of jack, these licensing terms originated from jquery, which also used
the 'and' version in the past and has since been corrected [1].
This patch changes the license terms to 'MIT or GPLv3' and also adds SPDX
headers [2].
[0] https://groups.google.com/g/libstrophe/c/JkFgr601JQc
[1] https://stackoverflow.com/q/2758409
[2] https://spdx.org
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Fedora patches OpenSSL and disables usage of the ECC curve we used
in the old certificate.
This patch changes the ECC curve to a supported one.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Like that we can test stuff without opening a PR, before it necessarily
lands on `master`.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Break the linked-list of children before releasing a child.
Before this patch it was possible, when a child is cloned and stored
for longer than the lifetime of its parent, that its `next` pointer
points to invalid memory that was already free'd when the parent stanza
was released.
This issue exists already since the initial version of
`xmpp_stanza_release()`.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
This patch handles the case where the server sends its list of features,
but the `<bind>` feature is missing.
A server doing so is violating RFC6120 (c.f. [0]), but it happened in [1].
Previously we ended up in a segfault, now we terminate the connection.
Reproducing this was done with netcat and profanity:
```
shell1 $ nc -l -p 5222
profanity $ /connect foo@127.0.0.1 tls disable
-> nc receives: '<?xml version="1.0"?><stream:stream to="127.0.0.1" xml:lang="en" version="1.0" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams">'
nc send: <?xml version="1.0"?>
<stream:stream from="127.0.0.1" id="foobarbaz" lang="en" version="1.0" xmlns:stream="http://etherx.jabber.org/streams">
<features xmlns="http://etherx.jabber.org/streams"><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms></features>
-> nc receives: '<auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">XXXXXXXXXX</auth>'
nc send: <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
-> nc receives: '<?xml version="1.0"?><stream:stream to="127.0.0.1" xml:lang="en" version="1.0" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams"><stream:stream from="127.0.0.1" id="foobarbaz" lang="en" version="1.0" xmlns:stream="http://etherx.jabber.org/streams">'
nc send: <?xml version="1.0"?>
<stream:stream from="127.0.0.1" id="foobarbaz" lang="en" version="1.0" xmlns:stream="http://etherx.jabber.org/streams">
<features xmlns="http://etherx.jabber.org/streams"/>
-> pre-patch this lead to a segfault of profanity, now the stream gets closed.
```
[0] https://datatracker.ietf.org/doc/html/rfc6120#section-7.2
[1] https://github.com/profanity-im/profanity/issues/1849
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
libstrophe uses non-blocking sockets and the connect() syscall may
return before a TCP connection is established. This doesn't allow
to catch all possible errors synchronously and some of the errors
are handled in the event handler.
In a scenario with multiple SRV records and/or multiple IP addresses
resolution, we need to repeat connection attempt on a failure.
xmpp_sock_t resolves the above problem. It keeps resolved records and
addresses to repeat connect attempt asynchronously.
The resolver maybe returned an error code but allocated an RR list. Free
this list now in the resolver instead of depending on the user to free it
even though there was an error.
This API is only library internal, but still it makes more sense like that.
This issue was discovered in CI job [0].
[0] https://github.com/strophe/libstrophe/actions/runs/3874980845/jobs/6776501943
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
If functions `xmpp_conn_set_cafile()` or `xmpp_conn_set_capath()` are
called twice they leaked the previously allocated memory.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Instead of using the "cloning version" `xmpp_stanza_add_child()` use the
version that takes ownership, so we don't have to release directly
afterwards.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Instead of always releasing the stanza after calling `send_stanza()`, this
is done inside the function now.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
If Valgrind complains in this testcase we found a bug in the internal
resolver implementation, but as we didn't have the broken message we also
couldn't reproduce the failure.
Now we can reproduce it if it happens again.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
... and forgetting to 1. clear the password cache and 2. print a message
of what exactly happened ...
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
This is done to support architectures where `rdtsc()` is not implemented.
In case it is available use `clock_gettime()`. Otherwise still fall back
to use `clock()`.
The first approach was to always use `clock_gettime()` if it is available
but the overhead it brings compared to `rdtsc()` is high, so I chose to
only try to use it if `rdtsc()` is not implemented.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Prevent assuming SM is enabled if the connection gets re-used without a
complete destroy&re-create of the connection object.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
... and extend build matrix of libressl.
Most of those new libressl build jobs are marked as `continue: true` since
either they don't build or they cause memory leaks (3.5/OPENBSD_7_1)
The `OPENBSD_X_Y` branches are also marked like that since they will
evolve and maybe break at a later point in time. Currently they represent
the buildable versions of their respective releases (3.3.6 resp. 3.4.3).
Also change CI distro to ubuntu-22.04 as using OpenSSL 3 on 20.04 fails.
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
github supports .git-blame-ignore-revs to ignore certain commits in
blame view, add the coding style change commit to this file
Can be used locally too with:
$ git blame --ignore-revs-file .git-blame-ignore-revs