From: Shane Synan Date: Sun, 4 Dec 2016 09:12:02 +0000 (-0600) Subject: Encourage SASL over NickServ when server supports X-Git-Tag: travis-deploy-test~317 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=d5b5dab4ffbdbf30612f49cb77e000ad07b800c2 Encourage SASL over NickServ when server supports Move Use SASL Authentication above Auto Identify. Change the label for SASL according to whether or not SASL support is advertised by the network. If disconnected or unknown, no change. Otherwise, set to "Use SASL Authentication (preferred)" when known, or "Use SASL Authentication (might not work)" when not advertised. Unfortunately there's no way to be sure, but this seems to do the right thing. One can still enable and disable as before. Add explanatory tooltips to authentication options, including recommending SASL if you need to identify before joining channels (this gets asked a lot in #quassel). --- diff --git a/src/qtui/settingspages/networkssettingspage.cpp b/src/qtui/settingspages/networkssettingspage.cpp index bcdc6cfd..52f062fb 100644 --- a/src/qtui/settingspages/networkssettingspage.cpp +++ b/src/qtui/settingspages/networkssettingspage.cpp @@ -32,6 +32,9 @@ #include "settingspagedlg.h" #include "util.h" +// IRCv3 capabilities +#include "irccap.h" + #include "settingspages/identitiessettingspage.h" NetworksSettingsPage::NetworksSettingsPage(QWidget *parent) @@ -89,12 +92,12 @@ NetworksSettingsPage::NetworksSettingsPage(QWidget *parent) connect(ui.identityList, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged())); //connect(ui.randomServer, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); connect(ui.performEdit, SIGNAL(textChanged()), this, SLOT(widgetHasChanged())); - connect(ui.autoIdentify, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); - connect(ui.autoIdentifyService, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged())); - connect(ui.autoIdentifyPassword, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged())); connect(ui.sasl, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); connect(ui.saslAccount, SIGNAL(textEdited(QString)), this, SLOT(widgetHasChanged())); connect(ui.saslPassword, SIGNAL(textEdited(QString)), this, SLOT(widgetHasChanged())); + connect(ui.autoIdentify, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.autoIdentifyService, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged())); + connect(ui.autoIdentifyPassword, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged())); connect(ui.useCustomEncodings, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); connect(ui.sendEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged())); connect(ui.recvEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged())); @@ -348,6 +351,43 @@ void NetworksSettingsPage::setItemState(NetworkId id, QListWidgetItem *item) } +void NetworksSettingsPage::setNetworkCapStates(NetworkId id) +{ + const Network *net = Client::network(id); + if ((Client::coreFeatures() & Quassel::CapNegotiation) + && net && net->connectionState() != Network::Disconnected) { + // If Capability Negotiation isn't supported by the core, no capabilities are active. + // If we're here, the network exists and is connected, check available capabilities... + // Don't use net->isConnected() as that won't be true during capability negotiation when + // capabilities are added and removed. + + // [SASL] + if (net->saslMaybeSupports(IrcCap::SaslMech::PLAIN)) { + // The network advertises support for SASL PLAIN. Encourage using it! Unfortunately we + // don't know for sure if it's desired or functional. + ui.sasl->setTitle(QString("%1 (%2)").arg(tr("Use SASL Authentication"), + tr("preferred"))); + } else { + // The network doesn't advertise support for SASL PLAIN. Here be dragons. + ui.sasl->setTitle(QString("%1 (%2)").arg(tr("Use SASL Authentication"), + tr("might not work"))); + } + // Split up the messages to ease translation and re-use existing "Use SASL Authentication" + // translations. If some languages rearrange phrases such that this would not make sense, + // these strings can be merged into one. + + // Add additional capability-dependent interface updates here + } else { + // We're not connected or the network doesn't yet exist. Don't assume anything and reset + // all capability-dependent interface elements to neutral. + // [SASL] + ui.sasl->setTitle(tr("Use SASL Authentication")); + + // Add additional capability-dependent interface updates here + } +} + + void NetworksSettingsPage::coreConnectionStateChanged(bool state) { this->setEnabled(state); @@ -434,6 +474,10 @@ void NetworksSettingsPage::clientNetworkAdded(NetworkId id) connect(Client::network(id), SIGNAL(connectionStateSet(Network::ConnectionState)), this, SLOT(networkConnectionStateChanged(Network::ConnectionState))); connect(Client::network(id), SIGNAL(connectionError(const QString &)), this, SLOT(networkConnectionError(const QString &))); + + // Handle capability changes in case a server dis/connects with the settings window open. + connect(Client::network(id), SIGNAL(capAdded(const QString &)), this, SLOT(clientNetworkCapsUpdated())); + connect(Client::network(id), SIGNAL(capRemoved(const QString &)), this, SLOT(clientNetworkCapsUpdated())); } @@ -478,6 +522,11 @@ void NetworksSettingsPage::networkConnectionStateChanged(Network::ConnectionStat } */ setItemState(net->networkId()); + if (net->networkId() == currentId) { + // Network is currently shown. Update the capability-dependent UI in case capabilities have + // changed. + setNetworkCapStates(currentId); + } setWidgetStates(); } @@ -545,6 +594,8 @@ void NetworksSettingsPage::displayNetwork(NetworkId id) } //setItemState(id); //ui.randomServer->setChecked(info.useRandomServer); + // Update the capability-dependent UI in case capabilities have changed. + setNetworkCapStates(id); ui.performEdit->setPlainText(info.perform.join("\n")); ui.autoIdentify->setChecked(info.useAutoIdentify); ui.autoIdentifyService->setText(info.autoIdentifyService); @@ -635,6 +686,22 @@ void NetworksSettingsPage::saveToNetworkInfo(NetworkInfo &info) } +void NetworksSettingsPage::clientNetworkCapsUpdated() +{ + // Grab the updated network + const Network *net = qobject_cast(sender()); + if (!net) { + qWarning() << "Update request for unknown network received!"; + return; + } + if (net->networkId() == currentId) { + // Network is currently shown. Update the capability-dependent UI in case capabilities have + // changed. + setNetworkCapStates(currentId); + } +} + + #ifdef HAVE_SSL void NetworksSettingsPage::sslUpdated() { diff --git a/src/qtui/settingspages/networkssettingspage.h b/src/qtui/settingspages/networkssettingspage.h index d760621a..e88f281d 100644 --- a/src/qtui/settingspages/networkssettingspage.h +++ b/src/qtui/settingspages/networkssettingspage.h @@ -58,6 +58,16 @@ private slots: void displayNetwork(NetworkId); void setItemState(NetworkId, QListWidgetItem *item = 0); + /** + * Update the capability-dependent settings according to what the server supports + * + * For example, this updates the SASL text for when the server advertises support. This should + * only be called on the currently displayed network. + * + * @param[in] id NetworkId referencing network used to update settings user interface. + */ + void setNetworkCapStates(NetworkId id); + void clientNetworkAdded(NetworkId); void clientNetworkRemoved(NetworkId); void clientNetworkUpdated(); @@ -66,6 +76,11 @@ private slots: void clientIdentityRemoved(IdentityId); void clientIdentityUpdated(); + /** + * Update the settings user interface according to capabilities advertised by the IRC server + */ + void clientNetworkCapsUpdated(); + #ifdef HAVE_SSL void sslUpdated(); #endif diff --git a/src/qtui/settingspages/networkssettingspage.ui b/src/qtui/settingspages/networkssettingspage.ui index 5b931604..160c6b3e 100644 --- a/src/qtui/settingspages/networkssettingspage.ui +++ b/src/qtui/settingspages/networkssettingspage.ui @@ -664,12 +664,15 @@ Note that Quassel IRC automatically rejoins channels, so /join will rarely be ne - + true + + Authenticate using your nickname and password before joining any channels + - Auto Identify + Use SASL Authentication true @@ -677,41 +680,50 @@ Note that Quassel IRC automatically rejoins channels, so /join will rarely be ne true - - - + + + true - - NickServ + + Account password + + + QLineEdit::Password - - + + true - - QLineEdit::Password + + Password: - + + + true + - Service: + Account: - - + + true + + Account name, often the same as your nickname + - Password: + @@ -719,12 +731,25 @@ Note that Quassel IRC automatically rejoins channels, so /join will rarely be ne - + + + <html><head/><body><p><span style=" font-weight:600;">Note:</span> because the identity has an ssl certificate set, SASL EXTERNAL will be used.</p></body></html> + + + true + + + + + true + + Authenticate to services using your password. Use SASL instead to identify before joining channels. + - Use SASL Authentication + Auto Identify true @@ -732,60 +757,53 @@ Note that Quassel IRC automatically rejoins channels, so /join will rarely be ne true - + - + true + + Service user to send your password to, usually NickServ + - + NickServ - + true + + Account password + QLineEdit::Password - - - - true - + + - Password: + Service: - - + + true - Account: + Password: - - - - <html><head/><body><p><span style=" font-weight:600;">Note:</span> because the identity has an ssl certificate set, SASL EXTERNAL will be used.</p></body></html> - - - true - - - @@ -794,7 +812,7 @@ Note that Quassel IRC automatically rejoins channels, so /join will rarely be ne 20 - 40 + 10 @@ -961,12 +979,12 @@ Unless you *really* know what you do, leave this as ISO-8859-1! messageRateBurstSize unlimitedMessageRate messageRateDelay - autoIdentify - autoIdentifyService - autoIdentifyPassword sasl saslAccount saslPassword + autoIdentify + autoIdentifyService + autoIdentifyPassword useCustomEncodings sendEncoding recvEncoding