WSJT-X/NetworkAccessManager.hpp
Bill Somerville 9af1379576 Fix handling of SSL/TLS exceptions allowing errors to be ignored for a session
Not persistent  but I'm not  sure they need to  be as sites  we access
should have valid certificates and  chains of trust. This should allow
users  with  baulked SSL  installations  or  incomplete CA  stores  to
proceed with network accesses at their discretion.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7378 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
2016-12-11 21:19:23 +00:00

77 lines
2.4 KiB
C++

#ifndef NETWORK_ACCESS_MANAGER_HPP__
#define NETWORK_ACCESS_MANAGER_HPP__
#include <QNetworkAccessManager>
#include <QList>
#include <QSslError>
#include <QNetworkReply>
#include <QString>
#include "MessageBox.hpp"
class QNetworkRequest;
class QIODevice;
class QWidget;
// sub-class QNAM to keep a list of accepted SSL errors and allow
// them in future replies
class NetworkAccessManager
: public QNetworkAccessManager
{
public:
NetworkAccessManager (QWidget * parent)
: QNetworkAccessManager (parent)
{
// handle SSL errors that have not been cached as allowed
// exceptions and offer them to the user to add to the ignored
// exception cache
connect (this, &QNetworkAccessManager::sslErrors, [this, &parent] (QNetworkReply * reply, QList<QSslError> const& errors) {
QString message;
QList<QSslError> new_errors;
for (auto const& error: errors)
{
if (!allowed_ssl_errors_.contains (error))
{
new_errors << error;
message += '\n' + reply->request ().url ().toDisplayString () + ": "
+ error.errorString ();
}
}
if (new_errors.size ())
{
QString certs;
for (auto const& cert : reply->sslConfiguration ().peerCertificateChain ())
{
certs += cert.toText () + '\n';
}
if (MessageBox::Ignore == MessageBox::query_message (parent, tr ("Network SSL Errors"), message, certs, MessageBox::Abort | MessageBox::Ignore))
{
// accumulate new SSL error exceptions that have been allowed
allowed_ssl_errors_.append (new_errors);
reply->ignoreSslErrors (allowed_ssl_errors_);
}
}
else
{
// no new exceptions so silently ignore the ones already allowed
reply->ignoreSslErrors (allowed_ssl_errors_);
}
});
}
protected:
QNetworkReply * createRequest (Operation operation, QNetworkRequest const& request, QIODevice * outgoing_data = nullptr) override
{
auto reply = QNetworkAccessManager::createRequest (operation, request, outgoing_data);
// errors are usually certificate specific so passing all cached
// exceptions here is ok
reply->ignoreSslErrors (allowed_ssl_errors_);
return reply;
}
private:
QList<QSslError> allowed_ssl_errors_;
};
#endif