summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlouiz’ <louiz@louiz.org>2020-08-12 09:40:36 +0200
committerlouiz’ <louiz@louiz.org>2020-08-12 09:40:36 +0200
commit063e6b127ecf92ca5bf8c4ecb137b60e3e7aa216 (patch)
tree7e9898c0f100d87c3480016b3ec5400828469116
parent4d6fdb0795b0d7e306988c6ff32f51545c2fd7f4 (diff)
downloadbiboumi-063e6b127ecf92ca5bf8c4ecb137b60e3e7aa216.tar.gz
biboumi-063e6b127ecf92ca5bf8c4ecb137b60e3e7aa216.tar.bz2
biboumi-063e6b127ecf92ca5bf8c4ecb137b60e3e7aa216.tar.xz
biboumi-063e6b127ecf92ca5bf8c4ecb137b60e3e7aa216.zip
Handle SASL failures by displaying a message and aborting the connection9.0-rc1
-rw-r--r--src/irc/irc_client.cpp25
-rw-r--r--src/irc/irc_client.hpp3
-rw-r--r--tests/end_to_end/scenarios/sasl.py42
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.']"),
)