aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2022-01-09 20:25:12 +0000
committerSaturneric <[email protected]>2022-01-09 20:25:12 +0000
commit3cff1c7d0cc46d2f10da1f7019d1478f7e0e3eaa (patch)
treed845fa4138d6ebb929116650dec3157d935520c5
parent<feature>(ui, resources): add imap folder support. (diff)
downloadGpgFrontend-3cff1c7d0cc46d2f10da1f7019d1478f7e0e3eaa.tar.gz
GpgFrontend-3cff1c7d0cc46d2f10da1f7019d1478f7e0e3eaa.zip
<fixed>(ui): fix SIGSEGV when closing.
1. Fixed the segfault problem when closing the program (problem with root certificate). 2. Added some code that is executed before the exit function is called, including releasing all the root certificates that have been loaded. 3. Optimized the preloading code of the root certificate.
Diffstat (limited to '')
-rw-r--r--src/before_exit.cpp32
-rw-r--r--src/init.cpp17
-rw-r--r--src/main.cpp6
-rw-r--r--src/ui/settings/GlobalSettingStation.cpp51
-rw-r--r--src/ui/settings/GlobalSettingStation.h19
5 files changed, 94 insertions, 31 deletions
diff --git a/src/before_exit.cpp b/src/before_exit.cpp
new file mode 100644
index 00000000..ba731203
--- /dev/null
+++ b/src/before_exit.cpp
@@ -0,0 +1,32 @@
+/**
+ * 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 <easyloggingpp/easylogging++.h>
+
+#include "ui/settings/GlobalSettingStation.h"
+
+void before_exit(int status, void *arg) {
+ LOG(INFO) << "called exit status" << status;
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().ResetRootCerts();
+}
diff --git a/src/init.cpp b/src/init.cpp
index e774ab6e..fffaaa1b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -27,15 +27,6 @@
#include "ui/settings/GlobalSettingStation.h"
-vmime::shared_ptr<vmime::security::cert::X509Certificate> load_x509_cert(
- const boost::filesystem::path& path) {
- auto out_buffer = GpgFrontend::read_all_data_in_file(path.string());
- auto cert = vmime::security::cert::X509Certificate::import(
- reinterpret_cast<const vmime::byte_t*>(out_buffer.data()),
- out_buffer.size());
- return cert;
-}
-
std::vector<boost::filesystem::path> get_files_of_directory(
const boost::filesystem::path& _path) {
namespace fs = boost::filesystem;
@@ -82,12 +73,12 @@ void init_certs() {
root_certs;
auto cert_file_paths = get_files_of_directory(
GpgFrontend::UI::GlobalSettingStation::GetInstance().GetCertsDir());
+
+ auto& _instance = GpgFrontend::UI::GlobalSettingStation::GetInstance();
for (const auto& cert_file_path : cert_file_paths) {
- auto _cert = load_x509_cert(cert_file_path);
- root_certs.push_back(_cert);
+ _instance.AddRootCert(cert_file_path);
}
- LOG(INFO) << _("root certs loaded") << root_certs.size();
- GpgFrontend::UI::GlobalSettingStation::GetInstance().SetRootCerts(root_certs);
+ LOG(INFO) << _("root certs loaded") << _instance.GetRootCerts().size();
}
void init_locale() {
diff --git a/src/main.cpp b/src/main.cpp
index 3df26886..7ef2db33 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -27,11 +27,9 @@
#include <cstdlib>
#include "GpgFrontendBuildInfo.h"
-#include "gpg/GpgContext.h"
#include "gpg/GpgFunctionObject.h"
#include "ui/MainWindow.h"
#include "ui/function/CtxCheckThread.h"
-#include "ui/settings/GlobalSettingStation.h"
// Easy Logging Cpp
INITIALIZE_EASYLOGGINGPP
@@ -43,6 +41,7 @@ extern void init_logging();
extern void init_certs();
extern void init_locale();
extern void handle_signal(int sig);
+extern void before_exit(int status, void* arg);
int main(int argc, char* argv[]) {
// Register Signals
@@ -50,6 +49,9 @@ int main(int argc, char* argv[]) {
signal(SIGFPE, handle_signal);
signal(SIGILL, handle_signal);
+ // clean something before exit
+ on_exit(before_exit, nullptr);
+
// Qt
Q_INIT_RESOURCE(gpgfrontend);
diff --git a/src/ui/settings/GlobalSettingStation.cpp b/src/ui/settings/GlobalSettingStation.cpp
index 43534926..4e9bac73 100644
--- a/src/ui/settings/GlobalSettingStation.cpp
+++ b/src/ui/settings/GlobalSettingStation.cpp
@@ -24,6 +24,10 @@
#include "GlobalSettingStation.h"
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+
+#include <vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp>
#include <vmime/vmime.hpp>
std::unique_ptr<GpgFrontend::UI::GlobalSettingStation>
@@ -50,10 +54,7 @@ void GpgFrontend::UI::GlobalSettingStation::Sync() noexcept {
}
}
-GpgFrontend::UI::GlobalSettingStation::GlobalSettingStation() noexcept
- : default_certs_verifier_(
- vmime::make_shared<
- vmime::security::cert::defaultCertificateVerifier>()) {
+GpgFrontend::UI::GlobalSettingStation::GlobalSettingStation() noexcept {
using namespace boost::filesystem;
using namespace libconfig;
@@ -98,8 +99,42 @@ GpgFrontend::UI::GlobalSettingStation::GlobalSettingStation() noexcept
}
}
-void GpgFrontend::UI::GlobalSettingStation::SetRootCerts(
- const std::vector<
- vmime::shared_ptr<vmime::security::cert::X509Certificate>>& certs) {
- default_certs_verifier_->setX509RootCAs(certs);
+void GpgFrontend::UI::GlobalSettingStation::AddRootCert(
+ const boost::filesystem::path& path) {
+ auto out_buffer = GpgFrontend::read_all_data_in_file(path.string());
+
+ auto mem_bio = std::shared_ptr<BIO>(
+ BIO_new_mem_buf(out_buffer.data(), static_cast<int>(out_buffer.size())),
+ [](BIO* _p) { BIO_free(_p); });
+
+ auto x509 = std::shared_ptr<X509>(
+ PEM_read_bio_X509(mem_bio.get(), nullptr, nullptr, nullptr),
+ [](X509* _p) { X509_free(_p); });
+
+ if (!x509) return;
+
+ root_certs_.push_back(x509);
}
+
+vmime::shared_ptr<vmime::security::cert::defaultCertificateVerifier>
+GpgFrontend::UI::GlobalSettingStation::GetCertVerifier() const {
+ auto p_cv =
+ vmime::make_shared<vmime::security::cert::defaultCertificateVerifier>();
+
+ std::vector<vmime::shared_ptr<vmime::security::cert::X509Certificate>>
+ _root_certs;
+ for (const auto& cert : root_certs_) {
+ _root_certs.push_back(
+ std::make_shared<vmime::security::cert::X509Certificate_OpenSSL>(
+ cert.get()));
+ }
+ return p_cv;
+}
+
+const std::vector<std::shared_ptr<X509>>&
+GpgFrontend::UI::GlobalSettingStation::GetRootCerts() {
+ return root_certs_;
+}
+
+GpgFrontend::UI::GlobalSettingStation::~GlobalSettingStation() noexcept =
+ default;
diff --git a/src/ui/settings/GlobalSettingStation.h b/src/ui/settings/GlobalSettingStation.h
index 0838dfa4..11c5e5f3 100644
--- a/src/ui/settings/GlobalSettingStation.h
+++ b/src/ui/settings/GlobalSettingStation.h
@@ -25,6 +25,8 @@
#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H
#define GPGFRONTEND_GLOBALSETTINGSTATION_H
+#include <openssl/x509.h>
+
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
@@ -45,6 +47,8 @@ class GlobalSettingStation : public QObject {
GlobalSettingStation() noexcept;
+ ~GlobalSettingStation() noexcept override;
+
libconfig::Setting& GetUISettings() noexcept { return ui_cfg.getRoot(); }
[[nodiscard]] boost::filesystem::path GetAppDir() const { return app_path; }
@@ -79,13 +83,13 @@ class GlobalSettingStation : public QObject {
[[nodiscard]] std::shared_ptr<
vmime::security::cert::defaultCertificateVerifier>
- GetCertVerifier() const {
- return default_certs_verifier_;
- }
+ GetCertVerifier() const;
+
+ void AddRootCert(const boost::filesystem::path& path);
+
+ const std::vector<std::shared_ptr<X509>>& GetRootCerts();
- void SetRootCerts(
- const std::vector<
- std::shared_ptr<vmime::security::cert::X509Certificate>>& certs);
+ void ResetRootCerts() { root_certs_.clear(); }
void Sync() noexcept;
@@ -132,8 +136,7 @@ class GlobalSettingStation : public QObject {
libconfig::Config ui_cfg;
- std::shared_ptr<vmime::security::cert::defaultCertificateVerifier>
- default_certs_verifier_;
+ std::vector<std::shared_ptr<X509>> root_certs_;
static std::unique_ptr<GlobalSettingStation> _instance;
};