Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.9.1 - Qt Creator : 4.4.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

Envoi de mail avec Qt/C++

2»

Réponses

  • Bonjour,
    le port 25 sans authentification a toujours quelques restrictions, et elles sont différentes selon le fournisseur du service.
    L'un va limiter l'envoi pour seulement les destinataires du nom de domaine,
    l'autre va le permettre qu'en php et pas les autres langages,
    Et pour finir, le nombre possible de mails pouvant être envoyé peut être limité
    En tout cas, il me semble que majoritairement il faut être connecté avec la FAI pour utiliser son port 25, quelquefois le port 25 d'une autre FAI n'est pas utilisable, que l'adresse de l'expéditeur doit effectivement être @fai.xx
    Mieux vaut utiliser un port utilisant SSL ou TLS avec authentification.
  • Si c’est le cas, il faut du coups que la machine se connecte au moins une fois et à chaque changement d'adresse IP, avec le MdP sur un navigateur web par exemple.
    Très discutable comme stratégie de sécurité.
    On est loin des méthodes de double vérification que propose google par exemple.
  • Si c’est le cas, il faut du coups que la machine se connecte au moins une fois et à chaque changement d'adresse IP, avec le MdP sur un navigateur web par exemple.
    J'ai pas compris, les limitations du port 25 doivent sûrement se faire côté serveur mail. Le client est passif dans le processus.
  • Bonjour,
    Sur Linux avec Qt 4.8 le code Qt fourni dans ce post ne fonctionne pas.
    Erreur 13 protocol inconnu
    Que faire ?
  • 23 Feb modifié
    Bonjour,

    Je n'ai pas regardé toute la conversation, mais personnellement j'utilise cette classe. Pour l'authentification, j'utilise ma propre adresse mail. Sans authentification, cela passe souvent en spam. Je ne sais pas si cela répond à ta question.

    le .cpp
    #include "smtp.h"

    Smtp::Smtp(const QString &user, const QString &pass, const QString &host, int port, int timeout)
    {
    qDebug()<<"Initialisation des parametres";

    socket = new QSslSocket(this);

    connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    connect(socket, SIGNAL(connected()), this, SLOT(connected() ) );
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,SLOT(errorReceived(QAbstractSocket::SocketError)));
    connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(stateChanged(QAbstractSocket::SocketState)));
    connect(socket, SIGNAL(disconnected()), this,SLOT(disconnected()));

    this->user = user;
    this->pass = pass;
    this->host = host;
    this->port = port;
    this->timeout = timeout;

    }
    void Smtp::sendMail(const QString &from, const QString &to, const QString &subject, const QString &body)
    {
    message = "To: " + to + "\n";
    message.append("From: " + from + "\n");
    message.append("Subject: " + subject + "\n");
    message.append(body);
    message.replace( QString::fromLatin1( "\n" ), QString::fromLatin1( "\r\n" ) );
    message.replace( QString::fromLatin1( "\r\n.\r\n" ),
    QString::fromLatin1( "\r\n..\r\n" ) );
    this->from = from;
    rcpt = to;
    state = Init;
    socket->connectToHostEncrypted(host, port); //"smtp.gmail.com" and 465 for gmail TLS
    if (!socket->waitForConnected(timeout))
    {
    // qDebug() << socket->errorString();
    }

    t = new QTextStream( socket );

    }

    Smtp::~Smtp()
    {
    //delete t;
    //delete socket;
    }
    void Smtp::stateChanged(QAbstractSocket::SocketState socketState)
    {

    qDebug()<<"L'état du soket change : "<< socketState;
    }

    void Smtp::errorReceived(QAbstractSocket::SocketError socketError)
    {
    qDebug()<<socketError;
    }

    void Smtp::disconnected()
    {
    qDebug()<<"Deconnection du smtp";
    qDebug()<<socket->errorString();
    }

    void Smtp::connected()
    {
    qDebug() << "Connected ";
    }

    void Smtp::readyRead()
    {

    qDebug()<<"readyRead()";
    // 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
    *t << "EHLO localhost" <<"\r\n";
    t->flush();

    state = HandShake;
    }
    //No need, because I'm using socket->startClienEncryption() which makes the SSL handshake for you
    /*
    else if (state == Tls && responseLine == "250")
    {
    // Trying AUTH
    qDebug() << "STarting Tls";
    *t << "STARTTLS" << "\r\n";
    t->flush();
    state = HandShake;
    }*/
    else if (state == HandShake && responseLine == "250")
    {
    socket->startClientEncryption();
    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() << "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("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("Failed to send message");
    }
    response = "";
    }
    le .h
    #ifndef SMTP_H
    #define SMTP_H

    #include <QSsl>
    #include <QtNetwork/qsslsocket.h>
    #include <QAbstractSocket>
    #include <QTcpSocket>
    #include <QString>
    #include <QTextStream>
    #include <QDebug>
    #include <QMessageBox>
    #include <QByteArray>

    class Smtp : public QObject
    {
    Q_OBJECT


    public:

    Smtp( const QString &user, const QString &pass, const QString &host, int port, int timeout);
    ~Smtp();

    void sendMail( const QString &from, const QString &to,const QString &subject, const QString &body);


    signals:
    void status(QString);

    private slots:
    void stateChanged(QAbstractSocket::SocketState socketState);
    void errorReceived(QAbstractSocket::SocketError socketError);
    void connected();
    void readyRead();
    void disconnected();

    private:
    int timeout;
    QString message;
    QTextStream *t;
    QSslSocket *socket;
    QString from;
    QString rcpt;
    QString response;
    QString user;
    QString pass;
    QString host;
    int port;
    enum states{Tls, HandShake ,Auth,User,Pass,Rcpt,Mail,Data,Init,Body,Quit,Close};
    int state;

    };
    #endif
    Puis,
    smtp = new Smtp("TonAdresseMail","Code","ServeurSMTP",465,3000);
    smtp->sendMail("Expéditeur","Destinataire", "Objet","CorpDuMail");
    Edit

    Ne pas oublier QT += network dans le .pro et installer openSSL je crois
    #include <QtNetwork/qsslsocket.h>
  • 23 Feb modifié
    Bonjour,
    Avec le code Qt j'obtiens :
    la connection OK mais :
    error "Error during SSL handshake: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol"

    Avec Qt 4.8 sur Linux, Windows et Mac.
  • Je suis novice sous Qt, donc tout ce que je dis est a prendre avec des "pincettes".
    Ecoute surtout les pontes qui te répondront après moi.
    Pour utiliser SSL avec Qt, il faut recompiler ce dernier afin qu'il incorpore les bonnes libs.
    de mon coté, voici ce que j'ai fait pour que cela fonctionne :
    forum.qtfr.org/discussion/18865/qt-static-et-openssl#latest
    encore une fois, je ne suis pas le meilleur pour te répondre.
  • Bonjour,
    Ca y est cela marche. Le problème venait de mon compte mail d'envoi smtp il n'y avait pas la sécurité SSL/TLS cochée. Avec cette option active tout fonctionne.

    Merci.
Connectez-vous ou Inscrivez-vous pour répondre.