diff options
-rw-r--r-- | src/irc/irc_client.cpp | 25 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 3 | ||||
-rw-r--r-- | tests/end_to_end/scenarios/sasl.py | 42 |
3 files changed, 66 insertions, 4 deletions
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 351f9f8..3ae5ac6 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -85,8 +85,14 @@ static const std::unordered_map<std::string, {"CAP", {&IrcClient::on_cap, {3, 0}}}, #ifdef WITH_SASL {"AUTHENTICATE", {&IrcClient::on_authenticate, {1, 0}}}, - {"903", {&IrcClient::on_sasl_success, {0, 0}}}, {"900", {&IrcClient::on_sasl_login, {3, 0}}}, + {"902", {&IrcClient::on_sasl_failure, {2, 0}}}, + {"903", {&IrcClient::on_sasl_success, {0, 0}}}, + {"904", {&IrcClient::on_sasl_failure, {2, 0}}}, + {"905", {&IrcClient::on_sasl_failure, {2, 0}}}, + {"906", {&IrcClient::on_sasl_failure, {2, 0}}}, + {"907", {&IrcClient::on_sasl_failure, {2, 0}}}, + {"908", {&IrcClient::on_sasl_failure, {2, 0}}}, #endif {"401", {&IrcClient::on_generic_error, {2, 0}}}, {"402", {&IrcClient::on_generic_error, {2, 0}}}, @@ -238,6 +244,7 @@ void IrcClient::on_connection_failed(const std::string& reason) "cancel", "item-not-found", "", reason); } + this->channels_to_join.clear(); } else // try the next port this->start(); @@ -1372,6 +1379,22 @@ void IrcClient::on_sasl_success(const IrcMessage &) this->cap_end(); } +void IrcClient::on_sasl_failure(const IrcMessage& message) +{ + this->sasl_state = SaslState::failure; + const auto reason = message.arguments[1]; + // Send an error message for all room that the user wanted to join + for (const auto& tuple: this->channels_to_join) + { + Iid iid(std::get<0>(tuple) + "%" + this->hostname, this->chantypes); + this->bridge.send_presence_error(iid, this->current_nick, + "cancel", "item-not-found", + "", reason); + } + this->channels_to_join.clear(); + this->send_quit_command(reason); +} + void IrcClient::on_sasl_login(const IrcMessage &message) { const auto& login = message.arguments[2]; diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 9f77e29..ac2f6a9 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -247,8 +247,9 @@ private: public: #ifdef WITH_SASL void on_authenticate(const IrcMessage& message); - void on_sasl_success(const IrcMessage& message); void on_sasl_login(const IrcMessage& message); + void on_sasl_success(const IrcMessage& message); + void on_sasl_failure(const IrcMessage& message); #endif /** * The channel has been completely joined (self presence, topic, all names diff --git a/tests/end_to_end/scenarios/sasl.py b/tests/end_to_end/scenarios/sasl.py index 5f71b7a..b3cc62d 100644 --- a/tests/end_to_end/scenarios/sasl.py +++ b/tests/end_to_end/scenarios/sasl.py @@ -26,9 +26,47 @@ scenario = ( "<field var='ports'><value>6667</value></field>" "<field var='nick'><value>RegisteredUser</value></field>" "<field var='tls_ports'><value>6697</value><value>6670</value></field>" + "<field var='throttle_limit'><value>9999</value></field>" "</x></command></iq>"), expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"), - send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' ><x xmlns='http://jabber.org/protocol/muc'/></presence>"), - sequences.connection(login="RegisteredUser") + # Joining a channel with the associated nick will work + send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/ignored' ><x xmlns='http://jabber.org/protocol/muc'/></presence>"), + sequences.connection(login="RegisteredUser"), + expect_stanza("/presence"), + expect_stanza("/message/subject"), + + # Leave the channel and disconnect from the server to try again differently + send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/RegisteredUser' type='unavailable' />"), + expect_stanza("/presence[@type='unavailable']"), + + # Configure an INCORRECT password + send_stanza("<iq type='set' id='id3' from='{jid_one}/{resource_one}' to='{irc_server_one}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"), + expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='sasl_password']", + after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='configure']", "sessionid"))), + + + send_stanza("<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='{irc_server_one}'>" + "<command xmlns='http://jabber.org/protocol/commands' node='configure' sessionid='{sessionid}' action='complete'>" + "<x xmlns='jabber:x:data' type='submit'>" + "<field var='sasl_password'><value>wrong wrong wrong</value></field>" + "<field var='ports'><value>6667</value></field>" + "<field var='nick'><value>RegisteredUser</value></field>" + "<field var='tls_ports'><value>6697</value><value>6670</value></field>" + "<field var='throttle_limit'><value>9999</value></field>" + "</x></command></iq>"), + expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"), + + send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/ignored' ><x xmlns='http://jabber.org/protocol/muc'/></presence>"), + # Here, the 6 connecting… connected messages from the connection attempt + expect_stanza("/message"), + expect_stanza("/message"), + expect_stanza("/message"), + expect_stanza("/message"), + expect_stanza("/message"), + expect_stanza("/message"), + expect_stanza("/presence[@type='error'][@from='#foo%{irc_server_one}/RegisteredUser']"), + expect_stanza("/message/body[text()='ERROR: Quit: SASL authentication failed: Invalid account credentials']"), + expect_stanza("/message/body[text()='ERROR: Connection closed.']"), ) |