|
|
@ -48,6 +48,7 @@ |
|
|
|
#include <QNetworkInterface> |
|
|
|
#include <QNetworkInterface> |
|
|
|
#include <QCryptographicHash> |
|
|
|
#include <QCryptographicHash> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
const short DEFAULT_PORT = 25; |
|
|
|
const short DEFAULT_PORT = 25; |
|
|
|
const short DEFAULT_PORT_SSL = 465; |
|
|
|
const short DEFAULT_PORT_SSL = 465; |
|
|
|
|
|
|
|
|
|
|
@ -76,6 +77,20 @@ QByteArray hmacMD5(QByteArray key, const QByteArray &msg) |
|
|
|
return QCryptographicHash::hash(total, QCryptographicHash::Md5); |
|
|
|
return QCryptographicHash::hash(total, QCryptographicHash::Md5); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray determineLocalAddress() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QByteArray address = "127.0.0.1"; |
|
|
|
|
|
|
|
foreach (const QHostAddress& addr, QNetworkInterface::allAddresses()) { |
|
|
|
|
|
|
|
if (addr == QHostAddress::LocalHost || addr == QHostAddress::LocalHostIPv6) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
address = addr.toString().toLatin1(); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return address; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
|
|
Smtp::Smtp(QObject *parent): QObject(parent), |
|
|
|
Smtp::Smtp(QObject *parent): QObject(parent), |
|
|
|
state(Init), use_ssl(false) { |
|
|
|
state(Init), use_ssl(false) { |
|
|
|
#ifndef QT_NO_OPENSSL |
|
|
|
#ifndef QT_NO_OPENSSL |
|
|
@ -290,20 +305,20 @@ QByteArray Smtp::encode_mime_header(const QString& key, const QString& value, QT |
|
|
|
|
|
|
|
|
|
|
|
void Smtp::ehlo() |
|
|
|
void Smtp::ehlo() |
|
|
|
{ |
|
|
|
{ |
|
|
|
QByteArray address = "127.0.0.1"; |
|
|
|
QByteArray address = determineLocalAddress(); |
|
|
|
foreach (const QHostAddress& addr, QNetworkInterface::allAddresses()) |
|
|
|
socket->write("ehlo " + address + "\r\n"); |
|
|
|
{ |
|
|
|
|
|
|
|
if (addr == QHostAddress::LocalHost || addr == QHostAddress::LocalHostIPv6) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
address = addr.toString().toLatin1(); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Send EHLO
|
|
|
|
|
|
|
|
socket->write("ehlo "+ address + "\r\n"); |
|
|
|
|
|
|
|
socket->flush(); |
|
|
|
socket->flush(); |
|
|
|
state = EhloSent; |
|
|
|
state = EhloSent; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Smtp::helo() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QByteArray address = determineLocalAddress(); |
|
|
|
|
|
|
|
socket->write("helo " + address + "\r\n"); |
|
|
|
|
|
|
|
socket->flush(); |
|
|
|
|
|
|
|
state = HeloSent; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Smtp::parseEhloResponse(const QByteArray& code, bool continued, const QString& line) |
|
|
|
void Smtp::parseEhloResponse(const QByteArray& code, bool continued, const QString& line) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (code != "250") { |
|
|
|
if (code != "250") { |
|
|
@ -311,9 +326,7 @@ void Smtp::parseEhloResponse(const QByteArray& code, bool continued, const QStri |
|
|
|
if (state == EhloSent) { |
|
|
|
if (state == EhloSent) { |
|
|
|
// try to send HELO instead of EHLO
|
|
|
|
// try to send HELO instead of EHLO
|
|
|
|
qDebug() << "EHLO failed, trying HELO instead..."; |
|
|
|
qDebug() << "EHLO failed, trying HELO instead..."; |
|
|
|
socket->write("helo\r\n"); |
|
|
|
helo(); |
|
|
|
socket->flush(); |
|
|
|
|
|
|
|
state = HeloSent; |
|
|
|
|
|
|
|
} 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
|
|
|
|