mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-24 04: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)
|
||||
{
|
||||
if (m_ignoreAllWarnings) {
|
||||
if (m_ignoreAllWarnings || reply->property("downReply").toBool()) {
|
||||
reply->ignoreSslErrors(errors);
|
||||
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();
|
||||
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
|
||||
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
|
||||
@ -174,43 +164,76 @@ void NetworkManager::sslError(QNetworkReply* reply, QList<QSslError> errors)
|
||||
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 text1 = tr("The page you are trying to access has the following errors in the SSL certificate:");
|
||||
|
||||
QString certs;
|
||||
|
||||
foreach(const QSslError & error, errors) {
|
||||
if (m_localCerts.contains(error.certificate())) {
|
||||
continue;
|
||||
}
|
||||
if (error.error() == QSslError::NoError) { //Weird behavior on Windows
|
||||
QHash<QSslCertificate, QStringList>::const_iterator i = errorHash.constBegin();
|
||||
while (i != errorHash.constEnd()) {
|
||||
const QSslCertificate &cert = i.key();
|
||||
const QStringList &errors = i.value();
|
||||
|
||||
if (m_localCerts.contains(cert) || errors.isEmpty()) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
QSslCertificate cert = error.certificate();
|
||||
certs += "<ul><li>";
|
||||
certs += tr("<b>Organization: </b>") + CertificateInfoWidget::clearCertSpecialSymbols(cert.subjectInfo(QSslCertificate::Organization));
|
||||
certs += "</li><li>";
|
||||
certs += tr("<b>Domain Name: </b>") + CertificateInfoWidget::clearCertSpecialSymbols(cert.subjectInfo(QSslCertificate::CommonName));
|
||||
certs += "</li><li>";
|
||||
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 += "<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 message = QString("<b>%1</b><p>%2</p>%3<p>%4</p>").arg(title, text1, certs, text2);
|
||||
|
||||
if (!certs.isEmpty()) {
|
||||
if (QMessageBox::critical(webPage->view(), tr("SSL Certificate Error!"), message,
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
|
||||
QMessageBox::StandardButton button = QMessageBox::critical(webPage->view(), tr("SSL Certificate Error!"), message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
if (button == QMessageBox::No) {
|
||||
// To prevent asking user more than once for the same certificate
|
||||
webPage->addRejectedCerts(errorHash.keys());
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(const QSslError & error, errors) {
|
||||
if (!m_localCerts.contains(error.certificate())) {
|
||||
addLocalCertificate(error.certificate());
|
||||
foreach(const QSslCertificate & cert, errorHash.keys()) {
|
||||
if (!m_localCerts.contains(cert)) {
|
||||
addLocalCertificate(cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -365,11 +388,12 @@ QNetworkReply* NetworkManager::createRequest(QNetworkAccessManager::Operation op
|
||||
void NetworkManager::removeLocalCertificate(const QSslCertificate &cert)
|
||||
{
|
||||
m_localCerts.removeOne(cert);
|
||||
|
||||
QList<QSslCertificate> certs = QSslSocket::defaultCaCertificates();
|
||||
certs.removeOne(cert);
|
||||
QSslSocket::setDefaultCaCertificates(certs);
|
||||
|
||||
//Delete cert file from profile
|
||||
// Delete cert file from profile
|
||||
bool deleted = false;
|
||||
QDirIterator it(mApp->currentProfilePath() + "certificates", QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
|
@ -67,6 +67,7 @@ WebPage::WebPage(QupZilla* mainClass)
|
||||
, m_speedDial(mApp->plugins()->speedDial())
|
||||
, m_fileWatcher(0)
|
||||
, m_runningLoop(0)
|
||||
, m_loadProgress(-1)
|
||||
, m_blockAlerts(false)
|
||||
, m_secureStatus(false)
|
||||
, m_adjustingScheduled(false)
|
||||
@ -142,11 +143,38 @@ bool WebPage::loadingError() const
|
||||
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()
|
||||
{
|
||||
return m_runningLoop;
|
||||
}
|
||||
|
||||
bool WebPage::isLoading() const
|
||||
{
|
||||
return m_loadProgress < 100;
|
||||
}
|
||||
|
||||
void WebPage::setUserAgent(const QString &agent)
|
||||
{
|
||||
if (!agent.isEmpty()) {
|
||||
@ -161,13 +189,15 @@ void WebPage::urlChanged(const QUrl &url)
|
||||
{
|
||||
Q_UNUSED(url)
|
||||
|
||||
m_adBlockedEntries.clear();
|
||||
m_blockAlerts = false;
|
||||
if (isLoading()) {
|
||||
m_adBlockedEntries.clear();
|
||||
m_blockAlerts = false;
|
||||
}
|
||||
}
|
||||
|
||||
void WebPage::progress(int prog)
|
||||
{
|
||||
Q_UNUSED(prog)
|
||||
m_loadProgress = prog;
|
||||
|
||||
bool secStatus = sslCertificate().isValid();
|
||||
|
||||
|
@ -67,8 +67,12 @@ public:
|
||||
void scheduleAdjustPage();
|
||||
bool isRunningLoop();
|
||||
|
||||
bool isLoading() const;
|
||||
bool loadingError() const;
|
||||
|
||||
void addRejectedCerts(const QList<QSslCertificate> &certs);
|
||||
bool containsRejectedCerts(const QList<QSslCertificate> &certs) const;
|
||||
|
||||
static void setUserAgent(const QString &agent);
|
||||
QString userAgentForUrl(const QUrl &url) const;
|
||||
|
||||
@ -123,12 +127,13 @@ private:
|
||||
TabbedWebView* m_view;
|
||||
SpeedDial* m_speedDial;
|
||||
QSslCertificate m_SslCert;
|
||||
QList<QSslCertificate> m_SslCerts;
|
||||
QList<QSslCertificate> m_rejectedSslCerts;
|
||||
QList<AdBlockedEntry> m_adBlockedEntries;
|
||||
QFileSystemWatcher* m_fileWatcher;
|
||||
|
||||
QEventLoop* m_runningLoop;
|
||||
|
||||
int m_loadProgress;
|
||||
bool m_blockAlerts;
|
||||
bool m_secureStatus;
|
||||
bool m_adjustingScheduled;
|
||||
|
Loading…
Reference in New Issue
Block a user