Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[IMAP] Do AUTHENTICATE PLAIN in two stages
Some servers(e.g yandex.ru) do not support AUTHENTICATE PLAIN in a
single command, according to RFC4616 this way is optional, so we allways
perform the authentication in two stages that is gurantee to be supported
by all implementations of the protocol.
  • Loading branch information
Valério Valério committed Feb 20, 2015
1 parent 3c5cbee commit 815bf24
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
11 changes: 8 additions & 3 deletions qmf/src/plugins/messageservices/imap/imapauthenticator.cpp
Expand Up @@ -52,11 +52,11 @@

namespace {

QMap<QMailAccountId, QList<QByteArray> > gResponses;

#ifdef USE_ACCOUNTS_QT
QString authPassword;
QMail::SaslMechanism responseAuthType;
QByteArray gResponse;
#endif
}

Expand Down Expand Up @@ -127,7 +127,9 @@ static QByteArray authenticationResponses(QList<QByteArray> &authList, const QMa
authPassword = QString::fromLatin1(authList.takeFirst());
responseAuthType = QMail::CramMd5Mechanism;
} else {
gResponses[id] = authList;
gResponse = authList.first();
// We need to clean this state, both the other auths available will work the same way
responseAuthType = QMail::PlainMechanism;
}
}
} else {
Expand Down Expand Up @@ -210,7 +212,10 @@ QByteArray ImapAuthenticator::getAuthentication(const QMailAccountConfiguration:
QByteArray ImapAuthenticator::getResponse(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QByteArray &challenge)
{
#ifdef USE_ACCOUNTS_QT
return QMailAuthenticator::getResponse(svcCfg, challenge, responseAuthType, authPassword);
if (responseAuthType == QMail::CramMd5Mechanism) {
return QMailAuthenticator::getResponse(svcCfg, challenge, responseAuthType, authPassword);
}
return gResponse;
#else
return QMailAuthenticator::getResponse(svcCfg, challenge);
#endif
Expand Down
20 changes: 11 additions & 9 deletions qmf/src/plugins/ssoauth/password/passwordplugin.cpp
Expand Up @@ -94,20 +94,22 @@ QMap<QString, QList<QByteArray> > SSOPasswordPlugin::getIMAPAuthentication(const
QMap<QString, QList<QByteArray> > result;

// Add PLAIN auth
QByteArray user(username.toLatin1());
QByteArray pass(password.toLatin1());
QByteArray user(username.toUtf8());
QByteArray pass(password.toUtf8());

result.insert(QString::fromLatin1("PLAIN"), QList<QByteArray>() << QByteArray("AUTHENTICATE PLAIN ")
+ QByteArray(user + '\0' + user + '\0' + pass).toBase64());
QList<QByteArray> plainAuth;
plainAuth.append(QByteArray("AUTHENTICATE PLAIN"));
plainAuth.append(QByteArray(user + '\0' + user + '\0' + pass));
result.insert(QString::fromLatin1("PLAIN"), plainAuth);

// Add LOGIN auth
result.insert(QString::fromLatin1("LOGIN"), QList<QByteArray>() << QByteArray("LOGIN") + ' ' + quoteIMAPString(username.toLatin1())
+ ' ' + quoteIMAPString(password.toLatin1()));
result.insert(QString::fromLatin1("LOGIN"), QList<QByteArray>() << QByteArray("LOGIN") + ' ' + quoteIMAPString(username.toUtf8())
+ ' ' + quoteIMAPString(password.toUtf8()));

// Add CRAM_MD5
QList<QByteArray> cramAuth;
cramAuth.append(QByteArray("AUTHENTICATE CRAM-MD5"));
cramAuth.append(QByteArray(password.toLatin1()));
cramAuth.append(QByteArray(password.toUtf8()));
result.insert(QString::fromLatin1("CRAM-MD5"), cramAuth);

return result;
Expand All @@ -120,8 +122,8 @@ QMap<QString, QList<QByteArray> > SSOPasswordPlugin::getPOPAuthentication(const

// Add PLAIN auth
QList<QByteArray> plainAuth;
plainAuth.append(QByteArray("USER ") + username.toLatin1());
plainAuth.append(QByteArray("PASS ") + password.toLatin1());
plainAuth.append(QByteArray("USER ") + username.toUtf8());
plainAuth.append(QByteArray("PASS ") + password.toUtf8());
result.insert(QString::fromLatin1("PLAIN"), plainAuth);

// Currently pop account does not have any auth settings, so only plain can be used
Expand Down

0 comments on commit 815bf24

Please sign in to comment.