aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2012-07-20 18:02:32 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2012-07-20 18:02:32 +0200
commit1b653eb9e6212678297281f5bca43bcd0b1a00fb (patch)
tree88033357f290e498f1028d3f194141d99812efcc
parent51eef84fd4104f19228ebd85fce89658b64464a2 (diff)
downloadqxmpp-1b653eb9e6212678297281f5bca43bcd0b1a00fb.tar.gz
add support for two-step PLAIN SASL
-rw-r--r--src/base/QXmppSasl.cpp5
-rw-r--r--src/server/QXmppIncomingClient.cpp44
-rw-r--r--tests/sasl.cpp23
-rw-r--r--tests/sasl.h1
4 files changed, 56 insertions, 17 deletions
diff --git a/src/base/QXmppSasl.cpp b/src/base/QXmppSasl.cpp
index d37644ca..a39194ec 100644
--- a/src/base/QXmppSasl.cpp
+++ b/src/base/QXmppSasl.cpp
@@ -642,6 +642,11 @@ QString QXmppSaslServerPlain::mechanism() const
QXmppSaslServer::Response QXmppSaslServerPlain::respond(const QByteArray &request, QByteArray &response)
{
if (m_step == 0) {
+ if (request.isEmpty()) {
+ response = QByteArray();
+ return Challenge;
+ }
+
QList<QByteArray> auth = request.split('\0');
if (auth.size() != 3) {
warning("QXmppSaslServerPlain : Invalid input");
diff --git a/src/server/QXmppIncomingClient.cpp b/src/server/QXmppIncomingClient.cpp
index 6065dda8..6a557548 100644
--- a/src/server/QXmppIncomingClient.cpp
+++ b/src/server/QXmppIncomingClient.cpp
@@ -50,6 +50,7 @@ public:
QXmppPasswordChecker *passwordChecker;
QXmppSaslServer *saslServer;
+ void checkCredentials(const QByteArray &response);
QString origin() const;
private:
@@ -64,6 +65,29 @@ QXmppIncomingClientPrivate::QXmppIncomingClientPrivate(QXmppIncomingClient *qq)
{
}
+void QXmppIncomingClientPrivate::checkCredentials(const QByteArray &response)
+{
+ QXmppPasswordRequest request;
+ request.setDomain(domain);
+ request.setUsername(saslServer->username());
+
+ if (saslServer->mechanism() == "PLAIN") {
+ request.setPassword(saslServer->password());
+
+ QXmppPasswordReply *reply = passwordChecker->checkPassword(request);
+ reply->setParent(q);
+ reply->setProperty("__sasl_raw", response);
+ QObject::connect(reply, SIGNAL(finished()),
+ q, SLOT(onPasswordReply()));
+ } else if (saslServer->mechanism() == "DIGEST-MD5") {
+ QXmppPasswordReply *reply = passwordChecker->getDigest(request);
+ reply->setParent(q);
+ reply->setProperty("__sasl_raw", response);
+ QObject::connect(reply, SIGNAL(finished()),
+ q, SLOT(onDigestReply()));
+ }
+}
+
QString QXmppIncomingClientPrivate::origin() const
{
QSslSocket *socket = q->socket();
@@ -249,15 +273,8 @@ void QXmppIncomingClient::handleStanza(const QDomElement &nodeRecv)
QXmppSaslServer::Response result = d->saslServer->respond(auth.value(), challenge);
if (result == QXmppSaslServer::InputNeeded) {
- // FIXME: this is PLAIN only
- QXmppPasswordRequest request;
- request.setDomain(d->saslServer->realm());
- request.setUsername(d->saslServer->username());
- request.setPassword(d->saslServer->password());
-
- QXmppPasswordReply *reply = d->passwordChecker->checkPassword(request);
- reply->setParent(this);
- connect(reply, SIGNAL(finished()), this, SLOT(onPasswordReply()));
+ // check credentials
+ d->checkCredentials(auth.value());
} else if (result == QXmppSaslServer::Challenge) {
sendPacket(QXmppSaslChallenge(challenge));
} else {
@@ -283,14 +300,7 @@ void QXmppIncomingClient::handleStanza(const QDomElement &nodeRecv)
QXmppSaslServer::Response result = d->saslServer->respond(response.value(), challenge);
if (result == QXmppSaslServer::InputNeeded) {
// check credentials
- QXmppPasswordRequest request;
- request.setUsername(d->saslServer->username());
- request.setDomain(d->domain);
-
- QXmppPasswordReply *reply = d->passwordChecker->getDigest(request);
- reply->setParent(this);
- reply->setProperty("__sasl_raw", response.value());
- connect(reply, SIGNAL(finished()), this, SLOT(onDigestReply()));
+ d->checkCredentials(response.value());
} else if (result == QXmppSaslServer::Succeeded) {
// authentication succeeded
d->jid = QString("%1@%2").arg(d->saslServer->username(), d->domain);
diff --git a/tests/sasl.cpp b/tests/sasl.cpp
index 8ea635b3..a5399294 100644
--- a/tests/sasl.cpp
+++ b/tests/sasl.cpp
@@ -231,3 +231,26 @@ void tst_QXmppSaslServer::testPlain()
delete server;
}
+
+void tst_QXmppSaslServer::testPlainChallenge()
+{
+ QXmppSaslServer *server = QXmppSaslServer::create("PLAIN");
+ QVERIFY(server != 0);
+ QCOMPARE(server->mechanism(), QLatin1String("PLAIN"));
+
+ // initial step returns challenge
+ QByteArray response;
+ QCOMPARE(server->respond(QByteArray(), response), QXmppSaslServer::Challenge);
+ QCOMPARE(response, QByteArray());
+
+ // initial step returns success
+ QCOMPARE(server->respond(QByteArray("\0foo\0bar", 8), response), QXmppSaslServer::InputNeeded);
+ QCOMPARE(response, QByteArray());
+ QCOMPARE(server->username(), QLatin1String("foo"));
+ QCOMPARE(server->password(), QLatin1String("bar"));
+
+ // any further step is an error
+ QCOMPARE(server->respond(QByteArray(), response), QXmppSaslServer::Failed);
+
+ delete server;
+}
diff --git a/tests/sasl.h b/tests/sasl.h
index 05c03ca5..0d2db34e 100644
--- a/tests/sasl.h
+++ b/tests/sasl.h
@@ -54,5 +54,6 @@ private slots:
void testAnonymous();
void testDigestMd5();
void testPlain();
+ void testPlainChallenge();
};