Mercurial > trustbridge
view ui/downloader.cpp @ 994:8fb1b912fd8e
Add test using the default download server used by the software
This should help to highlight problems in the real environement
but needs to be adapted when the server / server layout changes
just as the software..
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 01 Sep 2014 13:14:10 +0200 |
parents | 2949f1842955 |
children | 515345358b71 |
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #include "downloader.h" #ifndef DOWNLOAD_SERVER #define DOWNLOAD_SERVER "https://www.intevation.de" #endif #include <QFile> #include <QDir> #include <QDebug> #include <QStandardPaths> #include <QLocale> #include <QSaveFile> #include <QSettings> #include <polarssl/net.h> #include <polarssl/ssl.h> #include <polarssl/entropy.h> #include <polarssl/ctr_drbg.h> #include <polarssl/error.h> #include <polarssl/certs.h> #include <polarssl/ssl_ciphersuites.h> #define MAX_SW_SIZE 15728640 #define MAX_LIST_SIZE 1048576 #ifdef USE_CURL #include "sslconnection_curl.h" #else #include "sslconnection_bare.h" #endif #ifdef RELEASE_BUILD static int accept_ciphers[] = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, 0 }; #else static int accept_ciphers[] = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA, 0 }; #endif Downloader::Downloader(QObject* parent, const QString& url, const QByteArray& certificate, const QDateTime& newestSW, const QDateTime& newestList, const QString& resourceSW, const QString& resourceList, bool downloadSW): QThread(parent), mLastModSW(newestSW), mLastModList(newestList), mResourceSW(resourceSW), mResourceList(resourceList), mDownloadSW(downloadSW) { #ifdef USE_CURL mSSLConnection = new SSLConnectionCurl(url, certificate); /* Set up Proxy support. */ QSettings settings; QString settingsProxy = settings.value("ProxyURL").toString(); if (settingsProxy.isEmpty()) { QByteArray envProxy = qgetenv("http_proxy"); if (envProxy.size()) { settingsProxy = QString::fromLocal8Bit(envProxy); } } if (!settingsProxy.isEmpty()) { mSSLConnection->setProxy(QUrl(settingsProxy)); } #else mSSLConnection = new SSLConnectionBare(url, certificate); #endif setCiphersuites(accept_ciphers); } Downloader::~Downloader() { delete mSSLConnection; } void Downloader::setCiphersuites(int suites[]) { mSSLConnection->setCiphersuites(suites); } QString Downloader::getDataDirectory() { QString candidate = QStandardPaths::writableLocation(QStandardPaths::DataLocation); if (candidate.isEmpty()) { qDebug() << "Could not find writeable locaction for me"; return QString(); } QDir cDir(candidate); if (!cDir.exists()) { if (!cDir.mkpath(candidate)) { qDebug() << "Could not create path to: " << candidate; return QString(); } } return cDir.absolutePath(); } void Downloader::run() { int ret; QDateTime remoteModList; QDateTime remoteModSW; if (!mSSLConnection->initialized()) { emit error(tr("Failed to initialize SSL Module."), SSLConnection::ErrUnknown); return; } ret = mSSLConnection->connect(); if (ret != 0) { emit error(tr("Failed to connect."), mSSLConnection->getLastError()); return; } emit progress(tr("Connected"), 1, -1); remoteModSW = mSSLConnection->getLastModifiedHeader(mResourceSW); emit lastModifiedDate(remoteModSW); if (!remoteModSW.isValid()) { emit error (tr("Connection failed."), SSLConnection::InvalidResponse); qDebug() << "Could not parse headers for Software"; return; } if (!mLastModSW.isValid() || remoteModSW > mLastModSW) { QString dataDirectory = getDataDirectory(); if (dataDirectory.isEmpty()) { qDebug() << "Failed to get data directory"; return; } QString fileName = dataDirectory.append("/SW-") .append(remoteModSW.toString("yyyyMMddHHmmss")) #ifdef WIN32 .append(".exe"); #else .append(".sh"); #endif qDebug() << "fileName: " << fileName; if (mDownloadSW) { if (!mSSLConnection->downloadFile(mResourceSW, fileName, MAX_SW_SIZE)) { emit error(tr("Failed to download File"), SSLConnection::ConnectionLost); qDebug() << "Failed to download software update."; return; } QFile::setPermissions(fileName, QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner); } emit newSoftwareAvailable(fileName, remoteModSW); return; } remoteModList = mSSLConnection->getLastModifiedHeader(mResourceList); if (!remoteModList.isValid()) { emit error (tr("Connection failed."), SSLConnection::InvalidResponse); qDebug() << "Could not parse headers for List"; return; } if (!mLastModList.isValid() || remoteModList > mLastModList) { QString dataDirectory = getDataDirectory(); if (dataDirectory.isEmpty()) { qDebug() << "Failed to get data directory"; return; } QString fileName = dataDirectory.append("/list-") .append(remoteModList.toString("yyyyMMddHHmmss")) .append(".txt"); qDebug() << "fileName: " << fileName; if (!mSSLConnection->downloadFile(mResourceList, fileName, MAX_LIST_SIZE)) { return; } emit newListAvailable(fileName, remoteModList); } emit progress(tr("Closing"), 1, -1); }