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.com
D/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 TLS
D/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 encrypted
D/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
Bookmarks