Projet Bee-Honey't  1.0
BTS SN 2019
Types publics | Fonctions membres publiques | Attributs publics | Liste de tous les membres
Référence de la classe SimpleMail::SenderPrivate

#include <sender_p.h>

Graphe de collaboration de SimpleMail::SenderPrivate:
Collaboration graph

Types publics

enum  State { Error, Disconnected, Connected, Ready }
 

Fonctions membres publiques

 SenderPrivate (Sender *parent)
 
bool sendMail (MimeMessage &email)
 
void sendMessage (const QByteArray &data)
 
bool connectToHost ()
 
bool login ()
 
bool waitForResponse (int expectedCode)
 
bool processState ()
 
void setPeerVerificationType (const Sender::PeerVerificationType &type)
 

Attributs publics

State state = State::Disconnected
 
Senderq_ptr
 
QTcpSocket * socket = nullptr
 
QString lastError
 
QString host = QLatin1String("localhost")
 
int port = 25
 
Sender::ConnectionType connectionType
 
QString name = QHostInfo::localHostName()
 
Sender::PeerVerificationType peerVerificationType = Sender::VerifyPeer
 
QString user
 
QString password
 
Sender::AuthMethod authMethod = Sender::AuthNone
 
int connectionTimeout = 5000
 
int responseTimeout = 5000
 
int sendMessageTimeout = 60000
 
QByteArray responseText
 
int responseCode
 

Documentation des énumérations membres

◆ State

Valeurs énumérées
Error 
Disconnected 
Connected 
Ready 
33  {
34  Error,
36  Connected,
37  Ready
38  };
Definition: sender_p.h:34
Definition: sender_p.h:37
Definition: sender_p.h:36

Documentation des constructeurs et destructeur

◆ SenderPrivate()

SenderPrivate::SenderPrivate ( Sender parent)
262  :
263  q_ptr(parent)
264 {
265 
266 }
Sender * q_ptr
Definition: sender_p.h:50

Documentation des fonctions membres

◆ connectToHost()

bool SenderPrivate::connectToHost ( )

Références Connected, connectionTimeout, SimpleMail::Sender::ConnectionTimeoutError, connectionType, host, lastError, name, port, sendMessage(), SimpleMail::Sender::ServerError, socket, SimpleMail::Sender::SslConnection, state, SimpleMail::Sender::TcpConnection, SimpleMail::Sender::TlsConnection, et waitForResponse().

Référencé par processState().

