From 2a34abcd74d8d8369d81d9e4131d34185d9154a5 Mon Sep 17 00:00:00 2001 From: Jeremy Lainé Date: Thu, 17 Jan 2019 23:25:37 +0100 Subject: [sasl] order mechanisms to prefer the most secure The previous logic was: - use the preferred SASL mechanism if available - otherwise use the first supported mechanism offered by the server However RFC 6120, section 6.3.3 states: "The initiating entity MUST maintain its own preference order independent of the preference order of the receiving entity." The new logic is: - order our supported mechanisms from most secure to least secure - if the user sets QXmppConfiguration::saslMechanism, put it first - use the best mechanism supported by the server --- src/client/QXmppOutgoingClient.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/client/QXmppOutgoingClient.cpp') diff --git a/src/client/QXmppOutgoingClient.cpp b/src/client/QXmppOutgoingClient.cpp index 1fcb7c28..aef68070 100644 --- a/src/client/QXmppOutgoingClient.cpp +++ b/src/client/QXmppOutgoingClient.cpp @@ -451,8 +451,12 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv) if (saslAvailable && configuration().useSASLAuthentication()) { // supported and preferred SASL auth mechanisms - QStringList supportedMechanisms = QXmppSaslClient::availableMechanisms(); const QString preferredMechanism = configuration().saslAuthMechanism(); + QStringList supportedMechanisms = QXmppSaslClient::availableMechanisms(); + if (supportedMechanisms.contains(preferredMechanism)) { + supportedMechanisms.removeAll(preferredMechanism); + supportedMechanisms.prepend(preferredMechanism); + } if (configuration().facebookAppId().isEmpty() || configuration().facebookAccessToken().isEmpty()) supportedMechanisms.removeAll("X-FACEBOOK-PLATFORM"); if (configuration().windowsLiveAccessToken().isEmpty()) @@ -463,19 +467,16 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv) // determine SASL Authentication mechanism to use QStringList commonMechanisms; QString usedMechanism; - foreach (const QString &mechanism, features.authMechanisms()) { - if (supportedMechanisms.contains(mechanism)) + foreach (const QString &mechanism, supportedMechanisms) { + if (features.authMechanisms().contains(mechanism)) commonMechanisms << mechanism; } if (commonMechanisms.isEmpty()) { warning("No supported SASL Authentication mechanism available"); disconnectFromHost(); return; - } else if (!commonMechanisms.contains(preferredMechanism)) { - info(QString("Desired SASL Auth mechanism '%1' is not available, selecting first available one").arg(preferredMechanism)); - usedMechanism = commonMechanisms.first(); } else { - usedMechanism = preferredMechanism; + usedMechanism = commonMechanisms.first(); } d->saslClient = QXmppSaslClient::create(usedMechanism, this); -- cgit v1.2.3