Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Send Email with smtp tls connection

    Mobile and Embedded
    2
    9
    5271
    Loading More Posts
    • 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
      Alux last edited by

      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 Reply Quote 0
      • J
        Jeff Andle last edited by

        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 Reply Quote 0
        • A
          Alux last edited by

          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 Reply Quote 0
          • A
            Alux last edited by

            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 Reply Quote 0
            • J
              Jeff Andle last edited by

              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 Reply Quote 0
              • J
                Jeff Andle @Alux last edited by

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

                A 1 Reply Last reply Reply Quote 0
                • A
                  Alux last edited by

                  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 Reply Quote 0
                  • A
                    Alux @Jeff Andle last edited by

                    @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 Reply Quote 0
                    • J
                      Jeff Andle last edited by

                      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 Reply Quote 0
                      • First post
                        Last post