From 3a2ceeab312b783589b7a423e7152344881e655b Mon Sep 17 00:00:00 2001 From: nowrep Date: Sat, 7 Jan 2012 10:29:38 +0100 Subject: [PATCH] Automatic updates for ca-bundle.crt CA certificates bundle. - checking updates every 5 days from homepage qupzilla.com --- src/data/data.qrc | 1 + src/data/data/bundle_version | 1 + src/network/cabundleupdater.cpp | 101 ++++++++++++++++++++++++++++++++ src/network/cabundleupdater.h | 39 ++++++++++++ src/network/networkmanager.cpp | 7 +++ src/src.pro | 6 +- src/webview/webpage.cpp | 2 +- 7 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 src/data/data/bundle_version create mode 100644 src/network/cabundleupdater.cpp create mode 100644 src/network/cabundleupdater.h diff --git a/src/data/data.qrc b/src/data/data.qrc index e05b83edf..9123bbda4 100644 --- a/src/data/data.qrc +++ b/src/data/data.qrc @@ -3,5 +3,6 @@ data/browsedata.db data/profiles.ini data/ca-bundle.crt + data/bundle_version diff --git a/src/data/data/bundle_version b/src/data/data/bundle_version new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/src/data/data/bundle_version @@ -0,0 +1 @@ +1 diff --git a/src/network/cabundleupdater.cpp b/src/network/cabundleupdater.cpp new file mode 100644 index 000000000..b24f93dc3 --- /dev/null +++ b/src/network/cabundleupdater.cpp @@ -0,0 +1,101 @@ +#include "cabundleupdater.h" +#include "mainapplication.h" +#include "networkmanager.h" +#include "qupzilla.h" +#include "globalfunctions.h" + +CaBundleUpdater::CaBundleUpdater(NetworkManager* manager, QObject* parent) + : QObject(parent) + , m_manager(manager) + , m_progress(Start) + , m_latestBundleVersion(0) +{ + m_bundleVersionFileName = mApp->PROFILEDIR + "certificates/bundle_version"; + m_bundleFileName = mApp->PROFILEDIR + "certificates/ca-bundle.crt"; + m_lastUpdateFileName = mApp->PROFILEDIR + "certificates/last_update"; + + QTimer::singleShot(30 * 1000, this, SLOT(start())); +} + +void CaBundleUpdater::start() +{ + QFile updateFile(m_lastUpdateFileName); + bool updateNow = false; + + if (updateFile.exists()) { + if (!updateFile.open(QFile::ReadOnly)) { + qWarning() << "CaBundleUpdater::start cannot open file for reading" << m_lastUpdateFileName; + } + else { + QDateTime updateTime = QDateTime::fromString(updateFile.readAll()); + updateNow = updateTime.addDays(5) < QDateTime::currentDateTime(); + } + } + else { + updateNow = true; + } + + if (updateNow) { + m_progress = CheckLastUpdate; + + m_reply = m_manager->get(QNetworkRequest(QupZilla::WWWADDRESS + "/certs/bundle_version")); + connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished())); + } +} + +void CaBundleUpdater::replyFinished() +{ + if (m_progress == CheckLastUpdate) { + QByteArray response = m_reply->readAll().trimmed(); + m_reply->close(); + m_reply->deleteLater(); + + if (m_reply->error() != QNetworkReply::NoError || response.isEmpty()) { + return; + } + + m_latestBundleVersion = response.toInt(); + int currentBundleVersion = qz_readAllFileContents(m_bundleVersionFileName).trimmed().toInt(); + + if (m_latestBundleVersion == 0) { + return; + } + + if (m_latestBundleVersion > currentBundleVersion) { + m_progress = LoadBundle; + m_reply = m_manager->get(QNetworkRequest(QupZilla::WWWADDRESS + "/certs/ca-bundle.crt")); + connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished())); + } + + QFile file(m_lastUpdateFileName); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) { + qWarning() << "CaBundleUpdater::replyFinished cannot open file for writing" << m_lastUpdateFileName; + } + + file.write(QDateTime::currentDateTime().toString().toUtf8()); + } + else if (m_progress == LoadBundle) { + QByteArray response = m_reply->readAll(); + m_reply->close(); + m_reply->deleteLater(); + + if (m_reply->error() != QNetworkReply::NoError || response.isEmpty()) { + return; + } + + QFile file(m_bundleVersionFileName); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) { + qWarning() << "CaBundleUpdater::replyFinished cannot open file for writing" << m_bundleVersionFileName; + } + + file.write(QByteArray::number(m_latestBundleVersion)); + file.close(); + + file.setFileName(m_bundleFileName); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) { + qWarning() << "CaBundleUpdater::replyFinished cannot open file for writing" << m_bundleFileName; + } + + file.write(response); + } +} diff --git a/src/network/cabundleupdater.h b/src/network/cabundleupdater.h new file mode 100644 index 000000000..560e3f8ea --- /dev/null +++ b/src/network/cabundleupdater.h @@ -0,0 +1,39 @@ +#ifndef CABUNDLEUPDATER_H +#define CABUNDLEUPDATER_H + +#include +#include +#include +#include +#include + +class NetworkManager; +class CaBundleUpdater : public QObject +{ + Q_OBJECT +public: + explicit CaBundleUpdater(NetworkManager* manager, QObject* parent = 0); + +signals: + +public slots: + +private slots: + void start(); + void replyFinished(); + +private: + enum Progress { Start, CheckLastUpdate, LoadBundle }; + + NetworkManager* m_manager; + Progress m_progress; + QNetworkReply* m_reply; + + QString m_bundleVersionFileName; + QString m_bundleFileName; + QString m_lastUpdateFileName; + + int m_latestBundleVersion; +}; + +#endif // CABUNDLEUPDATER_H diff --git a/src/network/networkmanager.cpp b/src/network/networkmanager.cpp index a924de8ab..c593d5b98 100644 --- a/src/network/networkmanager.cpp +++ b/src/network/networkmanager.cpp @@ -29,6 +29,7 @@ #include "certificateinfowidget.h" #include "globalfunctions.h" #include "acceptlanguage.h" +#include "cabundleupdater.h" QString fileNameForCert(const QSslCertificate &cert) { @@ -83,6 +84,7 @@ void NetworkManager::loadSettings() QString certDir = mApp->PROFILEDIR + "certificates"; QString bundlePath = certDir + "/ca-bundle.crt"; + QString bundleVersionPath = certDir + "/bundle_version"; if (!QDir(certDir).exists()) { QDir dir(mApp->PROFILEDIR); @@ -92,6 +94,9 @@ void NetworkManager::loadSettings() if (!QFile::exists(bundlePath)) { QFile(":data/ca-bundle.crt").copy(bundlePath); QFile(bundlePath).setPermissions(QFile::ReadUser | QFile::WriteUser); + + QFile(":data/bundle_version").copy(bundleVersionPath); + QFile(bundleVersionPath).setPermissions(QFile::ReadUser | QFile::WriteUser); } QSslSocket::setDefaultCaCertificates(QSslCertificate::fromPath(bundlePath)); @@ -450,4 +455,6 @@ void NetworkManager::loadCertificates() #endif QSslSocket::setDefaultCaCertificates(m_caCerts + m_localCerts); + + new CaBundleUpdater(this, this); } diff --git a/src/src.pro b/src/src.pro index 231ef41bb..157532d2b 100644 --- a/src/src.pro +++ b/src/src.pro @@ -184,7 +184,8 @@ SOURCES += main.cpp\ navigation/siteicon.cpp \ navigation/goicon.cpp \ rss/rssicon.cpp \ - navigation/downicon.cpp + navigation/downicon.cpp \ + network/cabundleupdater.cpp HEADERS += \ 3rdparty/qtwin.h \ @@ -307,7 +308,8 @@ HEADERS += \ navigation/siteicon.h \ navigation/goicon.h \ rss/rssicon.h \ - navigation/downicon.h + navigation/downicon.h \ + network/cabundleupdater.h FORMS += \ preferences/autofillmanager.ui \ diff --git a/src/webview/webpage.cpp b/src/webview/webpage.cpp index 0bce7fa81..15a990075 100644 --- a/src/webview/webpage.cpp +++ b/src/webview/webpage.cpp @@ -127,7 +127,7 @@ void WebPage::watchedFileChanged(const QString &file) } } -void WebPage::printFrame(QWebFrame *frame) +void WebPage::printFrame(QWebFrame* frame) { p_QupZilla->printPage(frame); }