Handle SASL failures by displaying a message and aborting the connection
This commit is contained in:
+24
-1
@@ -85,8 +85,14 @@ static const std::unordered_map<std::string,
|
|||||||
{"CAP", {&IrcClient::on_cap, {3, 0}}},
|
{"CAP", {&IrcClient::on_cap, {3, 0}}},
|
||||||
#ifdef WITH_SASL
|
#ifdef WITH_SASL
|
||||||
{"AUTHENTICATE", {&IrcClient::on_authenticate, {1, 0}}},
|
{"AUTHENTICATE", {&IrcClient::on_authenticate, {1, 0}}},
|
||||||
{"903", {&IrcClient::on_sasl_success, {0, 0}}},
|
|
||||||
{"900", {&IrcClient::on_sasl_login, {3, 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
|
#endif
|
||||||
{"401", {&IrcClient::on_generic_error, {2, 0}}},
|
{"401", {&IrcClient::on_generic_error, {2, 0}}},
|
||||||
{"402", {&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",
|
"cancel", "item-not-found",
|
||||||
"", reason);
|
"", reason);
|
||||||
}
|
}
|
||||||
|
this->channels_to_join.clear();
|
||||||
}
|
}
|
||||||
else // try the next port
|
else // try the next port
|
||||||
this->start();
|
this->start();
|
||||||
@@ -1372,6 +1379,22 @@ void IrcClient::on_sasl_success(const IrcMessage &)
|
|||||||
this->cap_end();
|
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)
|
void IrcClient::on_sasl_login(const IrcMessage &message)
|
||||||
{
|
{
|
||||||
const auto& login = message.arguments[2];
|
const auto& login = message.arguments[2];
|
||||||
|
|||||||
@@ -247,8 +247,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
#ifdef WITH_SASL
|
#ifdef WITH_SASL
|
||||||
void on_authenticate(const IrcMessage& message);
|
void on_authenticate(const IrcMessage& message);
|
||||||
void on_sasl_success(const IrcMessage& message);
|
|
||||||
void on_sasl_login(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
|
#endif
|
||||||
/**
|
/**
|
||||||
* The channel has been completely joined (self presence, topic, all names
|
* The channel has been completely joined (self presence, topic, all names
|
||||||
|
|||||||
@@ -26,9 +26,47 @@ scenario = (
|
|||||||
"<field var='ports'><value>6667</value></field>"
|
"<field var='ports'><value>6667</value></field>"
|
||||||
"<field var='nick'><value>RegisteredUser</value></field>"
|
"<field var='nick'><value>RegisteredUser</value></field>"
|
||||||
"<field var='tls_ports'><value>6697</value><value>6670</value></field>"
|
"<field var='tls_ports'><value>6697</value><value>6670</value></field>"
|
||||||
|
"<field var='throttle_limit'><value>9999</value></field>"
|
||||||
"</x></command></iq>"),
|
"</x></command></iq>"),
|
||||||
expect_stanza("/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
|
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>"),
|
# Joining a channel with the associated nick will work
|
||||||
sequences.connection(login="RegisteredUser")
|
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.']"),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user