|
|
@ -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 "\"
|
|
|
@ -133,7 +132,7 @@ void Smtp::sendMail(const QString &from, const QString &to, const QString &subje |
|
|
|
+ "\r\n"; |
|
|
|
+ "\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); |
|
|
@ -153,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 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -185,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; |
|
|
@ -222,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; |
|
|
@ -233,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; |
|
|
@ -244,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; |
|
|
@ -255,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; |
|
|
@ -267,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; |
|
|
@ -308,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
|
|
|
@ -346,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; |
|
|
@ -361,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; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -418,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
|
|
|
@ -449,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; |
|
|
@ -469,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; |
|
|
|
} |
|
|
|
} |
|
|
|