Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[qmf] Handle SMTP response 504.
Handle SMTP response 504 and reset auth method if auth from caps is
enabled.
  • Loading branch information
Valerio Valerio committed Dec 18, 2014
1 parent fa30bf1 commit c4c2e08
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 57 deletions.
2 changes: 1 addition & 1 deletion qmf/src/libraries/qmfclient/ssosessionmanager.cpp
Expand Up @@ -113,7 +113,7 @@ void SSOSessionManager::cancel()

/*!
Creates a new SSO identity for the account identified by \a id for
the service to \a serviceType with the authentication type \a serviceAuthentication.
the service to \a serviceType.
Returns true if the account has one email service enabled and a valid identity stored
in ths accounts-sso database, otherwise returns false.
Expand Down
2 changes: 1 addition & 1 deletion qmf/src/libraries/qmfmessageserver/qmailauthenticator.cpp
Expand Up @@ -139,7 +139,7 @@ QByteArray QMailAuthenticator::getAuthentication(const QMailAccountConfiguration
*/
#ifdef USE_ACCOUNTS_QT
QByteArray QMailAuthenticator::getResponse(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QByteArray &challenge,
const QMail::SaslMechanism authType, const QString password)
const QMail::SaslMechanism authType, const QString &password)
{
QMailServiceConfiguration configuration(svcCfg);
if (!configuration.value("smtpusername").isEmpty() && authType == QMail::CramMd5Mechanism) {
Expand Down
2 changes: 1 addition & 1 deletion qmf/src/libraries/qmfmessageserver/qmailauthenticator.h
Expand Up @@ -54,7 +54,7 @@ class MESSAGESERVER_EXPORT QMailAuthenticator
static bool useEncryption(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QStringList &capabilities);
static QByteArray getAuthentication(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QStringList &capabilities);
#ifdef USE_ACCOUNTS_QT
static QByteArray getResponse(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QByteArray &challenge, const QMail::SaslMechanism authType, const QString password);
static QByteArray getResponse(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QByteArray &challenge, const QMail::SaslMechanism authType, const QString &password);
#else
static QByteArray getResponse(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QByteArray &challenge);
#endif
Expand Down
50 changes: 24 additions & 26 deletions qmf/src/plugins/messageservices/imap/imapauthenticator.cpp
Expand Up @@ -117,6 +117,25 @@ static QMail::SaslMechanism authFromCapabilities(const QStringList &capabilities
}
}

static QByteArray authenticationResponses(QList<QByteArray> &authList, const QMail::SaslMechanism &authType, const QMailAccountId &id)
{
QByteArray result;
if(!authList.empty()) {
result = authList.takeFirst();
if (!authList.empty()) {
if (authType == QMail::CramMd5Mechanism) {
authPassword = QString::fromLatin1(authList.takeFirst());
responseAuthType = QMail::CramMd5Mechanism;
} else {
gResponses[id] = authList;
}
}
} else {
qMailLog(IMAP) << "Failed to get authentication for method" << authType << "in account id:" << id;
}
return result;
}


QByteArray ImapAuthenticator::getAuthentication(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QStringList &capabilities, const QMap<QString, QList<QByteArray> > &ssoLogin)
{
Expand All @@ -128,8 +147,7 @@ QByteArray ImapAuthenticator::getAuthentication(const QMailAccountConfiguration:
// if we don't have auth yet, try to get it from the capabilities
if (ssoLogin.size() > 1 && authType == QMail::NoMechanism) {
qMailLog(IMAP) << "Discovering authentication from capabilities for account id:" << id;
QMail::SaslMechanism discoveredAuth = authFromCapabilities(capabilities, ssoLogin);
authType = discoveredAuth;
authType = authFromCapabilities(capabilities, ssoLogin);
if (authType != QMail::NoMechanism) {
QMailAccount account(id);
QMailAccountConfiguration accountConfig(id);
Expand All @@ -148,39 +166,19 @@ QByteArray ImapAuthenticator::getAuthentication(const QMailAccountConfiguration:
if (ssoLogin.size() == 1) {
QList<QString> keys = ssoLogin.keys();
auth = ssoLogin.value(keys.at(0));
result = auth.takeFirst();
if (auth.size()) {
// None of the current supported auths uses this
gResponses[id] = auth;
}
result = authenticationResponses(auth, authType, id);
qMailLog(IMAP) << "Using authentication method " << keys.at(0)
<< " for account id:" << id;
} else {
if (authType == QMail::CramMd5Mechanism) {
auth = ssoLogin.value("CRAM-MD5");
if (!auth.empty()) {
result = auth.takeFirst();
authPassword = QString::fromLatin1(auth.takeFirst());
responseAuthType = QMail::CramMd5Mechanism;
} else {
qMailLog(IMAP) << "Failed to get authentication for method CRAM-MD5 in account id:" << id;
}
result = authenticationResponses(auth, authType, id);
} else if (authType == QMail::PlainMechanism) {
auth = ssoLogin.value("PLAIN");
if (!auth.empty()) {
result = auth.takeFirst();
gResponses[id] = auth;
} else {
qMailLog(IMAP) << "Failed to get authentication for method PLAIN in account id:" << id;
}
result = authenticationResponses(auth, authType, id);
} else if (authType == QMail::LoginMechanism) {
auth = ssoLogin.value("LOGIN");
if (!auth.empty()) {
result = auth.takeFirst();
gResponses[id] = auth;
} else {
qMailLog(IMAP) << "Failed to get authentication for method LOGIN in account id:" << id;
}
result = authenticationResponses(auth, authType, id);
}
}
} else {
Expand Down
49 changes: 24 additions & 25 deletions qmf/src/plugins/messageservices/smtp/smtpauthenticator.cpp
Expand Up @@ -85,6 +85,25 @@ static SmtpConfiguration::AuthType authFromCapabilities(const QStringList &capab
}
}

static QByteArray authenticationResponses(QList<QByteArray> &authList, const SmtpConfiguration::AuthType &authType, const QMailAccountId &id)
{
QByteArray result;
if(!authList.empty()) {
result = authList.takeFirst();
if (!authList.empty()) {
if (authType == SmtpConfiguration::Auth_CRAMMD5) {
authPassword = QString::fromLatin1(authList.takeFirst());
responseAuthType = QMail::CramMd5Mechanism;
} else {
gResponses[id] = authList;
}
}
} else {
qMailLog(SMTP) << "Failed to get authentication for method" << authType << "in account id:" << id;
}
return result;
}

QByteArray SmtpAuthenticator::getAuthentication(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QStringList &capabilities, const QMap<QString, QList<QByteArray> > &ssoLogin)
{
QByteArray result;
Expand All @@ -96,8 +115,7 @@ QByteArray SmtpAuthenticator::getAuthentication(const QMailAccountConfiguration:
if (ssoLogin.size() > 1 && authType == SmtpConfiguration::Auth_NONE
&& smtpCfg.smtpAuthFromCapabilities()) {
qMailLog(SMTP) << "Discovering authentication from capabilities for account id:" << id;
SmtpConfiguration::AuthType discoveredAuth = authFromCapabilities(capabilities, ssoLogin);
authType = discoveredAuth;
authType = authFromCapabilities(capabilities, ssoLogin);;
if (authType != SmtpConfiguration::Auth_NONE) {
QMailAccount account(id);
QMailAccountConfiguration accountConfig(id);
Expand All @@ -117,38 +135,19 @@ QByteArray SmtpAuthenticator::getAuthentication(const QMailAccountConfiguration:
if (ssoLogin.size() == 1) {
QList<QString> keys = ssoLogin.keys();
auth = ssoLogin.value(keys.at(0));
result = auth.takeFirst();
if (auth.size()) {
gResponses[id] = auth;
}
result = authenticationResponses(auth, authType, id);
qMailLog(SMTP) << "Using authentication method " << keys.at(0)
<< " for account id:" << id;
} else {
if (authType == SmtpConfiguration::Auth_CRAMMD5) {
auth = ssoLogin.value("CRAM-MD5");
if (!auth.empty()) {
result = auth.takeFirst();
authPassword = QString::fromLatin1(auth.takeFirst());
responseAuthType = QMail::CramMd5Mechanism;
} else {
qMailLog(SMTP) << "Failed to get authentication for method CRAM-MD5 in account id:" << id;
}
result = authenticationResponses(auth, authType, id);
} else if (authType == SmtpConfiguration::Auth_PLAIN) {
auth = ssoLogin.value("PLAIN");
if (!auth.empty()) {
result = auth.takeFirst();
gResponses[id] = auth;
} else {
qMailLog(SMTP) << "Failed to get authentication for method PLAIN in account id:" << id;
}
result = authenticationResponses(auth, authType, id);
} else if (authType == SmtpConfiguration::Auth_LOGIN) {
auth = ssoLogin.value("LOGIN");
if (!auth.empty()) {
result = auth.takeFirst();
gResponses[id] = auth;
} else {
qMailLog(SMTP) << "Failed to get authentication for method LOGIN in account id:" << id;
}
result = authenticationResponses(auth, authType, id);
}
}
} else {
Expand Down
29 changes: 26 additions & 3 deletions qmf/src/plugins/messageservices/smtp/smtpclient.cpp
Expand Up @@ -110,6 +110,7 @@ SmtpClient::SmtpClient(QObject* parent)
, temporaryFile(0)
, waitingForBytes(0)
, notUsingAuth(false)
, authReset(false)
, authTimeout(0)
, ssoSessionManager(0)
, loginFailed(false)
Expand All @@ -128,6 +129,7 @@ SmtpClient::SmtpClient(QObject* parent)
, temporaryFile(0)
, waitingForBytes(0)
, notUsingAuth(false)
, authReset(false)
, authTimeout(0)
{
connect(QMailStore::instance(), SIGNAL(accountsUpdated(const QMailAccountIdList&)),
Expand Down Expand Up @@ -232,6 +234,7 @@ void SmtpClient::newConnection()
sending = true;
domainName = QByteArray();
outstandingResponses = 0;
authReset = false;

if (!transport) {
// Set up the transport
Expand Down Expand Up @@ -684,10 +687,30 @@ void SmtpClient::nextAction(const QString &response)
// We are now authenticated
status = Authenticated;
nextAction(QString());
} else if (responseCode == 530) {
operationFailed(QMailServiceAction::Status::ErrConfiguration, response);
} else if (responseCode == 504) {
// FIX ME: reset method used and try again to authenticated from caps
QMailAccountConfiguration::ServiceConfiguration serviceCfg = config.serviceConfiguration("smtp");
SmtpConfiguration smtpCfg(serviceCfg);
// reset method used and try again to authenticated from caps
if (smtpCfg.smtpAuthFromCapabilities() && !authReset) {
qMailLog(SMTP) << "Resetting AUTH TYPE";
authReset = true;
QMailAccountId id(smtpCfg.id());
QMailAccount account(id);
QMailAccountConfiguration accountConfig(id);
QMailAccountConfiguration::ServiceConfiguration serviceConf(accountConfig.serviceConfiguration("smtp"));
serviceConf.setValue("authentication", QString::number(QMail::NoMechanism));
if (!QMailStore::instance()->updateAccount(&account, &accountConfig)) {
qWarning() << "Unable to update account" << account.id() << "auth type!!!!";
operationFailed(QMailServiceAction::Status::ErrConfiguration, response);
}
// Restart the authentication process
QByteArray ehlo("EHLO " + localName());
sendCommand(ehlo);
status = Helo;
} else {
operationFailed(QMailServiceAction::Status::ErrConfiguration, response);
}
} else if (responseCode == 530) {
operationFailed(QMailServiceAction::Status::ErrConfiguration, response);
} else {
#ifdef USE_ACCOUNTS_QT
Expand Down
1 change: 1 addition & 0 deletions qmf/src/plugins/messageservices/smtp/smtpclient.h
Expand Up @@ -170,6 +170,7 @@ private slots:

QString bufferedResponse;
bool notUsingAuth;
bool authReset;

QTimer *authTimeout;

Expand Down

0 comments on commit c4c2e08

Please sign in to comment.