349 {
350  Q_Q(Sender);
351 
352  QSslSocket *sslSock = nullptr;
353  switch (connectionType) {
356  qCDebug(SIMPLEMAIL_SENDER) << "Connecting to host" << host << port;
357  socket->connectToHost(host, port);
358  break;
360  {
361  sslSock = qobject_cast<QSslSocket*>(socket);
362  if (sslSock) {
363  qCDebug(SIMPLEMAIL_SENDER) << "Connecting to host encrypted" << host << port;
364  sslSock->connectToHostEncrypted(host, port);
365  } else {
366  return false;
367  }
368  }
369  break;
370  }
371 
372  // Tries to connect to server
373  if (!socket->waitForConnected(connectionTimeout)) {
374  lastError = socket->errorString();
375  qCDebug(SIMPLEMAIL_SENDER) << "Connection failed" << socket->errorString();
376  Q_EMIT q->smtpError(Sender::ConnectionTimeoutError);
377  return false;
378  }
379 
380  // If the response code is not 220 (Service ready)
381  // means that is something wrong with the server
382  if (!waitForResponse(220)) {
383  Q_EMIT q->smtpError(Sender::ServerError);
384  return false;
385  }
386 
387  qCDebug(SIMPLEMAIL_SENDER) << "Sending EHLO" << name;
388  // Send a EHLO/HELO message to the server
389  // The client's first command must be EHLO/HELO
390  sendMessage("EHLO " + name.toLatin1());
391 
392  // The response code needs to be 250.
393  if (!waitForResponse(250)) {
394  Q_EMIT q->smtpError(Sender::ServerError);
395  return false;
396  }
397  qCDebug(SIMPLEMAIL_SENDER) << "Sent hello";
398 
400  qCDebug(SIMPLEMAIL_SENDER) << "Sending STARTTLS";
401 
402  // send a request to start TLS handshake
403  sendMessage(QByteArrayLiteral("STARTTLS"));
404 
405  // The response code needs to be 220.
406  if (!waitForResponse(220)) {
407  Q_EMIT q->smtpError(Sender::ServerError);
408  return false;
409  };
410 
411  sslSock = qobject_cast<QSslSocket *>(socket);
412  if (sslSock) {
413  qCDebug(SIMPLEMAIL_SENDER) << "Starting client encryption";
414  sslSock->startClientEncryption();
415 
416  if (!sslSock->waitForEncrypted(connectionTimeout)) {
417  qCDebug(SIMPLEMAIL_SENDER) << "Failed to encrypt connection" << sslSock->errorString();
418  Q_EMIT q->smtpError(Sender::ConnectionTimeoutError);
419  return false;
420  }
421  } else {
422  qCDebug(SIMPLEMAIL_SENDER) << "Failed to start TLS negotiation";
423  return false;
424  }
425 
426  qCDebug(SIMPLEMAIL_SENDER) << "Sending second EHLO" << name;
427  // Send ELHO one more time
428  sendMessage(QByteArrayLiteral("EHLO ") + name.toLatin1());
429 
430  // The response code needs to be 250.
431  if (!waitForResponse(250)) {
432  Q_EMIT q->smtpError(Sender::ServerError);
433  return false;
434  }
435  }
436 
438 
439  // If no errors occured the function returns true.
440  return true;
441 
442 }
QString name
Definition: sender_p.h:57
Sender::ConnectionType connectionType
Definition: sender_p.h:56
Definition: sender.h:56
Definition: sender.h:49
void sendMessage(const QByteArray &data)
Definition: sender.cpp:338
int connectionTimeout
Definition: sender_p.h:64
Definition: sender.h:30
QString host
Definition: sender_p.h:54
int port
Definition: sender_p.h:55
State state
Definition: sender_p.h:49
Definition: sender.h:58
bool waitForResponse(int expectedCode)
Definition: sender.cpp:497
QTcpSocket * socket
Definition: sender_p.h:51
QString lastError
Definition: sender_p.h:52
Definition: sender.h:57
Definition: sender_p.h:36

◆ login()

bool SenderPrivate::login ( )

Références SimpleMail::Sender::AuthenticationFailedError, SimpleMail::Sender::AuthLogin, authMethod, SimpleMail::Sender::AuthPlain, password, Ready, sendMessage(), state, user, et waitForResponse().

Référencé par processState().

445 {
446  Q_Q(Sender);
447 
448  if (authMethod == Sender::AuthPlain) {
449  qCDebug(SIMPLEMAIL_SENDER) << "Sending authentication plain";
450 
451  // Sending command: AUTH PLAIN base64('\0' + username + '\0' + password)
452  QString userpass = QLatin1Char('\0') + user + QLatin1Char('\0') + password;
453  sendMessage(QByteArrayLiteral("AUTH PLAIN ") + userpass.toLatin1().toBase64());
454 
455  // If the response is not 235 then the authentication was faild
456  if (!waitForResponse(235)) {
457  Q_EMIT q->smtpError(Sender::AuthenticationFailedError);
458  return false;
459  }
460  } else if (authMethod == Sender::AuthLogin) {
461  // Sending command: AUTH LOGIN
462  qCDebug(SIMPLEMAIL_SENDER) << "Sending authentication login";
463  sendMessage(QByteArrayLiteral("AUTH LOGIN"));
464 
465  // Wait for 334 response code
466  if (!waitForResponse(334)) {
467  Q_EMIT q->smtpError(Sender::AuthenticationFailedError);
468  return false;
469  }
470 
471  // Send the username in base64
472  qCDebug(SIMPLEMAIL_SENDER) << "Sending authentication user" << user;
473  sendMessage(user.toLatin1().toBase64());
474 
475  // Wait for 334
476  if (!waitForResponse(334)) {
477  Q_EMIT q->smtpError(Sender::AuthenticationFailedError);
478  return false;
479  }
480 
481  // Send the password in base64
482  qCDebug(SIMPLEMAIL_SENDER) << "Sending authentication password";
483  sendMessage(password.toUtf8().toBase64());
484 
485  // If the response is not 235 then the authentication was faild
486  if (!waitForResponse(235)) {
487  Q_EMIT q->smtpError(Sender::AuthenticationFailedError);
488  return false;
489  }
490  }
491 
493 
494  return true;
495 }
QString password
Definition: sender_p.h:61
Definition: sender.h:39
Definition: sender.h:38
void sendMessage(const QByteArray &data)
Definition: sender.cpp:338
Sender::AuthMethod authMethod
Definition: sender_p.h:62
Definition: sender.h:30
Definition: sender_p.h:37
QString user
Definition: sender_p.h:60
State state
Definition: sender_p.h:49
bool waitForResponse(int expectedCode)
Definition: sender.cpp:497

