Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some fixes #243

Merged
merged 10 commits into from
May 28, 2024
53 changes: 32 additions & 21 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,31 @@ jobs:
strategy:
matrix:
xssl_versions:
- { version: "master", continue: true, libressl: true }
- { version: "OPENBSD_7_4", continue: true, libressl: true }
- { version: "v3.8.1", continue: true, libressl: true }
- { version: "OPENBSD_7_3", continue: true, libressl: true }
- { version: "OPENBSD_7_2", continue: true, libressl: true }
- { version: "OPENBSD_7_1", continue: true, libressl: true }
- { version: "master", continue: true, libressl: true }
- { version: "OPENBSD_7_5", continue: true, libressl: true }
- { version: "v3.9.2", continue: true, libressl: true }
- { version: "OPENBSD_7_4", continue: true, libressl: true }
- { version: "v3.8.4", continue: true, libressl: true }
- { version: "OPENBSD_7_3", continue: true, libressl: true }
- { version: "OPENBSD_7_2", continue: true, libressl: true }
- { version: "OPENBSD_7_1", continue: true, libressl: true }
# https://github.com/libressl-portable/portable/issues/760
# - { version: "v3.5.2", continue: true, libressl: true }
- { version: "OPENBSD_7_0", continue: true, libressl: true }
- { version: "OPENBSD_7_0", continue: true, libressl: true }
# OPENBSD_7_0 is basically the "fixed v3.4.3"
# - { version: "v3.4.3", continue: true, libressl: true }
- { version: "v3.4.2", continue: true, libressl: true }
- { version: "OPENBSD_6_9", continue: true, libressl: true }
- { version: "v3.1.5", continue: true, libressl: true }
- { version: "v2.1.10", continue: true, libressl: true }
- { version: "openssl-3.0", continue: true, libressl: false }
- { version: "openssl-3.0.10", continue: false, libressl: false }
- { version: "openssl-3.1", continue: true, libressl: false }
- { version: "openssl-3.1.2", continue: false, libressl: false }
valgrind:
- { configure: '' , make: 'check' }
- { configure: '--enable-valgrind' , make: 'check-valgrind' }
# - { version: "v3.4.3", continue: true, libressl: true }
- { version: "v3.4.2", continue: true, libressl: true }
- { version: "OPENBSD_6_9", continue: true, libressl: true }
- { version: "v3.1.5", continue: true, libressl: true }
- { version: "v2.1.10", continue: true, libressl: true }
- { version: "openssl-3.0", continue: true, libressl: false }
- { version: "openssl-3.0.13", continue: false, libressl: false }
- { version: "openssl-3.1", continue: true, libressl: false }
- { version: "openssl-3.1.5", continue: false, libressl: false }
- { version: "openssl-3.2", continue: true, libressl: false }
- { version: "openssl-3.2.1", continue: false, libressl: false }
- { version: "openssl-3.3", continue: true, libressl: false }
- { version: "openssl-3.3.0", continue: false, libressl: false }
name: xSSL tests
continue-on-error: ${{ matrix.xssl_versions.continue }}
steps:
Expand All @@ -89,11 +92,19 @@ jobs:
- name: Build the library
run: |
./bootstrap.sh
./configure ${{ matrix.valgrind.configure }} PKG_CONFIG_PATH="${HOME}/xssl/lib/pkgconfig" CFLAGS="-Werror -g3" --prefix="${HOME}/xssl"
PKG_CONFIG_PATH="${HOME}/xssl/lib/pkgconfig" ./configure CFLAGS="-Werror -g3" --prefix="${HOME}/xssl"
make -j$(nproc)
- name: Run tests
run: |
make -j$(nproc) ${{ matrix.valgrind.make }}
LD_LIBRARY_PATH="${HOME}/xssl/lib" make -j$(nproc) check
- name: Build the library with Valgrind enabled
run: |
./bootstrap.sh
PKG_CONFIG_PATH="${HOME}/xssl/lib/pkgconfig" ./configure --enable-valgrind CFLAGS="-Werror -g3" --prefix="${HOME}/xssl"
make -j$(nproc)
- name: Run tests with Valgrind enabled
run: |
LD_LIBRARY_PATH="${HOME}/xssl/lib" make -j$(nproc) check-valgrind
- name: Error logs
if: ${{ failure() }}
run: |
Expand Down
6 changes: 4 additions & 2 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,11 @@ struct _xmpp_send_queue_t {
#define SASL_MASK_EXTERNAL (1 << 6)
#define SASL_MASK_SCRAMSHA1_PLUS (1 << 7)
#define SASL_MASK_SCRAMSHA256_PLUS (1 << 8)
#define SASL_MASK_SCRAMSHA512_PLUS (1 << 9)

#define SASL_MASK_SCRAM_PLUS \
(SASL_MASK_SCRAMSHA1_PLUS | SASL_MASK_SCRAMSHA256_PLUS)
#define SASL_MASK_SCRAM_PLUS \
(SASL_MASK_SCRAMSHA1_PLUS | SASL_MASK_SCRAMSHA256_PLUS | \
SASL_MASK_SCRAMSHA512_PLUS)
#define SASL_MASK_SCRAM_WEAK \
(SASL_MASK_SCRAMSHA1 | SASL_MASK_SCRAMSHA256 | SASL_MASK_SCRAMSHA512)
#define SASL_MASK_SCRAM (SASL_MASK_SCRAM_PLUS | SASL_MASK_SCRAM_WEAK)
Expand Down
12 changes: 9 additions & 3 deletions src/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,7 @@ int conn_tls_start(xmpp_conn_t *conn)
}

