Skip to content

Commit

Permalink
HTTP Creds: Do not send the password at every request
Browse files Browse the repository at this point in the history
  • Loading branch information
ogoffart committed Apr 27, 2015
1 parent ddfb7f3 commit ae17f58
Showing 1 changed file with 14 additions and 27 deletions.
41 changes: 14 additions & 27 deletions src/libsync/creds/httpcredentials.cpp
Expand Up @@ -16,6 +16,7 @@
#include <QMutex>
#include <QDebug>
#include <QNetworkReply>
#include <QAuthenticator>
#include <QSettings>
#include <QInputDialog>

Expand Down Expand Up @@ -80,22 +81,6 @@ const char certifPasswdC[] = "certificatePasswd";
const char authenticationFailedC[] = "owncloud-authentication-failed";
} // ns

class HttpCredentialsAccessManager : public AccessManager {
public:
HttpCredentialsAccessManager(const HttpCredentials *cred, QObject* parent = 0)
: AccessManager(parent), _cred(cred) {}
protected:
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) Q_DECL_OVERRIDE {
QByteArray credHash = QByteArray(_cred->user().toUtf8()+":"+_cred->password().toUtf8()).toBase64();
QNetworkRequest req(request);
req.setRawHeader(QByteArray("Authorization"), QByteArray("Basic ") + credHash);
//qDebug() << "Request for " << req.url() << "with authorization" << QByteArray::fromBase64(credHash);
return AccessManager::createRequest(op, req, outgoingData);
}
private:
const HttpCredentials *_cred;
};

HttpCredentials::HttpCredentials()
: _user(),
_password(),
Expand Down Expand Up @@ -188,7 +173,7 @@ QString HttpCredentials::certificatePasswd() const

QNetworkAccessManager* HttpCredentials::getQNAM() const
{
AccessManager* qnam = new HttpCredentialsAccessManager(this);
AccessManager* qnam = new AccessManager;

connect( qnam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)),
this, SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));
Expand Down Expand Up @@ -249,10 +234,7 @@ void HttpCredentials::fetch()
}
bool HttpCredentials::stillValid(QNetworkReply *reply)
{
return ((reply->error() != QNetworkReply::AuthenticationRequiredError)
// returned if user or password is incorrect
&& (reply->error() != QNetworkReply::OperationCanceledError
|| !reply->property(authenticationFailedC).toBool()));
return (reply->error() != QNetworkReply::AuthenticationRequiredError);
}

void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
Expand Down Expand Up @@ -383,13 +365,18 @@ void HttpCredentials::slotWriteJobDone(QKeychain::Job *job)

void HttpCredentials::slotAuthentication(QNetworkReply* reply, QAuthenticator* authenticator)
{
Q_UNUSED(authenticator)
// we cannot use QAuthenticator, because it sends username and passwords with latin1
// instead of utf8 encoding. Instead, we send it manually. Thus, if we reach this signal,
// those credentials were invalid and we terminate.
qDebug() << "Stop request: Authentication failed for " << reply->url().toString();
if (reply->property(authenticationFailedC).toBool()) {
qDebug() << "Authentication failed for " << reply->url().toString();
return;
}

// QNAM sends the user and password in latin-1, but the server expects UTF-8.
// So send mojibake on purpose
authenticator->setUser(QString::fromLatin1(user().toUtf8()));
authenticator->setPassword(QString::fromLatin1(password().toUtf8()));

// Set a property so we don't send the same password twice
reply->setProperty(authenticationFailedC, true);
reply->close();
}

QString HttpCredentialsGui::queryPassword(bool *ok)
Expand Down

0 comments on commit ae17f58

Please sign in to comment.