Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Send Email with smtp tls connection
QtWS25 Last Chance

Send Email with smtp tls connection

Scheduled Pinned Locked Moved Mobile and Embedded
9 Posts 2 Posters 6.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Alux
    wrote on last edited by
    #1

    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

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jeff Andle
      wrote on last edited by
      #2

      unless you are vested in writing your own, Tokes Attila has written a pretty good library https://github.com/bluetiger9/SmtpClient-for-Qt

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Alux
        wrote on last edited by
        #3

        hi, im not writing my code from first , i m using the open source library as u attention it.
        but i dont know why all thems not working in my system.
        i install qt 5.2 . should i add some library to it ?? for example openssl !

        1 Reply Last reply
        0
        • A Offline
          A Offline
          Alux
          wrote on last edited by
          #4

          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

          J 1 Reply Last reply
          0
          • J Offline
            J Offline
            Jeff Andle
            wrote on last edited by
            #5

            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/ssl

            QT 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.

            1 Reply Last reply
            0
            • A Alux

              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

              J Offline
              J Offline
              Jeff Andle
              wrote on last edited by
              #6

              @Alux yes, I had timeout errors before I got openssl working.

              A 1 Reply Last reply
              0
              • A Offline
                A Offline
                Alux
                wrote on last edited by
                #7

                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 ...

                1 Reply Last reply
                0
                • J Jeff Andle

                  @Alux yes, I had timeout errors before I got openssl working.

                  A Offline
                  A Offline
                  Alux
                  wrote on last edited by
                  #8

                  @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 ...

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    Jeff Andle
                    wrote on last edited by
                    #9

                    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.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved