Send Email with smtp tls connection
-
hi everybody.
i want to send email via smtp connection and use tls (STARTTLS) like gmail on port 587
everything is fine before starttls. and when i send starttls handshake to server
server response me with 220 response code but i cant encrypt the connection.here is my code :
socket->connectToHost(host, port);
.
.
.
.
.
.// SMTP is line-oriented
QString responseLine;
do
{
responseLine = socket->readLine();
response += responseLine;
}
while ( socket->canReadLine() && responseLine[3] != ' ' );responseLine.truncate( 3 );
qDebug() << "Server response code:" << responseLine;
qDebug() << "Server response: " << response;if ( state == Init && responseLine == "220" )
{
// banner was okay, let's go on
qDebug() <<"banner was okay, let's go on ";
*t << "EHLO kayer.co.ir" <<"\r\n";
t->flush();state = Tls;
}
//No need, because I'm using socket->startClienEncryption() which makes the SSL handshake for you
else if (state == Tls && responseLine == "250")
{
// Trying AUTH
qDebug() <<"Trying AUTH ";
qDebug() << "STarting Tls";
*t << "STARTTLS" << "\r\n";
t->flush();
state = HandShake;
}
else if (state == HandShake && responseLine == "220")
{
qDebug() <<"Send EHLO once again but now encrypted";
socket->startClientEncryption();
// socket->connectToHostEncrypted(host, port);
// socket->encryptedBytesAvailable();
// socket->encrypted();
if(!socket->waitForEncrypted(timeout))
{
qDebug() << socket->errorString();
state = Close;
}//Send EHLO once again but now encrypted
*t << "EHLO localhost" << "\r\n";
t->flush();
state = Auth;
}
else if (state == Auth && responseLine == "250")
{
// Trying AUTH
qDebug() <<"Trying AUTH";
qDebug() << "Auth";
*t << "AUTH LOGIN" << "\r\n";
t->flush();
state = User;
}
else if (state == User && responseLine == "334")
{
//Trying User
qDebug() << "Username";
//GMAIL is using XOAUTH2 protocol, which basically means that password and username has to be sent in base64 coding
//https://developers.google.com/gmail/xoauth2_protocol
*t << QByteArray().append(user).toBase64() << "\r\n";
t->flush();state = Pass;
}
else if (state == Pass && responseLine == "334")
{
//Trying pass
qDebug() << "Pass";
*t << QByteArray().append(pass).toBase64() << "\r\n";
t->flush();state = Mail;
}
else if ( state == Mail && responseLine == "235" )
{
// HELO response was okay (well, it has to be)//Apperantly for Google it is mandatory to have MAIL FROM and RCPT email formated the following way -> email@gmail.com
qDebug() << "MAIL FROM:<" << from << ">";
*t << "MAIL FROM:<" << from << ">\r\n";
t->flush();
state = Rcpt;
}
else if ( state == Rcpt && responseLine == "250" )
{
//Apperantly for Google it is mandatory to have MAIL FROM and RCPT email formated the following way -> email@gmail.com
*t << "RCPT TO:<" << rcpt << ">\r\n"; //r
t->flush();
state = Data;
}
else if ( state == Data && responseLine == "250" )
{*t << "DATA\r\n";
t->flush();
state = Body;
}
else if ( state == Body && responseLine == "354" )
{*t << message << "\r\n.\r\n";
t->flush();
state = Quit;
}
else if ( state == Quit && responseLine == "250" )
{*t << "QUIT\r\n";
t->flush();
// here, we just close.
state = Close;
emit status( tr( "Message sent" ) );
}
else if ( state == Close )
{
deleteLater();
return;
}
else
{
// something broke.
QMessageBox::warning( 0, tr( "Qt Simple SMTP client" ), tr( "Unexpected reply from SMTP server:\n\n" ) + response );
state = Close;
emit status( tr( "Failed to send message" ) );
}
response = "";===============================================
and this is my debugging :
..
..
..D/Qt ( 9333): smtp.cpp:55 (void Smtp::stateChanged(QAbstractSocket::SocketState)): stateChanged
D/Qt ( 9333): smtp.cpp:56 (void Smtp::stateChanged(QAbstractSocket::SocketState)): stateChanged QAbstractSocket::HostLookupState
D/Qt ( 9333): smtp.cpp:55 (void Smtp::stateChanged(QAbstractSocket::SocketState)): stateChanged
D/Qt ( 9333): smtp.cpp:56 (void Smtp::stateChanged(QAbstractSocket::SocketState)): stateChanged QAbstractSocket::ConnectingState
D/Qt ( 9333): smtp.cpp:55 (void Smtp::stateChanged(QAbstractSocket::SocketState)): stateChanged
D/Qt ( 9333): smtp.cpp:56 (void Smtp::stateChanged(QAbstractSocket::SocketState)): stateChanged QAbstractSocket::ConnectedState
D/Qt ( 9333): smtp.cpp:74 (void Smtp::connected()): Connected
D/Qt ( 9333): smtp.cpp:80 (void Smtp::readyRead()): readyRead
D/Qt ( 9333): smtp.cpp:93 (void Smtp::readyRead()): Server response code: "220"
D/Qt ( 9333): smtp.cpp:94 (void Smtp::readyRead()): Server response: "220 mail.ABC.com ESMTP Postfix (Debian/GNU)D/Qt ( 9333): "
D/Qt ( 9333): smtp.cpp:100 (void Smtp::readyRead()): banner was okay, let's go on
D/Qt ( 9333): smtp.cpp:80 (void Smtp::readyRead()): readyRead
D/Qt ( 9333): smtp.cpp:93 (void Smtp::readyRead()): Server response code: "250"
D/Qt ( 9333): smtp.cpp:94 (void Smtp::readyRead()): Server response: "250-mail.ABC.comD/Qt ( 9333): 250-PIPELINING
D/Qt ( 9333): 250-SIZE 35728640
D/Qt ( 9333): 250-ETRN
D/Qt ( 9333): 250-STARTTLS
D/Qt ( 9333): 250-ENHANCEDSTATUSCODES
D/Qt ( 9333): 250-8BITMIME
D/Qt ( 9333): 250 DSN
D/Qt ( 9333): "
D/Qt ( 9333): smtp.cpp:110 (void Smtp::readyRead()): Trying AUTH
D/Qt ( 9333): smtp.cpp:111 (void Smtp::readyRead()): STarting Tls
D/Qt ( 9333): smtp.cpp:80 (void Smtp::readyRead()): readyRead
D/Qt ( 9333): smtp.cpp:93 (void Smtp::readyRead()): Server response code: "220"
D/Qt ( 9333): smtp.cpp:94 (void Smtp::readyRead()): Server response: "220 2.0.0 Ready to start TLSD/Qt ( 9333): "
D/Qt ( 9333): smtp.cpp:95 (void Smtp::readyRead()): state: 1
D/Qt ( 9333): smtp.cpp:118 (void Smtp::readyRead()): Send EHLO once again but now encryptedD/Qt ( 9333): smtp.cpp:61 (void Smtp::errorReceived(QAbstractSocket::SocketError)) : error
D/Qt ( 9333): smtp.cpp:62 (void Smtp::errorReceived(QAbstractSocket::SocketError)) : error QAbstractSocket::SocketTimeoutError
D/Qt ( 9333): smtp.cpp:126 (void Smtp::readyRead()): "Network operation timed out"===========================
thanks for your attention and any idea will be appreciate -
unless you are vested in writing your own, Tokes Attila has written a pretty good library https://github.com/bluetiger9/SmtpClient-for-Qt
-
yes, I had to compile openssl 1.0.2d and Qt has to be built for openssl shared. I had to get libz to build openssl.
openssl config that I needed:
cd /home/jandle/Documents/Code/openssl-1.0.2d
export INSTALLDIR=/opt/CodeSourcery/bin
export PATH=$INSTALLDIR/bin:$PATH
export BUILDMACH=i686-pc-linux-gnu
export CROSS=arm-none-linux-gnueabi-
export CC=${CROSS}gcc
export LD=${CROSS}ld
export AS=${CROSS}as
export AR=${CROSS}ar
./Configure threads shared zlib linux-armv4 --openssldir=/home/isaw/sslQT build options I used:
cd /home/jandle/Documents/Code/QtArm./configure -release -no-qml-debug -prefix ../Libs/QtArm -opensource -confirm-license -shared -no-largefile -gui -widgets -plugin-sql-mysql -openssl -continue -xplatform arm-none-linux-gnueabi-g++ -platform linux-g++ -device-option CROSS_COMPILE=/opt/CodeSourcery/bin/arm-none-linux-gnueabi- -no-compile-examples -no-warnings-are-errors -no-pch -no-dbus -no-sse2 -no-cups -no-nis -no-xcb -no-eglfs -linuxfb -no-kms -no-opengl -system-proxies -qtlibinfix arm -l rt -qpa linuxfb -fontconfig -qt-freetype -I /home/jandle/Documents/Code/openssl-1.0.2d/include/ -silent -L /home/isaw/lib -qt-zlib
I need to do a diff to see if I edited SMTPEmail to make it compile and link. I know I had issues at first but I tried to keep all changes in my app side of the calls. I know I added printf debug statements.
-
hi , i have a problem like this, can u help me plz ?
my code is about send mail in smtp - tls connection on port 587 , but i have problem when i use socket->startClientEncryption(); and then i have timeout error.
plz help me about that. thank u
@Alux yes, I had timeout errors before I got openssl working.
-
thanks alot for your reply. but when i use QSslSocket::supportsSsl(); this is return True, and my system is has openssl package. but in linux and in windows i have problem after sending starttls command to server and server send me HandShake accept and then i use startClientEncryption and then i have connection timeout ...
-
@Alux yes, I had timeout errors before I got openssl working.
@Jeff-Andle thanks alot for your reply. but when i use QSslSocket::supportsSsl(); this is return True, and my system is has openssl package. but in linux and in windows i have problem after sending starttls command to server and server send me HandShake accept and then i use startClientEncryption and then i have connection timeout ...
-
Alex, I recently updated openssl to the latest rev over a security issue and have broken my app. I just today got back to where there isn't a seg fault and inside the library I am getting:
""The host name did not match any of the valid hosts for this certificate"
Socket error sending Ready Message"You might want to put in some console debugging to see what is returned in the error slots.
I did find a link about the certificates and hope I have time to address it before I travel at the end of the week.