Commit bf0d09cd authored by Laurent Montel's avatar Laurent Montel 😁

Merge remote-tracking branch 'origin/Applications/17.04'

parents 1666c706 4918895a
......@@ -33,8 +33,8 @@ inline bool initSASL()
#ifdef Q_OS_WIN32 //krazy:exclude=cpp
QByteArray libInstallPath(QFile::encodeName(QDir::toNativeSeparators(KGlobal::dirs()->installPath("lib") + QLatin1String("sasl2"))));
QByteArray configPath(QFile::encodeName(QDir::toNativeSeparators(KGlobal::dirs()->installPath("config") + QLatin1String("sasl2"))));
if (sasl_set_path(SASL_PATH_TYPE_PLUGIN, libInstallPath.data()) != SASL_OK ||
sasl_set_path(SASL_PATH_TYPE_CONFIG, configPath.data()) != SASL_OK) {
if (sasl_set_path(SASL_PATH_TYPE_PLUGIN, libInstallPath.data()) != SASL_OK
|| sasl_set_path(SASL_PATH_TYPE_CONFIG, configPath.data()) != SASL_OK) {
fprintf(stderr, "SASL path initialization failed!\n");
return false;
}
......
......@@ -32,17 +32,15 @@
#include "capabilities.h"
#include "response.h"
namespace KioSMTP
{
namespace KioSMTP {
Capabilities Capabilities::fromResponse(const Response &ehlo)
{
Capabilities c;
// first, check whether the response was valid and indicates success:
if (!ehlo.isOk()
|| ehlo.code() / 10 != 25 // ### restrict to 250 only?
|| ehlo.lines().empty()) {
|| ehlo.code() / 10 != 25 // ### restrict to 250 only?
|| ehlo.lines().empty()) {
return c;
}
......@@ -109,7 +107,7 @@ QStringList Capabilities::saslMethodsQSL() const
{
QStringList result;
for (QMap<QString, QStringList>::const_iterator it = mCapabilities.begin();
it != mCapabilities.end(); ++it) {
it != mCapabilities.end(); ++it) {
if (it.key() == QLatin1String("AUTH")) {
result += it.value();
} else if (it.key().startsWith(QLatin1String("AUTH="))) {
......@@ -120,5 +118,4 @@ QStringList Capabilities::saslMethodsQSL() const
result.removeDuplicates();
return result;
}
} // namespace KioSMTP
......@@ -36,9 +36,7 @@
#include <QStringList>
namespace KioSMTP
{
namespace KioSMTP {
class Response;
class Capabilities
......@@ -61,10 +59,12 @@ public:
{
return mCapabilities.find(cap.toUpper()) != mCapabilities.end();
}
bool have(const QByteArray &cap) const
{
return have(QString::fromLatin1(cap));
}
bool have(const char *cap) const
{
return have(QString::fromLatin1(cap));
......@@ -81,7 +81,6 @@ private:
QMap<QString, QStringList> mCapabilities;
};
} // namespace KioSMTP
#endif // __KIOSMTP_CAPABILITIES_H__
......@@ -43,9 +43,7 @@
#include <assert.h>
namespace KioSMTP
{
namespace KioSMTP {
static const sasl_callback_t callbacks[] = {
{ SASL_CB_ECHOPROMPT, nullptr, nullptr },
{ SASL_CB_NOECHOPROMPT, nullptr, nullptr },
......@@ -156,7 +154,7 @@ bool EHLOCommand::processResponse(const Response &r, TransactionState *ts)
return true;
}
mComplete = true;
if (r.code() / 10 == 25) { // 25x: success
if (r.code() / 10 == 25) { // 25x: success
parseFeatures(r);
return true;
}
......@@ -207,15 +205,12 @@ bool StartTLSCommand::processResponse(const Response &r, TransactionState *ts)
#define SASLERROR mSMTP->error(KIO::ERR_COULD_NOT_AUTHENTICATE, \
i18n("An error occurred during authentication: %1", \
QString::fromUtf8( sasl_errdetail( conn ) )));
QString::fromUtf8(sasl_errdetail(conn))));
//
// AUTH - rfc 2554
//
AuthCommand::AuthCommand(SMTPSessionInterface *smtp,
const char *mechanisms,
const QString &aFQDN,
KIO::AuthInfo &ai)
AuthCommand::AuthCommand(SMTPSessionInterface *smtp, const char *mechanisms, const QString &aFQDN, KIO::AuthInfo &ai)
: Command(smtp, CloseConnectionOnError | OnlyLastInPipeline)
, mAi(&ai)
, mFirstTime(true)
......@@ -242,7 +237,7 @@ AuthCommand::AuthCommand(SMTPSessionInterface *smtp,
if (result == SASL_INTERACT) {
if (!saslInteract(client_interact)) {
return;
};
}
}
} while (result == SASL_INTERACT);
if (result != SASL_CONTINUE && result != SASL_OK) {
......@@ -267,14 +262,13 @@ AuthCommand::~AuthCommand()
bool AuthCommand::saslInteract(void *in)
{
qCDebug(SMTP_LOG) << "saslInteract: ";
sasl_interact_t *interact = (sasl_interact_t *) in;
sasl_interact_t *interact = (sasl_interact_t *)in;
//some mechanisms do not require username && pass, so don't need a popup
//window for getting this info
for (; interact->id != SASL_CB_LIST_END; interact++) {
if (interact->id == SASL_CB_AUTHNAME ||
interact->id == SASL_CB_PASS) {
if (interact->id == SASL_CB_AUTHNAME
|| interact->id == SASL_CB_PASS) {
if (mAi->username.isEmpty() || mAi->password.isEmpty()) {
if (!mSMTP->openPasswordDialog(*mAi)) {
mSMTP->error(KIO::ERR_ABORTED, i18n("No authentication details supplied."));
......@@ -285,22 +279,24 @@ bool AuthCommand::saslInteract(void *in)
}
}
interact = (sasl_interact_t *) in;
interact = (sasl_interact_t *)in;
while (interact->id != SASL_CB_LIST_END) {
switch (interact->id) {
case SASL_CB_USER:
case SASL_CB_AUTHNAME: {
case SASL_CB_AUTHNAME:
{
qCDebug(SMTP_LOG) << "SASL_CB_[USER|AUTHNAME]: " << mAi->username;
const QByteArray baUserName = mAi->username.toUtf8();
interact->result = strdup(baUserName.constData());
interact->len = strlen((const char *) interact->result);
interact->len = strlen((const char *)interact->result);
break;
}
case SASL_CB_PASS: {
case SASL_CB_PASS:
{
qCDebug(SMTP_LOG) << "SASL_CB_PASS: [HIDDEN]";
const QByteArray baPassword = mAi->password.toUtf8();
interact->result = strdup(baPassword.constData());
interact->len = strlen((const char *) interact->result);
interact->len = strlen((const char *)interact->result);
break;
}
default:
......@@ -362,7 +358,7 @@ QByteArray AuthCommand::nextCommandLine(TransactionState *ts)
if (result == SASL_INTERACT) {
if (!saslInteract(client_interact)) {
return "";
};
}
}
} while (result == SASL_INTERACT);
if (result != SASL_CONTINUE && result != SASL_OK) {
......@@ -649,5 +645,4 @@ QByteArray QuitCommand::nextCommandLine(TransactionState *ts)
mNeedResponse = true;
return "QUIT\r\n";
}
} // namespace KioSMTP
......@@ -41,9 +41,7 @@ extern "C" {
#include <kio/authinfo.h>
namespace KioSMTP
{
namespace KioSMTP {
class Response;
class TransactionState;
class SMTPSessionInterface;
......@@ -145,10 +143,12 @@ public:
{
return mFlags & CloseConnectionOnError;
}
bool mustBeLastInPipeline() const
{
return mFlags & OnlyLastInPipeline;
}
bool mustBeFirstInPipeline() const
{
return mFlags & OnlyFirstInPipeline;
......@@ -200,8 +200,7 @@ public:
class AuthCommand : public Command
{
public:
AuthCommand(SMTPSessionInterface *smtp, const char *mechanisms,
const QString &aFQDN, KIO::AuthInfo &ai);
AuthCommand(SMTPSessionInterface *smtp, const char *mechanisms, const QString &aFQDN, KIO::AuthInfo &ai);
~AuthCommand();
bool doNotExecute(const TransactionState *ts) const Q_DECL_OVERRIDE;
QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
......@@ -226,8 +225,7 @@ private:
class MailFromCommand : public Command
{
public:
MailFromCommand(SMTPSessionInterface *smtp, const QByteArray &addr,
bool eightBit = false, unsigned int size = 0)
MailFromCommand(SMTPSessionInterface *smtp, const QByteArray &addr, bool eightBit = false, unsigned int size = 0)
: Command(smtp)
, mAddr(addr)
, m8Bit(eightBit)
......@@ -328,7 +326,6 @@ public:
QByteArray nextCommandLine(TransactionState *ts) Q_DECL_OVERRIDE;
};
} // namespace KioSMTP
#endif // __KIOSMTP_COMMAND_H__
......@@ -23,9 +23,7 @@
#include "smtpsessioninterface.h"
#include "smtp.h"
namespace KioSMTP
{
namespace KioSMTP {
class KioSlaveSession : public SMTPSessionInterface
{
public:
......@@ -46,7 +44,6 @@ public:
private:
SMTPProtocol *m_protocol;
};
}
#endif
......@@ -38,9 +38,7 @@
#include <assert.h>
namespace KioSMTP
{
namespace KioSMTP {
Request Request::fromURL(const QUrl &url)
{
Request request;
......@@ -192,5 +190,4 @@ QByteArray Request::headerFields(const QString &fromRealName) const
}
return result;
}
} // namespace KioSMTP
......@@ -37,9 +37,7 @@
class QUrl;
namespace KioSMTP
{
namespace KioSMTP {
class Request
{
public:
......@@ -57,10 +55,12 @@ public:
{
return mProfileName;
}
void setProfileName(const QString &profileName)
{
mProfileName = profileName;
}
bool hasProfile() const
{
return !profileName().isNull();
......@@ -70,6 +70,7 @@ public:
{
return mSubject;
}
void setSubject(const QString &subject)
{
mSubject = subject;
......@@ -79,10 +80,12 @@ public:
{
return mFromAddress;
}
void setFromAddress(const QString &fromAddress)
{
mFromAddress = fromAddress;
}
bool hasFromAddress() const
{
return !mFromAddress.isEmpty();
......@@ -92,6 +95,7 @@ public:
{
return to() + cc() + bcc();
}
bool hasRecipients() const
{
return !to().empty() || !cc().empty() || !bcc().empty();
......@@ -101,22 +105,27 @@ public:
{
return mTo;
}
QStringList cc() const
{
return mCc;
}
QStringList bcc() const
{
return mBcc;
}
void addTo(const QString &to)
{
mTo.push_back(to);
}
void addCc(const QString &cc)
{
mCc.push_back(cc);
}
void addBcc(const QString &bcc)
{
mBcc.push_back(bcc);
......@@ -126,6 +135,7 @@ public:
{
return mHeloHostname;
}
QByteArray heloHostnameCString() const;
void setHeloHostname(const QString &hostname)
{
......@@ -136,6 +146,7 @@ public:
{
return mEmitHeaders;
}
void setEmitHeaders(bool emitHeaders)
{
mEmitHeaders = emitHeaders;
......@@ -145,6 +156,7 @@ public:
{
return m8Bit;
}
void set8BitBody(bool a8Bit)
{
m8Bit = a8Bit;
......@@ -154,6 +166,7 @@ public:
{
return mSize;
}
void setSize(unsigned int size)
{
mSize = size;
......@@ -174,7 +187,6 @@ private:
bool m8Bit;
unsigned int mSize;
};
} // namespace KioSMTP
#endif // __KIOSMTP_REQUEST_H__
......@@ -36,12 +36,9 @@
#include <QByteArray>
namespace KioSMTP
{
namespace KioSMTP {
void Response::parseLine(const char *line, int len)
{
if (!isWellFormed()) {
return; // don't bother
}
......@@ -165,5 +162,4 @@ int Response::errorCode() const
}
}
}
} // namespace KioSMTP
......@@ -38,9 +38,7 @@ typedef QList<QByteArray> QCStringList;
class QString;
namespace KioSMTP
{
namespace KioSMTP {
class Response
{
public:
......@@ -56,6 +54,7 @@ public:
{
parseLine(line, qstrlen(line));
}
void parseLine(const char *line, int len);
/** Return an internationalized error message according to the
......@@ -85,14 +84,17 @@ public:
{
return mCode;
}
unsigned int first() const
{
return code() / 100;
}
unsigned int second() const
{
return (code() % 100) / 10;
}
unsigned int third() const
{
return code() % 10;
......@@ -102,10 +104,12 @@ public:
{
return first() <= 3 && first() >= 1;
}
bool isNegative() const
{
return first() == 4 || first() == 5;
}
bool isUnknown() const
{
return !isPositive() && !isNegative();
......@@ -120,6 +124,7 @@ public:
{
return mValid;
}
bool isComplete() const
{
return mSawLastLine;
......@@ -152,12 +157,13 @@ public:
#ifdef KIOSMTP_COMPARATORS
bool operator==(const Response &other) const
{
return mCode == other.mCode &&
mValid == other.mValid &&
mSawLastLine == other.mSawLastLine &&
mWellFormed == other.mWellFormed &&
mLines == other.mLines;
return mCode == other.mCode
&& mValid == other.mValid
&& mSawLastLine == other.mSawLastLine
&& mWellFormed == other.mWellFormed
&& mLines == other.mLines;
}
#endif
private:
......@@ -167,7 +173,6 @@ private:
bool mSawLastLine;
bool mWellFormed;
};
} // namespace KioSMTP
#endif // __KIOSMTP_RESPONSE_H__
......@@ -75,7 +75,7 @@ using std::unique_ptr;
#include <netdb.h>
extern "C" {
Q_DECL_EXPORT int kdemain(int argc, char **argv);
Q_DECL_EXPORT int kdemain(int argc, char **argv);
}
int kdemain(int argc, char **argv)
......@@ -98,8 +98,7 @@ int kdemain(int argc, char **argv)
return 0;
}
SMTPProtocol::SMTPProtocol(const QByteArray &pool, const QByteArray &app,
bool useSSL)
SMTPProtocol::SMTPProtocol(const QByteArray &pool, const QByteArray &app, bool useSSL)
: TCPSlaveBase(useSSL ? "smtps" : "smtp", pool, app, useSSL)
, m_sOldPort(0)
, m_opened(false)
......@@ -117,7 +116,6 @@ SMTPProtocol::~SMTPProtocol()
void SMTPProtocol::openConnection()
{
// Don't actually call smtp_open() yet. Just pretend that we are connected.
// We can't call smtp_open() here, as that does EHLO, and the EHLO command
// needs the fake hostname. However, we only get the fake hostname in put(), so
......@@ -137,8 +135,8 @@ void SMTPProtocol::special(const QByteArray &aData)
s >> what;
if (what == 'c') {
const QString response = m_sessionIface->capabilities().createSpecialResponse(
(isUsingSsl() && !isAutoSsl())
|| m_sessionIface->haveCapability("STARTTLS"));
(isUsingSsl() && !isAutoSsl())
|| m_sessionIface->haveCapability("STARTTLS"));
infoMessage(response);
} else if (what == 'N') {
if (!execute(Command::NOOP)) {
......@@ -220,7 +218,7 @@ void SMTPProtocol::put(const QUrl &url, int permissions, KIO::JobFlags flags)
}
if (request.is8BitBody()
&& !m_sessionIface->haveCapability("8BITMIME") && !m_sessionIface->eightBitMimeRequested()) {
&& !m_sessionIface->haveCapability("8BITMIME") && !m_sessionIface->eightBitMimeRequested()) {
error(KIO::ERR_SERVICE_NOT_AVAILABLE,
i18n("Your server (%1) does not support sending of 8-bit messages.\n"
"Please use base64 or quoted-printable encoding.", m_sServer));
......@@ -250,8 +248,7 @@ void SMTPProtocol::put(const QUrl &url, int permissions, KIO::JobFlags flags)
}
}
void SMTPProtocol::setHost(const QString &host, quint16 port,
const QString &user, const QString &pass)
void SMTPProtocol::setHost(const QString &host, quint16 port, const QString &user, const QString &pass)
{
m_sServer = host;
m_port = port;
......@@ -280,7 +277,6 @@ bool SMTPProtocol::sendCommandLine(const QByteArray &cmdline)
Response SMTPProtocol::getResponse(bool *ok)
{
if (ok) {
*ok = false;
}
......@@ -343,9 +339,9 @@ bool SMTPProtocol::executeQueuedCommands(TransactionState *ts)
if (cmdline.isEmpty()) {
continue;
}
if (!sendCommandLine(cmdline) ||
!batchProcessResponses(ts) ||
ts->failedFatally()) {
if (!sendCommandLine(cmdline)
|| !batchProcessResponses(ts)
|| ts->failedFatally()) {
smtp_close(false); // _hard_ shutdown
return false;
}
......@@ -368,7 +364,6 @@ QByteArray SMTPProtocol::collectPipelineCommands(TransactionState *ts)
unsigned int cmdLine_len = 0;
while (!mPendingCommandQueue.isEmpty()) {
Command *cmd = mPendingCommandQueue.head();
if (cmd->doNotExecute(ts)) {
......@@ -410,8 +405,8 @@ QByteArray SMTPProtocol::collectPipelineCommands(TransactionState *ts)
//
// 32 KB seems to be a sensible limit. Additionally, a job can only transfer
// 32 KB at once anyway.
if (dynamic_cast<TransferCommand *>(cmd) != nullptr &&
cmdLine_len >= 32 * 1024) {
if (dynamic_cast<TransferCommand *>(cmd) != nullptr
&& cmdLine_len >= 32 * 1024) {
return cmdLine;
}
}
......@@ -431,7 +426,6 @@ bool SMTPProtocol::batchProcessResponses(TransactionState *ts)
assert(ts);
while (!mSentCommandQueue.isEmpty()) {
Command *cmd = mSentCommandQueue.head();
assert(cmd->isComplete());
......@@ -469,7 +463,6 @@ bool SMTPProtocol::execute(int type, TransactionState *ts)
// ### when command queues are _not_ empty!)
bool SMTPProtocol::execute(Command *cmd, TransactionState *ts)
{
if (!cmd) {
qCritical() << "SMTPProtocol::execute() called with no command to run!";
}
......@@ -508,9 +501,9 @@ bool SMTPProtocol::execute(Command *cmd, TransactionState *ts)
return false;
}
if (!cmd->processResponse(r, ts)) {
if ((ts && ts->failedFatally()) ||
cmd->closeConnectionOnError() ||
!execute(Command::RSET)) {
if ((ts && ts->failedFatally())
|| cmd->closeConnectionOnError()
|| !execute(Command::RSET)) {
smtp_close(false);
}
return false;
......@@ -522,11 +515,11 @@ bool SMTPProtocol::execute(Command *cmd, TransactionState *ts)
bool SMTPProtocol::smtp_open(const QString &fakeHostname)
{
if (m_opened &&
m_sOldPort == m_port &&
m_sOldServer == m_sServer &&
m_sOldUser == m_sUser &&
(fakeHostname.isNull() || m_hostname == fakeHostname)) {
if (m_opened
&& m_sOldPort == m_port
&& m_sOldServer == m_sServer
&&<