mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 02:36:34 +01:00
NetworkManager: Fixed excessive questions about invalid SSL certificate
- user will now be asked only once if he rejects the certificate * works only within WebPage, so if user opens new tab, he will get the question again (in case he want to change his mind)
This commit is contained in:
parent
193a9371f0
commit
8542dc307f
@ -145,28 +145,18 @@ void NetworkManager::setSSLConfiguration(QNetworkReply* reply)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint qHash(const QSslCertificate &cert)
|
||||||
|
{
|
||||||
|
return qHash(cert.toPem());
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkManager::sslError(QNetworkReply* reply, QList<QSslError> errors)
|
void NetworkManager::sslError(QNetworkReply* reply, QList<QSslError> errors)
|
||||||
{
|
{
|
||||||
if (m_ignoreAllWarnings) {
|
if (m_ignoreAllWarnings || reply->property("downReply").toBool()) {
|
||||||
reply->ignoreSslErrors(errors);
|
reply->ignoreSslErrors(errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply->property("downReply").toBool()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int errorsIgnored = 0;
|
|
||||||
foreach(const QSslError & error, errors) {
|
|
||||||
if (m_ignoredCerts.contains(error.certificate())) {
|
|
||||||
++errorsIgnored;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorsIgnored == errors.count()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkRequest request = reply->request();
|
QNetworkRequest request = reply->request();
|
||||||
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
|
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
|
||||||
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
|
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
|
||||||
@ -174,43 +164,76 @@ void NetworkManager::sslError(QNetworkReply* reply, QList<QSslError> errors)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QHash<QSslCertificate, QStringList> errorHash;
|
||||||
|
foreach(const QSslError & error, errors) {
|
||||||
|
// Weird behavior on Windows
|
||||||
|
if (error.error() == QSslError::NoError) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSslCertificate &cert = error.certificate();
|
||||||
|
|
||||||
|
if (errorHash.contains(cert)) {
|
||||||
|
errorHash[cert].append(error.errorString());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorHash.insert(cert, QStringList(error.errorString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// User already rejected those certs on this page
|
||||||
|
if (webPage->containsRejectedCerts(errorHash.keys())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QString title = tr("SSL Certificate Error!");
|
QString title = tr("SSL Certificate Error!");
|
||||||
QString text1 = tr("The page you are trying to access has the following errors in the SSL certificate:");
|
QString text1 = tr("The page you are trying to access has the following errors in the SSL certificate:");
|
||||||
|
|
||||||
QString certs;
|
QString certs;
|
||||||
|
|
||||||
foreach(const QSslError & error, errors) {
|
QHash<QSslCertificate, QStringList>::const_iterator i = errorHash.constBegin();
|
||||||
if (m_localCerts.contains(error.certificate())) {
|
while (i != errorHash.constEnd()) {
|
||||||
continue;
|
const QSslCertificate &cert = i.key();
|
||||||
}
|
const QStringList &errors = i.value();
|
||||||
if (error.error() == QSslError::NoError) { //Weird behavior on Windows
|
|
||||||
|
if (m_localCerts.contains(cert) || errors.isEmpty()) {
|
||||||
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSslCertificate cert = error.certificate();
|
|
||||||
certs += "<ul><li>";
|
certs += "<ul><li>";
|
||||||
certs += tr("<b>Organization: </b>") + CertificateInfoWidget::clearCertSpecialSymbols(cert.subjectInfo(QSslCertificate::Organization));
|
certs += tr("<b>Organization: </b>") + CertificateInfoWidget::clearCertSpecialSymbols(cert.subjectInfo(QSslCertificate::Organization));
|
||||||
certs += "</li><li>";
|
certs += "</li><li>";
|
||||||
certs += tr("<b>Domain Name: </b>") + CertificateInfoWidget::clearCertSpecialSymbols(cert.subjectInfo(QSslCertificate::CommonName));
|
certs += tr("<b>Domain Name: </b>") + CertificateInfoWidget::clearCertSpecialSymbols(cert.subjectInfo(QSslCertificate::CommonName));
|
||||||
certs += "</li><li>";
|
certs += "</li><li>";
|
||||||
certs += tr("<b>Expiration Date: </b>") + cert.expiryDate().toString("hh:mm:ss dddd d. MMMM yyyy");
|
certs += tr("<b>Expiration Date: </b>") + cert.expiryDate().toString("hh:mm:ss dddd d. MMMM yyyy");
|
||||||
certs += "</li><li>";
|
|
||||||
certs += tr("<b>Error: </b>") + error.errorString();
|
|
||||||
certs += "</li></ul>";
|
certs += "</li></ul>";
|
||||||
|
|
||||||
|
certs += "<ul>";
|
||||||
|
foreach(const QString & error, errors) {
|
||||||
|
certs += "<li>";
|
||||||
|
certs += tr("<b>Error: </b>") + error;
|
||||||
|
certs += "</li>";
|
||||||
|
}
|
||||||
|
certs += "</ul>";
|
||||||
|
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString text2 = tr("Would you like to make an exception for this certificate?");
|
QString text2 = tr("Would you like to make an exception for this certificate?");
|
||||||
QString message = QString("<b>%1</b><p>%2</p>%3<p>%4</p>").arg(title, text1, certs, text2);
|
QString message = QString("<b>%1</b><p>%2</p>%3<p>%4</p>").arg(title, text1, certs, text2);
|
||||||
|
|
||||||
if (!certs.isEmpty()) {
|
if (!certs.isEmpty()) {
|
||||||
if (QMessageBox::critical(webPage->view(), tr("SSL Certificate Error!"), message,
|
QMessageBox::StandardButton button = QMessageBox::critical(webPage->view(), tr("SSL Certificate Error!"), message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
|
if (button == QMessageBox::No) {
|
||||||
|
// To prevent asking user more than once for the same certificate
|
||||||
|
webPage->addRejectedCerts(errorHash.keys());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(const QSslError & error, errors) {
|
foreach(const QSslCertificate & cert, errorHash.keys()) {
|
||||||
if (!m_localCerts.contains(error.certificate())) {
|
if (!m_localCerts.contains(cert)) {
|
||||||
addLocalCertificate(error.certificate());
|
addLocalCertificate(cert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,11 +388,12 @@ QNetworkReply* NetworkManager::createRequest(QNetworkAccessManager::Operation op
|
|||||||
void NetworkManager::removeLocalCertificate(const QSslCertificate &cert)
|
void NetworkManager::removeLocalCertificate(const QSslCertificate &cert)
|
||||||
{
|
{
|
||||||
m_localCerts.removeOne(cert);
|
m_localCerts.removeOne(cert);
|
||||||
|
|
||||||
QList<QSslCertificate> certs = QSslSocket::defaultCaCertificates();
|
QList<QSslCertificate> certs = QSslSocket::defaultCaCertificates();
|
||||||
certs.removeOne(cert);
|
certs.removeOne(cert);
|
||||||
QSslSocket::setDefaultCaCertificates(certs);
|
QSslSocket::setDefaultCaCertificates(certs);
|
||||||
|
|
||||||
//Delete cert file from profile
|
// Delete cert file from profile
|
||||||
bool deleted = false;
|
bool deleted = false;
|
||||||
QDirIterator it(mApp->currentProfilePath() + "certificates", QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
|
QDirIterator it(mApp->currentProfilePath() + "certificates", QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
@ -67,6 +67,7 @@ WebPage::WebPage(QupZilla* mainClass)
|
|||||||
, m_speedDial(mApp->plugins()->speedDial())
|
, m_speedDial(mApp->plugins()->speedDial())
|
||||||
, m_fileWatcher(0)
|
, m_fileWatcher(0)
|
||||||
, m_runningLoop(0)
|
, m_runningLoop(0)
|
||||||
|
, m_loadProgress(-1)
|
||||||
, m_blockAlerts(false)
|
, m_blockAlerts(false)
|
||||||
, m_secureStatus(false)
|
, m_secureStatus(false)
|
||||||
, m_adjustingScheduled(false)
|
, m_adjustingScheduled(false)
|
||||||
@ -142,11 +143,38 @@ bool WebPage::loadingError() const
|
|||||||
return !mainFrame()->findFirstElement("span[id=\"qupzilla-error-page\"]").isNull();
|
return !mainFrame()->findFirstElement("span[id=\"qupzilla-error-page\"]").isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebPage::addRejectedCerts(const QList<QSslCertificate> &certs)
|
||||||
|
{
|
||||||
|
foreach(const QSslCertificate & cert, certs) {
|
||||||
|
if (!m_rejectedSslCerts.contains(cert)) {
|
||||||
|
m_rejectedSslCerts.append(cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebPage::containsRejectedCerts(const QList<QSslCertificate> &certs) const
|
||||||
|
{
|
||||||
|
int matches = 0;
|
||||||
|
|
||||||
|
foreach(const QSslCertificate & cert, certs) {
|
||||||
|
if (m_rejectedSslCerts.contains(cert)) {
|
||||||
|
++matches;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches == certs.count();
|
||||||
|
}
|
||||||
|
|
||||||
bool WebPage::isRunningLoop()
|
bool WebPage::isRunningLoop()
|
||||||
{
|
{
|
||||||
return m_runningLoop;
|
return m_runningLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebPage::isLoading() const
|
||||||
|
{
|
||||||
|
return m_loadProgress < 100;
|
||||||
|
}
|
||||||
|
|
||||||
void WebPage::setUserAgent(const QString &agent)
|
void WebPage::setUserAgent(const QString &agent)
|
||||||
{
|
{
|
||||||
if (!agent.isEmpty()) {
|
if (!agent.isEmpty()) {
|
||||||
@ -161,13 +189,15 @@ void WebPage::urlChanged(const QUrl &url)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(url)
|
Q_UNUSED(url)
|
||||||
|
|
||||||
m_adBlockedEntries.clear();
|
if (isLoading()) {
|
||||||
m_blockAlerts = false;
|
m_adBlockedEntries.clear();
|
||||||
|
m_blockAlerts = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPage::progress(int prog)
|
void WebPage::progress(int prog)
|
||||||
{
|
{
|
||||||
Q_UNUSED(prog)
|
m_loadProgress = prog;
|
||||||
|
|
||||||
bool secStatus = sslCertificate().isValid();
|
bool secStatus = sslCertificate().isValid();
|
||||||
|
|
||||||
|
@ -67,8 +67,12 @@ public:
|
|||||||
void scheduleAdjustPage();
|
void scheduleAdjustPage();
|
||||||
bool isRunningLoop();
|
bool isRunningLoop();
|
||||||
|
|
||||||
|
bool isLoading() const;
|
||||||
bool loadingError() const;
|
bool loadingError() const;
|
||||||
|
|
||||||
|
void addRejectedCerts(const QList<QSslCertificate> &certs);
|
||||||
|
bool containsRejectedCerts(const QList<QSslCertificate> &certs) const;
|
||||||
|
|
||||||
static void setUserAgent(const QString &agent);
|
static void setUserAgent(const QString &agent);
|
||||||
QString userAgentForUrl(const QUrl &url) const;
|
QString userAgentForUrl(const QUrl &url) const;
|
||||||
|
|
||||||
@ -123,12 +127,13 @@ private:
|
|||||||
TabbedWebView* m_view;
|
TabbedWebView* m_view;
|
||||||
SpeedDial* m_speedDial;
|
SpeedDial* m_speedDial;
|
||||||
QSslCertificate m_SslCert;
|
QSslCertificate m_SslCert;
|
||||||
QList<QSslCertificate> m_SslCerts;
|
QList<QSslCertificate> m_rejectedSslCerts;
|
||||||
QList<AdBlockedEntry> m_adBlockedEntries;
|
QList<AdBlockedEntry> m_adBlockedEntries;
|
||||||
QFileSystemWatcher* m_fileWatcher;
|
QFileSystemWatcher* m_fileWatcher;
|
||||||
|
|
||||||
QEventLoop* m_runningLoop;
|
QEventLoop* m_runningLoop;
|
||||||
|
|
||||||
|
int m_loadProgress;
|
||||||
bool m_blockAlerts;
|
bool m_blockAlerts;
|
||||||
bool m_secureStatus;
|
bool m_secureStatus;
|
||||||
bool m_adjustingScheduled;
|
bool m_adjustingScheduled;
|
||||||
|
Loading…
Reference in New Issue
Block a user