mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-03 02:14:16 +00:00
Merge pull request #4831 from Chocobo1/mail_time
Fix malformed date header in email.
This commit is contained in:
commit
654c8edc6b
@ -58,9 +58,8 @@ namespace
|
|||||||
QByteArray hmacMD5(QByteArray key, const QByteArray &msg)
|
QByteArray hmacMD5(QByteArray key, const QByteArray &msg)
|
||||||
{
|
{
|
||||||
const int blockSize = 64; // HMAC-MD5 block size
|
const int blockSize = 64; // HMAC-MD5 block size
|
||||||
if (key.length() > blockSize) { // if key is longer than block size (64), reduce key length with MD5 compression
|
if (key.length() > blockSize) // if key is longer than block size (64), reduce key length with MD5 compression
|
||||||
key = QCryptographicHash::hash(key, QCryptographicHash::Md5);
|
key = QCryptographicHash::hash(key, QCryptographicHash::Md5);
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char "6"
|
QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char "6"
|
||||||
QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char "\"
|
QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char "\"
|
||||||
@ -123,18 +122,17 @@ void Smtp::sendMail(const QString &from, const QString &to, const QString &subje
|
|||||||
{
|
{
|
||||||
const Preferences* const pref = Preferences::instance();
|
const Preferences* const pref = Preferences::instance();
|
||||||
QTextCodec* latin1 = QTextCodec::codecForName("latin1");
|
QTextCodec* latin1 = QTextCodec::codecForName("latin1");
|
||||||
m_message = "";
|
m_message = "Date: " + getCurrentDateTime().toLatin1() + "\r\n"
|
||||||
m_message += encodeMimeHeader("Date", QDateTime::currentDateTime().toUTC().toString("ddd, d MMM yyyy hh:mm:ss UT"), latin1);
|
+ encodeMimeHeader("From", from, latin1)
|
||||||
m_message += encodeMimeHeader("From", from, latin1);
|
+ encodeMimeHeader("Subject", subject, latin1)
|
||||||
m_message += encodeMimeHeader("Subject", subject, latin1);
|
+ encodeMimeHeader("To", to, latin1)
|
||||||
m_message += encodeMimeHeader("To", to, latin1);
|
+ "MIME-Version: 1.0\r\n"
|
||||||
m_message += "MIME-Version: 1.0\r\n";
|
+ "Content-Type: text/plain; charset=UTF-8\r\n"
|
||||||
m_message += "Content-Type: text/plain; charset=UTF-8\r\n";
|
+ "Content-Transfer-Encoding: base64\r\n"
|
||||||
m_message += "Content-Transfer-Encoding: base64\r\n";
|
+ "\r\n";
|
||||||
m_message += "\r\n";
|
|
||||||
// Encode the body in base64
|
// Encode the body in base64
|
||||||
QString crlf_body = body;
|
QString crlf_body = body;
|
||||||
QByteArray b = crlf_body.replace("\n","\r\n").toUtf8().toBase64();
|
QByteArray b = crlf_body.replace("\n", "\r\n").toUtf8().toBase64();
|
||||||
int ct = b.length();
|
int ct = b.length();
|
||||||
for (int i = 0; i < ct; i += 78)
|
for (int i = 0; i < ct; i += 78)
|
||||||
m_message += b.mid(i, 78);
|
m_message += b.mid(i, 78);
|
||||||
@ -154,10 +152,10 @@ void Smtp::sendMail(const QString &from, const QString &to, const QString &subje
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#endif
|
#endif
|
||||||
m_socket->connectToHost(pref->getMailNotificationSMTP(), DEFAULT_PORT);
|
m_socket->connectToHost(pref->getMailNotificationSMTP(), DEFAULT_PORT);
|
||||||
m_useSsl = false;
|
m_useSsl = false;
|
||||||
#ifndef QT_NO_OPENSSL
|
#ifndef QT_NO_OPENSSL
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +184,7 @@ void Smtp::readyRead()
|
|||||||
ehlo();
|
ehlo();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logError("Connection failed, unrecognized reply: "+line);
|
logError("Connection failed, unrecognized reply: " + line);
|
||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -223,7 +221,7 @@ void Smtp::readyRead()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Authentication failed!
|
// Authentication failed!
|
||||||
logError("Authentication failed, msg: "+line);
|
logError("Authentication failed, msg: " + line);
|
||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -234,7 +232,7 @@ void Smtp::readyRead()
|
|||||||
m_state = Data;
|
m_state = Data;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logError("<mail from> was rejected by server, msg: "+line);
|
logError("<mail from> was rejected by server, msg: " + line);
|
||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -245,7 +243,7 @@ void Smtp::readyRead()
|
|||||||
m_state = Body;
|
m_state = Body;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logError("<Rcpt to> was rejected by server, msg: "+line);
|
logError("<Rcpt to> was rejected by server, msg: " + line);
|
||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -256,7 +254,7 @@ void Smtp::readyRead()
|
|||||||
m_state = Quit;
|
m_state = Quit;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logError("<data> was rejected by server, msg: "+line);
|
logError("<data> was rejected by server, msg: " + line);
|
||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -268,7 +266,7 @@ void Smtp::readyRead()
|
|||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logError("Message was rejected by the server, error: "+line);
|
logError("Message was rejected by the server, error: " + line);
|
||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -309,9 +307,9 @@ QByteArray Smtp::encodeMimeHeader(const QString &key, const QString &value, QTex
|
|||||||
line += "=?utf-8?b?";
|
line += "=?utf-8?b?";
|
||||||
for (int i = 0; i < ct; i += 4) {
|
for (int i = 0; i < ct; i += 4) {
|
||||||
/*if (line.length() > 72) {
|
/*if (line.length() > 72) {
|
||||||
rv += line + "?\n\r";
|
rv += line + "?\n\r";
|
||||||
line = " =?utf-8?b?";
|
line = " =?utf-8?b?";
|
||||||
}*/
|
}*/
|
||||||
line = line + base64.mid(i, 4);
|
line = line + base64.mid(i, 4);
|
||||||
}
|
}
|
||||||
line += "?="; // end encoded-word atom
|
line += "?="; // end encoded-word atom
|
||||||
@ -347,7 +345,7 @@ void Smtp::parseEhloResponse(const QByteArray &code, bool continued, const QStri
|
|||||||
else {
|
else {
|
||||||
// Both EHLO and HELO failed, chances are this is NOT
|
// Both EHLO and HELO failed, chances are this is NOT
|
||||||
// a SMTP server
|
// a SMTP server
|
||||||
logError("Both EHLO and HELO failed, msg: "+line);
|
logError("Both EHLO and HELO failed, msg: " + line);
|
||||||
m_state = Close;
|
m_state = Close;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -362,7 +360,7 @@ void Smtp::parseEhloResponse(const QByteArray &code, bool continued, const QStri
|
|||||||
else {
|
else {
|
||||||
// greeting followed by extensions
|
// greeting followed by extensions
|
||||||
m_state = EhloGreetReceived;
|
m_state = EhloGreetReceived;
|
||||||
qDebug () << "EHLO greet received";
|
qDebug() << "EHLO greet received";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,7 +417,7 @@ void Smtp::authenticate()
|
|||||||
// Skip authentication
|
// Skip authentication
|
||||||
logError("The SMTP server does not seem to support any of the authentications modes "
|
logError("The SMTP server does not seem to support any of the authentications modes "
|
||||||
"we support [CRAM-MD5|PLAIN|LOGIN], skipping authentication, "
|
"we support [CRAM-MD5|PLAIN|LOGIN], skipping authentication, "
|
||||||
"knowing it is likely to fail... Server Auth Modes: "+auth.join("|"));
|
"knowing it is likely to fail... Server Auth Modes: " + auth.join("|"));
|
||||||
m_state = Authenticated;
|
m_state = Authenticated;
|
||||||
// At this point the server will not send any response
|
// At this point the server will not send any response
|
||||||
// So fill the buffer with a fake one to pass the tests
|
// So fill the buffer with a fake one to pass the tests
|
||||||
@ -450,7 +448,7 @@ void Smtp::authCramMD5(const QByteArray& challenge)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
QByteArray response = m_username.toLatin1() + ' '
|
QByteArray response = m_username.toLatin1() + ' '
|
||||||
+ hmacMD5(m_password.toLatin1(), QByteArray::fromBase64(challenge)).toHex();
|
+ hmacMD5(m_password.toLatin1(), QByteArray::fromBase64(challenge)).toHex();
|
||||||
m_socket->write(response.toBase64() + "\r\n");
|
m_socket->write(response.toBase64() + "\r\n");
|
||||||
m_socket->flush();
|
m_socket->flush();
|
||||||
m_state = AuthSent;
|
m_state = AuthSent;
|
||||||
@ -470,7 +468,7 @@ void Smtp::authPlain()
|
|||||||
auth += m_password.toLatin1();
|
auth += m_password.toLatin1();
|
||||||
qDebug() << "password: " << m_password.toLatin1();
|
qDebug() << "password: " << m_password.toLatin1();
|
||||||
// Send it
|
// Send it
|
||||||
m_socket->write("auth plain "+ auth.toBase64() + "\r\n");
|
m_socket->write("auth plain " + auth.toBase64() + "\r\n");
|
||||||
m_socket->flush();
|
m_socket->flush();
|
||||||
m_state = AuthSent;
|
m_state = AuthSent;
|
||||||
}
|
}
|
||||||
@ -501,3 +499,29 @@ void Smtp::logError(const QString &msg)
|
|||||||
qDebug() << "Email Notification Error:" << msg;
|
qDebug() << "Email Notification Error:" << msg;
|
||||||
Logger::instance()->addMessage(tr("Email Notification Error:") + " " + msg, Log::CRITICAL);
|
Logger::instance()->addMessage(tr("Email Notification Error:") + " " + msg, Log::CRITICAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Smtp::getCurrentDateTime() const
|
||||||
|
{
|
||||||
|
// return date & time in the format specified in RFC 2822, section 3.3
|
||||||
|
const QDateTime nowDateTime = QDateTime::currentDateTime();
|
||||||
|
const QDate nowDate = nowDateTime.date();
|
||||||
|
const QLocale eng(QLocale::English);
|
||||||
|
|
||||||
|
QString timeStr = nowDateTime.time().toString("HH:mm:ss");
|
||||||
|
QString weekDayStr = eng.dayName(nowDate.dayOfWeek(), QLocale::ShortFormat);
|
||||||
|
QString dayStr = QString::number(nowDate.day());
|
||||||
|
QString monthStr = eng.monthName(nowDate.month(), QLocale::ShortFormat);
|
||||||
|
QString yearStr = QString::number(nowDate.year());
|
||||||
|
|
||||||
|
QDateTime tmp = nowDateTime;
|
||||||
|
tmp.setTimeSpec(Qt::UTC);
|
||||||
|
int timeOffsetHour = nowDateTime.secsTo(tmp) / 3600;
|
||||||
|
int timeOffsetMin = nowDateTime.secsTo(tmp) / 60 - (60 * timeOffsetHour);
|
||||||
|
int timeOffset = timeOffsetHour * 100 + timeOffsetMin;
|
||||||
|
char buf[6] = {0};
|
||||||
|
std::snprintf(buf, sizeof(buf), "%+05d", timeOffset);
|
||||||
|
QString timeOffsetStr = buf;
|
||||||
|
|
||||||
|
QString ret = weekDayStr + ", " + dayStr + " " + monthStr + " " + yearStr + " " + timeStr + " " + timeOffsetStr;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -102,6 +102,7 @@ namespace Net
|
|||||||
void authPlain();
|
void authPlain();
|
||||||
void authLogin();
|
void authLogin();
|
||||||
void logError(const QString &msg);
|
void logError(const QString &msg);
|
||||||
|
QString getCurrentDateTime() const;
|
||||||
|
|
||||||
QByteArray m_message;
|
QByteArray m_message;
|
||||||
#ifndef QT_NO_OPENSSL
|
#ifndef QT_NO_OPENSSL
|
||||||
|
Loading…
x
Reference in New Issue
Block a user