1
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:
nowrep 2012-07-03 15:22:42 +02:00
parent 193a9371f0
commit 8542dc307f
3 changed files with 93 additions and 34 deletions

View File

@ -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()) {

View File

@ -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();

View File

@ -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;