From 89a558dfbbbde668666e7d8af8f52c23fa61530b Mon Sep 17 00:00:00 2001 From: Jeremy Lainé Date: Wed, 18 Jul 2012 14:52:24 +0200 Subject: make QXmppStreamFeatures string-based to allow pluggable SASL --- src/client/QXmppConfiguration.h | 6 --- src/client/QXmppOutgoingClient.cpp | 87 +++++++++++++++++++------------------- 2 files changed, 44 insertions(+), 49 deletions(-) (limited to 'src/client') diff --git a/src/client/QXmppConfiguration.h b/src/client/QXmppConfiguration.h index d6423fb5..9d6ce65f 100644 --- a/src/client/QXmppConfiguration.h +++ b/src/client/QXmppConfiguration.h @@ -80,12 +80,6 @@ public: SASLXFacebookPlatform, ///< Facebook Platform }; - /// An enumeration for stream compression methods. - enum CompressionMethod - { - ZlibCompression = 0 ///< zlib compression - }; - QXmppConfiguration(); QXmppConfiguration(const QXmppConfiguration &other); ~QXmppConfiguration(); diff --git a/src/client/QXmppOutgoingClient.cpp b/src/client/QXmppOutgoingClient.cpp index 4afee079..10f82ad0 100644 --- a/src/client/QXmppOutgoingClient.cpp +++ b/src/client/QXmppOutgoingClient.cpp @@ -82,7 +82,7 @@ public: QString nonSASLAuthId; QXmppSaslDigestMd5 saslDigest; int saslDigestStep; - int saslMechanism; + QString saslMechanism; // Timers QTimer *pingTimer; @@ -90,9 +90,8 @@ public: }; QXmppOutgoingClientPrivate::QXmppOutgoingClientPrivate() - : sessionAvailable(false), - saslDigestStep(0), - saslMechanism(-1) + : sessionAvailable(false) + , saslDigestStep(0) { } @@ -246,7 +245,7 @@ void QXmppOutgoingClient::handleStart() // reset authentication step d->saslDigestStep = 0; - d->saslMechanism = -1; + d->saslMechanism = QString(); // reset session information d->bindId.clear(); @@ -338,45 +337,52 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv) } else if(saslAvailable) { - // determine SASL Authentication mechanism to use - const QList mechanisms = features.authMechanisms(); - if (mechanisms.isEmpty()) - { - warning("No supported SASL Authentication mechanism available"); - disconnectFromHost(); - return; - } - else if (!mechanisms.contains(configuration().sASLAuthMechanism())) - { - info("Desired SASL Auth mechanism is not available, selecting first available one"); - d->saslMechanism = mechanisms.first(); - } else { - d->saslMechanism = configuration().sASLAuthMechanism(); - } - - // send SASL Authentication request - switch(d->saslMechanism) - { + // supported and preferred SASL auth mechanisms + const QStringList supportedMechanisms = QStringList() << "PLAIN" << "DIGEST-MD5" << "ANONYMOUS" << "X-FACEBOOK-PLATFORM"; + QString preferredMechanism; + switch (configuration().sASLAuthMechanism()) { case QXmppConfiguration::SASLPlain: - { - QString userPass('\0' + configuration().user() + - '\0' + configuration().password()); - QByteArray data = ""; - data += userPass.toUtf8().toBase64(); - data += ""; - sendData(data); - } + preferredMechanism = "PLAIN"; break; case QXmppConfiguration::SASLDigestMD5: - sendData(""); + preferredMechanism = "DIGEST-MD5"; break; case QXmppConfiguration::SASLAnonymous: - sendData(""); + preferredMechanism = "ANONYMOUS"; break; case QXmppConfiguration::SASLXFacebookPlatform: - sendData(""); + preferredMechanism = "X-FACEBOOK-PLATFORM"; break; } + + // determine SASL Authentication mechanism to use + QStringList commonMechanisms; + foreach (const QString &mechanism, features.authMechanisms()) { + if (supportedMechanisms.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)); + d->saslMechanism = commonMechanisms.first(); + } else { + d->saslMechanism = preferredMechanism; + } + + // send SASL Authentication request + if (d->saslMechanism == "PLAIN") { + QString userPass('\0' + configuration().user() + + '\0' + configuration().password()); + QByteArray data = ""; + data += userPass.toUtf8().toBase64(); + data += ""; + sendData(data); + } else { + sendData(""); + } } // check whether bind is available @@ -419,9 +425,7 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv) } else if(nodeRecv.tagName() == "challenge") { - switch(d->saslMechanism) - { - case QXmppConfiguration::SASLDigestMD5: + if (d->saslMechanism == "DIGEST-MD5") { d->saslDigestStep++; switch (d->saslDigestStep) { @@ -436,14 +440,11 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv) disconnectFromHost(); break; } - break; - case QXmppConfiguration::SASLXFacebookPlatform: + } else if (d->saslMechanism == "X-FACEBOOK-PLATFORM") { sendAuthXFacebookResponse(nodeRecv.text()); - break; - default: + } else { warning("Unexpected SASL challenge"); disconnectFromHost(); - break; } } else if(nodeRecv.tagName() == "failure") -- cgit v1.2.3