diff options
Diffstat (limited to 'src')
90 files changed, 1203 insertions, 3731 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 512b7cbd..d17be5e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,12 +8,6 @@ if (UI_CORE) add_subdirectory(ui) endif () -if (SMTP_SUPPORT) - message(STATUS "Build SMTP Support") - add_compile_definitions(SMTP_SUPPORT) - add_subdirectory(smtp) -endif () - if (SERVER_SUPPORT) message(STATUS "Build Server Support") add_compile_definitions(SERVER_SUPPORT) @@ -240,24 +234,18 @@ if (APPLICATION_BUILD) if (ADVANCE_SUPPORT) set(GPGFRONTEND_BEFORE_UI_LIBS ${GPGFRONTEND_BEFORE_UI_LIBS} server) endif () - if (SMTP_SUPPORT) - set(GPGFRONTEND_BEFORE_UI_LIBS ${GPGFRONTEND_BEFORE_UI_LIBS} smtp) - endif () - set(GPGFRONTEND_LIBS ${GPGFRONTEND_AFTER_UI_LIBS} gpgfrontend_ui gpgfrontend_core ${GPGFRONTEND_BEFORE_UI_LIBS} easy_logging_pp) + set(GPGFRONTEND_LIBS ${GPGFRONTEND_AFTER_UI_LIBS} gpgfrontend_ui gpgfrontend_core ${GPGFRONTEND_BEFORE_UI_LIBS} easyloggingpp) set(QT_DEPENDENCY_LIBS Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core) IF (MINGW) message(STATUS "Link Application Static Library For MINGW") - find_library(libconfig NAMES libconfig++.a) - find_library(libintl NAMES libintl.a) - find_library(libiconv NAMES libiconv.a) target_link_libraries(${AppName} ${GPGFRONTEND_LIBS} ${QT_DEPENDENCY_LIBS} ${Boost_LIBRARIES} - ${libintl} ${libiconv} ${libconfig} crypto ssl) + crypto ssl) elseif (APPLE) message(STATUS "Link Application Static Library For macOS") target_link_libraries(${AppName} diff --git a/src/GpgFrontend.h.in b/src/GpgFrontend.h.in index 11934550..c6ff0518 100644 --- a/src/GpgFrontend.h.in +++ b/src/GpgFrontend.h.in @@ -45,7 +45,7 @@ // logging #define ELPP_DEFAULT_LOGGING_FLAGS 8192 -#include <easyloggingpp/easylogging++.h> +#include <easylogging++.h> #define PROJECT_NAME "@CMAKE_PROJECT_NAME@" #define OS_PLATFORM @OS_PLATFORM@ diff --git a/src/before_exit.cpp b/src/before_exit.cpp index ba731203..53878758 100644 --- a/src/before_exit.cpp +++ b/src/before_exit.cpp @@ -22,8 +22,6 @@ * */ -#include <easyloggingpp/easylogging++.h> - #include "ui/settings/GlobalSettingStation.h" void before_exit(int status, void *arg) { diff --git a/src/gpg/CMakeLists.txt b/src/gpg/CMakeLists.txt index f0c4c72e..693b9147 100644 --- a/src/gpg/CMakeLists.txt +++ b/src/gpg/CMakeLists.txt @@ -9,27 +9,20 @@ set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils) set(GPGME_LIB_DIR ${UTILS_DIR}/gpgme/lib) -if (EASY_LOGGING_PP) - set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} easy_logging_pp) -endif () -set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} config++) - +set(THIRD_PARTY_LIBS easyloggingpp config++) set(BOOST_LIBS Boost::date_time Boost::filesystem) if (MINGW) message(STATUS "Link GPG Static Library For MINGW") target_link_libraries(gpgfrontend_core ${THIRD_PARTY_LIBS} ${BOOST_LIBS} - gpgme gpg-error assuan wsock32) + gpgme assuan gpg-error wsock32) target_compile_features(gpgfrontend_core PUBLIC cxx_std_17) elseif (APPLE) - find_library(libgpgme NAMES libgpgme.a) - find_library(libgpg-error NAMES libgpg-error.a) - find_library(libassuan NAMES libassuan.a) message(STATUS "Link GPG Static Library For macOS") target_link_libraries(gpgfrontend_core ${THIRD_PARTY_LIBS} + gpgme assuan gpg-error ${BOOST_LIBS} - ${libgpgme} ${libgpg-error} ${libassuan} dl) if (XCODE_BUILD) set_target_properties(gpgfrontend_core @@ -39,12 +32,9 @@ elseif (APPLE) LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) endif () else () - find_library(libgpgme NAMES libgpgme.a) - find_library(libgpg-error NAMES libgpg-error.a) - find_library(libassuan NAMES libassuan.a) message(STATUS "Link GPG Static Library For Unix") target_link_libraries(gpgfrontend_core ${THIRD_PARTY_LIBS} - ${libgpgme} ${libgpg-error} ${libassuan} + gpgme assuan gpg-error ${BOOST_LIBS} pthread dl) endif () diff --git a/src/gpg/GpgConstants.h b/src/gpg/GpgConstants.h index d2f9b0b6..9ac0d7ad 100644 --- a/src/gpg/GpgConstants.h +++ b/src/gpg/GpgConstants.h @@ -25,7 +25,6 @@ #ifndef GPG_CONSTANTS_H #define GPG_CONSTANTS_H -#include <gpg-error.h> #include <gpgme.h> #include <cassert> diff --git a/src/gpg/GpgFunctionObject.h b/src/gpg/GpgFunctionObject.h index 404b2f84..9a2273d7 100644 --- a/src/gpg/GpgFunctionObject.h +++ b/src/gpg/GpgFunctionObject.h @@ -25,8 +25,6 @@ #ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H #define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H -#include <easyloggingpp/easylogging++.h> - #include <map> #include <memory> #include <mutex> diff --git a/src/gpg/GpgGenKeyInfo.cpp b/src/gpg/GpgGenKeyInfo.cpp index f67aaa1f..1274421d 100644 --- a/src/gpg/GpgGenKeyInfo.cpp +++ b/src/gpg/GpgGenKeyInfo.cpp @@ -24,8 +24,6 @@ #include "gpg/GpgGenKeyInfo.h" -#include <easyloggingpp/easylogging++.h> - #include <boost/date_time/gregorian/greg_date.hpp> #include <boost/date_time/gregorian/greg_duration.hpp> #include <boost/date_time/gregorian/gregorian_types.hpp> diff --git a/src/gpg/GpgGenKeyInfo.h b/src/gpg/GpgGenKeyInfo.h index 8f7d19ea..89030b15 100644 --- a/src/gpg/GpgGenKeyInfo.h +++ b/src/gpg/GpgGenKeyInfo.h @@ -31,6 +31,8 @@ #include <string> #include <vector> +#include "GpgFrontend.h" + namespace GpgFrontend { class GenKeyInfo { diff --git a/src/init.cpp b/src/init.cpp index fffaaa1b..30f0b683 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -94,7 +94,7 @@ void init_locale() { if (!general.exists("lang")) general.add("lang", libconfig::Setting::TypeString) = ""; - GpgFrontend::UI::GlobalSettingStation::GetInstance().Sync(); + GpgFrontend::UI::GlobalSettingStation::GetInstance().SyncSettings(); LOG(INFO) << "current system locale" << setlocale(LC_ALL, nullptr); diff --git a/src/main.cpp b/src/main.cpp index cf97380a..06edc084 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,7 @@ #include "GpgFrontendBuildInfo.h" #include "gpg/GpgFunctionObject.h" #include "ui/MainWindow.h" -#include "ui/function/CtxCheckThread.h" +#include "ui/thread/CtxCheckThread.h" // Easy Logging Cpp INITIALIZE_EASYLOGGINGPP diff --git a/src/signal.cpp b/src/signal.cpp index c5b6727e..c43229b3 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -22,10 +22,10 @@ * */ -#include <easyloggingpp/easylogging++.h> - #include <csetjmp> +#include "GpgFrontend.h" + extern jmp_buf recover_env; void handle_signal(int sig) { diff --git a/src/smtp/CMakeLists.txt b/src/smtp/CMakeLists.txt deleted file mode 100644 index afae322e..00000000 --- a/src/smtp/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -aux_source_directory(. SMTP_MIME_SOURCE) - -add_library(smtp STATIC ${SMTP_MIME_SOURCE}) - -target_link_libraries(smtp - Qt5::Network Qt5::Core) - -if(XCODE_BUILD) -set_target_properties(smtp - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) -endif()
\ No newline at end of file diff --git a/src/smtp/SmtpMime b/src/smtp/SmtpMime deleted file mode 100644 index 940996b8..00000000 --- a/src/smtp/SmtpMime +++ /dev/null @@ -1,31 +0,0 @@ -/* - 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/src/smtp/emailaddress.cpp b/src/smtp/emailaddress.cpp deleted file mode 100644 index c0ecaa0d..00000000 --- a/src/smtp/emailaddress.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - 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/emailaddress.h b/src/smtp/emailaddress.h deleted file mode 100644 index 90e4c1e9..00000000 --- a/src/smtp/emailaddress.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - 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() = default; - - explicit EmailAddress(const QString &address, const QString &name = ""); - - ~EmailAddress() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - void setName(const QString &name); - - void setAddress(const QString &address); - - [[nodiscard]] const QString &getName() const; - - [[nodiscard]] const QString &getAddress() const; - - /* [2] --- */ - - -private: - - /* [3] Private members */ - - QString name; - QString address; - - /* [3] --- */ -}; - -#endif // EMAILADDRESS_H diff --git a/src/smtp/mimeattachment.cpp b/src/smtp/mimeattachment.cpp deleted file mode 100644 index 033eecfb..00000000 --- a/src/smtp/mimeattachment.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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() = default; - -/* [1] --- */ - -/* [2] Protected methods */ - -void MimeAttachment::prepare() { - this->header += "Content-disposition: attachment\r\n"; - - /* !!! IMPORTANT !!! */ - MimeFile::prepare(); -} - -/* [2] --- */ diff --git a/src/smtp/mimeattachment.h b/src/smtp/mimeattachment.h deleted file mode 100644 index 6b98a65a..00000000 --- a/src/smtp/mimeattachment.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - 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 */ - - explicit MimeAttachment(QFile *file); - - MimeAttachment(const QByteArray &stream, const QString &fileName); - - ~MimeAttachment() override; - - /* [1] --- */ - -protected: - - /* [2] Protected methods */ - - void prepare() override; - - /* [2] --- */ -}; - -#endif // MIMEATTACHMENT_H diff --git a/src/smtp/mimecontentformatter.cpp b/src/smtp/mimecontentformatter.cpp deleted file mode 100644 index 8f538457..00000000 --- a/src/smtp/mimecontentformatter.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 (auto i : content) { - chars++; - if (!quotedPrintable) { - if (chars > max_length) { - out.append("\r\n"); - chars = 1; - } - } else { - if (i == '\n') { // new line - out.append(i); - chars = 0; - continue; - } - - if ((chars > max_length - 1) || - ((i == '=') && (chars > max_length - 3))) { - out.append('='); - out.append("\r\n"); - chars = 1; - } - } - out.append(i); - } - - return out; -} - -void MimeContentFormatter::setMaxLength(int l) { max_length = l; } - -int MimeContentFormatter::getMaxLength() const { return max_length; } diff --git a/src/smtp/mimecontentformatter.h b/src/smtp/mimecontentformatter.h deleted file mode 100644 index e6e3637f..00000000 --- a/src/smtp/mimecontentformatter.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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: - explicit MimeContentFormatter(int max_length = 76); - - void setMaxLength(int l); - - [[nodiscard]] int getMaxLength() const; - - [[nodiscard]] QString format(const QString &content, bool quotedPrintable = false) const; - -protected: - int max_length; - -}; - -#endif // MIMECONTENTFORMATTER_H diff --git a/src/smtp/mimefile.cpp b/src/smtp/mimefile.cpp deleted file mode 100644 index 4f095b84..00000000 --- a/src/smtp/mimefile.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - 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 = nullptr; - this->cName = fileName; - this->content = stream; -} - -MimeFile::~MimeFile() { - 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/mimefile.h b/src/smtp/mimefile.h deleted file mode 100644 index 46903da9..00000000 --- a/src/smtp/mimefile.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - 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); - - explicit MimeFile(QFile *f); - - ~MimeFile() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - QFile *file; - - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ - -}; - -#endif // MIMEFILE_H diff --git a/src/smtp/mimehtml.cpp b/src/smtp/mimehtml.cpp deleted file mode 100644 index 9f3a53c3..00000000 --- a/src/smtp/mimehtml.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - 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() = default; - -/* [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/mimehtml.h b/src/smtp/mimehtml.h deleted file mode 100644 index 8ce8c454..00000000 --- a/src/smtp/mimehtml.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - 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 */ - - explicit MimeHtml(const QString &html = ""); - - ~MimeHtml() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - void setHtml(const QString &html); - - [[nodiscard]] const QString &getHtml() const; - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ -}; - -#endif // MIMEHTML_H diff --git a/src/smtp/mimeinlinefile.cpp b/src/smtp/mimeinlinefile.cpp deleted file mode 100644 index a49167e8..00000000 --- a/src/smtp/mimeinlinefile.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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() = default; - -/* [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/mimeinlinefile.h b/src/smtp/mimeinlinefile.h deleted file mode 100644 index 916f7b76..00000000 --- a/src/smtp/mimeinlinefile.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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 */ - - explicit MimeInlineFile(QFile *f); - - ~MimeInlineFile() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ -}; - -#endif // MIMEINLINEFILE_H diff --git a/src/smtp/mimemessage.cpp b/src/smtp/mimemessage.cpp deleted file mode 100644 index 6c058e89..00000000 --- a/src/smtp/mimemessage.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - 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 <QDateTime> -#include <QLocale> -#include <typeinfo> - -#include "smtp/quotedprintable.h" - -/* [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 { - auto *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().isEmpty()) { - 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().isEmpty()) { - 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.empty()) { - 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.empty()) { - 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().isEmpty()) { - 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/mimemessage.h b/src/smtp/mimemessage.h deleted file mode 100644 index 24e4f108..00000000 --- a/src/smtp/mimemessage.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - 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 */ - - explicit MimeMessage(bool createAutoMimeConent = true); - - ~MimeMessage() override; - - /* [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); - - [[nodiscard]] const EmailAddress &getSender() const; - - [[nodiscard]] const QList<EmailAddress *> &getRecipients(RecipientType type = To) const; - - [[nodiscard]] const QString &getSubject() const; - - [[nodiscard]] const QList<MimePart *> &getParts() const; - - [[nodiscard]] 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/src/smtp/mimemultipart.cpp b/src/smtp/mimemultipart.cpp deleted file mode 100644 index 4dd00d1a..00000000 --- a/src/smtp/mimemultipart.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - 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((char)generator.generate())); - cBoundary = md5.result().toHex(); -} - -void MimeMultiPart::addPart(MimePart *part) { parts.append(part); } - -const QList<MimePart *> &MimeMultiPart::getParts() const { return parts; } - -void MimeMultiPart::prepare() { - QList<MimePart *>::iterator it; - - content.clear(); - 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/mimemultipart.h b/src/smtp/mimemultipart.h deleted file mode 100644 index b829a66f..00000000 --- a/src/smtp/mimemultipart.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - 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 */ - explicit MimeMultiPart(MultiPartType type = Related); - - /* [1] --- */ - - /* [2] Getters and Setters */ - - void setMimeType(MultiPartType type); - - [[nodiscard]] MultiPartType getMimeType() const; - - [[nodiscard]] const QList<MimePart *> &getParts() const; - - /* [2] --- */ - - /* [3] Public methods */ - - void addPart(MimePart *part); - - void prepare() override; - - /* [3] --- */ - -protected: - QList<MimePart *> parts; - - MultiPartType type; -}; - -#endif // MIMEMULTIPART_H diff --git a/src/smtp/mimepart.cpp b/src/smtp/mimepart.cpp deleted file mode 100644 index 10aa6cbc..00000000 --- a/src/smtp/mimepart.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - 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.clear(); -} - -/* [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.isEmpty()) - mimeString.append("; name=\"").append(cName).append("\""); - - if (!cCharset.isEmpty()) mimeString.append("; charset=").append(cCharset); - - if (!cBoundary.isEmpty()) 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 != nullptr) - 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/mimepart.h b/src/smtp/mimepart.h deleted file mode 100644 index 1a1386de..00000000 --- a/src/smtp/mimepart.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - 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() = default; - - /* [1] --- */ - - /* [2] Getters and Setters */ - - [[nodiscard]] const QString &getHeader() const; - - [[nodiscard]] const QByteArray &getContent() const; - - void setContent(const QByteArray &content); - - void setHeader(const QString &header); - - void addHeaderLine(const QString &line); - - void setContentId(const QString &cId); - - [[nodiscard]] const QString &getContentId() const; - - void setContentName(const QString &cName); - - [[nodiscard]] const QString &getContentName() const; - - void setContentType(const QString &cType); - - [[nodiscard]] const QString &getContentType() const; - - void setCharset(const QString &charset); - - [[nodiscard]] const QString &getCharset() const; - - void setEncoding(Encoding enc); - - [[nodiscard]] 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/src/smtp/mimetext.cpp b/src/smtp/mimetext.cpp deleted file mode 100644 index 3726647e..00000000 --- a/src/smtp/mimetext.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - 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() = default; - -/* [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/mimetext.h b/src/smtp/mimetext.h deleted file mode 100644 index c21a1c5e..00000000 --- a/src/smtp/mimetext.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - 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 */ - - explicit MimeText(const QString &text = ""); - - ~MimeText() override; - - /* [1] --- */ - - - /* [2] Getters and Setters*/ - - void setText(const QString &text); - - [[nodiscard]] const QString &getText() const; - - /* [2] --- */ - -protected: - - /* [3] Protected members */ - - QString text; - /* [3] --- */ - - - /* [4] Protected methods */ - - void prepare() override; - - /* [4] --- */ - -}; - -#endif // MIMETEXT_H diff --git a/src/smtp/quotedprintable.cpp b/src/smtp/quotedprintable.cpp deleted file mode 100644 index 93e51122..00000000 --- a/src/smtp/quotedprintable.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - 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 (char i : input) { - byte = 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/quotedprintable.h b/src/smtp/quotedprintable.h deleted file mode 100644 index 00ca3cf8..00000000 --- a/src/smtp/quotedprintable.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - 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/src/smtp/smtpclient.cpp b/src/smtp/smtpclient.cpp deleted file mode 100644 index 63202998..00000000 --- a/src/smtp/smtpclient.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* - 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.leftRef(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] --- */ diff --git a/src/smtp/smtpclient.h b/src/smtp/smtpclient.h deleted file mode 100644 index 29c507dc..00000000 --- a/src/smtp/smtpclient.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - 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 */ - - explicit SmtpClient(const QString &host = "localhost", int port = 25, ConnectionType ct = TcpConnection); - - ~SmtpClient() override; - - /* [1] --- */ - - - /* [2] Getters and Setters */ - - [[nodiscard]] const QString &getHost() const; - - void setHost(const QString &host); - - [[nodiscard]] int getPort() const; - - void setPort(int port); - - [[nodiscard]] const QString &getName() const; - - void setName(const QString &name); - - [[nodiscard]] ConnectionType getConnectionType() const; - - void setConnectionType(ConnectionType ct); - - [[nodiscard]] const QString &getUser() const; - - void setUser(const QString &user); - - [[nodiscard]] const QString &getPassword() const; - - void setPassword(const QString &password); - - [[nodiscard]] SmtpClient::AuthMethod getAuthMethod() const; - - void setAuthMethod(AuthMethod method); - - [[nodiscard]] const QString &getResponseText() const; - - [[nodiscard]] int getResponseCode() const; - - [[nodiscard]] int getConnectionTimeout() const; - - void setConnectionTimeout(int msec); - - [[nodiscard]] int getResponseTimeout() const; - - void setResponseTimeout(int msec); - - [[nodiscard]] 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 : public std::exception { - }; - - class SendMessageTimeoutException : public std::exception { - }; - - /* [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/src/smtp/smtpexports.h b/src/smtp/smtpexports.h deleted file mode 100644 index 4bad0da0..00000000 --- a/src/smtp/smtpexports.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SMTPEXPORTS_H -#define SMTPEXPORTS_H - -#ifdef SMTP_BUILD -#define SMTP_EXPORT -#else -#define SMTP_EXPORT -#endif - -#endif // SMTPEXPORTS_H diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index e9e88104..073da46f 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -1,30 +1,48 @@ # tracking source files aux_source_directory(. UI_SOURCE) -aux_source_directory(./aes UI_SOURCE) aux_source_directory(./keypair_details UI_SOURCE) aux_source_directory(./widgets UI_SOURCE) aux_source_directory(./keygen UI_SOURCE) aux_source_directory(./main_window UI_SOURCE) aux_source_directory(./help UI_SOURCE) aux_source_directory(./settings UI_SOURCE) -aux_source_directory(./function UI_SOURCE) +aux_source_directory(./thread UI_SOURCE) aux_source_directory(./details UI_SOURCE) aux_source_directory(./data_struct UI_SOURCE) +aux_source_directory(./encoding UI_SOURCE) if (SMTP_SUPPORT) aux_source_directory(./smtp UI_SOURCE) endif () - add_library(gpgfrontend_ui STATIC ${UI_SOURCE}) set(GPGFRONTEND_UI_LIB_NAME gpgfrontend_ui) + +# link smtp-mime +if (SMTP_SUPPORT) + target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} + smtp-mime) +endif () +# link json +target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} + nlohmann_json::nlohmann_json) +# Qt AES +target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} + QtAES) # link Qt target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core) # link vmime -find_library(libvmime NAMES libvmime.a) target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} - ${libvmime} anl ssl crypto) + vmime-static anl ssl crypto) +# link easyloggingpp +target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} + easyloggingpp) + +# link gpgfrontend_core +target_link_libraries(${GPGFRONTEND_UI_LIB_NAME} + gpgfrontend_core) + target_include_directories(gpgfrontend_ui PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/${GPGFRONTEND_UI_LIB_NAME}_autogen/include) diff --git a/src/ui/FindWidget.cpp b/src/ui/FindWidget.cpp index 6326b119..b95859a1 100644 --- a/src/ui/FindWidget.cpp +++ b/src/ui/FindWidget.cpp @@ -26,8 +26,8 @@ namespace GpgFrontend::UI { -FindWidget::FindWidget(QWidget* parent, QTextEdit* edit) : QWidget(parent) { - mTextpage = edit; +FindWidget::FindWidget(QWidget* parent, PlainTextEditorPage* edit) + : QWidget(parent), mTextpage(edit) { findEdit = new QLineEdit(this); auto* closeButton = new QPushButton( this->style()->standardIcon(QStyle::SP_TitleBarCloseButton), QString(), @@ -55,12 +55,13 @@ FindWidget::FindWidget(QWidget* parent, QTextEdit* edit) : QWidget(parent) { } void FindWidget::setBackground() { - QTextCursor cursor = mTextpage->textCursor(); + auto cursor = mTextpage->getTextPage()->textCursor(); // if match is found set background of QLineEdit to white, otherwise to red QPalette bgPalette(findEdit->palette()); if (!findEdit->text().isEmpty() && - mTextpage->document()->find(findEdit->text()).position() < 0) { + mTextpage->getTextPage()->document()->find(findEdit->text()).position() < + 0) { bgPalette.setColor(QPalette::Base, "#ececba"); } else { bgPalette.setColor(QPalette::Base, Qt::white); @@ -69,45 +70,45 @@ void FindWidget::setBackground() { } void FindWidget::slotFindNext() { - QTextCursor cursor = mTextpage->textCursor(); - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); + QTextCursor cursor = mTextpage->getTextPage()->textCursor(); + cursor = mTextpage->getTextPage()->document()->find( + findEdit->text(), cursor, QTextDocument::FindCaseSensitively); // if end of document is reached, restart search from beginning if (cursor.position() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); + cursor = mTextpage->getTextPage()->document()->find( + findEdit->text(), cursor, QTextDocument::FindCaseSensitively); } // cursor should not stay at -1, otherwise text is not editable // todo: check how gedit handles this if (cursor.position() != -1) { - mTextpage->setTextCursor(cursor); + mTextpage->getTextPage()->setTextCursor(cursor); } this->setBackground(); } void FindWidget::slotFind() { - QTextCursor cursor = mTextpage->textCursor(); + QTextCursor cursor = mTextpage->getTextPage()->textCursor(); if (cursor.anchor() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); + cursor = mTextpage->getTextPage()->document()->find( + findEdit->text(), cursor, QTextDocument::FindCaseSensitively); } else { - cursor = mTextpage->document()->find(findEdit->text(), cursor.anchor(), - QTextDocument::FindCaseSensitively); + cursor = mTextpage->getTextPage()->document()->find( + findEdit->text(), cursor.anchor(), QTextDocument::FindCaseSensitively); } // if end of document is reached, restart search from beginning if (cursor.position() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, - QTextDocument::FindCaseSensitively); + cursor = mTextpage->getTextPage()->document()->find( + findEdit->text(), cursor, QTextDocument::FindCaseSensitively); } // cursor should not stay at -1, otherwise text is not editable // todo: check how gedit handles this if (cursor.position() != -1) { - mTextpage->setTextCursor(cursor); + mTextpage->getTextPage()->setTextCursor(cursor); } this->setBackground(); } @@ -117,19 +118,20 @@ void FindWidget::slotFindPrevious() { flags |= QTextDocument::FindBackward; flags |= QTextDocument::FindCaseSensitively; - QTextCursor cursor = mTextpage->textCursor(); - cursor = mTextpage->document()->find(findEdit->text(), cursor, flags); + QTextCursor cursor = mTextpage->getTextPage()->textCursor(); + cursor = mTextpage->getTextPage()->document()->find(findEdit->text(), cursor, + flags); // if begin of document is reached, restart search from end if (cursor.position() == -1) { - cursor = - mTextpage->document()->find(findEdit->text(), QTextCursor::End, flags); + cursor = mTextpage->getTextPage()->document()->find( + findEdit->text(), QTextCursor::End, flags); } // cursor should not stay at -1, otherwise text is not editable // todo: check how gedit handles this if (cursor.position() != -1) { - mTextpage->setTextCursor(cursor); + mTextpage->getTextPage()->setTextCursor(cursor); } this->setBackground(); } @@ -150,11 +152,11 @@ void FindWidget::keyPressEvent(QKeyEvent* e) { } void FindWidget::slotClose() { - QTextCursor cursor = mTextpage->textCursor(); + QTextCursor cursor = mTextpage->getTextPage()->textCursor(); if (cursor.position() == -1) { cursor.setPosition(0); - mTextpage->setTextCursor(cursor); + mTextpage->getTextPage()->setTextCursor(cursor); } mTextpage->setFocus(); close(); diff --git a/src/ui/FindWidget.h b/src/ui/FindWidget.h index e4cbdaab..bc412012 100644 --- a/src/ui/FindWidget.h +++ b/src/ui/FindWidget.h @@ -26,7 +26,7 @@ #define FINDWIDGET_H #include "ui/GpgFrontendUI.h" -#include "ui/widgets/EditorPage.h" +#include "ui/widgets/PlainTextEditorPage.h" namespace GpgFrontend::UI { @@ -42,7 +42,7 @@ class FindWidget : public QWidget { * * @param parent The parent widget */ - explicit FindWidget(QWidget* parent, QTextEdit* edit); + explicit FindWidget(QWidget* parent, PlainTextEditorPage* edit); private: void keyPressEvent(QKeyEvent* e) override; @@ -53,8 +53,8 @@ class FindWidget : public QWidget { */ void setBackground(); - QTextEdit* mTextpage; /** Textedit associated to the notification */ - QLineEdit* findEdit; /** Label holding the text shown in infoBoard */ + PlainTextEditorPage* mTextpage; /** Textedit associated to the notification */ + QLineEdit* findEdit; /** Label holding the text shown in infoBoard */ private slots: diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h index 90e15324..fd7b814a 100644 --- a/src/ui/GpgFrontendUI.h +++ b/src/ui/GpgFrontendUI.h @@ -36,8 +36,14 @@ #undef LIBCONFIGXX_STATIC #define LIBCONFIGXX_STATIC +#include <qt-aes/qaesencryption.h> + #include <libconfig.h++> +#ifdef SMTP_SUPPORT +#include <SmtpMime> +#endif + /** * Resources File(s) Path Vars */ diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp index 3715b01a..d6656ba3 100755 --- a/src/ui/KeyMgmt.cpp +++ b/src/ui/KeyMgmt.cpp @@ -31,7 +31,6 @@ #include "gpg/function/GpgKeyOpera.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" -#include "ui/aes/qaesencryption.h" #include "ui/keygen/SubkeyGenerateDialog.h" #include "ui/settings/GlobalSettingStation.h" #include "ui/widgets/ExportKeyPackageDialog.h" @@ -371,7 +370,6 @@ void KeyMgmt::slotExportKeyToKeyPackage() { } void KeyMgmt::slotExportKeyToClipboard() { - auto keys_checked = key_list_->getChecked(); if (keys_checked->empty()) { QMessageBox::critical( @@ -465,7 +463,7 @@ void KeyMgmt::slotSaveWindowState() { key_management.add("window_state", libconfig::Setting::TypeString) = saveState().toBase64().toStdString(); - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } void KeyMgmt::slotExportAsOpenSSHFormat() { diff --git a/src/ui/KeyMgmt.h b/src/ui/KeyMgmt.h index e3f250eb..1e0ad5d2 100755 --- a/src/ui/KeyMgmt.h +++ b/src/ui/KeyMgmt.h @@ -25,9 +25,9 @@ #ifndef __KEYMGMT_H__ #define __KEYMGMT_H__ -#include "KeyImportDetailDialog.h" -#include "KeyServerImportDialog.h" #include "ui/GpgFrontendUI.h" +#include "ui/KeyImportDetailDialog.h" +#include "ui/KeyServerImportDialog.h" #include "ui/keygen/KeygenDialog.h" #include "ui/keypair_details/KeyDetailsDialog.h" #include "ui/widgets/KeyList.h" diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp index 9a118b93..7c59de6f 100644 --- a/src/ui/KeyServerImportDialog.cpp +++ b/src/ui/KeyServerImportDialog.cpp @@ -594,7 +594,7 @@ void KeyServerImportDialog::slotSaveWindowState() { import_from_keyserver["size"]["height"] = QWidget::height(); } - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } } // namespace GpgFrontend::UI diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index 2af6da78..2cab0f38 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -26,9 +26,10 @@ #include "ui/UserInterfaceUtils.h" #ifdef RELEASE -#include "ui/function/VersionCheckThread.h" +#include "ui/thread/VersionCheckThread.h" #endif #include "ui/SignalStation.h" +#include "ui/data_struct/SettingsObject.h" #include "ui/settings/GlobalSettingStation.h" namespace GpgFrontend::UI { @@ -143,62 +144,25 @@ void MainWindow::restoreSettings() { LOG(INFO) << _("Called"); try { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); - - if (!settings.exists("window") || - settings.lookup("window").getType() != libconfig::Setting::TypeGroup) - settings.add("window", libconfig::Setting::TypeGroup); - - auto& window = settings["window"]; + SettingsObject main_windows_state("main_windows_state"); - if (!window.exists("window_state")) - window.add("window_state", libconfig::Setting::TypeString) = - saveState().toBase64().toStdString(); - - std::string window_state = settings.lookup("window.window_state"); + std::string window_state = main_windows_state.Check( + "window_state", saveState().toBase64().toStdString()); // state sets pos & size of dock-widgets this->restoreState( QByteArray::fromBase64(QByteArray::fromStdString(window_state))); - if (!window.exists("window_save")) - window.add("window_save", libconfig::Setting::TypeBoolean) = true; - - bool window_save; - window.lookupValue("window_save", window_save); + bool window_save = main_windows_state.Check("window_save", true); // Restore window size & location if (window_save) { - if (!window.exists("window_pos")) - window.add("window_pos", libconfig::Setting::TypeGroup); - - auto& window_pos = window["window_pos"]; - - if (!window_pos.exists("x")) - window_pos.add("x", libconfig::Setting::TypeInt) = 100; - - if (!window_pos.exists("y")) - window_pos.add("y", libconfig::Setting::TypeInt) = 100; - - int x, y; - window_pos.lookupValue("x", x); - window_pos.lookupValue("y", y); + int x = main_windows_state.Check("window_pos").Check("x", 100), + y = main_windows_state.Check("window_pos").Check("y", 100); auto pos = QPoint(x, y); - if (!window.exists("window_size")) - window.add("window_size", libconfig::Setting::TypeGroup); - - auto& window_size = window["window_size"]; - - if (!window_size.exists("width")) - window_size.add("width", libconfig::Setting::TypeInt) = 800; - - if (!window_size.exists("height")) - window_size.add("height", libconfig::Setting::TypeInt) = 450; - - int width, height; - window_size.lookupValue("width", width); - window_size.lookupValue("height", height); + int width = main_windows_state.Check("window_size").Check("width", 800), + height = main_windows_state.Check("window_size").Check("height", 450); auto size = QSize(width, height); this->resize(size); @@ -208,61 +172,36 @@ void MainWindow::restoreSettings() { this->move(QPoint(100, 100)); } - if (!window.exists("icon_size")) - window.add("icon_size", libconfig::Setting::TypeGroup); - - auto& icon_size = window["icon_size"]; - - if (!icon_size.exists("width")) - icon_size.add("width", libconfig::Setting::TypeInt) = 24; - - if (!icon_size.exists("height")) - icon_size.add("height", libconfig::Setting::TypeInt) = 24; - - int width = icon_size["width"], height = icon_size["height"]; + int width = main_windows_state.Check("icon_size").Check("width", 24), + height = main_windows_state.Check("icon_size").Check("height", 24); LOG(INFO) << "icon_size" << width << height; - // info board font size - if (!window.exists("info_font_size")) - window.add("info_font_size", libconfig::Setting::TypeInt) = 10; + main_windows_state.Check("info_font_size", 10); + + // icon_style + int s_icon_style = + main_windows_state.Check("icon_style", Qt::ToolButtonTextUnderIcon); + auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); + this->setToolButtonStyle(icon_style); + importButton->setToolButtonStyle(icon_style); // icons ize this->setIconSize(QSize(width, height)); importButton->setIconSize(QSize(width, height)); - if (!settings.exists("keyserver") || - settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup) - settings.add("keyserver", libconfig::Setting::TypeGroup); - - auto& keyserver = settings["keyserver"]; - - if (!keyserver.exists("server_list")) { - keyserver.add("server_list", libconfig::Setting::TypeList); - - auto& server_list = keyserver["server_list"]; - server_list.add(libconfig::Setting::TypeString) = "http://keys.gnupg.net"; - server_list.add(libconfig::Setting::TypeString) = - "https://keyserver.ubuntu.com"; - server_list.add(libconfig::Setting::TypeString) = - "http://pool.sks-keyservers.net"; - } + SettingsObject key_server_json("key_server"); - if (!keyserver.exists("default_server")) { - keyserver.add("default_server", libconfig::Setting::TypeString) = - "https://keyserver.ubuntu.com"; + if (!key_server_json.contains("server_list")) { + key_server_json["server_list"] = {"https://keyserver.ubuntu.com", + "http://keys.gnupg.net", + "http://pool.sks-keyservers.net"}; } - if (!window.exists("icon_style")) { - window.add("icon_style", libconfig::Setting::TypeInt) = - Qt::ToolButtonTextUnderIcon; + if (!key_server_json.contains("default_server")) { + key_server_json["default_server"] = 0; } - int s_icon_style = window.lookup("icon_style"); - - // icon_style - auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); - this->setToolButtonStyle(icon_style); - importButton->setToolButtonStyle(icon_style); + auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); if (!settings.exists("general") || settings.lookup("general").getType() != libconfig::Setting::TypeGroup) @@ -282,28 +221,24 @@ void MainWindow::restoreSettings() { bool save_key_checked = true; general.lookupValue("save_key_checked", save_key_checked); - // Checked Keys - if (save_key_checked) { - if (!general.exists("save_key_checked_key_ids")) { - general.add("save_key_checked_key_ids", libconfig::Setting::TypeList); - } - auto key_ids_ptr = std::make_unique<KeyIdArgsList>(); - auto& save_key_checked_key_ids = general["save_key_checked_key_ids"]; - const auto key_ids_size = - general.lookup("save_key_checked_key_ids").getLength(); - for (auto i = 0; i < key_ids_size; i++) { - std::string key_id = save_key_checked_key_ids[i]; - LOG(INFO) << "get checked key id" << key_id; - key_ids_ptr->push_back(key_id); + try { + // Checked Keys + SettingsObject default_key_checked("default_key_checked"); + if (save_key_checked) { + auto key_ids_ptr = std::make_unique<KeyIdArgsList>(); + for (auto& it : default_key_checked) { + std::string key_id = it; + LOG(INFO) << "get checked key id" << key_id; + key_ids_ptr->push_back(key_id); + } + mKeyList->setChecked(std::move(key_ids_ptr)); } - mKeyList->setChecked(std::move(key_ids_ptr)); + } catch (...) { + LOG(ERROR) << "restore default_key_checked failed"; } - auto& smtp = settings["smtp"]; - - if (!smtp.exists("enable")) { - smtp.add("enable", libconfig::Setting::TypeBoolean) = true; - } + SettingsObject smtp_passport("smtp_passport"); + smtp_passport.Check("enable", false); prohibit_update_checking_ = false; try { @@ -318,35 +253,34 @@ void MainWindow::restoreSettings() { LOG(ERROR) << "cannot resolve settings"; } - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } void MainWindow::saveSettings() { auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); try { + SettingsObject main_windows_state("main_windows_state"); + // window position and size - settings["window"]["window_state"] = saveState().toBase64().toStdString(); - settings["window"]["window_pos"]["x"] = pos().x(); - settings["window"]["window_pos"]["y"] = pos().y(); + main_windows_state["window_state"] = saveState().toBase64().toStdString(); + main_windows_state["window_pos"]["x"] = pos().x(); + main_windows_state["window_pos"]["y"] = pos().y(); - settings["window"]["window_size"]["width"] = size().width(); - settings["window"]["window_size"]["height"] = size().height(); + main_windows_state["window_size"]["width"] = size().width(); + main_windows_state["window_size"]["height"] = size().height(); bool save_key_checked = settings.lookup("general.save_key_checked"); // keyid-list of private checked keys if (save_key_checked) { - auto& key_ids = settings.lookup("general.save_key_checked_key_ids"); - const int key_ids_size = key_ids.getLength(); - for (auto i = 0; i < key_ids_size; i++) key_ids.remove(i); auto key_ids_need_to_store = mKeyList->getChecked(); - for (size_t i = 0; i < key_ids_need_to_store->size(); i++) { - std::string key_id = (*key_ids_need_to_store)[i]; - key_ids.add(libconfig::Setting::TypeString) = key_id; - } + SettingsObject default_key_checked("default_key_checked"); + default_key_checked.clear(); + for (const auto& key_id : *key_ids_need_to_store) + default_key_checked.push_back(key_id); } else { settings["general"].remove("save_key_checked"); } @@ -354,7 +288,7 @@ void MainWindow::saveSettings() { LOG(ERROR) << "cannot save settings"; }; - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } void MainWindow::closeAttachmentDock() { diff --git a/src/ui/Wizard.cpp b/src/ui/Wizard.cpp index a8576627..78cea649 100644 --- a/src/ui/Wizard.cpp +++ b/src/ui/Wizard.cpp @@ -69,7 +69,7 @@ void Wizard::slotWizardAccepted() { } else { wizard["show_wizard"] = false; } - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } catch (...) { LOG(ERROR) << _("Setting Operation Error"); } diff --git a/src/ui/aes/qaesencryption.cpp b/src/ui/aes/qaesencryption.cpp deleted file mode 100644 index 9103fb8e..00000000 --- a/src/ui/aes/qaesencryption.cpp +++ /dev/null @@ -1,626 +0,0 @@ -#include "qaesencryption.h" -#include <QDebug> -#include <QVector> - -#ifdef USE_INTEL_AES_IF_AVAILABLE -#include "aesni/aesni-key-exp.h" -#include "aesni/aesni-enc-ecb.h" -#include "aesni/aesni-enc-cbc.h" -#endif - -/* - * Static Functions - * */ -QByteArray QAESEncryption::Crypt(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &rawText, - const QByteArray &key, const QByteArray &iv, QAESEncryption::Padding padding) -{ - return QAESEncryption(level, mode, padding).encode(rawText, key, iv); -} - -QByteArray QAESEncryption::Decrypt(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &rawText, - const QByteArray &key, const QByteArray &iv, QAESEncryption::Padding padding) -{ - return QAESEncryption(level, mode, padding).decode(rawText, key, iv); -} - -QByteArray QAESEncryption::ExpandKey(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &key) -{ - return QAESEncryption(level, mode).expandKey(key); -} - -QByteArray QAESEncryption::RemovePadding(const QByteArray &rawText, QAESEncryption::Padding padding) -{ - if (rawText.isEmpty()) - return rawText; - - QByteArray ret(rawText); - switch (padding) - { - case Padding::ZERO: - //Works only if the last byte of the decoded array is not zero - while (ret.at(ret.length()-1) == 0x00) - ret.remove(ret.length()-1, 1); - break; - case Padding::PKCS7: -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - ret.remove(ret.length() - ret.back(), ret.back()); -#else - ret.remove(ret.length() - ret.at(ret.length() - 1), ret.at(ret.length() - 1)); -#endif - break; - case Padding::ISO: - { - // Find the last byte which is not zero - int marker_index = ret.length() - 1; - for (; marker_index >= 0; --marker_index) - { - if (ret.at(marker_index) != 0x00) - { - break; - } - } - - // And check if it's the byte for marking padding - if (ret.at(marker_index) == '\x80') - { - ret.truncate(marker_index); - } - break; - } - default: - //do nothing - break; - } - return ret; -} -/* - * End Static function declarations - * */ - -/* - * Local Functions - * */ - -namespace { - -quint8 xTime(quint8 x) -{ - return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); -} - -quint8 multiply(quint8 x, quint8 y) -{ - return (((y & 1) * x) ^ ((y>>1 & 1) * xTime(x)) ^ ((y>>2 & 1) * xTime(xTime(x))) ^ ((y>>3 & 1) - * xTime(xTime(xTime(x)))) ^ ((y>>4 & 1) * xTime(xTime(xTime(xTime(x)))))); -} - -} - -/* - * End Local functions - * */ - -QAESEncryption::QAESEncryption(Aes level, Mode mode, - Padding padding) - : m_nb(4), m_blocklen(16), m_level(level), m_mode(mode), m_padding(padding) - , m_aesNIAvailable(false), m_state(nullptr) -{ -#ifdef USE_INTEL_AES_IF_AVAILABLE - m_aesNIAvailable = check_aesni_support(); -#endif - - switch (level) - { - case AES_128: { - AES128 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - case AES_192: { - AES192 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - case AES_256: { - AES256 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - default: { - AES128 aes; - m_nk = aes.nk; - m_keyLen = aes.keylen; - m_nr = aes.nr; - m_expandedKey = aes.expandedKey; - } - break; - } - -} -QByteArray QAESEncryption::getPadding(int currSize, int alignment) -{ - int size = (alignment - currSize % alignment) % alignment; - switch(m_padding) - { - case Padding::ZERO: - return QByteArray(size, 0x00); - break; - case Padding::PKCS7: - if (size == 0) - size = alignment; - return QByteArray(size, size); - break; - case Padding::ISO: - if (size > 0) - return QByteArray (size - 1, 0x00).prepend('\x80'); - break; - default: - return QByteArray(size, 0x00); - break; - } - return QByteArray(); -} - -QByteArray QAESEncryption::expandKey(const QByteArray &key) -{ - -#ifdef USE_INTEL_AES_IF_AVAILABLE - if (true){ - switch(m_level) { - case AES_128: { - AES128 aes128; - quint8 ret[aes128.expandedKey]; - memset(ret, 0x00, sizeof(ret)); - quint8 uchar_key[key.size()]; - memcpy(uchar_key, key.data(), key.size()); - AES_128_Key_Expansion(uchar_key, ret); - return QByteArray((char*) ret, aes128.expandedKey); - } - break; - case AES_192: { - AES192 aes192; - quint8 ret[aes192.expandedKey]; - memset(ret, 0x00, sizeof(ret)); - quint8 uchar_key[key.size()]; - memcpy(uchar_key, key.data(), key.size()); - - AES_192_Key_Expansion(uchar_key, ret); - return QByteArray((char*) ret, aes192.expandedKey); - } - break; - case AES_256: { - AES256 aes256; - quint8 ret[aes256.expandedKey]; - memset(ret, 0x00, sizeof(ret)); - quint8 uchar_key[key.size()]; - memcpy(uchar_key, key.data(), key.size()); - - AES_256_Key_Expansion(uchar_key, ret); - return QByteArray((char*) ret, aes256.expandedKey); - } - break; - default: - return QByteArray(); - break; - } - } else -#endif - { - - int i, k; - quint8 tempa[4]; // Used for the column/row operations - QByteArray roundKey(key); // The first round key is the key itself. - - // All other round keys are found from the previous round keys. - //i == Nk - for(i = m_nk; i < m_nb * (m_nr + 1); i++) - { - tempa[0] = (quint8) roundKey.at((i-1) * 4 + 0); - tempa[1] = (quint8) roundKey.at((i-1) * 4 + 1); - tempa[2] = (quint8) roundKey.at((i-1) * 4 + 2); - tempa[3] = (quint8) roundKey.at((i-1) * 4 + 3); - - if (i % m_nk == 0) - { - // This function shifts the 4 bytes in a word to the left once. - // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] - - // Function RotWord() - k = tempa[0]; - tempa[0] = tempa[1]; - tempa[1] = tempa[2]; - tempa[2] = tempa[3]; - tempa[3] = k; - - // Function Subword() - tempa[0] = getSBoxValue(tempa[0]); - tempa[1] = getSBoxValue(tempa[1]); - tempa[2] = getSBoxValue(tempa[2]); - tempa[3] = getSBoxValue(tempa[3]); - - tempa[0] = tempa[0] ^ Rcon[i/m_nk]; - } - - if (m_level == AES_256 && i % m_nk == 4) - { - // Function Subword() - tempa[0] = getSBoxValue(tempa[0]); - tempa[1] = getSBoxValue(tempa[1]); - tempa[2] = getSBoxValue(tempa[2]); - tempa[3] = getSBoxValue(tempa[3]); - } - roundKey.insert(i * 4 + 0, (quint8) roundKey.at((i - m_nk) * 4 + 0) ^ tempa[0]); - roundKey.insert(i * 4 + 1, (quint8) roundKey.at((i - m_nk) * 4 + 1) ^ tempa[1]); - roundKey.insert(i * 4 + 2, (quint8) roundKey.at((i - m_nk) * 4 + 2) ^ tempa[2]); - roundKey.insert(i * 4 + 3, (quint8) roundKey.at((i - m_nk) * 4 + 3) ^ tempa[3]); - } - return roundKey; - } -} - -// This function adds the round key to state. -// The round key is added to the state by an XOR function. -void QAESEncryption::addRoundKey(const quint8 round, const QByteArray &expKey) -{ - QByteArray::iterator it = m_state->begin(); - for(int i=0; i < 16; ++i) - it[i] = (quint8) it[i] ^ (quint8) expKey.at(round * m_nb * 4 + (i/4) * m_nb + (i%4)); -} - -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -void QAESEncryption::subBytes() -{ - QByteArray::iterator it = m_state->begin(); - for(int i = 0; i < 16; i++) - it[i] = getSBoxValue((quint8) it[i]); -} - -// The ShiftRows() function shifts the rows in the state to the left. -// Each row is shifted with different offset. -// Offset = Row number. So the first row is not shifted. -void QAESEncryption::shiftRows() -{ - QByteArray::iterator it = m_state->begin(); - quint8 temp; - //Keep in mind that QByteArray is column-driven!! - - //Shift 1 to left - temp = (quint8)it[1]; - it[1] = (quint8)it[5]; - it[5] = (quint8)it[9]; - it[9] = (quint8)it[13]; - it[13] = (quint8)temp; - - //Shift 2 to left - temp = (quint8)it[2]; - it[2] = (quint8)it[10]; - it[10] = (quint8)temp; - temp = (quint8)it[6]; - it[6] = (quint8)it[14]; - it[14] = (quint8)temp; - - //Shift 3 to left - temp = (quint8)it[3]; - it[3] = (quint8)it[15]; - it[15] = (quint8)it[11]; - it[11] = (quint8)it[7]; - it[7] = (quint8)temp; -} - -// MixColumns function mixes the columns of the state matrix -//optimized!! -void QAESEncryption::mixColumns() -{ - QByteArray::iterator it = m_state->begin(); - quint8 tmp, tm, t; - - for(int i = 0; i < 16; i += 4){ - t = (quint8)it[i]; - tmp = (quint8)it[i] ^ (quint8)it[i+1] ^ (quint8)it[i+2] ^ (quint8)it[i+3] ; - - tm = xTime( (quint8)it[i] ^ (quint8)it[i+1] ); - it[i] = (quint8)it[i] ^ (quint8)tm ^ (quint8)tmp; - - tm = xTime( (quint8)it[i+1] ^ (quint8)it[i+2]); - it[i+1] = (quint8)it[i+1] ^ (quint8)tm ^ (quint8)tmp; - - tm = xTime( (quint8)it[i+2] ^ (quint8)it[i+3]); - it[i+2] =(quint8)it[i+2] ^ (quint8)tm ^ (quint8)tmp; - - tm = xTime((quint8)it[i+3] ^ (quint8)t); - it[i+3] =(quint8)it[i+3] ^ (quint8)tm ^ (quint8)tmp; - } -} - -// MixColumns function mixes the columns of the state matrix. -// The method used to multiply may be difficult to understand for the inexperienced. -// Please use the references to gain more information. -void QAESEncryption::invMixColumns() -{ - QByteArray::iterator it = m_state->begin(); - quint8 a,b,c,d; - for(int i = 0; i < 16; i+=4){ - a = (quint8) it[i]; - b = (quint8) it[i+1]; - c = (quint8) it[i+2]; - d = (quint8) it[i+3]; - - it[i] = (quint8) (multiply(a, 0x0e) ^ multiply(b, 0x0b) ^ multiply(c, 0x0d) ^ multiply(d, 0x09)); - it[i+1] = (quint8) (multiply(a, 0x09) ^ multiply(b, 0x0e) ^ multiply(c, 0x0b) ^ multiply(d, 0x0d)); - it[i+2] = (quint8) (multiply(a, 0x0d) ^ multiply(b, 0x09) ^ multiply(c, 0x0e) ^ multiply(d, 0x0b)); - it[i+3] = (quint8) (multiply(a, 0x0b) ^ multiply(b, 0x0d) ^ multiply(c, 0x09) ^ multiply(d, 0x0e)); - } -} - -// The SubBytes Function Substitutes the values in the -// state matrix with values in an S-box. -void QAESEncryption::invSubBytes() -{ - QByteArray::iterator it = m_state->begin(); - for(int i = 0; i < 16; ++i) - it[i] = getSBoxInvert((quint8) it[i]); -} - -void QAESEncryption::invShiftRows() -{ - QByteArray::iterator it = m_state->begin(); - uint8_t temp; - - //Keep in mind that QByteArray is column-driven!! - - //Shift 1 to right - temp = (quint8)it[13]; - it[13] = (quint8)it[9]; - it[9] = (quint8)it[5]; - it[5] = (quint8)it[1]; - it[1] = (quint8)temp; - - //Shift 2 - temp = (quint8)it[10]; - it[10] = (quint8)it[2]; - it[2] = (quint8)temp; - temp = (quint8)it[14]; - it[14] = (quint8)it[6]; - it[6] = (quint8)temp; - - //Shift 3 - temp = (quint8)it[7]; - it[7] = (quint8)it[11]; - it[11] = (quint8)it[15]; - it[15] = (quint8)it[3]; - it[3] = (quint8)temp; -} - -QByteArray QAESEncryption::byteXor(const QByteArray &a, const QByteArray &b) -{ - QByteArray::const_iterator it_a = a.begin(); - QByteArray::const_iterator it_b = b.begin(); - QByteArray ret; - - //for(int i = 0; i < m_blocklen; i++) - for(int i = 0; i < std::min(a.size(), b.size()); i++) - ret.insert(i,it_a[i] ^ it_b[i]); - - return ret; -} - -// Cipher is the main function that encrypts the PlainText. -QByteArray QAESEncryption::cipher(const QByteArray &expKey, const QByteArray &in) -{ - - //m_state is the input buffer... - QByteArray output(in); - m_state = &output; - - // Add the First round key to the state before starting the rounds. - addRoundKey(0, expKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr-1 rounds are executed in the loop below. - for(quint8 round = 1; round < m_nr; ++round){ - subBytes(); - shiftRows(); - mixColumns(); - addRoundKey(round, expKey); - } - - // The last round is given below. - // The MixColumns function is not here in the last round. - subBytes(); - shiftRows(); - addRoundKey(m_nr, expKey); - - return output; -} - -QByteArray QAESEncryption::invCipher(const QByteArray &expKey, const QByteArray &in) -{ - //m_state is the input buffer.... handle it! - QByteArray output(in); - m_state = &output; - - // Add the First round key to the state before starting the rounds. - addRoundKey(m_nr, expKey); - - // There will be Nr rounds. - // The first Nr-1 rounds are identical. - // These Nr-1 rounds are executed in the loop below. - for(quint8 round=m_nr-1; round>0 ; round--){ - invShiftRows(); - invSubBytes(); - addRoundKey(round, expKey); - invMixColumns(); - } - - // The last round is given below. - // The MixColumns function is not here in the last round. - invShiftRows(); - invSubBytes(); - addRoundKey(0, expKey); - - return output; -} - -QByteArray QAESEncryption::printArray(uchar* arr, int size) -{ - QByteArray print(""); - for(int i=0; i<size; i++) - print.append(arr[i]); - - return print.toHex(); -} - -QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv) -{ - if (m_mode >= CBC && (iv.isEmpty() || iv.size() != m_blocklen)) - return QByteArray(); - - QByteArray expandedKey = expandKey(key); - QByteArray alignedText(rawText); - - //Fill array with padding - alignedText.append(getPadding(rawText.size(), m_blocklen)); - - switch(m_mode) - { - case ECB: { -#ifdef USE_INTEL_AES_IF_AVAILABLE - if (m_aesNIAvailable){ - unsigned char in[alignedText.size()]; - memcpy(in, alignedText.data(), alignedText.size()); - unsigned char out[alignedText.size()]; - memcpy(out, alignedText.data(), alignedText.size()); - char expKey[expandedKey.size()]; - memcpy(expKey, expandedKey.data(), expandedKey.size()); - AES_ECB_encrypt(in, out, alignedText.size(), - expKey, m_nr); - return QByteArray((char*)out, alignedText.size()); - } -#endif - QByteArray ret; - for(int i=0; i < alignedText.size(); i+= m_blocklen) - ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); - return ret; - } - break; - case CBC: { -#ifdef USE_INTEL_AES_IF_AVAILABLE - if (m_aesNIAvailable){ - quint8 in[alignedText.size()]; - memcpy(in, alignedText.constData(), alignedText.size()); - quint8 ivec[iv.size()]; - memcpy(ivec, iv.data(), iv.size()); - char out[alignedText.size()]; - memset(out, 0x00, alignedText.size()); - char expKey[expandedKey.size()]; - memcpy(expKey, expandedKey.data(), expandedKey.size()); - AES_CBC_encrypt(in, - (unsigned char*) out, - ivec, - alignedText.size(), - expKey, - m_nr); - return QByteArray(out, alignedText.size()); - } -#endif - QByteArray ret; - QByteArray ivTemp(iv); - for(int i=0; i < alignedText.size(); i+= m_blocklen) { - alignedText.replace(i, m_blocklen, byteXor(alignedText.mid(i, m_blocklen),ivTemp)); - ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); - ivTemp = ret.mid(i, m_blocklen); - } - return ret; - } - break; - case CFB: { - QByteArray ret; - ret.append(byteXor(alignedText.left(m_blocklen), cipher(expandedKey, iv))); - for(int i=0; i < alignedText.size(); i+= m_blocklen) { - if (i+m_blocklen < alignedText.size()) - ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, ret.mid(i, m_blocklen)))); - } - return ret; - } - break; - case OFB: { - QByteArray ret; - QByteArray ofbTemp; - ofbTemp.append(cipher(expandedKey, iv)); - for (int i=m_blocklen; i < alignedText.size(); i += m_blocklen){ - ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen))); - } - ret.append(byteXor(alignedText, ofbTemp)); - return ret; - } - break; - default: break; - } - return QByteArray(); -} - -QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv) -{ - if (m_mode >= CBC && (iv.isEmpty() || iv.size() != m_blocklen)) - return QByteArray(); - - QByteArray ret; - QByteArray expandedKey = expandKey(key); - - switch(m_mode) - { - case ECB: - for(int i=0; i < rawText.size(); i+= m_blocklen) - ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); - break; - case CBC: { - QByteArray ivTemp(iv); - for(int i=0; i < rawText.size(); i+= m_blocklen){ - ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); - ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),ivTemp)); - ivTemp = rawText.mid(i, m_blocklen); - } - } - break; - case CFB: { - ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv))); - for(int i=0; i < rawText.size(); i+= m_blocklen){ - if (i+m_blocklen < rawText.size()) { - ret.append(byteXor(rawText.mid(i+m_blocklen, m_blocklen), - cipher(expandedKey, rawText.mid(i, m_blocklen)))); - } - } - } - break; - case OFB: { - QByteArray ofbTemp; - ofbTemp.append(cipher(expandedKey, iv)); - for (int i=m_blocklen; i < rawText.size(); i += m_blocklen){ - ofbTemp.append(cipher(expandedKey, ofbTemp.right(m_blocklen))); - } - ret.append(byteXor(rawText, ofbTemp)); - } - break; - default: - //do nothing - break; - } - return ret; -} - -QByteArray QAESEncryption::removePadding(const QByteArray &rawText) -{ - return RemovePadding(rawText, (Padding) m_padding); -} diff --git a/src/ui/aes/qaesencryption.h b/src/ui/aes/qaesencryption.h deleted file mode 100644 index ec8023b3..00000000 --- a/src/ui/aes/qaesencryption.h +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef QAESENCRYPTION_H -#define QAESENCRYPTION_H - -#ifdef QtAES_EXPORTS -#include "qtaes_export.h" -#else -#define QTAESSHARED_EXPORT -#endif - -#include <QByteArray> -#include <QObject> - -#ifdef __linux__ -#ifndef __LP64__ -#define do_rdtsc _do_rdtsc -#endif -#endif - -class QTAESSHARED_EXPORT QAESEncryption : public QObject { - Q_OBJECT - public: - enum Aes { AES_128, AES_192, AES_256 }; - - enum Mode { ECB, CBC, CFB, OFB }; - - enum Padding { ZERO, PKCS7, ISO }; - - static QByteArray Crypt( - QAESEncryption::Aes level, QAESEncryption::Mode mode, - const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray(), - QAESEncryption::Padding padding = QAESEncryption::ISO); - static QByteArray Decrypt( - QAESEncryption::Aes level, QAESEncryption::Mode mode, - const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray(), - QAESEncryption::Padding padding = QAESEncryption::ISO); - static QByteArray ExpandKey(QAESEncryption::Aes level, - QAESEncryption::Mode mode, const QByteArray &key); - static QByteArray RemovePadding( - const QByteArray &rawText, - QAESEncryption::Padding padding = QAESEncryption::ISO); - - QAESEncryption(QAESEncryption::Aes level, QAESEncryption::Mode mode, - QAESEncryption::Padding padding = QAESEncryption::ISO); - - QByteArray encode(const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray()); - QByteArray decode(const QByteArray &rawText, const QByteArray &key, - const QByteArray &iv = QByteArray()); - QByteArray removePadding(const QByteArray &rawText); - QByteArray expandKey(const QByteArray &key); - - QByteArray printArray(uchar *arr, int size); - Q_SIGNALS: - - public Q_SLOTS: - - private: - int m_nb; - int m_blocklen; - int m_level; - int m_mode; - int m_nk; - int m_keyLen; - quint8 m_nr; - int m_expandedKey; - int m_padding; - bool m_aesNIAvailable; - QByteArray *m_state; - - struct AES256 { - int nk = 8; - int keylen = 32; - int nr = 14; - int expandedKey = 240; - }; - - struct AES192 { - int nk = 6; - int keylen = 24; - int nr = 12; - int expandedKey = 209; - }; - - struct AES128 { - int nk = 4; - int keylen = 16; - int nr = 10; - int expandedKey = 176; - }; - - quint8 getSBoxValue(quint8 num) { return sbox[num]; } - quint8 getSBoxInvert(quint8 num) { return rsbox[num]; } - - void addRoundKey(const quint8 round, const QByteArray &expKey); - void subBytes(); - void shiftRows(); - void mixColumns(); - void invMixColumns(); - void invSubBytes(); - void invShiftRows(); - QByteArray getPadding(int currSize, int alignment); - QByteArray cipher(const QByteArray &expKey, const QByteArray &in); - QByteArray invCipher(const QByteArray &expKey, const QByteArray &in); - QByteArray byteXor(const QByteArray &a, const QByteArray &b); - - const quint8 sbox[256] = { - // 0 1 2 3 4 5 6 7 8 9 A B C - // D E F - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, - 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, - 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, - 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, - 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, - 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, - 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, - 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, - 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, - 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, - 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, - 0xb0, 0x54, 0xbb, 0x16}; - - const quint8 rsbox[256] = { - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, - 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, - 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, - 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, - 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, - 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, - 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, - 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, - 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, - 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0c, 0x7d}; - - // The round constant word array, Rcon[i], contains the values given by - // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field - // GF(2^8) Only the first 14 elements are needed - const quint8 Rcon[14] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, - 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab}; -}; - -#endif // QAESENCRYPTION_H diff --git a/src/ui/data_struct/SettingsObject.cpp b/src/ui/data_struct/SettingsObject.cpp new file mode 100644 index 00000000..d8d1b76c --- /dev/null +++ b/src/ui/data_struct/SettingsObject.cpp @@ -0,0 +1,61 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "SettingsObject.h" + +nlohmann::json& GpgFrontend::UI::SettingsObject::Check( + const std::string& key, nlohmann::json default_value) { + if (!nlohmann::json::contains(key)) + nlohmann::json::operator[](key) = std::move(default_value); + return nlohmann::json::operator[](key); +} + +GpgFrontend::UI::SettingsObject GpgFrontend::UI::SettingsObject::Check( + const std::string& key) { + if (!nlohmann::json::contains(key)) nlohmann::json::operator[](key) = {}; + return SettingsObject{nlohmann::json::operator[](key), false}; +} + +GpgFrontend::UI::SettingsObject::SettingsObject(std::string settings_name) + : settings_name_(std::move(settings_name)) { + try { + auto _json_optional = + GlobalSettingStation::GetInstance().GetDataObject(settings_name_); + + if (_json_optional.has_value()) { + nlohmann::json::operator=(_json_optional.value()); + } + + } catch (...) { + } +} + +GpgFrontend::UI::SettingsObject::SettingsObject(nlohmann::json _sub_json, bool) + : nlohmann::json(std::move(_sub_json)), settings_name_({}) {} + +GpgFrontend::UI::SettingsObject::~SettingsObject() { + if (!settings_name_.empty()) + GpgFrontend::UI::GlobalSettingStation::GetInstance().SaveDataObj( + settings_name_, *this); +} diff --git a/src/ui/data_struct/SettingsObject.h b/src/ui/data_struct/SettingsObject.h new file mode 100644 index 00000000..af63b74f --- /dev/null +++ b/src/ui/data_struct/SettingsObject.h @@ -0,0 +1,51 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_SETTINGSOBJECT_H +#define GPGFRONTEND_SETTINGSOBJECT_H + +#include <utility> + +#include "ui/settings/GlobalSettingStation.h" + +namespace GpgFrontend::UI { + +class SettingsObject : public nlohmann::json { + public: + explicit SettingsObject(std::string settings_name); + + explicit SettingsObject(nlohmann::json _sub_json, bool); + + ~SettingsObject(); + + nlohmann::json& Check(const std::string& key, nlohmann::json default_value); + + SettingsObject Check(const std::string& key); + + private: + std::string settings_name_; +}; +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SETTINGSOBJECT_H diff --git a/src/ui/details/VerifyDetailsDialog.h b/src/ui/details/VerifyDetailsDialog.h index 5de648f6..21affdb4 100644 --- a/src/ui/details/VerifyDetailsDialog.h +++ b/src/ui/details/VerifyDetailsDialog.h @@ -26,7 +26,7 @@ #define __VERIFYDETAILSDIALOG_H__ #include "ui/GpgFrontendUI.h" -#include "ui/widgets/EditorPage.h" +#include "ui/widgets/PlainTextEditorPage.h" #include "ui/widgets/VerifyKeyDetailBox.h" namespace GpgFrontend::UI { diff --git a/src/ui/encoding/TextEncodingDetect.cpp b/src/ui/encoding/TextEncodingDetect.cpp new file mode 100644 index 00000000..22ae5897 --- /dev/null +++ b/src/ui/encoding/TextEncodingDetect.cpp @@ -0,0 +1,313 @@ +// +// Copyright 2015-2016 Jonathan Bennett <[email protected]> +// +// https://www.autoitscript.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Includes +#include "TextEncodingDetect.h" + +using namespace AutoIt::Common; + +static const unsigned char TextEncodingDetect_UTF16_BOM_LE[] = { + (unsigned char)(0xFF), (unsigned char)(0xFE)}; +static const unsigned char TextEncodingDetect_UTF16_BOM_BE[] = { + (unsigned char)(0xFE), (unsigned char)(0xFF)}; +static const unsigned char TextEncodingDetect_UTF8_BOM[] = { + (unsigned char)(0xEF), (unsigned char)(0xBB), (unsigned char)(0xBF)}; + +const unsigned char *TextEncodingDetect::utf16_bom_le_ = + TextEncodingDetect_UTF16_BOM_LE; +const unsigned char *TextEncodingDetect::utf16_bom_be_ = + TextEncodingDetect_UTF16_BOM_BE; +const unsigned char *TextEncodingDetect::utf8_bom_ = + TextEncodingDetect_UTF8_BOM; + +/////////////////////////////////////////////////////////////////////////////// +// Constructor() +// Default constructor +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::TextEncodingDetect() { + // By default, assume nulls can't appear in ANSI/ASCII/UTF8 text files + null_suggests_binary_ = true; + + // Set defaults for utf16 detection based the use of odd/even nulls + utf16_expected_null_percent_ = 70; + utf16_unexpected_null_percent_ = 10; +} + +/////////////////////////////////////////////////////////////////////////////// +// Set the percentages used in utf16 detection using nulls. +/////////////////////////////////////////////////////////////////////////////// + +void TextEncodingDetect::SetUtf16UnexpectedNullPercent(int percent) { + if (percent > 0 && percent < 100) utf16_expected_null_percent_ = percent; +} + +void TextEncodingDetect::SetUtf16ExpectedNullPercent(int percent) { + if (percent > 0 && percent < 100) utf16_unexpected_null_percent_ = percent; +} + +/////////////////////////////////////////////////////////////////////////////// +// Simple function to return the length of the BOM for a particular encoding +// mode. +/////////////////////////////////////////////////////////////////////////////// + +int TextEncodingDetect::GetBOMLengthFromEncodingMode(Encoding encoding) { + int length = 0; + + if (encoding == UTF16_BE_BOM || encoding == UTF16_LE_BOM) + length = 2; + else if (encoding == UTF8_BOM) + length = 3; + + return length; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains a valid BOM and returns the encoding based on it. +// Returns encoding "None" if there is no BOM. +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckBOM( + const unsigned char *pBuffer, size_t size) { + // Check for BOM + if (size >= 2 && pBuffer[0] == utf16_bom_le_[0] && + pBuffer[1] == utf16_bom_le_[1]) { + return UTF16_LE_BOM; + } else if (size >= 2 && pBuffer[0] == utf16_bom_be_[0] && + pBuffer[1] == utf16_bom_be_[1]) { + return UTF16_BE_BOM; + } else if (size >= 3 && pBuffer[0] == utf8_bom_[0] && + pBuffer[1] == utf8_bom_[1] && pBuffer[2] == utf8_bom_[2]) { + return UTF8_BOM; + } else { + return None; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains a valid BOM and returns the encoding based on it. +// If it doesn't contain a BOM it tries to guess what the encoding is or +// "None" if it just looks like binary data. +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::DetectEncoding( + const unsigned char *pBuffer, size_t size) const { + // First check if we have a BOM and return that if so + Encoding encoding = CheckBOM(pBuffer, size); + if (encoding != None) return encoding; + + // Now check for valid UTF8 + encoding = CheckUTF8(pBuffer, size); + if (encoding != None) return encoding; + + // Now try UTF16 + encoding = CheckUTF16NewlineChars(pBuffer, size); + if (encoding != None) return encoding; + + encoding = CheckUTF16ASCII(pBuffer, size); + if (encoding != None) return encoding; + + // ANSI or None (binary) then + if (!DoesContainNulls(pBuffer, size)) + return ANSI; + else { + // Found a null, return based on the preference in null_suggests_binary_ + if (null_suggests_binary_) + return None; + else + return ANSI; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains valid utf8. Returns: +// None - not valid utf8 +// UTF8_NOBOM - valid utf8 encodings and multibyte sequences +// ASCII - Only data in the 0-127 range. +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckUTF8( + const unsigned char *pBuffer, size_t size) const { + // UTF8 Valid sequences + // 0xxxxxxx ASCII + // 110xxxxx 10xxxxxx 2-byte + // 1110xxxx 10xxxxxx 10xxxxxx 3-byte + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4-byte + // + // Width in UTF8 + // Decimal Width + // 0-127 1 byte + // 194-223 2 bytes + // 224-239 3 bytes + // 240-244 4 bytes + // + // Subsequent chars are in the range 128-191 + + bool only_saw_ascii_range = true; + size_t pos = 0; + int more_chars; + + while (pos < size) { + unsigned char ch = pBuffer[pos++]; + + if (ch == 0 && null_suggests_binary_) { + return None; + } else if (ch <= 127) { + // 1 byte + more_chars = 0; + } else if (ch >= 194 && ch <= 223) { + // 2 Byte + more_chars = 1; + } else if (ch >= 224 && ch <= 239) { + // 3 Byte + more_chars = 2; + } else if (ch >= 240 && ch <= 244) { + // 4 Byte + more_chars = 3; + } else { + return None; // Not utf8 + } + + // Check secondary chars are in range if we are expecting any + while (more_chars && pos < size) { + only_saw_ascii_range = false; // Seen non-ascii chars now + + ch = pBuffer[pos++]; + if (ch < 128 || ch > 191) return None; // Not utf8 + + --more_chars; + } + } + + // If we get to here then only valid UTF-8 sequences have been processed + + // If we only saw chars in the range 0-127 then we can't assume UTF8 (the + // caller will need to decide) + if (only_saw_ascii_range) + return ASCII; + else + return UTF8_NOBOM; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains text that looks like utf16 by scanning for +// newline chars that would be present even in non-english text. +// Returns: +// None - not valid utf16 +// UTF16_LE_NOBOM - looks like utf16 le +// UTF16_BE_NOBOM - looks like utf16 be +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckUTF16NewlineChars( + const unsigned char *pBuffer, size_t size) { + if (size < 2) return None; + + // Reduce size by 1 so we don't need to worry about bounds checking for pairs + // of bytes + size--; + + int le_control_chars = 0; + int be_control_chars = 0; + unsigned char ch1, ch2; + + size_t pos = 0; + while (pos < size) { + ch1 = pBuffer[pos++]; + ch2 = pBuffer[pos++]; + + if (ch1 == 0) { + if (ch2 == 0x0a || ch2 == 0x0d) ++be_control_chars; + } else if (ch2 == 0) { + if (ch1 == 0x0a || ch1 == 0x0d) ++le_control_chars; + } + + // If we are getting both LE and BE control chars then this file is not + // utf16 + if (le_control_chars && be_control_chars) return None; + } + + if (le_control_chars) + return UTF16_LE_NOBOM; + else if (be_control_chars) + return UTF16_BE_NOBOM; + else + return None; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains text that looks like utf16. This is done based +// the use of nulls which in ASCII/script like text can be useful to identify. +// Returns: +// None - not valid utf16 +// UTF16_LE_NOBOM - looks like utf16 le +// UTF16_BE_NOBOM - looks like utf16 be +/////////////////////////////////////////////////////////////////////////////// + +TextEncodingDetect::Encoding TextEncodingDetect::CheckUTF16ASCII( + const unsigned char *pBuffer, size_t size) const { + int num_odd_nulls = 0; + int num_even_nulls = 0; + + // Get even nulls + size_t pos = 0; + while (pos < size) { + if (pBuffer[pos] == 0) num_even_nulls++; + + pos += 2; + } + + // Get odd nulls + pos = 1; + while (pos < size) { + if (pBuffer[pos] == 0) num_odd_nulls++; + + pos += 2; + } + + double even_null_threshold = (num_even_nulls * 2.0) / size; + double odd_null_threshold = (num_odd_nulls * 2.0) / size; + double expected_null_threshold = utf16_expected_null_percent_ / 100.0; + double unexpected_null_threshold = utf16_unexpected_null_percent_ / 100.0; + + // Lots of odd nulls, low number of even nulls + if (even_null_threshold < unexpected_null_threshold && + odd_null_threshold > expected_null_threshold) + return UTF16_LE_NOBOM; + + // Lots of even nulls, low number of odd nulls + if (odd_null_threshold < unexpected_null_threshold && + even_null_threshold > expected_null_threshold) + return UTF16_BE_NOBOM; + + // Don't know + return None; +} + +/////////////////////////////////////////////////////////////////////////////// +// Checks if a buffer contains any nulls. Used to check for binary vs text data. +/////////////////////////////////////////////////////////////////////////////// + +bool TextEncodingDetect::DoesContainNulls(const unsigned char *pBuffer, + size_t size) { + size_t pos = 0; + while (pos < size) { + if (pBuffer[pos++] == 0) return true; + } + + return false; +} diff --git a/src/ui/encoding/TextEncodingDetect.h b/src/ui/encoding/TextEncodingDetect.h new file mode 100644 index 00000000..6d861716 --- /dev/null +++ b/src/ui/encoding/TextEncodingDetect.h @@ -0,0 +1,85 @@ +#pragma once +#ifndef TEXT_ENCODING_DETECT_H_ +#define TEXT_ENCODING_DETECT_H_ + +// +// Copyright 2015 Jonathan Bennett <[email protected]> +// +// https://www.autoitscript.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Includes +#include <stddef.h> + +namespace AutoIt::Common { +class TextEncodingDetect { + public: + enum Encoding { + None, // Unknown or binary + ANSI, // 0-255 + ASCII, // 0-127 + UTF8_BOM, // UTF8 with BOM + UTF8_NOBOM, // UTF8 without BOM + UTF16_LE_BOM, // UTF16 LE with BOM + UTF16_LE_NOBOM, // UTF16 LE without BOM + UTF16_BE_BOM, // UTF16-BE with BOM + UTF16_BE_NOBOM, // UTF16-BE without BOM + }; + + TextEncodingDetect(); + ~TextEncodingDetect() = default; + + static Encoding CheckBOM( + const unsigned char *pBuffer, + size_t size); // Just check if there is a BOM and return + Encoding DetectEncoding(const unsigned char *pBuffer, size_t size) + const; // Check BOM and also guess if there is no BOM + static int GetBOMLengthFromEncodingMode( + Encoding encoding); // Just return the BOM length of a given mode + + void SetNullSuggestsBinary(bool null_suggests_binary) { + null_suggests_binary_ = null_suggests_binary; + } + void SetUtf16UnexpectedNullPercent(int percent); + void SetUtf16ExpectedNullPercent(int percent); + + private: + TextEncodingDetect(const TextEncodingDetect &); + const TextEncodingDetect &operator=(const TextEncodingDetect &); + + static const unsigned char *utf16_bom_le_; + static const unsigned char *utf16_bom_be_; + static const unsigned char *utf8_bom_; + + bool null_suggests_binary_; + int utf16_expected_null_percent_; + int utf16_unexpected_null_percent_; + + Encoding CheckUTF8(const unsigned char *pBuffer, + size_t size) const; // Check for valid UTF8 with no BOM + static Encoding CheckUTF16NewlineChars( + const unsigned char *pBuffer, + size_t size); // Check for valid UTF16 with no BOM via control chars + Encoding CheckUTF16ASCII(const unsigned char *pBuffer, size_t size) + const; // Check for valid UTF16 with no BOM via null distribution + static bool DoesContainNulls(const unsigned char *pBuffer, + size_t size); // Check for nulls +}; + +} // namespace AutoIt::Common + +////////////////////////////////////////////////////////////////////// + +#endif diff --git a/src/ui/help/AboutDialog.cpp b/src/ui/help/AboutDialog.cpp index 78ff5557..91e2923e 100644 --- a/src/ui/help/AboutDialog.cpp +++ b/src/ui/help/AboutDialog.cpp @@ -25,8 +25,8 @@ #include "ui/help/AboutDialog.h" #include "GpgFrontendBuildInfo.h" -#include "function/VersionCheckThread.h" #include "ui/settings/GlobalSettingStation.h" +#include "ui/thread/VersionCheckThread.h" namespace GpgFrontend::UI { diff --git a/src/ui/keypair_details/KeyPairOperaTab.cpp b/src/ui/keypair_details/KeyPairOperaTab.cpp index 57eb8164..0ee61593 100644 --- a/src/ui/keypair_details/KeyPairOperaTab.cpp +++ b/src/ui/keypair_details/KeyPairOperaTab.cpp @@ -64,7 +64,7 @@ KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent) auto* edit_password_button = new QPushButton(_("Modify Password")); connect(edit_password_button, SIGNAL(clicked()), this, SLOT(slotModifyPassword())); - + vbox_p_k->addWidget(edit_expires_button); vbox_p_k->addWidget(edit_password_button); } diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp index 286cef3a..3f509f3c 100644 --- a/src/ui/main_window/MainWindowFileSlotFunction.cpp +++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp @@ -211,8 +211,8 @@ void MainWindow::slotFileSign() { if (keys->empty()) { QMessageBox::critical( - this, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check the key in the key toolbox on the right.")); return; } @@ -383,8 +383,8 @@ void MainWindow::slotFileEncryptSign() { if (p_keys->empty()) { QMessageBox::critical( - this, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check the key in the key toolbox on the right.")); return; } diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 57fb5bae..593fe6fe 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -61,7 +61,7 @@ void MainWindow::slotEncrypt() { // Symmetric Encrypt auto ret = QMessageBox::information( this, _("Symmetric Encryption"), - _("No Key Selected. Do you want to encrypt with a " + _("No Key Checked. Do you want to encrypt with a " "symmetric cipher using a passphrase?"), QMessageBox::Ok | QMessageBox::Cancel); @@ -69,7 +69,8 @@ void MainWindow::slotEncrypt() { process_operation(this, _("Symmetrically Encrypting"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); + auto buffer = + edit->curTextPage()->getTextPage()->toPlainText().toStdString(); error = GpgFrontend::BasicOperator::GetInstance().EncryptSymmetric( buffer, tmp, result); } catch (const std::runtime_error& e) { @@ -82,7 +83,7 @@ void MainWindow::slotEncrypt() { for (const auto& key : *keys) { if (!key.CanEncrActual()) { QMessageBox::information( - nullptr, _("Invalid Operation"), + this, _("Invalid Operation"), QString(_( "The selected key contains a key that does not actually have a " "encrypt usage.")) + @@ -94,7 +95,8 @@ void MainWindow::slotEncrypt() { process_operation(this, _("Encrypting"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); + auto buffer = + edit->curTextPage()->getTextPage()->toPlainText().toStdString(); error = GpgFrontend::BasicOperator::GetInstance().Encrypt( std::move(keys), buffer, tmp, result); } catch (const std::runtime_error& e) { @@ -114,7 +116,8 @@ void MainWindow::slotEncrypt() { infoBoard->resetOptionActionsMenu(); #ifdef SMTP_SUPPORT if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - send_an_email(this, infoBoard, edit->curTextPage()->toPlainText()); + send_an_email(this, infoBoard, + edit->curTextPage()->getTextPage()->toPlainText()); #endif } else { QMessageBox::critical(this, _("Error"), @@ -130,8 +133,8 @@ void MainWindow::slotSign() { if (key_ids->empty()) { QMessageBox::critical( - this, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check the key in the key toolbox on the right.")); return; } @@ -157,7 +160,11 @@ void MainWindow::slotSign() { process_operation(this, _("Signing"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); + auto buffer = edit->curTextPage() + ->getTextPage() + ->toPlainText() + .toUtf8() + .toStdString(); error = GpgFrontend::BasicOperator::GetInstance().Sign( std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result); } catch (const std::runtime_error& e) { @@ -183,7 +190,7 @@ void MainWindow::slotDecrypt() { if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; auto decrypted = std::make_unique<ByteArray>(); - QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + QByteArray text = edit->curTextPage()->getTextPage()->toPlainText().toUtf8(); if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { QMessageBox::critical( @@ -234,7 +241,7 @@ void MainWindow::slotFind() { void MainWindow::slotVerify() { if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; - auto text = edit->curTextPage()->toPlainText().toUtf8(); + auto text = edit->curTextPage()->getTextPage()->toPlainText().toUtf8(); // TODO(Saturneric) PreventNoDataErr auto sig_buffer = std::make_unique<ByteArray>(); @@ -273,8 +280,8 @@ void MainWindow::slotEncryptSign() { if (key_ids->empty()) { QMessageBox::critical( - nullptr, _("No Key Selected"), - _("Please select the key in the key toolbox on the right.")); + this, _("No Key Checked"), + _("Please check some key in the key toolbox on the right.")); return; } @@ -285,7 +292,7 @@ void MainWindow::slotEncryptSign() { if (!key_can_encrypt) { QMessageBox::critical( - nullptr, _("Invalid KeyPair"), + this, _("Invalid KeyPair"), QString(_("The selected keypair cannot be used for encryption.")) + "<br/><br/>" + _("For example the Following Key:") + " <br/>" + QString::fromStdString(key.uids()->front().uid())); @@ -317,7 +324,11 @@ void MainWindow::slotEncryptSign() { auto tmp = std::make_unique<ByteArray>(); process_operation(this, _("Encrypting and Signing"), [&]() { try { - auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString(); + auto buffer = edit->curTextPage() + ->getTextPage() + ->toPlainText() + .toUtf8() + .toStdString(); error = GpgFrontend::BasicOperator::GetInstance().EncryptSign( std::move(keys), std::move(signer_keys), buffer, tmp, encr_result, sign_result); @@ -352,7 +363,8 @@ void MainWindow::slotEncryptSign() { infoBoard->resetOptionActionsMenu(); #ifdef SMTP_SUPPORT if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) - send_an_email(this, infoBoard, edit->curTextPage()->toPlainText(), false); + send_an_email(this, infoBoard, + edit->curTextPage()->getTextPage()->toPlainText(), false); #endif #ifdef ADVANCE_SUPPORT @@ -376,7 +388,7 @@ void MainWindow::slotEncryptSign() { void MainWindow::slotDecryptVerify() { if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; - QString plainText = edit->curTextPage()->toPlainText(); + QString plainText = edit->curTextPage()->getTextPage()->toPlainText(); #ifdef ADVANCE_SUPPORT if (plainText.trimmed().startsWith( @@ -453,7 +465,8 @@ void MainWindow::slotAppendSelectedKeys() { auto key_ids = mKeyList->getSelected(); GpgKeyImportExporter::GetInstance().ExportKeys(key_ids, exported); - edit->curTextPage()->append(QString::fromStdString(*exported)); + edit->curTextPage()->getTextPage()->appendPlainText( + QString::fromStdString(*exported)); } void MainWindow::slotCopyMailAddressToClipboard() { @@ -462,7 +475,7 @@ void MainWindow::slotCopyMailAddressToClipboard() { auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front()); if (!key.good()) { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); + QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } QClipboard* cb = QApplication::clipboard(); @@ -477,7 +490,7 @@ void MainWindow::slotShowKeyDetails() { if (key.good()) { new KeyDetailsDialog(key, this); } else { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); + QMessageBox::critical(this, _("Error"), _("Key Not Found.")); } } diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 0c0204f4..9f40ec9d 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -41,7 +41,7 @@ void MainWindow::slotStartWizard() { void MainWindow::slotImportKeyFromEdit() { if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; CommonUtils::GetInstance()->slotImportKeys( - this, edit->curTextPage()->toPlainText().toStdString()); + this, edit->curTextPage()->getTextPage()->toPlainText().toStdString()); } void MainWindow::slotOpenKeyManagement() { @@ -139,7 +139,7 @@ void MainWindow::slotCleanDoubleLinebreaks() { return; } - QString content = edit->curTextPage()->toPlainText(); + QString content = edit->curTextPage()->getTextPage()->toPlainText(); content.replace("\n\n", "\n"); edit->slotFillTextEditWithText(content); } @@ -149,7 +149,7 @@ void MainWindow::slotAddPgpHeader() { return; } - QString content = edit->curTextPage()->toPlainText().trimmed(); + QString content = edit->curTextPage()->getTextPage()->toPlainText().trimmed(); content.prepend("\n\n").prepend(GpgConstants::PGP_CRYPT_BEGIN); content.append("\n").append(GpgConstants::PGP_CRYPT_END); @@ -162,7 +162,7 @@ void MainWindow::slotCutPgpHeader() { return; } - QString content = edit->curTextPage()->toPlainText(); + QString content = edit->curTextPage()->getTextPage()->toPlainText(); int start = content.indexOf(GpgConstants::PGP_CRYPT_BEGIN); int end = content.indexOf(GpgConstants::PGP_CRYPT_END); diff --git a/src/ui/settings/GlobalSettingStation.cpp b/src/ui/settings/GlobalSettingStation.cpp index 4e9bac73..e1e5f6f4 100644 --- a/src/ui/settings/GlobalSettingStation.cpp +++ b/src/ui/settings/GlobalSettingStation.cpp @@ -41,7 +41,7 @@ GpgFrontend::UI::GlobalSettingStation::GetInstance() { return *_instance; } -void GpgFrontend::UI::GlobalSettingStation::Sync() noexcept { +void GpgFrontend::UI::GlobalSettingStation::SyncSettings() noexcept { using namespace libconfig; try { ui_cfg.writeFile(ui_config_path.string().c_str()); @@ -74,6 +74,19 @@ GpgFrontend::UI::GlobalSettingStation::GlobalSettingStation() noexcept { if (!is_directory(ui_config_dir_path)) create_directory(ui_config_dir_path); + if (!is_directory(app_secure_path)) create_directory(app_secure_path); + + if (!exists(app_secure_key_path)) { + init_app_secure_key(); + } + + const auto key = + GpgFrontend::read_all_data_in_file(app_secure_key_path.string()); + hash_key_ = QCryptographicHash::hash(QByteArray::fromStdString(key), + QCryptographicHash::Sha256); + + if (!exists(app_data_objs_path)) create_directory(app_data_objs_path); + if (!exists(ui_config_path)) { try { this->ui_cfg.writeFile(ui_config_path.string().c_str()); @@ -136,5 +149,118 @@ GpgFrontend::UI::GlobalSettingStation::GetRootCerts() { return root_certs_; } +std::string GpgFrontend::UI::GlobalSettingStation::generate_passphrase( + int len) { + std::uniform_int_distribution<int> dist(999, 99999); + static const char alphanum[] = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + std::string tmp_str; + tmp_str.reserve(len); + + for (int i = 0; i < len; ++i) { + tmp_str += alphanum[dist(mt) % (sizeof(alphanum) - 1)]; + } + + return tmp_str; +} + +void GpgFrontend::UI::GlobalSettingStation::init_app_secure_key() { + GpgFrontend::write_buffer_to_file(app_secure_key_path.string(), + generate_passphrase(256)); + boost::filesystem::permissions( + app_secure_key_path, + boost::filesystem::owner_read | boost::filesystem::owner_write); +} + +std::string GpgFrontend::UI::GlobalSettingStation::SaveDataObj( + const std::string& _key, const nlohmann::json& value) { + std::string _hash_obj_key = {}; + if (_key.empty()) { + _hash_obj_key = + QCryptographicHash::hash( + hash_key_ + QByteArray::fromStdString( + generate_passphrase(32) + + to_iso_extended_string( + boost::posix_time::second_clock::local_time())), + QCryptographicHash::Sha256) + .toHex() + .toStdString(); + } else { + _hash_obj_key = + QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key), + QCryptographicHash::Sha256) + .toHex() + .toStdString(); + } + + const auto obj_path = app_data_objs_path / _hash_obj_key; + + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + auto encoded = + encryption.encode(QByteArray::fromStdString(to_string(value)), hash_key_); + + GpgFrontend::write_buffer_to_file(obj_path.string(), encoded.toStdString()); + + return _key.empty() ? _hash_obj_key : std::string(); +} + +std::optional<nlohmann::json> +GpgFrontend::UI::GlobalSettingStation::GetDataObject(const std::string& _key) { + try { + auto _hash_obj_key = + QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key), + QCryptographicHash::Sha256) + .toHex() + .toStdString(); + + const auto obj_path = app_data_objs_path / _hash_obj_key; + + if (!boost::filesystem::exists(obj_path)) { + return {}; + } + + auto buffer = GpgFrontend::read_all_data_in_file(obj_path.string()); + auto encoded = QByteArray::fromStdString(buffer); + + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + + auto decoded = + encryption.removePadding(encryption.decode(encoded, hash_key_)); + + return nlohmann::json::parse(decoded.toStdString()); + } catch (...) { + return {}; + } +} +std::optional<nlohmann::json> +GpgFrontend::UI::GlobalSettingStation::GetDataObjectByRef( + const std::string& _ref) { + if (_ref.size() != 64) return {}; + + try { + auto _hash_obj_key = _ref; + const auto obj_path = app_data_objs_path / _hash_obj_key; + + if (!boost::filesystem::exists(obj_path)) return {}; + + auto buffer = GpgFrontend::read_all_data_in_file(obj_path.string()); + auto encoded = QByteArray::fromStdString(buffer); + + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + + auto decoded = + encryption.removePadding(encryption.decode(encoded, hash_key_)); + + return nlohmann::json::parse(decoded.toStdString()); + } catch (...) { + return {}; + } +} + GpgFrontend::UI::GlobalSettingStation::~GlobalSettingStation() noexcept = default; diff --git a/src/ui/settings/GlobalSettingStation.h b/src/ui/settings/GlobalSettingStation.h index 11c5e5f3..457a5a2f 100644 --- a/src/ui/settings/GlobalSettingStation.h +++ b/src/ui/settings/GlobalSettingStation.h @@ -27,6 +27,7 @@ #include <openssl/x509.h> +#include <nlohmann/json.hpp> #include <boost/filesystem/operations.hpp> #include <boost/filesystem/path.hpp> @@ -91,7 +92,13 @@ class GlobalSettingStation : public QObject { void ResetRootCerts() { root_certs_.clear(); } - void Sync() noexcept; + void SyncSettings() noexcept; + + std::string SaveDataObj(const std::string& _key, const nlohmann::json& value); + + std::optional<nlohmann::json> GetDataObject(const std::string& _key); + + std::optional<nlohmann::json> GetDataObjectByRef(const std::string& _ref); private: // Program Location @@ -105,6 +112,9 @@ class GlobalSettingStation : public QObject { // Program Data Location boost::filesystem::path app_log_path = app_data_path / "logs"; + // object storage path + boost::filesystem::path app_data_objs_path = app_data_path / "objs"; + #ifdef LINUX_INSTALL_BUILD // Program Data Location boost::filesystem::path app_resource_path = @@ -127,6 +137,10 @@ class GlobalSettingStation : public QObject { QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) .toStdString(); + boost::filesystem::path app_secure_path = app_configure_path / "secure"; + + boost::filesystem::path app_secure_key_path = app_secure_path / "app.key"; + // Configure File Directory Location boost::filesystem::path ui_config_dir_path = app_configure_path / "UserInterface"; @@ -138,7 +152,17 @@ class GlobalSettingStation : public QObject { std::vector<std::shared_ptr<X509>> root_certs_; + std::random_device rd; + + std::mt19937 mt; + + QByteArray hash_key_; + static std::unique_ptr<GlobalSettingStation> _instance; + + void init_app_secure_key(); + + std::string generate_passphrase(int len); }; } // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsDialog.cpp b/src/ui/settings/SettingsDialog.cpp index 01e4094f..dc84e8ac 100644 --- a/src/ui/settings/SettingsDialog.cpp +++ b/src/ui/settings/SettingsDialog.cpp @@ -38,7 +38,6 @@ namespace GpgFrontend::UI { SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent) { - tabWidget = new QTabWidget(); generalTab = new GeneralTab(); appearanceTab = new AppearanceTab(); @@ -126,7 +125,7 @@ void SettingsDialog::slotAccept() { LOG(INFO) << "apply done"; // write settings to filesystem - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); LOG(INFO) << "restart needed" << getRestartNeeded(); if (getRestartNeeded()) { diff --git a/src/ui/settings/SettingsKeyServer.cpp b/src/ui/settings/SettingsKeyServer.cpp index 0cba7b51..533c8316 100644 --- a/src/ui/settings/SettingsKeyServer.cpp +++ b/src/ui/settings/SettingsKeyServer.cpp @@ -25,7 +25,7 @@ #include "SettingsKeyServer.h" #include "GlobalSettingStation.h" -#include "ui/function/TestListedKeyServerThread.h" +#include "ui/thread/TestListedKeyServerThread.h" #include "ui_KeyServerSettings.h" namespace GpgFrontend::UI { diff --git a/src/ui/settings/SettingsNetwork.cpp b/src/ui/settings/SettingsNetwork.cpp index c457c1a0..0aec38c4 100644 --- a/src/ui/settings/SettingsNetwork.cpp +++ b/src/ui/settings/SettingsNetwork.cpp @@ -24,7 +24,7 @@ #include "SettingsNetwork.h" -#include "ui/function/ProxyConnectionTestThread.h" +#include "ui/thread/ProxyConnectionTestThread.h" #include "ui/settings//GlobalSettingStation.h" #include "ui_NetworkSettings.h" diff --git a/src/ui/settings/SettingsSendMail.cpp b/src/ui/settings/SettingsSendMail.cpp index f0acb10d..728cfc66 100644 --- a/src/ui/settings/SettingsSendMail.cpp +++ b/src/ui/settings/SettingsSendMail.cpp @@ -24,13 +24,9 @@ #include "SettingsSendMail.h" -#ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#endif - -#include "ui/function/SMTPSendMailThread.h" -#include "ui/function/SMTPTestThread.h" -#include "ui/settings/GlobalSettingStation.h" +#include "ui/data_struct/SettingsObject.h" +#include "ui/thread/SMTPSendMailThread.h" +#include "ui/thread/SMTPTestThread.h" #include "ui_SendMailSettings.h" namespace GpgFrontend::UI { @@ -97,87 +93,39 @@ SendMailTab::SendMailTab(QWidget* parent) } void SendMailTab::setSettings() { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + auto smtp_passport = SettingsObject("smtp_passport"); - try { - std::string mail_address = settings.lookup("smtp.mail_address"); - ui->smtpServerAddressEdit->setText(mail_address.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("mail_address"); - } + ui->smtpServerAddressEdit->setText( + std::string{smtp_passport.Check("smtp_address", {})}.c_str()); - try { - std::string std_username = settings.lookup("smtp.username"); - ui->usernameEdit->setText(std_username.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("username"); - } + ui->usernameEdit->setText( + std::string{smtp_passport.Check("username", {})}.c_str()); - try { - std::string std_password = settings.lookup("smtp.password"); - ui->passwordEdit->setText(std_password.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("password"); - } + ui->passwordEdit->setText( + std::string{smtp_passport.Check("password", {})}.c_str()); - try { - int port = settings.lookup("smtp.port"); - ui->portSpin->setValue(port); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("port"); - } + ui->portSpin->setValue(int{smtp_passport.Check("port", 25)}); - ui->connextionSecurityComboBox->setCurrentText("None"); - try { - std::string connection_type = settings.lookup("smtp.connection_type"); - ui->connextionSecurityComboBox->setCurrentText(connection_type.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("connection_type"); - } + ui->connextionSecurityComboBox->setCurrentText( + std::string{smtp_passport.Check("connection_type", "None")}.c_str()); - try { - std::string default_sender = settings.lookup("smtp.default_sender"); - ui->defaultSenderEmailEdit->setText(default_sender.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("default_sender"); - } + ui->defaultSenderEmailEdit->setText( + std::string{smtp_passport.Check("default_sender", {})}.c_str()); - try { - std::string default_sender_gpg_key_id = - settings.lookup("smtp.default_sender_gpg_key_id"); - ui->gpgKeyIDEdit->setText(default_sender_gpg_key_id.c_str()); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") - << _("default_sender_gpg_key_id"); - } + ui->gpgKeyIDEdit->setText( + std::string{smtp_passport.Check("default_sender_gpg_key_id", {})} + .c_str()); + + ui->identityCheckBox->setChecked( + bool{smtp_passport.Check("identity_enable", false)}); + + ui->enableCheckBox->setChecked(bool{smtp_passport.Check("enable", false)}); - ui->identityCheckBox->setCheckState(Qt::Unchecked); - try { - bool identity_enable = settings.lookup("smtp.identity_enable"); - if (identity_enable) - ui->identityCheckBox->setCheckState(Qt::Checked); - else - ui->identityCheckBox->setCheckState(Qt::Unchecked); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("identity_enable"); - } - { auto state = ui->identityCheckBox->checkState(); switch_ui_identity_enabled(state == Qt::Checked); } - ui->enableCheckBox->setCheckState(Qt::Unchecked); - try { - bool smtp_enable = settings.lookup("smtp.enable"); - if (smtp_enable) - ui->enableCheckBox->setCheckState(Qt::Checked); - else - ui->enableCheckBox->setCheckState(Qt::Unchecked); - } catch (...) { - LOG(ERROR) << _("Setting Operation Error") << _("save_key_checked"); - } - { auto state = ui->enableCheckBox->checkState(); switch_ui_enabled(state == Qt::Checked); @@ -185,76 +133,33 @@ void SendMailTab::setSettings() { } void SendMailTab::applySettings() { - auto& settings = - GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings(); - - if (!settings.exists("smtp") || - settings.lookup("smtp").getType() != libconfig::Setting::TypeGroup) - settings.add("smtp", libconfig::Setting::TypeGroup); - - auto& smtp = settings["smtp"]; + try { + auto smtp_passport = SettingsObject("smtp_passport"); - if (!smtp.exists("mail_address")) - smtp.add("mail_address", libconfig::Setting::TypeString) = + smtp_passport["smtp_address"] = ui->smtpServerAddressEdit->text().toStdString(); - else { - smtp["mail_address"] = ui->smtpServerAddressEdit->text().toStdString(); - } - if (!smtp.exists("username")) - smtp.add("username", libconfig::Setting::TypeString) = - ui->usernameEdit->text().toStdString(); - else { - smtp["username"] = ui->usernameEdit->text().toStdString(); - } + smtp_passport["username"] = ui->usernameEdit->text().toStdString(); - if (!smtp.exists("password")) - smtp.add("password", libconfig::Setting::TypeString) = - ui->passwordEdit->text().toStdString(); - else { - smtp["password"] = ui->passwordEdit->text().toStdString(); - } + smtp_passport["password"] = ui->passwordEdit->text().toStdString(); - if (!smtp.exists("port")) - smtp.add("port", libconfig::Setting::TypeInt) = ui->portSpin->value(); - else { - smtp["port"] = ui->portSpin->value(); - } + smtp_passport["port"] = ui->portSpin->value(); - if (!smtp.exists("connection_type")) - smtp.add("connection_type", libconfig::Setting::TypeString) = - ui->connextionSecurityComboBox->currentText().toStdString(); - else { - smtp["connection_type"] = + smtp_passport["connection_type"] = ui->connextionSecurityComboBox->currentText().toStdString(); - } - if (!smtp.exists("default_sender")) - smtp.add("default_sender", libconfig::Setting::TypeString) = + smtp_passport["default_sender"] = ui->defaultSenderEmailEdit->text().toStdString(); - else { - smtp["default_sender"] = ui->defaultSenderEmailEdit->text().toStdString(); - } - if (!smtp.exists("default_sender_gpg_key_id")) - smtp.add("default_sender_gpg_key_id", libconfig::Setting::TypeString) = + smtp_passport["default_sender_gpg_key_id"] = ui->gpgKeyIDEdit->text().toStdString(); - else { - smtp["default_sender_gpg_key_id"] = ui->gpgKeyIDEdit->text().toStdString(); - } - if (!smtp.exists("identity_enable")) - smtp.add("identity_enable", libconfig::Setting::TypeBoolean) = - ui->identityCheckBox->isChecked(); - else { - smtp["identity_enable"] = ui->identityCheckBox->isChecked(); - } + smtp_passport["identity_enable"] = ui->identityCheckBox->isChecked(); - if (!smtp.exists("enable")) - smtp.add("enable", libconfig::Setting::TypeBoolean) = - ui->enableCheckBox->isChecked(); - else { - smtp["enable"] = ui->enableCheckBox->isChecked(); + smtp_passport["enable"] = ui->enableCheckBox->isChecked(); + + } catch (...) { + LOG(ERROR) << _("apply settings failed"); } } diff --git a/src/ui/settings/SettingsSendMail.h b/src/ui/settings/SettingsSendMail.h index c866fa5f..75b03c77 100644 --- a/src/ui/settings/SettingsSendMail.h +++ b/src/ui/settings/SettingsSendMail.h @@ -25,7 +25,6 @@ #ifndef GPGFRONTEND_SETTINGSSENDMAIL_H #define GPGFRONTEND_SETTINGSSENDMAIL_H -#include "smtp/SmtpMime" #include "ui/GpgFrontendUI.h" class Ui_SendMailSettings; diff --git a/src/ui/smtp/SendMailDialog.cpp b/src/ui/smtp/SendMailDialog.cpp index 3f0b87cd..badbed57 100644 --- a/src/ui/smtp/SendMailDialog.cpp +++ b/src/ui/smtp/SendMailDialog.cpp @@ -31,9 +31,8 @@ #include "ui_SendMailDialog.h" #ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#include "ui/function/SMTPSendMailThread.h" #include "ui/settings/GlobalSettingStation.h" +#include "ui/thread/SMTPSendMailThread.h" #endif namespace GpgFrontend::UI { diff --git a/src/ui/function/CtxCheckThread.cpp b/src/ui/thread/CtxCheckThread.cpp index b51954e1..b51954e1 100644 --- a/src/ui/function/CtxCheckThread.cpp +++ b/src/ui/thread/CtxCheckThread.cpp diff --git a/src/ui/function/CtxCheckThread.h b/src/ui/thread/CtxCheckThread.h index 74bdb491..74bdb491 100644 --- a/src/ui/function/CtxCheckThread.h +++ b/src/ui/thread/CtxCheckThread.h diff --git a/src/ui/function/FileReadThread.cpp b/src/ui/thread/FileReadThread.cpp index 270f50e7..04f713bd 100644 --- a/src/ui/function/FileReadThread.cpp +++ b/src/ui/thread/FileReadThread.cpp @@ -29,39 +29,41 @@ namespace GpgFrontend::UI { -FileReadThread::FileReadThread(std::string path) : path(std::move(path)) {} +FileReadThread::FileReadThread(std::string path) : path(std::move(path)) { + qRegisterMetaType<std::string>("std::string"); +} void FileReadThread::run() { - LOG(INFO) << "Started"; + LOG(INFO) << "started"; boost::filesystem::path read_file_path(this->path); if (is_regular_file(read_file_path)) { - LOG(INFO) << "Read Open"; + LOG(INFO) << "read open"; - auto fp = fopen(read_file_path.string().c_str(), "r"); + auto fp = fopen(read_file_path.string().c_str(), "rb"); size_t read_size; - LOG(INFO) << "Thread Start Reading"; + LOG(INFO) << "thread start reading"; - char buffer[8192]; + char buffer[4096]; while ((read_size = fread(buffer, sizeof(char), sizeof buffer, fp)) > 0) { // Check isInterruptionRequested if (QThread::currentThread()->isInterruptionRequested()) { - LOG(INFO) << "Read Thread isInterruptionRequested "; + LOG(INFO) << "thread is interruption requested "; fclose(fp); return; } - LOG(INFO) << "Read Thread Read block size " << read_size; + LOG(INFO) << "block size " << read_size; std::string buffer_str(buffer, read_size); - emit sendReadBlock(QString::fromStdString(buffer_str)); + emit sendReadBlock(buffer_str); #ifdef RELEASE QThread::msleep(32); #else - QThread::msleep(48); + QThread::msleep(128); #endif } fclose(fp); emit readDone(); - LOG(INFO) << "Thread End Reading"; + LOG(INFO) << "thread end reading"; } } diff --git a/src/ui/function/FileReadThread.h b/src/ui/thread/FileReadThread.h index 46ed6cbc..65982848 100644 --- a/src/ui/function/FileReadThread.h +++ b/src/ui/thread/FileReadThread.h @@ -37,7 +37,7 @@ class FileReadThread : public QThread { signals: - void sendReadBlock(const QString& block); + void sendReadBlock(const std::string& block); void readDone(); diff --git a/src/ui/function/ProxyConnectionTestThread.cpp b/src/ui/thread/ProxyConnectionTestThread.cpp index 76cf525e..76cf525e 100644 --- a/src/ui/function/ProxyConnectionTestThread.cpp +++ b/src/ui/thread/ProxyConnectionTestThread.cpp diff --git a/src/ui/function/ProxyConnectionTestThread.h b/src/ui/thread/ProxyConnectionTestThread.h index 4ef75050..4ef75050 100644 --- a/src/ui/function/ProxyConnectionTestThread.h +++ b/src/ui/thread/ProxyConnectionTestThread.h diff --git a/src/ui/function/SMTPSendMailThread.cpp b/src/ui/thread/SMTPSendMailThread.cpp index edfd3156..edfd3156 100644 --- a/src/ui/function/SMTPSendMailThread.cpp +++ b/src/ui/thread/SMTPSendMailThread.cpp diff --git a/src/ui/function/SMTPSendMailThread.h b/src/ui/thread/SMTPSendMailThread.h index e5c9e27f..3d723670 100644 --- a/src/ui/function/SMTPSendMailThread.h +++ b/src/ui/thread/SMTPSendMailThread.h @@ -27,10 +27,6 @@ #include <utility> -#ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#endif - #include "ui/GpgFrontendUI.h" namespace GpgFrontend::UI { diff --git a/src/ui/function/SMTPTestThread.cpp b/src/ui/thread/SMTPTestThread.cpp index 0eb267f2..0eb267f2 100644 --- a/src/ui/function/SMTPTestThread.cpp +++ b/src/ui/thread/SMTPTestThread.cpp diff --git a/src/ui/function/SMTPTestThread.h b/src/ui/thread/SMTPTestThread.h index db61d97d..c51ac3fd 100644 --- a/src/ui/function/SMTPTestThread.h +++ b/src/ui/thread/SMTPTestThread.h @@ -27,11 +27,8 @@ #include <utility> -#ifdef SMTP_SUPPORT -#include "smtp/SmtpMime" -#endif - #include "ui/GpgFrontendUI.h" + namespace GpgFrontend::UI { class SMTPTestThread : public QThread { diff --git a/src/ui/function/TestListedKeyServerThread.cpp b/src/ui/thread/TestListedKeyServerThread.cpp index 4f816860..4f816860 100644 --- a/src/ui/function/TestListedKeyServerThread.cpp +++ b/src/ui/thread/TestListedKeyServerThread.cpp diff --git a/src/ui/function/TestListedKeyServerThread.h b/src/ui/thread/TestListedKeyServerThread.h index 99fd6c6d..99fd6c6d 100644 --- a/src/ui/function/TestListedKeyServerThread.h +++ b/src/ui/thread/TestListedKeyServerThread.h diff --git a/src/ui/function/VersionCheckThread.cpp b/src/ui/thread/VersionCheckThread.cpp index 2a1cf9af..8b2487d8 100644 --- a/src/ui/function/VersionCheckThread.cpp +++ b/src/ui/thread/VersionCheckThread.cpp @@ -25,9 +25,9 @@ #include "VersionCheckThread.h" #include <QMetaType> +#include <nlohmann/json.hpp> #include "GpgFrontendBuildInfo.h" -#include "json/json.hpp" namespace GpgFrontend::UI { diff --git a/src/ui/function/VersionCheckThread.h b/src/ui/thread/VersionCheckThread.h index 0db9770c..0db9770c 100644 --- a/src/ui/function/VersionCheckThread.h +++ b/src/ui/thread/VersionCheckThread.h diff --git a/src/ui/widgets/EditorPage.cpp b/src/ui/widgets/EditorPage.cpp deleted file mode 100644 index b73974a7..00000000 --- a/src/ui/widgets/EditorPage.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. - * - */ - -#include "ui/widgets/EditorPage.h" - -#include <boost/filesystem.hpp> -#include <utility> - -#include "ui/function/FileReadThread.h" - -namespace GpgFrontend::UI { - -EditorPage::EditorPage(QString filePath, QWidget* parent) - : QWidget(parent), full_file_path_(std::move(filePath)) { - // Set the Textedit properties - textPage = new QTextEdit(); - textPage->setAcceptRichText(false); - - // Set the layout style - mainLayout = new QVBoxLayout(); - mainLayout->setSpacing(0); - mainLayout->addWidget(textPage); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); - - textPage->setFocus(); - - // Front in same width - this->setFont({"Courier"}); - this->setAttribute(Qt::WA_DeleteOnClose); -} - -const QString& EditorPage::getFilePath() const { return full_file_path_; } - -QTextEdit* EditorPage::getTextPage() { return textPage; } - -void EditorPage::setFilePath(const QString& filePath) { - full_file_path_ = filePath; -} - -void EditorPage::showNotificationWidget(QWidget* widget, - const char* className) { - widget->setProperty(className, true); - mainLayout->addWidget(widget); -} - -void EditorPage::closeNoteByClass(const char* className) { - QList<QWidget*> widgets = findChildren<QWidget*>(); - for (QWidget* widget : widgets) { - if (widget->property(className) == true) { - widget->close(); - } - } -} - -void EditorPage::slotFormatGpgHeader() { - QString content = textPage->toPlainText(); - - // Get positions of the gpg-headers, if they exist - int start = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN); - int startSig = - content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN); - int endSig = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_END); - - if (start < 0 || startSig < 0 || endSig < 0 || signMarked) { - return; - } - - signMarked = true; - - // Set the fontstyle for the header - QTextCharFormat signFormat; - signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); - signFormat.setFontPointSize(9); - - // set font style for the signature - QTextCursor cursor(textPage->document()); - cursor.setPosition(startSig, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); - cursor.setCharFormat(signFormat); - - // set the font style for the header - int headEnd = content.indexOf("\n\n", start); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); - cursor.setCharFormat(signFormat); -} - -void EditorPage::ReadFile() { - LOG(INFO) << "Called"; - - read_done_ = false; - - auto text_page = this->getTextPage(); - text_page->setReadOnly(true); - auto thread = new FileReadThread(this->full_file_path_.toStdString()); - - connect(thread, &FileReadThread::sendReadBlock, this, - &EditorPage::slotInsertText); - - connect(thread, &FileReadThread::readDone, this, [=]() { - LOG(INFO) << "thread read done"; - text_page->document()->setModified(false); - text_page->setReadOnly(false); - }); - - connect(thread, &FileReadThread::finished, this, [=]() { - LOG(INFO) << "thread finished"; - thread->deleteLater(); - read_done_ = true; - read_hread_ = nullptr; - }); - - connect(this, &EditorPage::destroyed, [=]() { - LOG(INFO) << "request interruption for read thread"; - thread->requestInterruption(); - read_hread_ = nullptr; - }); - this->read_hread_ = thread; - thread->start(); -} - -void EditorPage::slotInsertText(const QString& text) { - this->getTextPage()->insertPlainText(text); -} -void EditorPage::PrepareToDestroy() { - if (read_hread_) { - read_hread_->requestInterruption(); - read_hread_ = nullptr; - } -} - -} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/ExportKeyPackageDialog.cpp b/src/ui/widgets/ExportKeyPackageDialog.cpp index d99e966a..b82ceb32 100644 --- a/src/ui/widgets/ExportKeyPackageDialog.cpp +++ b/src/ui/widgets/ExportKeyPackageDialog.cpp @@ -28,7 +28,6 @@ #include "gpg/function/GpgKeyGetter.h" #include "gpg/function/GpgKeyImportExporter.h" -#include "ui/aes/qaesencryption.h" #include "ui_ExportKeyPackageDialog.h" GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( diff --git a/src/ui/widgets/ExportKeyPackageDialog.h b/src/ui/widgets/ExportKeyPackageDialog.h index a254b453..a07cda69 100644 --- a/src/ui/widgets/ExportKeyPackageDialog.h +++ b/src/ui/widgets/ExportKeyPackageDialog.h @@ -37,7 +37,7 @@ class ExportKeyPackageDialog : public QDialog { public: explicit ExportKeyPackageDialog(KeyIdArgsListPtr key_ids, QWidget* parent); - std::string generate_passphrase(const int len); + std::string generate_passphrase(int len); private: std::shared_ptr<Ui_exportKeyPackageDialog> ui; diff --git a/src/ui/widgets/InfoBoardWidget.h b/src/ui/widgets/InfoBoardWidget.h index 8d37be6c..816da849 100644 --- a/src/ui/widgets/InfoBoardWidget.h +++ b/src/ui/widgets/InfoBoardWidget.h @@ -25,7 +25,7 @@ #ifndef __VERIFYNOTIFICATION_H__ #define __VERIFYNOTIFICATION_H__ -#include "EditorPage.h" +#include "PlainTextEditorPage.h" #include "gpg/result_analyse/VerifyResultAnalyse.h" #include "ui/details/VerifyDetailsDialog.h" diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 89634f95..8b93a088 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -355,7 +355,7 @@ void KeyList::dropEvent(QDropEvent* event) { else { general["confirm_import_keys"] = checkBox->isChecked(); } - GlobalSettingStation::GetInstance().Sync(); + GlobalSettingStation::GetInstance().SyncSettings(); } if (event->mimeData()->hasUrls()) { @@ -584,7 +584,7 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { type_steam << "#"; } - if(it->HasCardKey()) { + if (it->HasCardKey()) { type_steam << "^"; } diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp new file mode 100644 index 00000000..6fe8977e --- /dev/null +++ b/src/ui/widgets/PlainTextEditorPage.cpp @@ -0,0 +1,258 @@ +/** + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#include "ui/widgets/PlainTextEditorPage.h" + +#include <boost/filesystem.hpp> +#include <boost/format.hpp> +#include <utility> + +#include "ui/encoding/TextEncodingDetect.h" +#include "ui/thread/FileReadThread.h" +#include "ui_PlainTextEditor.h" + +namespace GpgFrontend::UI { + +PlainTextEditorPage::PlainTextEditorPage(QString filePath, QWidget* parent) + : QWidget(parent), + ui(std::make_shared<Ui_PlainTextEditor>()), + full_file_path_(std::move(filePath)) { + ui->setupUi(this); + + if (full_file_path_.isEmpty()) read_done_ = true; + + ui->textPage->setFocus(); + ui->loadingLabel->setHidden(true); + + // Front in same width + this->setFont({"Courier"}); + this->setAttribute(Qt::WA_DeleteOnClose); + + this->ui->characterLabel->setText(_("0 character")); + this->ui->lfLabel->setText(_("None")); + this->ui->encodingLabel->setText(_("Binary")); + + connect(ui->textPage, &QPlainTextEdit::textChanged, this, [=]() { + if (!read_done_) return; + + auto text = ui->textPage->document()->toPlainText(); + auto str = boost::format(_("%1% character(s)")) % text.size(); + this->ui->characterLabel->setText(str.str().c_str()); + + detect_cr_lf(text); + detect_encoding(text.toStdString()); + }); + + ui->loadingLabel->setText(_("Loading...")); +} + +const QString& PlainTextEditorPage::getFilePath() const { + return full_file_path_; +} + +QPlainTextEdit* PlainTextEditorPage::getTextPage() { return ui->textPage; } + +void PlainTextEditorPage::setFilePath(const QString& filePath) { + full_file_path_ = filePath; +} + +void PlainTextEditorPage::showNotificationWidget(QWidget* widget, + const char* className) { + widget->setProperty(className, true); + ui->verticalLayout->addWidget(widget); +} + +void PlainTextEditorPage::closeNoteByClass(const char* className) { + QList<QWidget*> widgets = findChildren<QWidget*>(); + for (QWidget* widget : widgets) { + if (widget->property(className) == true) { + widget->close(); + } + } +} + +void PlainTextEditorPage::slotFormatGpgHeader() { + QString content = ui->textPage->toPlainText(); + + // Get positions of the gpg-headers, if they exist + int start = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN); + int startSig = + content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN); + int endSig = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_END); + + if (start < 0 || startSig < 0 || endSig < 0 || signMarked) { + return; + } + + signMarked = true; + + // Set the fontstyle for the header + QTextCharFormat signFormat; + signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); + signFormat.setFontPointSize(9); + + // set font style for the signature + QTextCursor cursor(ui->textPage->document()); + cursor.setPosition(startSig, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); + cursor.setCharFormat(signFormat); + + // set the font style for the header + int headEnd = content.indexOf("\n\n", start); + cursor.setPosition(start, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); + cursor.setCharFormat(signFormat); +} + +void PlainTextEditorPage::ReadFile() { + LOG(INFO) << "called"; + + read_done_ = false; + read_bytes_ = 0; + ui->textPage->setEnabled(false); + ui->textPage->setReadOnly(true); + ui->textPage->blockSignals(true); + ui->loadingLabel->setHidden(false); + ui->textPage->document()->blockSignals(true); + + auto text_page = this->getTextPage(); + text_page->setReadOnly(true); + auto thread = new FileReadThread(this->full_file_path_.toStdString()); + + connect(thread, &FileReadThread::sendReadBlock, this, + &PlainTextEditorPage::slotInsertText); + + connect(thread, &FileReadThread::readDone, this, [=]() { + LOG(INFO) << "thread read done"; + if (!binary_mode_) { + text_page->setReadOnly(false); + } + }); + + connect(thread, &FileReadThread::finished, this, [=]() { + LOG(INFO) << "thread finished"; + thread->deleteLater(); + read_done_ = true; + read_thread_ = nullptr; + ui->textPage->setEnabled(true); + text_page->document()->setModified(false); + ui->textPage->blockSignals(false); + ui->textPage->document()->blockSignals(false); + ui->loadingLabel->setHidden(true); + }); + + connect(this, &PlainTextEditorPage::destroyed, [=]() { + LOG(INFO) << "request interruption for read thread"; + thread->requestInterruption(); + read_thread_ = nullptr; + }); + this->read_thread_ = thread; + thread->start(); +} + +std::string binary_to_string(const std::string& source) { + static char syms[] = "0123456789ABCDEF"; + std::stringstream ss; + for (unsigned char c : source) + ss << syms[((c >> 4) & 0xf)] << syms[c & 0xf] << " "; + return ss.str(); +} + +void PlainTextEditorPage::slotInsertText(const std::string& data) { + LOG(INFO) << "data size" << data.size(); + read_bytes_ += data.size(); + // If binary format is detected, the entire file is converted to binary format + // for display + bool if_last_binary_mode = binary_mode_; + if (!binary_mode_) { + detect_encoding(data); + } + + if (binary_mode_) { + if (if_last_binary_mode != binary_mode_) { + auto text_buffer = + ui->textPage->document()->toRawText().toLocal8Bit().toStdString(); + ui->textPage->clear(); + this->getTextPage()->insertPlainText( + binary_to_string(text_buffer).c_str()); + this->ui->lfLabel->setText("None"); + } + this->getTextPage()->insertPlainText(binary_to_string(data).c_str()); + + auto str = boost::format(_("%1% byte(s)")) % read_bytes_; + this->ui->characterLabel->setText(str.str().c_str()); + } else { + this->getTextPage()->insertPlainText(data.c_str()); + + auto text = this->getTextPage()->toPlainText(); + auto str = boost::format(_("%1% character(s)")) % text.size(); + this->ui->characterLabel->setText(str.str().c_str()); + detect_cr_lf(text); + } +} + +void PlainTextEditorPage::PrepareToDestroy() { + if (read_thread_) { + read_thread_->requestInterruption(); + read_thread_ = nullptr; + } +} + +void PlainTextEditorPage::detect_encoding(const std::string& data) { + AutoIt::Common::TextEncodingDetect text_detect; + AutoIt::Common::TextEncodingDetect::Encoding encoding = + text_detect.DetectEncoding((unsigned char*)(data.data()), data.size()); + + if (encoding == AutoIt::Common::TextEncodingDetect::None) { + binary_mode_ = true; + ui->encodingLabel->setText(_("Binary")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::ASCII) { + ui->encodingLabel->setText(_("ASCII(7 bits)")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::ANSI) { + ui->encodingLabel->setText(_("ASCII(8 bits)")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::UTF8_BOM || + encoding == AutoIt::Common::TextEncodingDetect::UTF8_NOBOM) { + ui->encodingLabel->setText(_("UTF-8")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::UTF16_LE_BOM || + encoding == AutoIt::Common::TextEncodingDetect::UTF16_LE_NOBOM) { + ui->encodingLabel->setText(_("UTF-16")); + } else if (encoding == AutoIt::Common::TextEncodingDetect::UTF16_BE_BOM || + encoding == AutoIt::Common::TextEncodingDetect::UTF16_BE_NOBOM) { + ui->encodingLabel->setText(_("UTF-16(BE)")); + } +} + +void PlainTextEditorPage::detect_cr_lf(const QString& data) { + if (binary_mode_) { + this->ui->lfLabel->setText("None"); + return; + } + if (data.contains("\r\n")) { + this->ui->lfLabel->setText("CRLF"); + } else { + this->ui->lfLabel->setText("LF"); + } +} + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/EditorPage.h b/src/ui/widgets/PlainTextEditorPage.h index d1bc1ac2..24823c06 100644 --- a/src/ui/widgets/EditorPage.h +++ b/src/ui/widgets/PlainTextEditorPage.h @@ -28,12 +28,7 @@ #include "gpg/GpgConstants.h" #include "ui/GpgFrontendUI.h" -QT_BEGIN_NAMESPACE -class QVBoxLayout; -class QHBoxLayout; -class QString; -class QLabel; -QT_END_NAMESPACE +class Ui_PlainTextEditor; namespace GpgFrontend::UI { @@ -41,7 +36,7 @@ namespace GpgFrontend::UI { * @brief Class for handling a single tab of the tabwidget * */ -class EditorPage : public QWidget { +class PlainTextEditorPage : public QWidget { Q_OBJECT public: /** @@ -50,7 +45,8 @@ class EditorPage : public QWidget { * @param filePath Path of the file handled in this tab * @param parent Pointer to the parent widget */ - explicit EditorPage(QString filePath = "", QWidget* parent = nullptr); + explicit PlainTextEditorPage(QString filePath = "", + QWidget* parent = nullptr); /** * @details Get the filepath of the currently activated tab. @@ -67,7 +63,7 @@ class EditorPage : public QWidget { /** * @details Return pointer tp the textedit of the currently activated tab. */ - QTextEdit* getTextPage(); + QPlainTextEdit* getTextPage(); /** * @details Show additional widget at buttom of currently active tab @@ -91,12 +87,17 @@ class EditorPage : public QWidget { void PrepareToDestroy(); private: - QTextEdit* textPage; /** The textedit of the tab */ - QVBoxLayout* mainLayout; /** The layout for the tab */ + std::shared_ptr<Ui_PlainTextEditor> ui; QString full_file_path_; /** The path to the file handled in the tab */ bool signMarked{}; /** true, if the signed header is marked, false if not */ bool read_done_ = false; - QThread* read_hread_ = nullptr; + QThread* read_thread_ = nullptr; + bool binary_mode_ = false; + size_t read_bytes_ = 0; + + void detect_encoding(const std::string& data); + + void detect_cr_lf(const QString& data); private slots: @@ -105,7 +106,7 @@ class EditorPage : public QWidget { */ void slotFormatGpgHeader(); - void slotInsertText(const QString& text); + void slotInsertText(const std::string& data); }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp index be6ec181..a8ff8d73 100644 --- a/src/ui/widgets/TextEdit.cpp +++ b/src/ui/widgets/TextEdit.cpp @@ -50,7 +50,7 @@ TextEdit::TextEdit(QWidget* parent) : QWidget(parent) { void TextEdit::slotNewTab() { QString header = _("untitled") + QString::number(++countPage) + ".txt"; - auto* page = new EditorPage(); + auto* page = new PlainTextEditorPage(); auto index = tabWidget->addTab(page, header); tabWidget->setTabIcon(index, QIcon(":file.png")); tabWidget->setCurrentIndex(tabWidget->count() - 1); @@ -80,11 +80,11 @@ void TextEdit::slotOpenFile(QString& path) { LOG(INFO) << "path" << path.toStdString(); auto result = file.open(QIODevice::ReadOnly | QIODevice::Text); if (result) { - auto* page = new EditorPage(path); + auto* page = new PlainTextEditorPage(path); connect(page->getTextPage()->document(), &QTextDocument::modificationChanged, this, &TextEdit::slotShowModified); - + QApplication::setOverrideCursor(Qt::WaitCursor); auto index = tabWidget->addTab(page, strippedName(path)); tabWidget->setTabIcon(index, QIcon(":file.png")); @@ -111,7 +111,7 @@ void TextEdit::slotOpen() { QFile file(fileName); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto* page = new EditorPage(fileName); + auto* page = new PlainTextEditorPage(fileName); QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); @@ -165,7 +165,7 @@ bool TextEdit::saveFile(const QString& fileName) { QFile file(fileName); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - EditorPage* page = slotCurPageTextEdit(); + PlainTextEditorPage* page = slotCurPageTextEdit(); QTextStream outputStream(&file); QApplication::setOverrideCursor(Qt::WaitCursor); @@ -197,7 +197,7 @@ bool TextEdit::slotSaveAs() { return true; } - EditorPage* page = slotCurPageTextEdit(); + PlainTextEditorPage* page = slotCurPageTextEdit(); QString path; if (!page->getFilePath().isEmpty()) { path = page->getFilePath(); @@ -250,7 +250,7 @@ void TextEdit::removeTab(int index) { * If it returns false, the close event should be aborted. */ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { - EditorPage* page = slotCurPageTextEdit(); + PlainTextEditorPage* page = slotCurPageTextEdit(); // if this page is no textedit, there should be nothing to save if (page == nullptr) { return true; @@ -352,13 +352,8 @@ bool TextEdit::maybeSaveAnyTab() { return false; } -QTextEdit* TextEdit::curTextPage() const { - auto* curTextPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); - if (curTextPage != nullptr) { - return curTextPage->getTextPage(); - } else { - return nullptr; - } +PlainTextEditorPage* TextEdit::curTextPage() const { + return qobject_cast<PlainTextEditorPage*>(tabWidget->currentWidget()); } FilePage* TextEdit::curFilePage() const { @@ -372,8 +367,9 @@ FilePage* TextEdit::curFilePage() const { int TextEdit::tabCount() const { return tabWidget->count(); } -EditorPage* TextEdit::slotCurPageTextEdit() const { - auto* curPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); +PlainTextEditorPage* TextEdit::slotCurPageTextEdit() const { + auto* curPage = + qobject_cast<PlainTextEditorPage*>(tabWidget->currentWidget()); return curPage; } @@ -387,7 +383,7 @@ void TextEdit::slotQuote() const { return; } - QTextCursor cursor(curTextPage()->document()); + QTextCursor cursor(curTextPage()->getTextPage()->document()); // beginEditBlock and endEditBlock() let operation look like single undo/redo // operation @@ -405,10 +401,10 @@ void TextEdit::slotQuote() const { } void TextEdit::slotFillTextEditWithText(const QString& text) const { - QTextCursor cursor(curTextPage()->document()); + QTextCursor cursor(curTextPage()->getTextPage()->document()); cursor.beginEditBlock(); - this->curTextPage()->selectAll(); - this->curTextPage()->insertPlainText(text); + this->curTextPage()->getTextPage()->selectAll(); + this->curTextPage()->getTextPage()->insertPlainText(text); cursor.endEditBlock(); } @@ -425,7 +421,7 @@ void TextEdit::loadFile(const QString& fileName) { } QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); - curTextPage()->setPlainText(in.readAll()); + curTextPage()->getTextPage()->setPlainText(in.readAll()); QApplication::restoreOverrideCursor(); slotCurPageTextEdit()->setFilePath(fileName); tabWidget->setTabText(tabWidget->currentIndex(), strippedName(fileName)); @@ -445,7 +441,7 @@ void TextEdit::slotPrint() { #ifndef QT_NO_PRINTER QTextDocument* document; if (curTextPage() != nullptr) { - document = curTextPage()->document(); + document = curTextPage()->getTextPage()->document(); } QPrinter printer; @@ -464,7 +460,7 @@ void TextEdit::slotShowModified() const { QString title = tabWidget->tabText(index); // if doc is modified now, add leading * to title, // otherwise remove the leading * from the title - if (curTextPage()->document()->isModified()) { + if (curTextPage()->getTextPage()->document()->isModified()) { tabWidget->setTabText(index, title.prepend("* ")); } else { tabWidget->setTabText(index, title.remove(0, 2)); @@ -494,7 +490,7 @@ QHash<int, QString> TextEdit::unsavedDocuments() const { // gedit like "unsaved changed"-dialog for (int i = 0; i < tabWidget->count(); i++) { - auto* ep = qobject_cast<EditorPage*>(tabWidget->widget(i)); + auto* ep = qobject_cast<PlainTextEditorPage*>(tabWidget->widget(i)); if (ep != nullptr && ep->ReadDone() && ep->getTextPage()->document()->isModified()) { QString doc_name = tabWidget->tabText(i); @@ -513,7 +509,7 @@ void TextEdit::slotCut() const { return; } - curTextPage()->cut(); + curTextPage()->getTextPage()->cut(); } void TextEdit::slotCopy() const { @@ -522,7 +518,7 @@ void TextEdit::slotCopy() const { } if (curTextPage() != nullptr) { - curTextPage()->copy(); + curTextPage()->getTextPage()->copy(); } } @@ -531,7 +527,7 @@ void TextEdit::slotPaste() const { return; } - curTextPage()->paste(); + curTextPage()->getTextPage()->paste(); } void TextEdit::slotUndo() const { @@ -539,7 +535,7 @@ void TextEdit::slotUndo() const { return; } - curTextPage()->undo(); + curTextPage()->getTextPage()->undo(); } void TextEdit::slotRedo() const { @@ -547,7 +543,7 @@ void TextEdit::slotRedo() const { return; } - curTextPage()->redo(); + curTextPage()->getTextPage()->redo(); } void TextEdit::slotZoomIn() const { @@ -556,7 +552,7 @@ void TextEdit::slotZoomIn() const { } if (curTextPage() != nullptr) { - curTextPage()->zoomIn(); + curTextPage()->getTextPage()->zoomIn(); } } @@ -566,7 +562,7 @@ void TextEdit::slotZoomOut() const { } if (curTextPage() != nullptr) { - curTextPage()->zoomOut(); + curTextPage()->getTextPage()->zoomOut(); } } @@ -574,7 +570,7 @@ void TextEdit::slotSelectAll() const { if (tabWidget->count() == 0 || curTextPage() == nullptr) { return; } - curTextPage()->selectAll(); + curTextPage()->getTextPage()->selectAll(); } void TextEdit::slotFilePagePathChanged(const QString& path) const { diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h index e877ccc1..c1f44969 100644 --- a/src/ui/widgets/TextEdit.h +++ b/src/ui/widgets/TextEdit.h @@ -26,9 +26,9 @@ #define __TEXTEDIT_H__ #include "ui/QuitDialog.h" -#include "ui/widgets/EditorPage.h" #include "ui/widgets/FilePage.h" #include "ui/widgets/HelpPage.h" +#include "ui/widgets/PlainTextEditorPage.h" namespace GpgFrontend::UI { /** @@ -66,7 +66,7 @@ class TextEdit : public QWidget { * @return \li reference to QTextEdit if tab has one * \li 0 otherwise (e.g. if helppage) */ - [[nodiscard]] QTextEdit* curTextPage() const; + [[nodiscard]] PlainTextEditorPage* curTextPage() const; [[nodiscard]] FilePage* curFilePage() const; @@ -84,7 +84,7 @@ class TextEdit : public QWidget { * @details Return pointer to the currently activated text edit tab page. * */ - EditorPage* slotCurPageTextEdit() const; + PlainTextEditorPage* slotCurPageTextEdit() const; /** * @details Return pointer to the currently activated file treeview tab page. |