summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/rbutilqt/base/httpget.cpp23
-rw-r--r--utils/rbutilqt/base/httpget.h5
-rw-r--r--utils/rbutilqt/rbutilqt.cpp42
-rw-r--r--utils/rbutilqt/rbutilqt.h1
4 files changed, 70 insertions, 1 deletions
diff --git a/utils/rbutilqt/base/httpget.cpp b/utils/rbutilqt/base/httpget.cpp
index fb74514e73..0cd9236209 100644
--- a/utils/rbutilqt/base/httpget.cpp
+++ b/utils/rbutilqt/base/httpget.cpp
@@ -20,6 +20,7 @@
20 20
21#include <QNetworkAccessManager> 21#include <QNetworkAccessManager>
22#include <QNetworkRequest> 22#include <QNetworkRequest>
23#include <QSslConfiguration>
23 24
24#include "httpget.h" 25#include "httpget.h"
25#include "Logger.h" 26#include "Logger.h"
@@ -27,6 +28,7 @@
27QString HttpGet::m_globalUserAgent; //< globally set user agent for requests 28QString HttpGet::m_globalUserAgent; //< globally set user agent for requests
28QDir HttpGet::m_globalCache; //< global cach path value for new objects 29QDir HttpGet::m_globalCache; //< global cach path value for new objects
29QNetworkProxy HttpGet::m_globalProxy; 30QNetworkProxy HttpGet::m_globalProxy;
31QList<QSslCertificate> HttpGet::m_acceptedClientCerts;
30 32
31HttpGet::HttpGet(QObject *parent) 33HttpGet::HttpGet(QObject *parent)
32 : QObject(parent), 34 : QObject(parent),
@@ -211,9 +213,30 @@ void HttpGet::startRequest(QUrl url)
211 connect(m_reply, &QNetworkReply::errorOccurred, this, &HttpGet::networkError); 213 connect(m_reply, &QNetworkReply::errorOccurred, this, &HttpGet::networkError);
212#endif 214#endif
213 connect(m_reply, &QNetworkReply::downloadProgress, this, &HttpGet::downloadProgress); 215 connect(m_reply, &QNetworkReply::downloadProgress, this, &HttpGet::downloadProgress);
216 connect(m_reply, &QNetworkReply::sslErrors, this, &HttpGet::gotSslError);
214} 217}
215 218
216 219
220void HttpGet::gotSslError(const QList<QSslError> &errors)
221{
222 LOG_WARNING() << "Got SSL error" << errors;
223
224 // if this is a cert error, and only if we already accepted a remote cert
225 // ignore the error.
226 // This will make QNAM continue the request and finish it.
227 if (errors.size() == 1
228 && errors.at(0).error() == QSslError::UnableToGetLocalIssuerCertificate
229 && m_acceptedClientCerts.contains(m_reply->sslConfiguration().peerCertificate())) {
230 LOG_INFO() << "client cert temporarily trusted by user.";
231 m_reply->ignoreSslErrors();
232 }
233 else {
234 LOG_ERROR() << m_reply->sslConfiguration().peerCertificate().toText();
235 emit sslError(errors.at(0), m_reply->sslConfiguration().peerCertificate());
236 }
237
238}
239
217void HttpGet::networkError(QNetworkReply::NetworkError error) 240void HttpGet::networkError(QNetworkReply::NetworkError error)
218{ 241{
219 LOG_ERROR() << "NetworkError occured:" << error << m_reply->errorString(); 242 LOG_ERROR() << "NetworkError occured:" << error << m_reply->errorString();
diff --git a/utils/rbutilqt/base/httpget.h b/utils/rbutilqt/base/httpget.h
index 443a606e6d..fb5b920b47 100644
--- a/utils/rbutilqt/base/httpget.h
+++ b/utils/rbutilqt/base/httpget.h
@@ -73,6 +73,8 @@ class HttpGet : public QObject
73 //< set global user agent string 73 //< set global user agent string
74 static void setGlobalUserAgent(const QString& u) 74 static void setGlobalUserAgent(const QString& u)
75 { m_globalUserAgent = u; } 75 { m_globalUserAgent = u; }
76 static void addTrustedPeerCert(QSslCertificate cert)
77 { m_acceptedClientCerts.append(cert);}
76 78
77 public slots: 79 public slots:
78 void abort(void); 80 void abort(void);
@@ -81,14 +83,17 @@ class HttpGet : public QObject
81 void done(QNetworkReply::NetworkError error); 83 void done(QNetworkReply::NetworkError error);
82 void dataReadProgress(int, int); 84 void dataReadProgress(int, int);
83 void headerFinished(void); 85 void headerFinished(void);
86 void sslError(const QSslError& error, const QSslCertificate& peerCert);
84 87
85 private slots: 88 private slots:
86 void requestFinished(QNetworkReply* reply); 89 void requestFinished(QNetworkReply* reply);
87 void startRequest(QUrl url); 90 void startRequest(QUrl url);
88 void downloadProgress(qint64 received, qint64 total); 91 void downloadProgress(qint64 received, qint64 total);
89 void networkError(QNetworkReply::NetworkError error); 92 void networkError(QNetworkReply::NetworkError error);
93 void gotSslError(const QList<QSslError> &errors);
90 94
91 private: 95 private:
96 static QList<QSslCertificate> m_acceptedClientCerts;
92 static QString m_globalUserAgent; 97 static QString m_globalUserAgent;
93 static QNetworkProxy m_globalProxy; 98 static QNetworkProxy m_globalProxy;
94 QNetworkAccessManager m_mgr; 99 QNetworkAccessManager m_mgr;
diff --git a/utils/rbutilqt/rbutilqt.cpp b/utils/rbutilqt/rbutilqt.cpp
index 6d0da3390f..680303859e 100644
--- a/utils/rbutilqt/rbutilqt.cpp
+++ b/utils/rbutilqt/rbutilqt.cpp
@@ -205,6 +205,7 @@ void RbUtilQt::downloadInfo()
205 // try to get the current build information 205 // try to get the current build information
206 daily = new HttpGet(this); 206 daily = new HttpGet(this);
207 connect(daily, &HttpGet::done, this, &RbUtilQt::downloadDone); 207 connect(daily, &HttpGet::done, this, &RbUtilQt::downloadDone);
208 connect(daily, &HttpGet::sslError, this, &RbUtilQt::sslError);
208 connect(qApp, &QGuiApplication::lastWindowClosed, daily, &HttpGet::abort); 209 connect(qApp, &QGuiApplication::lastWindowClosed, daily, &HttpGet::abort);
209 daily->setCache(false); 210 daily->setCache(false);
210 ui.statusbar->showMessage(tr("Downloading build information, please wait ...")); 211 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
@@ -213,10 +214,49 @@ void RbUtilQt::downloadInfo()
213 daily->getFile(QUrl(PlayerBuildInfo::instance()->value(PlayerBuildInfo::BuildInfoUrl).toString())); 214 daily->getFile(QUrl(PlayerBuildInfo::instance()->value(PlayerBuildInfo::BuildInfoUrl).toString()));
214} 215}
215 216
217void RbUtilQt::sslError(const QSslError& error, const QSslCertificate& peerCert)
218{
219 LOG_WARNING() << "sslError" << (int)error.error();
220 // On Rockbox Utility start we always try to get the build info first.
221 // Thus we can use that to catch potential certificate errors.
222 // If the user accepts the certificate we'll have HttpGet ignore all cert
223 // errors for the exact certificate we got during this first request.
224 // Thus we don't need to handle cert errors later anymore.
225 if (error.error() == QSslError::UnableToGetLocalIssuerCertificate) {
226 QMessageBox mb(this);
227 mb.setWindowTitle(tr("Certificate error"));
228 mb.setIcon(QMessageBox::Warning);
229 mb.setText(tr("%1\n\n"
230 "Issuer: %2\n"
231 "Subject: %3\n"
232 "Valid since: %4\n"
233 "Valid until: %5\n\n"
234 "Temporarily trust certificate?")
235 .arg(error.errorString())
236 .arg(peerCert.issuerInfo(QSslCertificate::Organization).at(0))
237 .arg(peerCert.subjectDisplayName())
238 .arg(peerCert.effectiveDate().toString())
239 .arg(peerCert.expiryDate().toString())
240 );
241 mb.setDetailedText(peerCert.toText());
242 mb.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
243
244 auto r = mb.exec();
245 if (r == QMessageBox::Yes) {
246 HttpGet::addTrustedPeerCert(peerCert);
247 downloadInfo();
248 }
249 else {
250 downloadDone(QNetworkReply::OperationCanceledError);
251 }
252 }
253}
254
216 255
217void RbUtilQt::downloadDone(QNetworkReply::NetworkError error) 256void RbUtilQt::downloadDone(QNetworkReply::NetworkError error)
218{ 257{
219 if(error != QNetworkReply::NoError) { 258 if(error != QNetworkReply::NoError
259 && error != QNetworkReply::SslHandshakeFailedError) {
220 LOG_INFO() << "network error:" << daily->errorString(); 260 LOG_INFO() << "network error:" << daily->errorString();
221 ui.statusbar->showMessage(tr("Can't get version information!")); 261 ui.statusbar->showMessage(tr("Can't get version information!"));
222 QMessageBox::critical(this, tr("Network error"), 262 QMessageBox::critical(this, tr("Network error"),
diff --git a/utils/rbutilqt/rbutilqt.h b/utils/rbutilqt/rbutilqt.h
index c507317fa2..9caa8a1267 100644
--- a/utils/rbutilqt/rbutilqt.h
+++ b/utils/rbutilqt/rbutilqt.h
@@ -72,6 +72,7 @@ class RbUtilQt : public QMainWindow
72 bool m_auto; 72 bool m_auto;
73 73
74 private slots: 74 private slots:
75 void sslError(const QSslError& error, const QSslCertificate& peerCert);
75 void shutdown(void); 76 void shutdown(void);
76 void about(void); 77 void about(void);
77 void help(void); 78 void help(void);