diff options
author | Saturneric <[email protected]> | 2021-07-14 12:05:24 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2021-07-14 12:05:24 +0000 |
commit | a0b5b56e8f5009ac13e800d4db4bcd35109c08cb (patch) | |
tree | b1553a354c1b61300b81e1e009e54aca7674ec6a | |
parent | Update Workflow (diff) | |
download | GpgFrontend-a0b5b56e8f5009ac13e800d4db4bcd35109c08cb.tar.gz GpgFrontend-a0b5b56e8f5009ac13e800d4db4bcd35109c08cb.zip |
Add SMTP Library.
Diffstat (limited to '')
28 files changed, 2295 insertions, 3 deletions
diff --git a/include/smtp/SmtpMime b/include/smtp/SmtpMime new file mode 100644 index 00000000..940996b8 --- /dev/null +++ b/include/smtp/SmtpMime @@ -0,0 +1,31 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef SMTPMIME_H +#define SMTPMIME_H + +#include "smtpclient.h" +#include "mimepart.h" +#include "mimehtml.h" +#include "mimeattachment.h" +#include "mimemessage.h" +#include "mimetext.h" +#include "mimeinlinefile.h" +#include "mimefile.h" + +#endif // SMTPMIME_H diff --git a/include/smtp/emailaddress.h b/include/smtp/emailaddress.h new file mode 100644 index 00000000..4ecf6efc --- /dev/null +++ b/include/smtp/emailaddress.h @@ -0,0 +1,61 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef EMAILADDRESS_H +#define EMAILADDRESS_H + +#include <QObject> + +#include "smtpexports.h" + +class SMTP_EXPORT EmailAddress : public QObject +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + EmailAddress(); + EmailAddress(const QString & address, const QString & name=""); + + ~EmailAddress(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + void setName(const QString & name); + void setAddress(const QString & address); + + const QString & getName() const; + const QString & getAddress() const; + + /* [2] --- */ + + +private: + + /* [3] Private members */ + + QString name; + QString address; + + /* [3] --- */ +}; + +#endif // EMAILADDRESS_H diff --git a/include/smtp/mimeattachment.h b/include/smtp/mimeattachment.h new file mode 100644 index 00000000..4a92e9a1 --- /dev/null +++ b/include/smtp/mimeattachment.h @@ -0,0 +1,51 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMEATTACHMENT_H +#define MIMEATTACHMENT_H + +#include <QFile> +#include "mimepart.h" +#include "mimefile.h" + +#include "smtpexports.h" + +class SMTP_EXPORT MimeAttachment : public MimeFile +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + MimeAttachment(QFile* file); + MimeAttachment(const QByteArray& stream, const QString& fileName); + + ~MimeAttachment(); + + /* [1] --- */ + +protected: + + /* [2] Protected methods */ + + virtual void prepare(); + + /* [2] --- */ +}; + +#endif // MIMEATTACHMENT_H diff --git a/include/smtp/mimecontentformatter.h b/include/smtp/mimecontentformatter.h new file mode 100644 index 00000000..bf751588 --- /dev/null +++ b/include/smtp/mimecontentformatter.h @@ -0,0 +1,43 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMECONTENTFORMATTER_H +#define MIMECONTENTFORMATTER_H + +#include <QObject> +#include <QByteArray> + +#include "smtpexports.h" + +class SMTP_EXPORT MimeContentFormatter : public QObject +{ + Q_OBJECT +public: + MimeContentFormatter (int max_length = 76); + + void setMaxLength(int l); + int getMaxLength() const; + + QString format(const QString &content, bool quotedPrintable = false) const; + +protected: + int max_length; + +}; + +#endif // MIMECONTENTFORMATTER_H diff --git a/include/smtp/mimefile.h b/include/smtp/mimefile.h new file mode 100644 index 00000000..13f444de --- /dev/null +++ b/include/smtp/mimefile.h @@ -0,0 +1,62 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMEFILE_H +#define MIMEFILE_H + +#include "mimepart.h" +#include <QFile> + +#include "smtpexports.h" + +class SMTP_EXPORT MimeFile : public MimePart +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + MimeFile(const QByteArray& stream, const QString& fileName); + MimeFile(QFile *f); + ~MimeFile(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + QFile* file; + + /* [3] --- */ + + + /* [4] Protected methods */ + + virtual void prepare(); + + /* [4] --- */ + +}; + +#endif // MIMEFILE_H diff --git a/include/smtp/mimehtml.h b/include/smtp/mimehtml.h new file mode 100644 index 00000000..f3f54300 --- /dev/null +++ b/include/smtp/mimehtml.h @@ -0,0 +1,61 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMEHTML_H +#define MIMEHTML_H + +#include "mimetext.h" + +#include "smtpexports.h" + +class SMTP_EXPORT MimeHtml : public MimeText +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + MimeHtml(const QString &html = ""); + ~MimeHtml(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + void setHtml(const QString & html); + + const QString& getHtml() const; + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + /* [3] --- */ + + + /* [4] Protected methods */ + + virtual void prepare(); + + /* [4] --- */ +}; + +#endif // MIMEHTML_H diff --git a/include/smtp/mimeinlinefile.h b/include/smtp/mimeinlinefile.h new file mode 100644 index 00000000..98fe3cab --- /dev/null +++ b/include/smtp/mimeinlinefile.h @@ -0,0 +1,56 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMEINLINEFILE_H +#define MIMEINLINEFILE_H + +#include "mimefile.h" + +#include "smtpexports.h" + +class SMTP_EXPORT MimeInlineFile : public MimeFile +{ +public: + + /* [1] Constructors and Destructors */ + + MimeInlineFile(QFile *f); + ~MimeInlineFile(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + /* [3] --- */ + + + /* [4] Protected methods */ + + virtual void prepare(); + + /* [4] --- */ +}; + +#endif // MIMEINLINEFILE_H diff --git a/include/smtp/mimemessage.h b/include/smtp/mimemessage.h new file mode 100644 index 00000000..3b8fd7c7 --- /dev/null +++ b/include/smtp/mimemessage.h @@ -0,0 +1,98 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMEMESSAGE_H +#define MIMEMESSAGE_H + +#include "mimepart.h" +#include "mimemultipart.h" +#include "emailaddress.h" +#include <QList> + +#include "smtpexports.h" + +class SMTP_EXPORT MimeMessage : public QObject +{ +public: + + enum RecipientType { + To, // primary + Cc, // carbon copy + Bcc // blind carbon copy + }; + + /* [1] Constructors and Destructors */ + + MimeMessage(bool createAutoMimeConent = true); + ~MimeMessage(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + void setSender(EmailAddress* e); + void addRecipient(EmailAddress* rcpt, RecipientType type = To); + void addTo(EmailAddress* rcpt); + void addCc(EmailAddress* rcpt); + void addBcc(EmailAddress* rcpt); + void setSubject(const QString & subject); + void addPart(MimePart* part); + void setReplyTo(EmailAddress* rto); + + void setInReplyTo(const QString& inReplyTo); + + void setHeaderEncoding(MimePart::Encoding); + + const EmailAddress & getSender() const; + const QList<EmailAddress*> & getRecipients(RecipientType type = To) const; + const QString & getSubject() const; + const QList<MimePart*> & getParts() const; + const EmailAddress* getReplyTo() const; + + MimePart& getContent(); + void setContent(MimePart *content); + /* [2] --- */ + + + /* [3] Public methods */ + + virtual QString toString(); + + /* [3] --- */ + +protected: + + /* [4] Protected members */ + + EmailAddress* sender; + EmailAddress* replyTo; + QList<EmailAddress*> recipientsTo, recipientsCc, recipientsBcc; + QString subject; + QString mInReplyTo; + MimePart *content; + bool autoMimeContentCreated; + + MimePart::Encoding hEncoding; + + /* [4] --- */ + + +}; + +#endif // MIMEMESSAGE_H diff --git a/include/smtp/mimemultipart.h b/include/smtp/mimemultipart.h new file mode 100644 index 00000000..d241906f --- /dev/null +++ b/include/smtp/mimemultipart.h @@ -0,0 +1,72 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMEMULTIPART_H +#define MIMEMULTIPART_H + +#include "mimepart.h" + +#include "smtpexports.h" + +class SMTP_EXPORT MimeMultiPart : public MimePart { + Q_OBJECT +public: + /* [0] Enums */ + enum MultiPartType { + Mixed = 0, // RFC 2046, section 5.1.3 + Digest = 1, // RFC 2046, section 5.1.5 + Alternative = 2, // RFC 2046, section 5.1.4 + Related = 3, // RFC 2387 + Report = 4, // RFC 6522 + Signed = 5, // RFC 1847, section 2.1 + Encrypted = 6 // RFC 1847, section 2.2 + }; + + /* [0] --- */ + + /* [1] Constructors and Destructors */ + MimeMultiPart(const MultiPartType type = Related); + + ~MimeMultiPart(); + + /* [1] --- */ + + /* [2] Getters and Setters */ + + void setMimeType(const MultiPartType type); + MultiPartType getMimeType() const; + + const QList<MimePart *> &getParts() const; + + /* [2] --- */ + + /* [3] Public methods */ + + void addPart(MimePart *part); + + virtual void prepare(); + + /* [3] --- */ + +protected: + QList<MimePart *> parts; + + MultiPartType type; +}; + +#endif // MIMEMULTIPART_H diff --git a/include/smtp/mimepart.h b/include/smtp/mimepart.h new file mode 100644 index 00000000..d2201bc3 --- /dev/null +++ b/include/smtp/mimepart.h @@ -0,0 +1,100 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMEPART_H +#define MIMEPART_H + +#include "mimecontentformatter.h" +#include <QObject> + +#include "smtpexports.h" + +class SMTP_EXPORT MimePart : public QObject { + Q_OBJECT +public: + /* [0] Enumerations */ + enum Encoding { _7Bit, _8Bit, Base64, QuotedPrintable }; + + /* [0] --- */ + + /* [1] Constructors and Destructors */ + + MimePart(); + ~MimePart(); + + /* [1] --- */ + + /* [2] Getters and Setters */ + + const QString &getHeader() const; + const QByteArray &getContent() const; + + void setContent(const QByteArray &content); + void setHeader(const QString &header); + + void addHeaderLine(const QString &line); + + void setContentId(const QString &cId); + const QString &getContentId() const; + + void setContentName(const QString &cName); + const QString &getContentName() const; + + void setContentType(const QString &cType); + const QString &getContentType() const; + + void setCharset(const QString &charset); + const QString &getCharset() const; + + void setEncoding(Encoding enc); + Encoding getEncoding() const; + + MimeContentFormatter &getContentFormatter(); + + /* [2] --- */ + + /* [3] Public methods */ + + virtual QString toString(); + + virtual void prepare(); + + /* [3] --- */ + +protected: + /* [4] Protected members */ + + QString header; + QByteArray content; + + QString cId; + QString cName; + QString cType; + QString cCharset; + QString cBoundary; + Encoding cEncoding; + + QString mimeString; + bool prepared; + + MimeContentFormatter formatter; + + /* [4] --- */ +}; + +#endif // MIMEPART_H diff --git a/include/smtp/mimetext.h b/include/smtp/mimetext.h new file mode 100644 index 00000000..c0d29835 --- /dev/null +++ b/include/smtp/mimetext.h @@ -0,0 +1,62 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef MIMETEXT_H +#define MIMETEXT_H + +#include "mimepart.h" + +#include "smtpexports.h" + +class SMTP_EXPORT MimeText : public MimePart +{ +public: + + /* [1] Constructors and Destructors */ + + MimeText(const QString &text = ""); + ~MimeText(); + + /* [1] --- */ + + + /* [2] Getters and Setters*/ + + void setText(const QString & text); + + const QString & getText() const; + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + QString text; + /* [3] --- */ + + + /* [4] Protected methods */ + + void prepare(); + + /* [4] --- */ + +}; + +#endif // MIMETEXT_H diff --git a/include/smtp/quotedprintable.h b/include/smtp/quotedprintable.h new file mode 100644 index 00000000..03d3acf8 --- /dev/null +++ b/include/smtp/quotedprintable.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef QUOTEDPRINTABLE_H +#define QUOTEDPRINTABLE_H + +#include <QObject> +#include <QByteArray> + +#include "smtpexports.h" + +class SMTP_EXPORT QuotedPrintable : public QObject +{ + Q_OBJECT +public: + + static QString encode(const QByteArray &input); + static QByteArray decode(const QString &input); + +private: + QuotedPrintable(); +}; + +#endif // QUOTEDPRINTABLE_H diff --git a/include/smtp/smtpclient.h b/include/smtp/smtpclient.h new file mode 100644 index 00000000..26afe81c --- /dev/null +++ b/include/smtp/smtpclient.h @@ -0,0 +1,184 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#ifndef SMTPCLIENT_H +#define SMTPCLIENT_H + +#include <QObject> +#include <QtNetwork/QSslSocket> + +#include "mimemessage.h" +#include "smtpexports.h" + +class SMTP_EXPORT SmtpClient : public QObject +{ + Q_OBJECT +public: + + /* [0] Enumerations */ + + enum AuthMethod + { + AuthPlain, + AuthLogin + }; + + enum SmtpError + { + ConnectionTimeoutError, + ResponseTimeoutError, + SendDataTimeoutError, + AuthenticationFailedError, + ServerError, // 4xx smtp error + ClientError // 5xx smtp error + }; + + enum ConnectionType + { + TcpConnection, + SslConnection, + TlsConnection // STARTTLS + }; + + /* [0] --- */ + + + /* [1] Constructors and Destructors */ + + SmtpClient(const QString & host = "localhost", int port = 25, ConnectionType ct = TcpConnection); + + ~SmtpClient(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + const QString& getHost() const; + void setHost(const QString &host); + + int getPort() const; + void setPort(int port); + + const QString& getName() const; + void setName(const QString &name); + + ConnectionType getConnectionType() const; + void setConnectionType(ConnectionType ct); + + const QString & getUser() const; + void setUser(const QString &user); + + const QString & getPassword() const; + void setPassword(const QString &password); + + SmtpClient::AuthMethod getAuthMethod() const; + void setAuthMethod(AuthMethod method); + + const QString & getResponseText() const; + int getResponseCode() const; + + int getConnectionTimeout() const; + void setConnectionTimeout(int msec); + + int getResponseTimeout() const; + void setResponseTimeout(int msec); + + int getSendMessageTimeout() const; + void setSendMessageTimeout(int msec); + + QTcpSocket* getSocket(); + + + /* [2] --- */ + + + /* [3] Public methods */ + + bool connectToHost(); + + bool login(); + bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin); + + bool sendMail(MimeMessage& email); + + void quit(); + + + /* [3] --- */ + +protected: + + /* [4] Protected members */ + + QTcpSocket *socket; + + QString host; + int port; + ConnectionType connectionType; + QString name; + + QString user; + QString password; + AuthMethod authMethod; + + int connectionTimeout; + int responseTimeout; + int sendMessageTimeout; + + + QString responseText; + int responseCode; + + + class ResponseTimeoutException {}; + class SendMessageTimeoutException {}; + + /* [4] --- */ + + + /* [5] Protected methods */ + + void waitForResponse(); + + void sendMessage(const QString &text); + + /* [5] --- */ + +protected slots: + + /* [6] Protected slots */ + + void socketStateChanged(QAbstractSocket::SocketState state); + void socketError(QAbstractSocket::SocketError error); + void socketReadyRead(); + + /* [6] --- */ + + +signals: + + /* [7] Signals */ + + void smtpError(SmtpClient::SmtpError e); + + /* [7] --- */ + +}; + +#endif // SMTPCLIENT_H diff --git a/include/smtp/smtpexports.h b/include/smtp/smtpexports.h new file mode 100644 index 00000000..0c4919f3 --- /dev/null +++ b/include/smtp/smtpexports.h @@ -0,0 +1,10 @@ +#ifndef SMTPEXPORTS_H
+#define SMTPEXPORTS_H
+
+#ifdef SMTP_BUILD
+#define SMTP_EXPORT Q_DECL_EXPORT
+#else
+#define SMTP_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // SMTPEXPORTS_H
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 243570e5..03eaac9e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,7 @@ set(ALL_SOURCE_FILE) add_subdirectory(gpg) add_subdirectory(ui) +add_subdirectory(smtp) aux_source_directory(. BASE_SOURCE) @@ -121,19 +122,19 @@ endif() IF (MINGW) message(STATUS "Link Application Static Library For MINGW") target_link_libraries(${AppName} - gpgfrontend-ui gpg + smtp gpgfrontend-ui gpg Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core crypto ssl) elseif(APPLE) message(STATUS "Link Application Static Library For macOS") target_link_libraries(${AppName} - gpgfrontend-ui gpg + smtp gpgfrontend-ui gpg Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core crypto ssl) else() message(STATUS "Link Application Static Library For UNIX") target_link_libraries(${AppName} - gpgfrontend-ui gpg + smtp gpgfrontend-ui gpg Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core crypto ssl pthread) endif() diff --git a/src/smtp/CMakeLists.txt b/src/smtp/CMakeLists.txt new file mode 100644 index 00000000..8e341f98 --- /dev/null +++ b/src/smtp/CMakeLists.txt @@ -0,0 +1,6 @@ +aux_source_directory(. SMTP_MIME_SOURCE) + +add_library(smtp STATIC ${SMTP_MIME_SOURCE}) + +target_link_libraries(smtp + Qt5::Network Qt5::Core) diff --git a/src/smtp/emailaddress.cpp b/src/smtp/emailaddress.cpp new file mode 100644 index 00000000..8e7309a8 --- /dev/null +++ b/src/smtp/emailaddress.cpp @@ -0,0 +1,44 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/emailaddress.h" + +/* [1] Constructors and Destructors */ + +EmailAddress::EmailAddress(const QString &address, const QString &name) { + this->address = address; + this->name = name; +} + +EmailAddress::~EmailAddress() {} + +/* [1] --- */ + +/* [2] Getters and Setters */ + +void EmailAddress::setName(const QString &name) { this->name = name; } + +void EmailAddress::setAddress(const QString &address) { + this->address = address; +} + +const QString &EmailAddress::getName() const { return name; } + +const QString &EmailAddress::getAddress() const { return address; } + +/* [2] --- */ diff --git a/src/smtp/mimeattachment.cpp b/src/smtp/mimeattachment.cpp new file mode 100644 index 00000000..df2f4011 --- /dev/null +++ b/src/smtp/mimeattachment.cpp @@ -0,0 +1,42 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimeattachment.h" +#include <QFileInfo> + +/* [1] Constructors and Destructors */ + +MimeAttachment::MimeAttachment(QFile *file) : MimeFile(file) {} +MimeAttachment::MimeAttachment(const QByteArray &stream, + const QString &fileName) + : MimeFile(stream, fileName) {} + +MimeAttachment::~MimeAttachment() {} + +/* [1] --- */ + +/* [2] Protected methods */ + +void MimeAttachment::prepare() { + this->header += "Content-disposition: attachment\r\n"; + + /* !!! IMPORTANT !!! */ + MimeFile::prepare(); +} + +/* [2] --- */ diff --git a/src/smtp/mimecontentformatter.cpp b/src/smtp/mimecontentformatter.cpp new file mode 100644 index 00000000..847185c0 --- /dev/null +++ b/src/smtp/mimecontentformatter.cpp @@ -0,0 +1,59 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimecontentformatter.h" + +MimeContentFormatter::MimeContentFormatter(int max_length) + : max_length(max_length) {} + +QString MimeContentFormatter::format(const QString &content, + bool quotedPrintable) const { + + QString out; + + int chars = 0; + for (int i = 0; i < content.length(); ++i) { + chars++; + if (!quotedPrintable) { + if (chars > max_length) { + out.append("\r\n"); + chars = 1; + } + } else { + if (content[i] == '\n') { // new line + out.append(content[i]); + chars = 0; + continue; + } + + if ((chars > max_length - 1) || + ((content[i] == '=') && (chars > max_length - 3))) { + out.append('='); + out.append("\r\n"); + chars = 1; + } + } + out.append(content[i]); + } + + return out; +} + +void MimeContentFormatter::setMaxLength(int l) { max_length = l; } + +int MimeContentFormatter::getMaxLength() const { return max_length; } diff --git a/src/smtp/mimefile.cpp b/src/smtp/mimefile.cpp new file mode 100644 index 00000000..96e5172e --- /dev/null +++ b/src/smtp/mimefile.cpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimefile.h" +#include <QFileInfo> + +/* [1] Constructors and Destructors */ + +MimeFile::MimeFile(QFile *file) { + this->file = file; + this->cType = "application/octet-stream"; + this->cName = QFileInfo(*file).fileName(); + this->cEncoding = Base64; +} + +MimeFile::MimeFile(const QByteArray &stream, const QString &fileName) { + this->cEncoding = Base64; + this->cType = "application/octet-stream"; + this->file = 0; + this->cName = fileName; + this->content = stream; +} + +MimeFile::~MimeFile() { + if (file) + delete file; +} + +/* [1] --- */ + +/* [2] Getters and setters */ + +/* [2] --- */ + +/* [3] Protected methods */ + +void MimeFile::prepare() { + if (this->file) { + file->open(QIODevice::ReadOnly); + this->content = file->readAll(); + file->close(); + } + /* !!! IMPORTANT !!!! */ + MimePart::prepare(); +} + +/* [3] --- */ diff --git a/src/smtp/mimehtml.cpp b/src/smtp/mimehtml.cpp new file mode 100644 index 00000000..6d264c15 --- /dev/null +++ b/src/smtp/mimehtml.cpp @@ -0,0 +1,46 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimehtml.h" + +/* [1] Constructors and Destructors */ + +MimeHtml::MimeHtml(const QString &html) : MimeText(html) { + this->cType = "text/html"; +} + +MimeHtml::~MimeHtml() {} + +/* [1] --- */ + +/* [2] Getters and Setters */ + +void MimeHtml::setHtml(const QString &html) { this->text = html; } + +const QString &MimeHtml::getHtml() const { return text; } + +/* [2] --- */ + +/* [3] Protected methods */ + +void MimeHtml::prepare() { + /* !!! IMPORTANT !!! */ + MimeText::prepare(); +} + +/* [3] --- */ diff --git a/src/smtp/mimeinlinefile.cpp b/src/smtp/mimeinlinefile.cpp new file mode 100644 index 00000000..0798696b --- /dev/null +++ b/src/smtp/mimeinlinefile.cpp @@ -0,0 +1,42 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimeinlinefile.h" + +/* [1] Constructors and Destructors */ + +MimeInlineFile::MimeInlineFile(QFile *f) : MimeFile(f) {} + +MimeInlineFile::~MimeInlineFile() {} + +/* [1] --- */ + +/* [2] Getters and Setters */ + +/* [2] --- */ + +/* [3] Protected methods */ + +void MimeInlineFile::prepare() { + this->header += "Content-Disposition: inline\r\n"; + + /* !!! IMPORTANT !!! */ + MimeFile::prepare(); +} + +/* [3] --- */ diff --git a/src/smtp/mimemessage.cpp b/src/smtp/mimemessage.cpp new file mode 100644 index 00000000..5d748bbb --- /dev/null +++ b/src/smtp/mimemessage.cpp @@ -0,0 +1,308 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimemessage.h" +#include "smtp/quotedprintable.h" + +#include <QDateTime> +#include <QLocale> +#include <typeinfo> + +/* [1] Constructors and Destructors */ +MimeMessage::MimeMessage(bool createAutoMimeContent) + : replyTo(nullptr), hEncoding(MimePart::_8Bit) { + if (createAutoMimeContent) + this->content = new MimeMultiPart(); + + autoMimeContentCreated = createAutoMimeContent; +} + +MimeMessage::~MimeMessage() { + if (this->autoMimeContentCreated) { + this->autoMimeContentCreated = false; + delete (this->content); + } +} + +/* [1] --- */ + +/* [2] Getters and Setters */ +MimePart &MimeMessage::getContent() { return *content; } + +void MimeMessage::setContent(MimePart *content) { + if (this->autoMimeContentCreated) { + this->autoMimeContentCreated = false; + delete (this->content); + } + this->content = content; +} + +void MimeMessage::setReplyTo(EmailAddress *rto) { replyTo = rto; } + +void MimeMessage::setSender(EmailAddress *e) { + this->sender = e; + e->setParent(this); +} + +void MimeMessage::addRecipient(EmailAddress *rcpt, RecipientType type) { + switch (type) { + case To: + recipientsTo << rcpt; + break; + case Cc: + recipientsCc << rcpt; + break; + case Bcc: + recipientsBcc << rcpt; + break; + } + + rcpt->setParent(this); +} + +void MimeMessage::addTo(EmailAddress *rcpt) { this->recipientsTo << rcpt; } + +void MimeMessage::addCc(EmailAddress *rcpt) { this->recipientsCc << rcpt; } + +void MimeMessage::addBcc(EmailAddress *rcpt) { this->recipientsBcc << rcpt; } + +void MimeMessage::setSubject(const QString &subject) { + this->subject = subject; +} + +void MimeMessage::addPart(MimePart *part) { + if (typeid(*content) == typeid(MimeMultiPart)) { + ((MimeMultiPart *)content)->addPart(part); + }; +} + +void MimeMessage::setInReplyTo(const QString &inReplyTo) { + mInReplyTo = inReplyTo; +} + +void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc) { + this->hEncoding = hEnc; +} + +const EmailAddress &MimeMessage::getSender() const { return *sender; } + +const QList<EmailAddress *> & +MimeMessage::getRecipients(RecipientType type) const { + switch (type) { + default: + case To: + return recipientsTo; + case Cc: + return recipientsCc; + case Bcc: + return recipientsBcc; + } +} + +const EmailAddress *MimeMessage::getReplyTo() const { return replyTo; } + +const QString &MimeMessage::getSubject() const { return subject; } + +const QList<MimePart *> &MimeMessage::getParts() const { + if (typeid(*content) == typeid(MimeMultiPart)) { + return ((MimeMultiPart *)content)->getParts(); + } else { + QList<MimePart *> *res = new QList<MimePart *>(); + res->append(content); + return *res; + } +} + +/* [2] --- */ + +/* [3] Public Methods */ + +QString MimeMessage::toString() { + QString mime; + + /* =========== MIME HEADER ============ */ + + /* ---------- Sender / From ----------- */ + mime = "From:"; + if (sender->getName() != "") { + switch (hEncoding) { + case MimePart::Base64: + mime += " =?utf-8?B?" + + QByteArray().append(sender->getName().toUtf8()).toBase64() + "?="; + break; + case MimePart::QuotedPrintable: + mime += " =?utf-8?Q?" + + QuotedPrintable::encode( + QByteArray().append(sender->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += " " + sender->getName(); + } + } + mime += " <" + sender->getAddress() + ">\r\n"; + /* ---------------------------------- */ + + /* ------- Recipients / To ---------- */ + mime += "To:"; + QList<EmailAddress *>::iterator it; + int i; + for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) { + if (i != 0) { + mime += ","; + } + + if ((*it)->getName() != "") { + switch (hEncoding) { + case MimePart::Base64: + mime += " =?utf-8?B?" + + QByteArray().append((*it)->getName().toUtf8()).toBase64() + + "?="; + break; + case MimePart::QuotedPrintable: + mime += " =?utf-8?Q?" + + QuotedPrintable::encode( + QByteArray().append((*it)->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += " " + (*it)->getName(); + } + } + mime += " <" + (*it)->getAddress() + ">"; + } + mime += "\r\n"; + /* ---------------------------------- */ + + /* ------- Recipients / Cc ---------- */ + if (recipientsCc.size() != 0) { + mime += "Cc:"; + } + for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i) { + if (i != 0) { + mime += ","; + } + + if ((*it)->getName() != "") { + switch (hEncoding) { + case MimePart::Base64: + mime += " =?utf-8?B?" + + QByteArray().append((*it)->getName().toUtf8()).toBase64() + + "?="; + break; + case MimePart::QuotedPrintable: + mime += " =?utf-8?Q?" + + QuotedPrintable::encode( + QByteArray().append((*it)->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += " " + (*it)->getName(); + } + } + mime += " <" + (*it)->getAddress() + ">"; + } + if (recipientsCc.size() != 0) { + mime += "\r\n"; + } + /* ---------------------------------- */ + + /* ------------ Subject ------------- */ + mime += "Subject: "; + + switch (hEncoding) { + case MimePart::Base64: + mime += "=?utf-8?B?" + QByteArray().append(subject.toUtf8()).toBase64() + "?="; + break; + case MimePart::QuotedPrintable: + mime += "=?utf-8?Q?" + + QuotedPrintable::encode(QByteArray().append(subject.toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += subject; + } + mime += "\r\n"; + /* ---------------------------------- */ + + /* ---------- Reply-To -------------- */ + if (replyTo) { + mime += "Reply-To: "; + if (replyTo->getName() != "") { + switch (hEncoding) { + case MimePart::Base64: + mime += " =?utf-8?B?" + + QByteArray().append(replyTo->getName().toUtf8()).toBase64() + "?="; + break; + case MimePart::QuotedPrintable: + mime += " =?utf-8?Q?" + + QuotedPrintable::encode(QByteArray().append(replyTo->getName().toUtf8())) + .replace(' ', "_") + .replace(':', "=3A") + + "?="; + break; + default: + mime += " " + replyTo->getName(); + } + } + mime += " <" + replyTo->getAddress() + ">\r\n"; + } + + /* ---------------------------------- */ + + mime += "MIME-Version: 1.0\r\n"; + if (!mInReplyTo.isEmpty()) { + mime += "In-Reply-To: <" + mInReplyTo + ">\r\n"; + mime += "References: <" + mInReplyTo + ">\r\n"; + } + + QDateTime now = QDateTime::currentDateTime(); +#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined + QString shortDayName = + QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat); + QString shortMonthName = + QLocale::c().monthName(now.date().month(), QLocale::ShortFormat); + int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60; + char timezoneSign = utcOffset >= 0 ? '+' : '-'; + utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset; + QString timezone = QString("%1%2%3") + .arg(timezoneSign) + .arg(utcOffset / 60, 2, 10, QChar('0')) + .arg(utcOffset % 60, 2, 10, QChar('0')); + mime += QString("Date: %1\r\n") + .arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3") + .arg(shortDayName) + .arg(shortMonthName) + .arg(timezone)); +#else // Qt5 supported + mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date)); +#endif // support RFC2822Date + + mime += content->toString(); + return mime; +} + +/* [3] --- */ diff --git a/src/smtp/mimemultipart.cpp b/src/smtp/mimemultipart.cpp new file mode 100644 index 00000000..8307e6cc --- /dev/null +++ b/src/smtp/mimemultipart.cpp @@ -0,0 +1,72 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimemultipart.h" +#include <QCryptographicHash> +#include <QRandomGenerator> +#include <QTime> + +const QString MULTI_PART_NAMES[] = { + "multipart/mixed", // Mixed + "multipart/digest", // Digest + "multipart/alternative", // Alternative + "multipart/related", // Related + "multipart/report", // Report + "multipart/signed", // Signed + "multipart/encrypted" // Encrypted +}; + +MimeMultiPart::MimeMultiPart(MultiPartType type) { + this->type = type; + this->cType = MULTI_PART_NAMES[this->type]; + this->cEncoding = _8Bit; + + QRandomGenerator generator; + + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(QByteArray().append(generator.generate())); + cBoundary = md5.result().toHex(); +} + +MimeMultiPart::~MimeMultiPart() {} + +void MimeMultiPart::addPart(MimePart *part) { parts.append(part); } + +const QList<MimePart *> &MimeMultiPart::getParts() const { return parts; } + +void MimeMultiPart::prepare() { + QList<MimePart *>::iterator it; + + content = ""; + for (it = parts.begin(); it != parts.end(); it++) { + content += QString("--" + cBoundary + "\r\n").toUtf8(); + (*it)->prepare(); + content += (*it)->toString().toUtf8(); + }; + + content += QString("--" + cBoundary + "--\r\n").toUtf8(); + + MimePart::prepare(); +} + +void MimeMultiPart::setMimeType(const MultiPartType type) { + this->type = type; + this->cType = MULTI_PART_NAMES[type]; +} + +MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const { return type; } diff --git a/src/smtp/mimepart.cpp b/src/smtp/mimepart.cpp new file mode 100644 index 00000000..37acc203 --- /dev/null +++ b/src/smtp/mimepart.cpp @@ -0,0 +1,161 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimepart.h" +#include "smtp/quotedprintable.h" + +/* [1] Constructors and Destructors */ + +MimePart::MimePart() { + cEncoding = _7Bit; + prepared = false; + cBoundary = ""; +} + +MimePart::~MimePart() { return; } + +/* [1] --- */ + +/* [2] Getters and Setters */ + +void MimePart::setContent(const QByteArray &content) { + this->content = content; +} + +void MimePart::setHeader(const QString &header) { this->header = header; } + +void MimePart::addHeaderLine(const QString &line) { + this->header += line + "\r\n"; +} + +const QString &MimePart::getHeader() const { return header; } + +const QByteArray &MimePart::getContent() const { return content; } + +void MimePart::setContentId(const QString &cId) { this->cId = cId; } + +const QString &MimePart::getContentId() const { return this->cId; } + +void MimePart::setContentName(const QString &cName) { this->cName = cName; } + +const QString &MimePart::getContentName() const { return this->cName; } + +void MimePart::setContentType(const QString &cType) { this->cType = cType; } + +const QString &MimePart::getContentType() const { return this->cType; } + +void MimePart::setCharset(const QString &charset) { this->cCharset = charset; } + +const QString &MimePart::getCharset() const { return this->cCharset; } + +void MimePart::setEncoding(Encoding enc) { this->cEncoding = enc; } + +MimePart::Encoding MimePart::getEncoding() const { return this->cEncoding; } + +MimeContentFormatter &MimePart::getContentFormatter() { + return this->formatter; +} + +/* [2] --- */ + +/* [3] Public methods */ + +QString MimePart::toString() { + if (!prepared) + prepare(); + + return mimeString; +} + +/* [3] --- */ + +/* [4] Protected methods */ + +void MimePart::prepare() { + mimeString = QString(); + + /* === Header Prepare === */ + + /* Content-Type */ + mimeString.append("Content-Type: ").append(cType); + + if (cName != "") + mimeString.append("; name=\"").append(cName).append("\""); + + if (cCharset != "") + mimeString.append("; charset=").append(cCharset); + + if (cBoundary != "") + mimeString.append("; boundary=").append(cBoundary); + + mimeString.append("\r\n"); + /* ------------ */ + + /* Content-Transfer-Encoding */ + mimeString.append("Content-Transfer-Encoding: "); + switch (cEncoding) { + case _7Bit: + mimeString.append("7bit\r\n"); + break; + case _8Bit: + mimeString.append("8bit\r\n"); + break; + case Base64: + mimeString.append("base64\r\n"); + break; + case QuotedPrintable: + mimeString.append("quoted-printable\r\n"); + break; + } + /* ------------------------ */ + + /* Content-Id */ + if (cId != NULL) + mimeString.append("Content-ID: <").append(cId).append(">\r\n"); + /* ---------- */ + + /* Addition header lines */ + + mimeString.append(header).append("\r\n"); + + /* ------------------------- */ + + /* === End of Header Prepare === */ + + /* === Content === */ + switch (cEncoding) { + case _7Bit: + mimeString.append(QString(content).toLatin1()); + break; + case _8Bit: + mimeString.append(content); + break; + case Base64: + mimeString.append(formatter.format(content.toBase64())); + break; + case QuotedPrintable: + mimeString.append(formatter.format(QuotedPrintable::encode(content), true)); + break; + } + mimeString.append("\r\n"); + /* === End of Content === */ + + prepared = true; +} + +/* [4] --- */ diff --git a/src/smtp/mimetext.cpp b/src/smtp/mimetext.cpp new file mode 100644 index 00000000..1fe5b96f --- /dev/null +++ b/src/smtp/mimetext.cpp @@ -0,0 +1,52 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/mimetext.h" + +/* [1] Constructors and Destructors */ + +MimeText::MimeText(const QString &txt) { + this->text = txt; + this->cType = "text/plain"; + this->cCharset = "utf-8"; + this->cEncoding = _8Bit; +} + +MimeText::~MimeText() {} + +/* [1] --- */ + +/* [2] Getters and Setters */ + +void MimeText::setText(const QString &text) { this->text = text; } + +const QString &MimeText::getText() const { return text; } + +/* [2] --- */ + +/* [3] Protected Methods */ + +void MimeText::prepare() { + this->content.clear(); + this->content.append(text.toUtf8()); + + /* !!! IMPORTANT !!! */ + MimePart::prepare(); +} + +/* [3] --- */ diff --git a/src/smtp/quotedprintable.cpp b/src/smtp/quotedprintable.cpp new file mode 100644 index 00000000..24b5afa1 --- /dev/null +++ b/src/smtp/quotedprintable.cpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/quotedprintable.h" + +QString QuotedPrintable::encode(const QByteArray &input) { + QString output; + + char byte; + const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + for (int i = 0; i < input.length(); ++i) { + byte = input[i]; + + if ((byte == 0x20) || ((byte >= 33) && (byte <= 126) && (byte != 61))) { + output.append(byte); + } else { + output.append('='); + output.append(hex[((byte >> 4) & 0x0F)]); + output.append(hex[(byte & 0x0F)]); + } + } + + return output; +} + +QByteArray QuotedPrintable::decode(const QString &input) { + // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B + // C D E F + const int hexVal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, + 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15}; + + QByteArray output; + + for (int i = 0; i < input.length(); ++i) { + if (input.at(i).toLatin1() == '=') { + output.append((hexVal[input.at(i + 1).toLatin1() - '0'] << 4) + + hexVal[input.at(i + 2).toLatin1() - '0']); + i += 2; + } else { + output.append(input.at(i).toLatin1()); + } + } + + return output; +} diff --git a/src/smtp/smtpclient.cpp b/src/smtp/smtpclient.cpp new file mode 100644 index 00000000..f1d9fe0d --- /dev/null +++ b/src/smtp/smtpclient.cpp @@ -0,0 +1,405 @@ +/* + Copyright (c) 2011-2012 - Tőkés Attila + + This file is part of SmtpClient for Qt. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + See the LICENSE file for more details. +*/ + +#include "smtp/smtpclient.h" + +#include <QByteArray> +#include <QFileInfo> + +/* [1] Constructors and destructors */ + +SmtpClient::SmtpClient(const QString &host, int port, + ConnectionType connectionType) + : socket(NULL), name("localhost"), authMethod(AuthPlain), + connectionTimeout(5000), responseTimeout(5000), + sendMessageTimeout(60000) { + setConnectionType(connectionType); + + this->host = host; + this->port = port; + + connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, + SLOT(socketStateChanged(QAbstractSocket::SocketState))); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, + SLOT(socketError(QAbstractSocket::SocketError))); + connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead())); +} + +SmtpClient::~SmtpClient() { + if (socket) + delete socket; +} + +/* [1] --- */ + +/* [2] Getters and Setters */ + +void SmtpClient::setUser(const QString &user) { this->user = user; } + +void SmtpClient::setPassword(const QString &password) { + this->password = password; +} + +void SmtpClient::setAuthMethod(AuthMethod method) { this->authMethod = method; } + +void SmtpClient::setHost(const QString &host) { this->host = host; } + +void SmtpClient::setPort(int port) { this->port = port; } + +void SmtpClient::setConnectionType(ConnectionType ct) { + this->connectionType = ct; + + if (socket) + delete socket; + + switch (connectionType) { + case TcpConnection: + socket = new QTcpSocket(this); + break; + case SslConnection: + case TlsConnection: + socket = new QSslSocket(this); + } +} + +const QString &SmtpClient::getHost() const { return this->host; } + +const QString &SmtpClient::getUser() const { return this->user; } + +const QString &SmtpClient::getPassword() const { return this->password; } + +SmtpClient::AuthMethod SmtpClient::getAuthMethod() const { + return this->authMethod; +} + +int SmtpClient::getPort() const { return this->port; } + +SmtpClient::ConnectionType SmtpClient::getConnectionType() const { + return connectionType; +} + +const QString &SmtpClient::getName() const { return this->name; } + +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; } + +int SmtpClient::getConnectionTimeout() const { return connectionTimeout; } + +void SmtpClient::setConnectionTimeout(int msec) { connectionTimeout = msec; } + +int SmtpClient::getResponseTimeout() const { return responseTimeout; } + +void SmtpClient::setResponseTimeout(int msec) { responseTimeout = msec; } +int SmtpClient::getSendMessageTimeout() const { return sendMessageTimeout; } +void SmtpClient::setSendMessageTimeout(int msec) { sendMessageTimeout = msec; } + +/* [2] --- */ + +/* [3] Public methods */ + +bool SmtpClient::connectToHost() { + 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)) { + emit smtpError(ConnectionTimeoutError); + return false; + } + + try { + // Wait for the server's response + waitForResponse(); + + // If the response code is not 220 (Service ready) + // means that is something wrong with the server + if (responseCode != 220) { + emit smtpError(ServerError); + return false; + } + + // Send a EHLO/HELO message to the server + // The client's first command must be EHLO/HELO + 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; + } + + 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) { + return false; + } catch (SendMessageTimeoutException) { + return false; + } + + // If no errors occured the function returns true. + return true; +} + +bool SmtpClient::login() { return login(user, password, authMethod); } + +bool SmtpClient::login(const QString &user, const QString &password, + AuthMethod method) { + try { + if (method == AuthPlain) { + // Sending command: AUTH PLAIN base64('\0' + username + '\0' + password) + sendMessage("AUTH PLAIN " + QByteArray() + .append((char)0) + .append(user.toUtf8()) + .append((char)0) + .append(password.toUtf8()) + .toBase64()); + + // Wait for the server's response + waitForResponse(); + + // If the response is not 235 then the authentication was faild + if (responseCode != 235) { + emit smtpError(AuthenticationFailedError); + return false; + } + } else if (method == AuthLogin) { + // Sending command: AUTH LOGIN + sendMessage("AUTH LOGIN"); + + // Wait for 334 response code + waitForResponse(); + if (responseCode != 334) { + emit smtpError(AuthenticationFailedError); + return false; + } + + // Send the username in base64 + sendMessage(QByteArray().append(user.toUtf8()).toBase64()); + + // Wait for 334 + waitForResponse(); + if (responseCode != 334) { + emit smtpError(AuthenticationFailedError); + return false; + } + + // Send the password in base64 + sendMessage(QByteArray().append(password.toUtf8()).toBase64()); + + // Wait for the server's responce + waitForResponse(); + + // If the response is not 235 then the authentication was faild + if (responseCode != 235) { + emit smtpError(AuthenticationFailedError); + return false; + } + } + } catch (ResponseTimeoutException) { + // Responce Timeout exceeded + emit smtpError(AuthenticationFailedError); + return false; + } catch (SendMessageTimeoutException) { + // Send Timeout exceeded + emit smtpError(AuthenticationFailedError); + return false; + } + + return true; +} + +bool SmtpClient::sendMail(MimeMessage &email) { + try { + // Send the MAIL command with the sender + sendMessage("MAIL FROM:<" + email.getSender().getAddress() + ">"); + + waitForResponse(); + + if (responseCode != 250) + return false; + + // Send RCPT command for each recipient + QList<EmailAddress *>::const_iterator it, itEnd; + // To (primary recipients) + for (it = email.getRecipients().begin(), + itEnd = email.getRecipients().end(); + it != itEnd; ++it) { + + sendMessage("RCPT TO:<" + (*it)->getAddress() + ">"); + waitForResponse(); + + if (responseCode != 250) + return false; + } + + // Cc (carbon copy) + for (it = email.getRecipients(MimeMessage::Cc).begin(), + itEnd = email.getRecipients(MimeMessage::Cc).end(); + it != itEnd; ++it) { + sendMessage("RCPT TO:<" + (*it)->getAddress() + ">"); + waitForResponse(); + + if (responseCode != 250) + return false; + } + + // Bcc (blind carbon copy) + for (it = email.getRecipients(MimeMessage::Bcc).begin(), + itEnd = email.getRecipients(MimeMessage::Bcc).end(); + it != itEnd; ++it) { + sendMessage("RCPT TO:<" + (*it)->getAddress() + ">"); + waitForResponse(); + + if (responseCode != 250) + return false; + } + + // Send DATA command + sendMessage("DATA"); + waitForResponse(); + + if (responseCode != 354) + return false; + + sendMessage(email.toString()); + + // Send \r\n.\r\n to end the mail data + sendMessage("."); + + waitForResponse(); + + if (responseCode != 250) + return false; + } catch (ResponseTimeoutException) { + return false; + } catch (SendMessageTimeoutException) { + return false; + } + + return true; +} + +void SmtpClient::quit() { + try { + sendMessage("QUIT"); + } catch (SmtpClient::SendMessageTimeoutException) { + // Manually close the connection to the smtp server if message "QUIT" wasn't + // received by the smtp server + if (socket->state() == QAbstractSocket::ConnectedState || + socket->state() == QAbstractSocket::ConnectingState || + socket->state() == QAbstractSocket::HostLookupState) + socket->disconnectFromHost(); + } +} + +/* [3] --- */ + +/* [4] Protected methods */ + +void SmtpClient::waitForResponse() { + do { + if (!socket->waitForReadyRead(responseTimeout)) { + emit smtpError(ResponseTimeoutError); + throw ResponseTimeoutException(); + } + + while (socket->canReadLine()) { + // Save the server's response + responseText = socket->readLine(); + + // Extract the respose code from the server's responce (first 3 digits) + responseCode = responseText.left(3).toInt(); + + if (responseCode / 100 == 4) + emit smtpError(ServerError); + + if (responseCode / 100 == 5) + emit smtpError(ClientError); + + if (responseText[3] == ' ') { + return; + } + } + } while (true); +} + +void SmtpClient::sendMessage(const QString &text) { + socket->write(text.toUtf8() + "\r\n"); + if (!socket->waitForBytesWritten(sendMessageTimeout)) { + emit smtpError(SendDataTimeoutError); + throw SendMessageTimeoutException(); + } +} + +/* [4] --- */ + +/* [5] Slots for the socket's signals */ + +void SmtpClient::socketStateChanged(QAbstractSocket::SocketState /*state*/) {} + +void SmtpClient::socketError(QAbstractSocket::SocketError /*socketError*/) {} + +void SmtpClient::socketReadyRead() {} + +/* [5] --- */ |