◆ processState()

bool SenderPrivate::processState ( )

Références Connected, connectToHost(), Disconnected, Error, login(), Ready, socket, et state.

Référencé par sendMail().

542 {
543  switch (state) {
546  if (socket->state() != QAbstractSocket::ConnectedState) {
548  if (socket->state() != QAbstractSocket::UnconnectedState) {
549  socket->disconnectFromHost();
550  socket->waitForDisconnected();
551  }
552  }
553  break;
554  default:
555  break;
556  }
557 
558  while (state != SenderPrivate::Ready) {
559  qCDebug(SIMPLEMAIL_SENDER) << "Processing state" << state;
560  switch (state) {
562  if (!connectToHost()) {
564  return false;
565  }
566  break;
568  if (!login()) {
570  return false;
571  }
572  break;
574  // try again
575  socket->disconnectFromHost();
576  socket->waitForDisconnected();
577  break;
579  break;
580  }
581  }
582  return true;
583 }
bool login()
Definition: sender.cpp:444
Definition: sender_p.h:34
Definition: sender_p.h:37
State state
Definition: sender_p.h:49
QTcpSocket * socket
Definition: sender_p.h:51
bool connectToHost()
Definition: sender.cpp:348
Definition: sender_p.h:36

◆ sendMail()

bool SenderPrivate::sendMail ( MimeMessage email)

Références SimpleMail::EmailAddress::address(), SimpleMail::MimeMessage::bccRecipients(), SimpleMail::MimeMessage::ccRecipients(), processState(), SimpleMail::MimeMessage::sender(), sendMessage(), socket, SimpleMail::MimeMessage::toRecipients(), waitForResponse(), et SimpleMail::MimeMessage::write().

