diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-07-20 10:59:53 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-07-20 10:59:53 +0200 |
| commit | 15cab790071aabfc62977d590b89f54a5fa6e92d (patch) | |
| tree | 4b75e1269ab983d06130340325a4ee97baf901e7 /src | |
| parent | a609100c2a0eb19ef4b9c7a571366281ca722ac8 (diff) | |
| download | qxmpp-15cab790071aabfc62977d590b89f54a5fa6e92d.tar.gz | |
first stab at factoring out server-side SASL
Diffstat (limited to 'src')
| -rw-r--r-- | src/base/QXmppSaslAuth.cpp | 149 | ||||
| -rw-r--r-- | src/base/QXmppSaslAuth.h | 28 | ||||
| -rw-r--r-- | src/base/QXmppSaslAuth_p.h | 49 |
3 files changed, 225 insertions, 1 deletions
diff --git a/src/base/QXmppSaslAuth.cpp b/src/base/QXmppSaslAuth.cpp index 0ae3b1df..ead1188f 100644 --- a/src/base/QXmppSaslAuth.cpp +++ b/src/base/QXmppSaslAuth.cpp @@ -104,7 +104,7 @@ void QXmppSaslClient::setServiceType(const QString &serviceType) d->serviceType = serviceType; } -/// Returns the host. +/// Returns the username. QString QXmppSaslClient::username() const { @@ -308,6 +308,153 @@ bool QXmppSaslClientPlain::respond(const QByteArray &challenge, QByteArray &resp } } +class QXmppSaslServerPrivate +{ +public: + QString username; + QString password; +}; + +QXmppSaslServer::QXmppSaslServer(QObject *parent) + : QXmppLoggable(parent) + , d(new QXmppSaslServerPrivate) +{ +} + +QXmppSaslServer::~QXmppSaslServer() +{ + delete d; +} + +/// Creates an SASL server for the given mechanism. + +QXmppSaslServer* QXmppSaslServer::create(const QString &mechanism, QObject *parent) +{ + if (mechanism == "PLAIN") { + return new QXmppSaslServerPlain(parent); + } else if (mechanism == "DIGEST-MD5") { + return new QXmppSaslServerDigestMd5(parent); + } else if (mechanism == "ANONYMOUS") { + return new QXmppSaslServerAnonymous(parent); + } +} + +/// Returns the username. + +QString QXmppSaslServer::username() const +{ + return d->username; +} + +/// Sets the username. + +void QXmppSaslServer::setUsername(const QString &username) +{ + d->username = username; +} + +/// Returns the password. + +QString QXmppSaslServer::password() const +{ + return d->password; +} + +/// Sets the password. + +void QXmppSaslServer::setPassword(const QString &password) +{ + d->password = password; +} + +QXmppSaslServerAnonymous::QXmppSaslServerAnonymous(QObject *parent) + : QXmppSaslServer(parent) + , m_step(0) +{ +} + +QString QXmppSaslServerAnonymous::mechanism() const +{ + return "ANONYMOUS"; +} + +QXmppSaslServer::Response QXmppSaslServerAnonymous::respond(const QByteArray &request, QByteArray &response) +{ + Q_UNUSED(request); + if (m_step == 0) { + m_step++; + response = QByteArray(); + return Succeeded; + } else { + warning("QXmppSaslServerAnonymous : Invalid step"); + return Failed; + } +} + +QXmppSaslServerDigestMd5::QXmppSaslServerDigestMd5(QObject *parent) + : QXmppSaslServer(parent) + , m_step(0) +{ +} + +QString QXmppSaslServerDigestMd5::mechanism() const +{ + return "DIGEST-MD5"; +} + +QXmppSaslServer::Response QXmppSaslServerDigestMd5::respond(const QByteArray &request, QByteArray &response) +{ + if (m_step == 0) { + // generate nonce + m_saslDigest.setNonce(QXmppSaslDigestMd5::generateNonce()); + //m_saslDigest.setQop("auth"); + + QMap<QByteArray, QByteArray> challenge; + challenge["nonce"] = m_saslDigest.nonce(); + //challenge["realm"] = m_domain.toUtf8(); + challenge["qop"] = "auth"; + challenge["charset"] = "utf-8"; + challenge["algorithm"] = "md5-sess"; + + m_step++; + response = QXmppSaslDigestMd5::serializeMessage(challenge); + return Challenge; + } else { + return Failed; + } +} + +QXmppSaslServerPlain::QXmppSaslServerPlain(QObject *parent) + : QXmppSaslServer(parent) + , m_step(0) +{ +} + +QString QXmppSaslServerPlain::mechanism() const +{ + return "PLAIN"; +} + +QXmppSaslServer::Response QXmppSaslServerPlain::respond(const QByteArray &request, QByteArray &response) +{ + if (m_step == 0) { + QList<QByteArray> auth = request.split('\0'); + if (auth.size() != 3) { + warning("QXmppSaslServerPlain : Invalid input"); + return Failed; + } + setUsername(QString::fromUtf8(auth[1])); + setPassword(QString::fromUtf8(auth[2])); + + m_step++; + response = QByteArray(); + return Succeeded; + } else { + warning("QXmppSaslServerPlain : Invalid step"); + return Failed; + } +} + QByteArray QXmppSaslDigestMd5::authzid() const { return m_authzid; diff --git a/src/base/QXmppSaslAuth.h b/src/base/QXmppSaslAuth.h index b6428eb8..9026d757 100644 --- a/src/base/QXmppSaslAuth.h +++ b/src/base/QXmppSaslAuth.h @@ -32,6 +32,7 @@ #include "QXmppLogger.h" class QXmppSaslClientPrivate; +class QXmppSaslServerPrivate; class QXMPP_EXPORT QXmppSaslDigestMd5 { @@ -105,4 +106,31 @@ private: QXmppSaslClientPrivate *d; }; +class QXMPP_EXPORT QXmppSaslServer : public QXmppLoggable +{ +public: + enum Response { + Challenge = 0, + Succeeded = 1, + Failed = 2 + }; + + QXmppSaslServer(QObject *parent = 0); + virtual ~QXmppSaslServer(); + + QString username() const; + void setUsername(const QString &username); + + QString password() const; + void setPassword(const QString &password); + + virtual QString mechanism() const = 0; + virtual Response respond(const QByteArray &challenge, QByteArray &response) = 0; + + static QXmppSaslServer* create(const QString &mechanism, QObject *parent = 0); + +private: + QXmppSaslServerPrivate *d; +}; + #endif diff --git a/src/base/QXmppSaslAuth_p.h b/src/base/QXmppSaslAuth_p.h index 18c1829e..10a20cfb 100644 --- a/src/base/QXmppSaslAuth_p.h +++ b/src/base/QXmppSaslAuth_p.h @@ -81,4 +81,53 @@ private: int m_step; }; +class QXmppSaslServerAnonymous : public QXmppSaslServer +{ +public: + QXmppSaslServerAnonymous(QObject *parent = 0); + QString mechanism() const; + + Response respond(const QByteArray &challenge, QByteArray &response); + +private: + int m_step; +}; + +class QXmppSaslServerDigestMd5 : public QXmppSaslServer +{ +public: + QXmppSaslServerDigestMd5(QObject *parent = 0); + QString mechanism() const; + + Response respond(const QByteArray &challenge, QByteArray &response); + +private: + QXmppSaslDigestMd5 m_saslDigest; + int m_step; +}; + +class QXmppSaslServerFacebook : public QXmppSaslServer +{ +public: + QXmppSaslServerFacebook(QObject *parent = 0); + QString mechanism() const; + + Response respond(const QByteArray &challenge, QByteArray &response); + +private: + int m_step; +}; + +class QXmppSaslServerPlain : public QXmppSaslServer +{ +public: + QXmppSaslServerPlain(QObject *parent = 0); + QString mechanism() const; + + Response respond(const QByteArray &challenge, QByteArray &response); + +private: + int m_step; +}; + #endif |
