diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2011-01-17 13:31:32 +0000 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2011-01-17 13:31:32 +0000 |
| commit | 8000f0b96e7b7cfbe4cf631bc243671fa8d5f7fd (patch) | |
| tree | 76819bbb6a6910e61e862b9ba6a38c6a93278b0b /src | |
| parent | bae979bf028adb8c6b72102a97dbc9a3eee4984f (diff) | |
| download | qxmpp-8000f0b96e7b7cfbe4cf631bc243671fa8d5f7fd.tar.gz | |
* do not hardcoded QXmppIncomingClient inactivity timeout
* make QXmppPasswordChecker return more informative codes
Diffstat (limited to 'src')
| -rw-r--r-- | src/QXmppIncomingClient.cpp | 51 | ||||
| -rw-r--r-- | src/QXmppIncomingClient.h | 10 |
2 files changed, 51 insertions, 10 deletions
diff --git a/src/QXmppIncomingClient.cpp b/src/QXmppIncomingClient.cpp index 71c3b664..47abb244 100644 --- a/src/QXmppIncomingClient.cpp +++ b/src/QXmppIncomingClient.cpp @@ -64,12 +64,15 @@ QXmppIncomingClient::QXmppIncomingClient(QSslSocket *socket, const QString &doma d->domain = domain; d->saslStep = 0; - setObjectName("C2S-in"); - setSocket(socket); + if (socket) { + info(QString("Incoming client connection from %1 %2").arg( + socket->peerAddress().toString(), + QString::number(socket->peerPort()))); + setSocket(socket); + } // create inactivity timer d->idleTimer = new QTimer(this); - d->idleTimer->setInterval(70000); d->idleTimer->setSingleShot(true); bool check = connect(d->idleTimer, SIGNAL(timeout()), this, SLOT(slotTimeout())); @@ -109,6 +112,17 @@ QString QXmppIncomingClient::jid() const return jid; } +/// Sets the number of seconds after which a client will be disconnected +/// for inactivity. + +void QXmppIncomingClient::setInactivityTimeout(int secs) +{ + d->idleTimer->stop(); + d->idleTimer->setInterval(secs * 1000); + if (d->idleTimer->interval()) + d->idleTimer->start(); +} + /// Sets the password checker used to verify client credentials. /// /// \param checker @@ -121,7 +135,8 @@ void QXmppIncomingClient::setPasswordChecker(QXmppPasswordChecker *checker) void QXmppIncomingClient::handleStream(const QDomElement &streamElement) { - d->idleTimer->start(); + if (d->idleTimer->interval()) + d->idleTimer->start(); d->saslStep = 0; // start stream @@ -151,7 +166,7 @@ void QXmppIncomingClient::handleStream(const QDomElement &streamElement) // send stream features QXmppStreamFeatures features; - if (!socket()->isEncrypted() && !socket()->localCertificate().isNull() && !socket()->privateKey().isNull()) + if (socket() && !socket()->isEncrypted() && !socket()->localCertificate().isNull() && !socket()->privateKey().isNull()) features.setTlsMode(QXmppStreamFeatures::Enabled); if (!d->username.isEmpty()) { @@ -173,7 +188,8 @@ void QXmppIncomingClient::handleStanza(const QDomElement &nodeRecv) { const QString ns = nodeRecv.namespaceURI(); - d->idleTimer->start(); + if (d->idleTimer->interval()) + d->idleTimer->start(); if (ns == ns_tls && nodeRecv.tagName() == "starttls") { @@ -192,21 +208,37 @@ void QXmppIncomingClient::handleStanza(const QDomElement &nodeRecv) QList<QByteArray> auth = QByteArray::fromBase64(nodeRecv.text().toAscii()).split('\0'); if (auth.size() != 3) { - sendData("<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"); + sendData("<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><incorrect-encoding/></failure>"); disconnectFromHost(); return; } const QString username = QString::fromUtf8(auth[1]); const QString password = QString::fromUtf8(auth[2]); - if (d->passwordChecker && d->passwordChecker->checkPassword(username, password)) + if (!d->passwordChecker) { + // FIXME: what type of failure? + warning(QString("Cannot authenticate '%1', no password checker").arg(username)); + sendData("<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"); + disconnectFromHost(); + return; + } + + QXmppPasswordChecker::Error error = d->passwordChecker->checkPassword(username, password); + if (error == QXmppPasswordChecker::NoError) { d->username = username; + info(QString("Authentication succeeded for '%1'").arg(d->username)); sendData("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"); - } else { + } else if (error == QXmppPasswordChecker::AuthorizationError) { + warning(QString("Authentication failed for '%1'").arg(username)); sendData("<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized/></failure>"); disconnectFromHost(); return; + } else { + warning(QString("Temporary authentication failure for '%1'").arg(username)); + sendData("<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><temporary-auth-failure/></failure>"); + disconnectFromHost(); + return; } } else if (mechanism == "DIGEST-MD5") @@ -277,6 +309,7 @@ void QXmppIncomingClient::handleStanza(const QDomElement &nodeRecv) { // authentication succeeded d->saslStep = 3; + info(QString("Authentication succeeded for '%1'").arg(d->username)); sendData("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"); } } diff --git a/src/QXmppIncomingClient.h b/src/QXmppIncomingClient.h index 384cac82..22b05c48 100644 --- a/src/QXmppIncomingClient.h +++ b/src/QXmppIncomingClient.h @@ -34,11 +34,18 @@ class QXmppIncomingClientPrivate; class QXmppPasswordChecker { public: + /// This enum is used to describe authentication errors. + enum Error { + NoError = 0, + AuthorizationError, + TemporaryError, + }; + /// Checks that the given credentials are valid. /// /// \param username /// \param password - virtual bool checkPassword(const QString &username, const QString &password) = 0; + virtual Error checkPassword(const QString &username, const QString &password) = 0; virtual bool getPassword(const QString &username, QString &password); virtual bool hasGetPassword() const; }; @@ -58,6 +65,7 @@ public: bool isConnected() const; QString jid() const; + void setInactivityTimeout(int secs); void setPasswordChecker(QXmppPasswordChecker *checker); signals: |
