From 1560ab819f1af18846ffbb004fe71bbfe1f26ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20T=C5=91k=C3=A9s?= Date: Tue, 24 Jul 2012 19:21:36 +0300 Subject: [PATCH] Added support for TLS connection (STARTTLS). Added getters for responseCode, responseText and socket. --- src/smtpclient.cpp | 95 ++++++++++++++++++++++++++++++++++------------ src/smtpclient.h | 11 +++++- 2 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/smtpclient.cpp b/src/smtpclient.cpp index e83e118..75a717c 100644 --- a/src/smtpclient.cpp +++ b/src/smtpclient.cpp @@ -24,21 +24,13 @@ /* [1] Constructors and destructors */ -SmtpClient::SmtpClient(const QString & host, int port, ConnectionType ct) : +SmtpClient::SmtpClient(const QString & host, int port, ConnectionType connectionType) : name("localhost"), authMethod(AuthPlain), connectionTimeout(5000), responseTimeout(5000) { - if (ct == TcpConnection) - this->useSsl = false; - else if (ct == SslConnection) - this->useSsl = true; - - if (useSsl == false) - socket = new QTcpSocket(this); - else - socket = new QSslSocket(this); + setConnectionType(connectionType); this->host = host; this->port = port; @@ -85,15 +77,17 @@ void SmtpClient::setPort(int port) void SmtpClient::setConnectionType(ConnectionType ct) { - if (ct == TcpConnection) - this->useSsl = false; - else if (ct == SslConnection) - this->useSsl = true; + this->connectionType = ct; - if (useSsl == false) + switch (connectionType) + { + case TcpConnection: socket = new QTcpSocket(this); - else + break; + case SslConnection: + case TlsConnection: socket = new QSslSocket(this); + } } const QString& SmtpClient::getHost() const @@ -123,10 +117,7 @@ int SmtpClient::getPort() const SmtpClient::ConnectionType SmtpClient::getConnectionType() const { - if (useSsl) - return SslConnection; - else - return TcpConnection; + return connectionType; } const QString& SmtpClient::getName() const @@ -139,6 +130,20 @@ void SmtpClient::setName(const QString &name) this->name = name; } +const QString & SmtpClient::getResponseText() const +{ + return responseText; +} + +int SmtpClient::getResponseCode() const +{ + return responseCode; +} + +QTcpSocket* SmtpClient::getSocket() { + return socket; +} + /* [2] --- */ @@ -146,10 +151,17 @@ void SmtpClient::setName(const QString &name) bool SmtpClient::connectToHost() { - if (useSsl) - ((QSslSocket*) socket)->connectToHostEncrypted(host, port); - else + switch (connectionType) + { + case TlsConnection: + case TcpConnection: socket->connectToHost(host, port); + break; + case SslConnection: + ((QSslSocket*) socket)->connectToHostEncrypted(host, port); + break; + + } // Tries to connect to server if (!socket->waitForConnected(connectionTimeout)) @@ -179,11 +191,44 @@ bool SmtpClient::connectToHost() waitForResponse(); // The response code needs to be 250. - if (responseCode != 250) - { + if (responseCode != 250) { emit smtpError(ServerError); return false; } + + if (connectionType == TlsConnection) { + // send a request to start TLS handshake + sendMessage("STARTTLS"); + + // Wait for the server's response + waitForResponse(); + + // The response code needs to be 220. + if (responseCode != 220) { + emit smtpError(ServerError); + return false; + }; + + ((QSslSocket*) socket)->startClientEncryption(); + + if (!((QSslSocket*) socket)->waitForEncrypted(connectionTimeout)) { + qDebug() << ((QSslSocket*) socket)->errorString(); + emit SmtpError(ConnectionTimeoutError); + return false; + } + + // Send ELHO one more time + sendMessage("EHLO " + name); + + // Wait for the server's response + waitForResponse(); + + // The response code needs to be 250. + if (responseCode != 250) { + emit smtpError(ServerError); + return false; + } + } } catch (ResponseTimeoutException) { diff --git a/src/smtpclient.h b/src/smtpclient.h index c646010..f2bc161 100644 --- a/src/smtpclient.h +++ b/src/smtpclient.h @@ -50,7 +50,8 @@ public: enum ConnectionType { TcpConnection, - SslConnection + SslConnection, + TlsConnection // STARTTLS }; /* [0] --- */ @@ -88,6 +89,12 @@ public: SmtpClient::AuthMethod getAuthMethod() const; void setAuthMethod(AuthMethod method); + const QString & getResponseText() const; + int getResponseCode() const; + + QTcpSocket* getSocket(); + + /* [2] --- */ @@ -113,7 +120,7 @@ protected: QString host; int port; - bool useSsl; + ConnectionType connectionType; QString name; QString user;