Przeglądaj źródła

Implemented verifying downloads

Downloaded template data gets verified against its stored md5-checksum prior to usage. If check fails, fallback to local data included in resources.
Felix Turo 3 lat temu
rodzic
commit
ca5620bd23
3 zmienionych plików z 48 dodań i 18 usunięć
  1. 2 0
      openPilotLog.pro
  2. 11 10
      src/functions/alog.cpp
  3. 35 8
      src/gui/dialogues/firstrundialog.cpp

+ 2 - 0
openPilotLog.pro

@@ -33,6 +33,7 @@ SOURCES += \
     src/classes/atailentry.cpp \
     src/classes/atranslator.cpp \
     src/classes/ajson.cpp \
+    src/classes/ahash.cpp \
     src/database/adatabase.cpp \
     src/database/adatabasesetup.cpp \
     src/database/adbsetup.cpp \
@@ -71,6 +72,7 @@ HEADERS += \
     src/database/adatabase.h \
     src/classes/atranslator.h \
     src/classes/ajson.h \
+    src/classes/ahash.h \
     src/database/adatabasesetup.h \
     src/database/adbsetup.h \
     src/database/adatabasetypes.h \

+ 11 - 10
src/functions/alog.cpp

@@ -17,6 +17,7 @@
  */
 #include "alog.h"
 #include <QMessageBox>
+#include <QTextStream>
 
 namespace ALog {
 
@@ -100,25 +101,25 @@ void aMessageHandler(QtMsgType type, const QMessageLogContext &context,
 
     switch (type) {
         case QtDebugMsg:
-            QTextStream(stdout) << DEB_HEADER_CONSOLE << msg << Qt::endl << D_SPACER << function << "\033[m" << Qt::endl;
+            QTextStream(stdout) << DEB_HEADER_CONSOLE << msg << endl << D_SPACER << function << "\033[m" << endl;
             if(logDebug)
-                log_stream << timeNow() << DEB_HEADER << msg << D_SPACER << function << Qt::endl;
+                log_stream << timeNow() << DEB_HEADER << msg << D_SPACER << function << endl;
             break;
         case QtInfoMsg:
-            log_stream << timeNow() << INFO_HEADER << msg << SPACER << function << Qt::endl;
-            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg << Qt::endl;
+            log_stream << timeNow() << INFO_HEADER << msg << SPACER << function << endl;
+            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg << endl;
             break;
         case QtWarningMsg:
-            log_stream << timeNow() << WARN_HEADER << msg << SPACER << Qt::endl;
-            QTextStream(stdout) << WARN_HEADER_CONSOLE << msg << Qt::endl;
+            log_stream << timeNow() << WARN_HEADER << msg << SPACER << endl;
+            QTextStream(stdout) << WARN_HEADER_CONSOLE << msg << endl;
             break;
         case QtCriticalMsg:
-            log_stream << timeNow() << CRIT_HEADER << msg << SPACER << Qt::endl;
-            QTextStream(stdout) << CRIT_HEADER_CONSOLE << msg << Qt::endl;
+            log_stream << timeNow() << CRIT_HEADER << msg << SPACER << endl;
+            QTextStream(stdout) << CRIT_HEADER_CONSOLE << msg << endl;
             break;
     default:
-            log_stream << timeNow() << INFO_HEADER << msg << function << Qt::endl;
-            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg << Qt::endl;
+            log_stream << timeNow() << INFO_HEADER << msg << function << endl;
+            QTextStream(stdout) << INFO_HEADER_CONSOLE << msg << endl;
             break;
     }
 }

+ 35 - 8
src/gui/dialogues/firstrundialog.cpp

@@ -31,6 +31,7 @@
 #include <QKeyEvent>
 #include "src/classes/astyle.h"
 #include "src/functions/adatetime.h"
+#include "src/classes/ahash.h"
 
 FirstRunDialog::FirstRunDialog(QWidget *parent) :
     QDialog(parent),
@@ -131,7 +132,7 @@ bool FirstRunDialog::finishSetup()
         QMessageBox message_box(QMessageBox::Question, tr("Existing Database found"),
                                    tr("An existing database file has been detected on your system.<br>"
                                    "Would you like to create a backup of the existing database?<br><br>"
-                                   "Note: if you select no, the existing database will be overwritten. This"
+                                   "Note: if you select no, the existing database will be overwritten. This "
                                    "action is irreversible."),
                                    QMessageBox::Yes | QMessageBox::No, this);
         message_box.setDefaultButton(QMessageBox::Yes);
@@ -207,6 +208,7 @@ bool FirstRunDialog::downloadTemplates(QString branch_name)
     QDir template_dir(AStandardPaths::directory(AStandardPaths::Templates));
 
     const auto template_tables = aDB->getTemplateTableNames();
+    // Download json files
     for (const auto& table : template_tables) {
         QEventLoop loop;
         ADownload* dl = new ADownload;
@@ -225,19 +227,44 @@ bool FirstRunDialog::downloadTemplates(QString branch_name)
         if (downloaded_file.size() == 0)
             return false; // ssl/network error
     }
-    return true;
+    // Download checksum files
+    for (const auto& table : template_tables) {
+        QEventLoop loop;
+        ADownload* dl = new ADownload;
+        QObject::connect(dl, &ADownload::done, &loop, &QEventLoop::quit );
+        dl->setTarget(QUrl(template_url_string + table + QLatin1String(".md5")));
+        dl->setFileName(template_dir.absoluteFilePath(table + QLatin1String(".md5")));
+
+        DEB << "Downloading: " << template_url_string + table + QLatin1String(".md5");
+        DEB << "To:" << AStandardPaths::directory(AStandardPaths::Templates);
+
+        dl->download();
+        dl->deleteLater();
+        loop.exec(); // event loop waits for download done signal before allowing loop to continue
+
+        QFileInfo downloaded_file(template_dir.filePath(table + QLatin1String(".md5")));
+        if (downloaded_file.size() == 0)
+            return false; // ssl/network error
+    }
+    // check downloadad files
+    return verifyTemplates();
 }
 
 bool FirstRunDialog::verifyTemplates()
 {
     QDir template_dir(AStandardPaths::directory(AStandardPaths::Templates));
-    const QStringList entries = template_dir.entryList(QStringList{"*.md5"}, QDir::Files, QDir::Time);
+    const auto table_names = aDB->getTemplateTableNames();
+    for (const auto &table_name : table_names) {
+        const QString path = AStandardPaths::asChildOfDir(AStandardPaths::Templates, table_name);
 
-    //QVector<QFile> json_files;
-    //for (const auto &table_name : aDB->getTemplateTableNames()) {
-    //    json_files.append(QFile(AStandardPaths::asChildOfDir(AStandardPaths::Templates, table_name)));
-    //}
+        QFileInfo check_file(path + QLatin1String(".json"));
+        AHash hash(check_file);
 
+        QFileInfo md5_file(path + QLatin1String(".md5"));
+        if (!hash.compare(md5_file))
+            return false;
+    }
+    return true;
 }
 
 void FirstRunDialog::writeSettings()
@@ -300,7 +327,7 @@ bool FirstRunDialog::setupDatabase()
         useRessourceData = false;
         if (!downloadTemplates(ui->branchLineEdit->text())) {
             QMessageBox message_box(this);
-            message_box.setText(tr("Downloading latest data has failed.<br><br>Using local data instead."));
+            message_box.setText(tr("Downloading or verifying latest data has failed.<br><br>Using local data instead."));
             message_box.exec();
             useRessourceData = true; // fall back
         }