if (conn->tls != NULL) {
struct conn_interface old_intf = conn->intf;
conn->intf = tls_intf;
conn->intf.conn = conn;
if (tls_start(conn->tls)) {
Expand All @@ -1102,6 +1103,7 @@ int conn_tls_start(xmpp_conn_t *conn)
tls_free(conn->tls);
conn->tls = NULL;
conn->tls_failed = 1;
conn->intf = old_intf;
}
}
if (rc != 0) {
Expand Down Expand Up @@ -1435,6 +1437,7 @@ char *xmpp_conn_send_queue_drop_element(xmpp_conn_t *conn,
xmpp_queue_element_t which)
{
xmpp_send_queue_t *t;
int disconnected = conn->state == XMPP_STATE_DISCONNECTED;

/* Fast return paths */
/* empty queue */
Expand All @@ -1443,7 +1446,7 @@ char *xmpp_conn_send_queue_drop_element(xmpp_conn_t *conn,
/* one element in queue */
if (conn->send_queue_head == conn->send_queue_tail) {
/* head is already sent out partially */
if (conn->send_queue_head->wip)
if (conn->send_queue_head->wip && !disconnected)
return NULL;
/* the element is no USER element */
if (conn->send_queue_head->owner != XMPP_QUEUE_USER)
Expand All @@ -1467,7 +1470,7 @@ char *xmpp_conn_send_queue_drop_element(xmpp_conn_t *conn,
return NULL;

/* head is already sent out partially */
if (t == conn->send_queue_head && t->wip)
if (t == conn->send_queue_head && t->wip && !disconnected)
t = t->next;

/* search forward to find the first USER element */
Expand All @@ -1481,8 +1484,11 @@ char *xmpp_conn_send_queue_drop_element(xmpp_conn_t *conn,
/* In case there exists a SM stanza that is linked to the
* one we're currently dropping, also delete that one.
*/
if (t->next && t->next->userdata == t)
if (t->next && t->next->userdata == t) {
strophe_free(conn->ctx, _drop_send_queue_element(conn, t->next));
/* reset the flag, so we restart to send `<r>` stanzas */
conn->sm_state->r_sent = 0;
}
/* Finally drop the element */
return _drop_send_queue_element(conn, t);
}
Expand Down
11 changes: 11 additions & 0 deletions src/scram.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,23 @@ const struct hash_alg scram_sha512 = {
(void (*)(void *, const uint8_t *, size_t))sha512_process,
(void (*)(void *, uint8_t *))sha512_done};

const struct hash_alg scram_sha512_plus = {
"SCRAM-SHA-512-PLUS",
SASL_MASK_SCRAMSHA512_PLUS,
SHA512_DIGEST_SIZE,
(void (*)(const uint8_t *, size_t, uint8_t *))sha512_hash,
(void (*)(void *))sha512_init,
(void (*)(void *, const uint8_t *, size_t))sha512_process,
(void (*)(void *, uint8_t *))sha512_done};

/* The order of this list defines the order in which the SCRAM algorithms are
* tried if the server supports them.
* Their order is derived from
* https://datatracker.ietf.org/doc/html/draft-ietf-kitten-password-storage
*/
const struct hash_alg *scram_algs[] = {
/* *1 */
&scram_sha512_plus,
/* *1 */
&scram_sha256_plus,
/* *1 */
Expand Down
5 changes: 3 additions & 2 deletions src/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ static void sock_getaddrinfo(xmpp_sock_t *xsock)
rc = getaddrinfo(xsock->srv_rr_cur->target, service, &hints,
&xsock->ainfo_list);
if (rc != 0) {
strophe_debug(xsock->ctx, "sock", "getaddrinfo() failed with %d",
strophe_debug(xsock->ctx, "sock",
"getaddrinfo() failed with %s (%d)", gai_strerror(rc),
rc);
xsock->ainfo_list = NULL;
}
Expand Down Expand Up @@ -236,7 +237,7 @@ sock_t sock_connect(xmpp_sock_t *xsock)
if (rc != 0) {
strophe_debug(xsock->ctx, "sock",
"User's setsockopt callback"
"failed with %d (errno=%d)",
" failed with %d (errno=%d)",
rc, errno);
}
}
Expand Down
41 changes: 39 additions & 2 deletions src/tls_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@

#if OPENSSL_VERSION_NUMBER < 0x30000000L
#define STROPHE_ERR_func_error_string(e) ERR_func_error_string(e)
#define STROPHE_SSL_get1_peer_certificate(s) SSL_get_peer_certificate(s)
#else
#define STROPHE_ERR_func_error_string(e) ""
#define STROPHE_SSL_get1_peer_certificate(s) SSL_get1_peer_certificate(s)
#endif

#if OPENSSL_VERSION_NUMBER < 0x10100000L
Expand Down Expand Up @@ -109,6 +111,7 @@ struct _tls {
X509 *client_cert;
void *channel_binding_data;
size_t channel_binding_size;
FILE *keylogfile;
int lasterror;
};

Expand Down Expand Up @@ -556,6 +559,36 @@ static int _tls_password_callback(char *buf, int size, int rwflag, void *u)
return tls_caching_password_callback(buf, size, u);
}

#if OPENSSL_VERSION_NUMBER >= 0x10101000L
static void _keylog_cb(const SSL *ssl, const char *line)
{
xmpp_conn_t *conn = SSL_get_app_data(ssl);
fwrite(line, strlen(line), 1, conn->tls->keylogfile);
fputc('\n', conn->tls->keylogfile);
fflush(conn->tls->keylogfile);
}
#endif

static void _try_open_keylogfile(tls_t *tls)
{
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
const char *first_line = "# SSL Key logfile generated by libstrophe\n";
const char *SSLKEYLOGFILE = getenv("SSLKEYLOGFILE");
if (!SSLKEYLOGFILE || *SSLKEYLOGFILE == '\0')
return;
tls->keylogfile = fopen(SSLKEYLOGFILE, "abe");
if (!tls->keylogfile) {
strophe_warn(tls->ctx, "tls", "Could not open SSL keylog file %s",
SSLKEYLOGFILE);
return;
}
fwrite(first_line, strlen(first_line), 1, tls->keylogfile);
SSL_CTX_set_keylog_callback(tls->ssl_ctx, _keylog_cb);
#else
UNUSED(tls);
#endif
}

tls_t *tls_new(xmpp_conn_t *conn)
{
tls_t *tls = strophe_alloc(conn->ctx, sizeof(*tls));
Expand Down Expand Up @@ -699,6 +732,8 @@ tls_t *tls_new(xmpp_conn_t *conn)
ret = SSL_set_fd(tls->ssl, conn->sock);
if (ret <= 0)
goto err_free_ssl;

_try_open_keylogfile(tls);
}

return tls;
Expand All @@ -717,6 +752,8 @@ tls_t *tls_new(xmpp_conn_t *conn)

void tls_free(tls_t *tls)
{
if (tls->keylogfile)
fclose(tls->keylogfile);
strophe_free(tls->ctx, tls->channel_binding_data);
SSL_free(tls->ssl);
X509_free(tls->client_cert);
Expand All @@ -727,7 +764,7 @@ void tls_free(tls_t *tls)
xmpp_tlscert_t *tls_peer_cert(xmpp_conn_t *conn)
{
if (conn && conn->tls && conn->tls->ssl) {
X509 *cert = SSL_get_peer_certificate(conn->tls->ssl);
X509 *cert = STROPHE_SSL_get1_peer_certificate(conn->tls->ssl);
if (cert) {
xmpp_tlscert_t *tlscert = _x509_to_tlscert(conn->ctx, cert);
X509_free(cert);
Expand Down Expand Up @@ -999,7 +1036,7 @@ static void _tls_dump_cert_info(tls_t *tls)
X509 *cert;
char *name;

cert = SSL_get_peer_certificate(tls->ssl);
cert = STROPHE_SSL_get1_peer_certificate(tls->ssl);
if (cert == NULL)
strophe_debug(tls->ctx, "tls", "Certificate was not presented by peer");
else {
Expand Down
Loading