diff --git a/src/auth.c b/src/auth.c index a1bc3b5f..5378afcd 100644 --- a/src/auth.c +++ b/src/auth.c @@ -602,8 +602,18 @@ static int _make_scram_init_msg(struct scram_user_data *scram) l = strophe_snprintf(message, message_len, "p=%s,,n=%s,r=%s", binding_type, node, buf); } else { - l = strophe_snprintf(message, message_len, "%c,,n=%s,r=%s", - is_secured ? 'y' : 'n', node, buf); + char cb_flag = 'n'; + const char *dummy_type; + size_t dummy_len; + + /* determine if channel binding is supported before advertising it */ + if (is_secured && + tls_init_channel_binding(conn->tls, &dummy_type, &dummy_len) == 0) { + cb_flag = 'y'; + } + + l = strophe_snprintf(message, message_len, "%c,,n=%s,r=%s", cb_flag, + node, buf); } if (l < 0 || (size_t)l >= message_len) { goto err_msg; @@ -820,9 +830,11 @@ static void _auth(xmpp_conn_t *conn) scram_ctx->sasl_plus = scram_ctx->alg->mask & SASL_MASK_SCRAM_PLUS ? 1 : 0; if (_make_scram_init_msg(scram_ctx)) { + /* Gracefully drop the unsupported mechanism and try the next */ + conn->sasl_support &= ~scram_ctx->alg->mask; strophe_free(conn->ctx, scram_ctx); xmpp_stanza_release(auth); - disconnect_mem_error(conn); + _auth(conn); return; } @@ -1759,6 +1771,4 @@ void auth_handle_open_raw(xmpp_conn_t *conn) } void auth_handle_open_stub(xmpp_conn_t *conn) -{ - strophe_warn(conn->ctx, "auth", "Stub callback is called."); -} +{ strophe_warn(conn->ctx, "auth", "Stub callback is called."); } diff --git a/src/tls_schannel.c b/src/tls_schannel.c index 65783ecf..f139085a 100644 --- a/src/tls_schannel.c +++ b/src/tls_schannel.c @@ -479,7 +479,7 @@ int tls_read(struct conn_interface *intf, void *buff, size_t len) int read; tls->readybufferpos += bytes; newbuff += bytes; - read = tls_read(tls, newbuff, len - bytes); + read = tls_read(intf, newbuff, len - bytes); if (read == -1) { if (tls_is_recoverable(intf, tls->lasterror)) { @@ -553,7 +553,7 @@ int tls_read(struct conn_interface *intf, void *buff, size_t len) tls->recvbufferpos = 0; } - return tls_read(tls, buff, len); + return tls_read(intf, buff, len); } else if (ret == SEC_E_INCOMPLETE_MESSAGE) { tls->lasterror = SEC_E_INCOMPLETE_MESSAGE; return -1; @@ -611,7 +611,7 @@ int tls_write(struct conn_interface *intf, const void *buff, size_t len) int sent = 0, ret, remain = len; tls_t *tls = intf->conn->tls; - ret = tls_clear_pending_write(tls); + ret = tls_clear_pending_write(intf); if (ret <= 0) { return ret; } @@ -667,9 +667,9 @@ int tls_write(struct conn_interface *intf, const void *buff, size_t len) tls->sendbufferpos = 0; - ret = tls_clear_pending_write(tls); + ret = tls_clear_pending_write(intf); - if (ret == -1 && !tls_is_recoverable(intf, tls_error(tls))) { + if (ret == -1 && !tls_is_recoverable(intf, tls_error(intf))) { return -1; } @@ -682,7 +682,7 @@ int tls_write(struct conn_interface *intf, const void *buff, size_t len) } if (ret == 0 || - (ret == -1 && tls_is_recoverable(intf, tls_error(tls)))) { + (ret == -1 && tls_is_recoverable(intf, tls_error(intf)))) { return sent; } }