269 {
270  qCDebug(SIMPLEMAIL_SENDER) << "Sending MAIL" << this;
271 
272  if (!processState()) {
273  return false;
274  }
275 
276  qCDebug(SIMPLEMAIL_SENDER) << "Sending MAIL command";
277  // Send the MAIL command with the sender
278  sendMessage("MAIL FROM: <" + email.sender().address().toLatin1() + '>');
279  if (!waitForResponse(250)) {
280  return false;
281  }
282 
283  qCDebug(SIMPLEMAIL_SENDER) << "Sending RCPT TO command";
284  // Send RCPT command for each recipient
285  // To (primary recipients)
286  const auto toRecipients = email.toRecipients();
287  for (const EmailAddress &rcpt : toRecipients) {
288  sendMessage("RCPT TO: <" + rcpt.address().toLatin1() + '>');
289 
290  if (!waitForResponse(250)) {
291  return false;
292  }
293  }
294 
295  // Cc (carbon copy)
296  const auto ccRecipients = email.ccRecipients();
297  for (const EmailAddress &rcpt : ccRecipients) {
298  sendMessage("RCPT TO: <" + rcpt.address().toLatin1() + '>');
299 
300  if (!waitForResponse(250)) {
301  return false;
302  }
303  }
304 
305  // Bcc (blind carbon copy)
306  const auto bccRecipients = email.bccRecipients();
307  for (const EmailAddress &rcpt : bccRecipients) {
308  sendMessage("RCPT TO: <" + rcpt.address().toLatin1() + '>');
309 
310  if (!waitForResponse(250)) {
311  return false;
312  }
313  }
314 
315  qCDebug(SIMPLEMAIL_SENDER) << "Sending DATA command";
316  // Send DATA command
317  sendMessage(QByteArrayLiteral("DATA"));
318 
319  if (!waitForResponse(354)) {
320  return false;
321  }
322 
323  qCDebug(SIMPLEMAIL_SENDER) << "Sending email";
324  if (!email.write(socket)) {
325  return false;
326  }
327 
328  // Send \r\n.\r\n to end the mail data
329  sendMessage(QByteArrayLiteral("\r\n."));
330  if (!waitForResponse(250)) {
331  return false;
332  }
333  qCDebug(SIMPLEMAIL_SENDER) << "Mail sent";
334 
335  return true;
336 }
bool processState()
Definition: sender.cpp:541
EmailAddress sender() const
Definition: mimemessage.cpp:188
QList< EmailAddress > bccRecipients() const
Definition: mimemessage.cpp:156
QList< EmailAddress > toRecipients() const
Definition: mimemessage.cpp:120
void sendMessage(const QByteArray &data)
Definition: sender.cpp:338
bool write(QIODevice *device)
Definition: mimemessage.cpp:64
QString address() const
Definition: emailaddress.cpp:71
QList< EmailAddress > ccRecipients() const
Definition: mimemessage.cpp:144
bool waitForResponse(int expectedCode)
Definition: sender.cpp:497
Definition: emailaddress.h:29
QTcpSocket * socket
Definition: sender_p.h:51

◆ sendMessage()

void SenderPrivate::sendMessage ( const QByteArray &  data)

Références SimpleMail::Sender::SendDataTimeoutError, sendMessageTimeout, et socket.

Référencé par connectToHost(), login(), et sendMail().

339 {
340  Q_Q(Sender);
341  socket->write(data);
342  socket->write("\r\n", 2);
343  if (!socket->waitForBytesWritten(sendMessageTimeout)) {
344  Q_EMIT q->smtpError(Sender::SendDataTimeoutError);
345  }
346 }
int sendMessageTimeout
Definition: sender_p.h:66
Definition: sender.h:30
QTcpSocket * socket
Definition: sender_p.h:51

◆ setPeerVerificationType()

void SenderPrivate::setPeerVerificationType ( const Sender::PeerVerificationType type)

Références connectionType, peerVerificationType, socket, SimpleMail::Sender::SslConnection, SimpleMail::Sender::TlsConnection, SimpleMail::Sender::VerifyNone, et SimpleMail::Sender::VerifyPeer.

586 {
587  peerVerificationType = type;
588  if (socket != Q_NULLPTR)
589  {
591  {
592  switch (type) {
593  case Sender::VerifyNone:
594  static_cast<QSslSocket*>(socket)->setPeerVerifyMode(QSslSocket::VerifyNone);
595  break;
596  case Sender::VerifyPeer:
597  default:
598  static_cast<QSslSocket*>(socket)->setPeerVerifyMode(QSslSocket::VerifyPeer);
599  break;
600  }
601  }
602  }
603 }
Definition: sender.h:65
Sender::ConnectionType connectionType
Definition: sender_p.h:56
Definition: sender.h:64
Sender::PeerVerificationType peerVerificationType
Definition: sender_p.h:58
Definition: sender.h:58
QTcpSocket * socket
Definition: sender_p.h:51
Definition: sender.h:57

◆ waitForResponse()

bool SenderPrivate::waitForResponse ( int  expectedCode)

