diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-07-18 14:52:24 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-07-18 14:52:24 +0200 |
| commit | 89a558dfbbbde668666e7d8af8f52c23fa61530b (patch) | |
| tree | d04f4a29641a5a35d308623fedf0a0306b49746f /src | |
| parent | 088c9cdd984a08d044064a24a4f898d290297b02 (diff) | |
| download | qxmpp-89a558dfbbbde668666e7d8af8f52c23fa61530b.tar.gz | |
make QXmppStreamFeatures string-based to allow pluggable SASL
Diffstat (limited to 'src')
| -rw-r--r-- | src/base/QXmppStreamFeatures.cpp | 58 | ||||
| -rw-r--r-- | src/base/QXmppStreamFeatures.h | 13 | ||||
| -rw-r--r-- | src/client/QXmppConfiguration.h | 6 | ||||
| -rw-r--r-- | src/client/QXmppOutgoingClient.cpp | 87 | ||||
| -rw-r--r-- | src/server/QXmppIncomingClient.cpp | 6 |
5 files changed, 64 insertions, 106 deletions
diff --git a/src/base/QXmppStreamFeatures.cpp b/src/base/QXmppStreamFeatures.cpp index 75ae559d..e3918cc6 100644 --- a/src/base/QXmppStreamFeatures.cpp +++ b/src/base/QXmppStreamFeatures.cpp @@ -64,22 +64,22 @@ void QXmppStreamFeatures::setNonSaslAuthMode(QXmppStreamFeatures::Mode mode) m_nonSaslAuthMode = mode; } -QList<QXmppConfiguration::SASLAuthMechanism> QXmppStreamFeatures::authMechanisms() const +QStringList QXmppStreamFeatures::authMechanisms() const { return m_authMechanisms; } -void QXmppStreamFeatures::setAuthMechanisms(QList<QXmppConfiguration::SASLAuthMechanism> &mechanisms) +void QXmppStreamFeatures::setAuthMechanisms(const QStringList &mechanisms) { m_authMechanisms = mechanisms; } -QList<QXmppConfiguration::CompressionMethod> QXmppStreamFeatures::compressionMethods() const +QStringList QXmppStreamFeatures::compressionMethods() const { return m_compressionMethods; } -void QXmppStreamFeatures::setCompressionMethods(QList<QXmppConfiguration::CompressionMethod> &methods) +void QXmppStreamFeatures::setCompressionMethods(const QStringList &methods) { m_compressionMethods = methods; } @@ -128,8 +128,7 @@ void QXmppStreamFeatures::parse(const QDomElement &element) QDomElement subElement = compression.firstChildElement("method"); while(!subElement.isNull()) { - if (subElement.text() == QLatin1String("zlib")) - m_compressionMethods << QXmppConfiguration::ZlibCompression; + m_compressionMethods << subElement.text(); subElement = subElement.nextSiblingElement("method"); } } @@ -139,16 +138,8 @@ void QXmppStreamFeatures::parse(const QDomElement &element) if (mechs.namespaceURI() == ns_sasl) { QDomElement subElement = mechs.firstChildElement("mechanism"); - while(!subElement.isNull()) - { - if (subElement.text() == QLatin1String("PLAIN")) - m_authMechanisms << QXmppConfiguration::SASLPlain; - else if (subElement.text() == QLatin1String("DIGEST-MD5")) - m_authMechanisms << QXmppConfiguration::SASLDigestMD5; - else if (subElement.text() == QLatin1String("ANONYMOUS")) - m_authMechanisms << QXmppConfiguration::SASLAnonymous; - else if (subElement.text() == QLatin1String("X-FACEBOOK-PLATFORM")) - m_authMechanisms << QXmppConfiguration::SASLXFacebookPlatform; + while(!subElement.isNull()) { + m_authMechanisms << subElement.text(); subElement = subElement.nextSiblingElement("mechanism"); } } @@ -178,43 +169,16 @@ void QXmppStreamFeatures::toXml(QXmlStreamWriter *writer) const { writer->writeStartElement("compression"); writer->writeAttribute("xmlns", ns_compressFeature); - for (int i = 0; i < m_compressionMethods.size(); i++) - { - writer->writeStartElement("method"); - switch (m_compressionMethods[i]) - { - case QXmppConfiguration::ZlibCompression: - writer->writeCharacters("zlib"); - break; - } - writer->writeEndElement(); - } + foreach (const QString &method, m_compressionMethods) + writer->writeTextElement("method", method); writer->writeEndElement(); } if (!m_authMechanisms.isEmpty()) { writer->writeStartElement("mechanisms"); writer->writeAttribute("xmlns", ns_sasl); - for (int i = 0; i < m_authMechanisms.size(); i++) - { - writer->writeStartElement("mechanism"); - switch (m_authMechanisms[i]) - { - case QXmppConfiguration::SASLPlain: - writer->writeCharacters("PLAIN"); - break; - case QXmppConfiguration::SASLDigestMD5: - writer->writeCharacters("DIGEST-MD5"); - break; - case QXmppConfiguration::SASLAnonymous: - writer->writeCharacters("ANONYMOUS"); - break; - case QXmppConfiguration::SASLXFacebookPlatform: - writer->writeCharacters("X-FACEBOOK-PLATFORM"); - break; - } - writer->writeEndElement(); - } + foreach (const QString &mechanism, m_authMechanisms) + writer->writeTextElement("mechanism", mechanism); writer->writeEndElement(); } writer->writeEndElement(); diff --git a/src/base/QXmppStreamFeatures.h b/src/base/QXmppStreamFeatures.h index 2aa191ea..93176318 100644 --- a/src/base/QXmppStreamFeatures.h +++ b/src/base/QXmppStreamFeatures.h @@ -24,7 +24,6 @@ #ifndef QXMPPSTREAMFEATURES_H #define QXMPPSTREAMFEATURES_H -#include "QXmppConfiguration.h" #include "QXmppStanza.h" class QXMPP_EXPORT QXmppStreamFeatures : public QXmppStanza @@ -48,11 +47,11 @@ public: Mode nonSaslAuthMode() const; void setNonSaslAuthMode(Mode mode); - QList<QXmppConfiguration::SASLAuthMechanism> authMechanisms() const; - void setAuthMechanisms(QList<QXmppConfiguration::SASLAuthMechanism> &mecanisms); + QStringList authMechanisms() const; + void setAuthMechanisms(const QStringList &mechanisms); - QList<QXmppConfiguration::CompressionMethod> compressionMethods() const; - void setCompressionMethods(QList<QXmppConfiguration::CompressionMethod> &methods); + QStringList compressionMethods() const; + void setCompressionMethods(const QStringList &methods); Mode tlsMode() const; void setTlsMode(Mode mode); @@ -69,8 +68,8 @@ private: Mode m_sessionMode; Mode m_nonSaslAuthMode; Mode m_tlsMode; - QList<QXmppConfiguration::SASLAuthMechanism> m_authMechanisms; - QList<QXmppConfiguration::CompressionMethod> m_compressionMethods; + QStringList m_authMechanisms; + QStringList m_compressionMethods; }; #endif 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<QXmppConfiguration::SASLAuthMechanism> 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 = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>"; - data += userPass.toUtf8().toBase64(); - data += "</auth>"; - sendData(data); - } + preferredMechanism = "PLAIN"; break; case QXmppConfiguration::SASLDigestMD5: - sendData("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>"); + preferredMechanism = "DIGEST-MD5"; break; case QXmppConfiguration::SASLAnonymous: - sendData("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>"); + preferredMechanism = "ANONYMOUS"; break; case QXmppConfiguration::SASLXFacebookPlatform: - sendData("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-FACEBOOK-PLATFORM'/>"); + 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 = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>"; + data += userPass.toUtf8().toBase64(); + data += "</auth>"; + sendData(data); + } else { + sendData("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='" + d->saslMechanism.toLatin1() + "'/>"); + } } // 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") diff --git a/src/server/QXmppIncomingClient.cpp b/src/server/QXmppIncomingClient.cpp index 721f7e47..c81c20be 100644 --- a/src/server/QXmppIncomingClient.cpp +++ b/src/server/QXmppIncomingClient.cpp @@ -200,10 +200,10 @@ void QXmppIncomingClient::handleStream(const QDomElement &streamElement) } else if (d->passwordChecker) { - QList<QXmppConfiguration::SASLAuthMechanism> mechanisms; - mechanisms << QXmppConfiguration::SASLPlain; + QStringList mechanisms; + mechanisms << "PLAIN"; if (d->passwordChecker->hasGetPassword()) - mechanisms << QXmppConfiguration::SASLDigestMD5; + mechanisms << "DIGEST-MD5"; features.setAuthMechanisms(mechanisms); } sendPacket(features); |