Références SimpleMail::Sender::ClientError, lastError, responseCode, responseText, responseTimeout, SimpleMail::Sender::ResponseTimeoutError, SimpleMail::Sender::ServerError, et socket.

Référencé par connectToHost(), login(), et sendMail().

498 {
499  Q_Q(Sender);
500 
501  do {
502  if (!socket->waitForReadyRead(responseTimeout)) {
503  lastError = QObject::tr("Response timed out");
504  qCDebug(SIMPLEMAIL_SENDER) << "Response timed out";
505  Q_EMIT q->smtpError(Sender::ResponseTimeoutError);
506  return false;
507  }
508 
509  while (socket->canReadLine()) {
510  // Save the server's response
511  responseText = socket->readLine().trimmed();
512  qCDebug(SIMPLEMAIL_SENDER) << "Got response" << responseText;
513 
514  // Extract the respose code from the server's responce (first 3 digits)
515  responseCode = responseText.left(3).toInt();
516 
517  if (responseCode / 100 == 4) {
518  lastError = QString::fromLatin1(responseText);
519  Q_EMIT q->smtpError(Sender::ServerError);
520  }
521 
522  if (responseCode / 100 == 5) {
523  lastError = QString::fromLatin1(responseText);
524  Q_EMIT q->smtpError(Sender::ClientError);
525  }
526 
527  if (responseText[3] == ' ') {
528  if (responseCode != expectedCode) {
529  lastError = QString::fromLatin1(responseText);
530  qCDebug(SIMPLEMAIL_SENDER) << "Unexpected server response" << lastError << expectedCode;
531  return false;
532  }
533  return true;
534  }
535  }
536  } while (true);
537 
538  return false;
539 }
QByteArray responseText
Definition: sender_p.h:68
int responseTimeout
Definition: sender_p.h:65
int responseCode
Definition: sender_p.h:69
Definition: sender.h:49
Definition: sender.h:50
Definition: sender.h:30
QTcpSocket * socket
Definition: sender_p.h:51
QString lastError
Definition: sender_p.h:52

Documentation des données membres

◆ authMethod

Sender::AuthMethod SimpleMail::SenderPrivate::authMethod = Sender::AuthNone

Référencé par login().

◆ connectionTimeout

int SimpleMail::SenderPrivate::connectionTimeout = 5000

Référencé par connectToHost().

◆ connectionType

Sender::ConnectionType SimpleMail::SenderPrivate::connectionType

◆ host

QString SimpleMail::SenderPrivate::host = QLatin1String("localhost")

Référencé par connectToHost().

◆ lastError

QString SimpleMail::SenderPrivate::lastError

Référencé par connectToHost(), et waitForResponse().

◆ name

QString SimpleMail::SenderPrivate::name = QHostInfo::localHostName()

Référencé par connectToHost().

◆ password

QString SimpleMail::SenderPrivate::password

Référencé par login().

◆ peerVerificationType

Sender::PeerVerificationType SimpleMail::SenderPrivate::peerVerificationType = Sender::VerifyPeer

Référencé par setPeerVerificationType().

◆ port

int SimpleMail::SenderPrivate::port = 25

Référencé par connectToHost().

◆ q_ptr

Sender* SimpleMail::SenderPrivate::q_ptr

◆ responseCode

int SimpleMail::SenderPrivate::responseCode

Référencé par waitForResponse().

◆ responseText

QByteArray SimpleMail::SenderPrivate::responseText

Référencé par waitForResponse().

◆ responseTimeout

int SimpleMail::SenderPrivate::responseTimeout = 5000

Référencé par waitForResponse().

◆ sendMessageTimeout

int SimpleMail::SenderPrivate::sendMessageTimeout = 60000

Référencé par sendMessage().

◆ socket

QTcpSocket* SimpleMail::SenderPrivate::socket = nullptr

◆ state

State SimpleMail::SenderPrivate::state = State::Disconnected

Référencé par connectToHost(), login(), et processState().

◆ user

QString SimpleMail::SenderPrivate::user

Référencé par login().


La documentation de cette classe a été générée à partir des fichiers suivants :