summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/sslinfodialog_p.h107
-rw-r--r--src/webpage.cpp175
-rw-r--r--src/webpage.h7
-rw-r--r--src/websslinfo.cpp211
-rw-r--r--src/websslinfo.h73
6 files changed, 548 insertions, 26 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d41ebfe0..bc4e91c8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -23,6 +23,7 @@ SET( rekonq_KDEINIT_SRCS
webinspectorpanel.cpp
webpage.cpp
webpluginfactory.cpp
+ websslinfo.cpp
websnap.cpp
webview.cpp
webtab.cpp
diff --git a/src/sslinfodialog_p.h b/src/sslinfodialog_p.h
new file mode 100644
index 00000000..44d3ab7c
--- /dev/null
+++ b/src/sslinfodialog_p.h
@@ -0,0 +1,107 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2000-2003 George Staikos <staikos@kde.org>
+ * Copyright (C) 2000 Malte Starostik <malte@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef SSLINFODIALOG_P_H
+#define SSLINFODIALOG_P_H
+
+#include <kdemacros.h>
+
+#include <KDE/KDialog>
+#include <ktcpsocket.h>
+
+// NOTE: We need a copy of this header file is needed here because it
+// is never installed by default by KIO.
+
+/**
+ * KDE SSL Information Dialog
+ *
+ * This class creates a dialog that can be used to display information about
+ * an SSL session.
+ *
+ * There are NO GUARANTEES that KSslInfoDialog will remain binary compatible/
+ * Contact staikos@kde.org for details if needed.
+ *
+ * @author George Staikos <staikos@kde.org>
+ * @see KSSL
+ * @short KDE SSL Information Dialog
+ */
+class KDE_EXPORT KSslInfoDialog : public KDialog
+{
+Q_OBJECT
+
+public:
+ /**
+ * Construct a KSSL Information Dialog
+ *
+ * @param parent the parent widget
+ */
+ explicit KSslInfoDialog(QWidget *parent = 0);
+
+ /**
+ * Destroy this dialog
+ */
+ virtual ~KSslInfoDialog();
+
+ /**
+ * Tell the dialog if the connection has portions that may not be
+ * secure (ie. a mixture of secure and insecure frames)
+ *
+ * @param isIt true if security is in question
+ */
+ void setSecurityInQuestion(bool isIt);
+
+ /**
+ * Set information to display about the SSL connection.
+ *
+ * @param certificateChain the certificate chain leading from the certificate
+ * authority to the peer.
+ * @param ip the ip of the remote host
+ * @param host the remote hostname
+ * @param sslProtocol the version of SSL in use (SSLv2, SSLv3, TLSv1)
+ * @param cipher the cipher in use
+ * @param usedBits the used bits of the key
+ * @param bits the key size of the cipher in use
+ * @param validationErrors errors validating the certificates, if any
+ */
+ void setSslInfo(const QList<QSslCertificate> &certificateChain,
+ const QString &ip, const QString &host,
+ const QString &sslProtocol, const QString &cipher,
+ int usedBits, int bits,
+ const QList<QList<KSslError::Error> > &validationErrors);
+
+ void setMainPartEncrypted(bool);
+ void setAuxiliaryPartsEncrypted(bool);
+
+ static QList<QList<KSslError::Error> > errorsFromString(const QString &s);
+
+private Q_SLOTS:
+ void launchConfig();
+ void displayFromChain(int);
+
+private:
+ void updateWhichPartsEncrypted();
+
+ class KSslInfoDialogPrivate;
+ KSslInfoDialogPrivate* const d;
+};
+
+#endif // SSLINFODIALOG_P_H
diff --git a/src/webpage.cpp b/src/webpage.cpp
index 0e7b3d8a..395e9073 100644
--- a/src/webpage.cpp
+++ b/src/webpage.cpp
@@ -45,6 +45,8 @@
#include "networkaccessmanager.h"
#include "adblockmanager.h"
+#include "sslinfodialog_p.h"
+
// KDE Includes
#include <KStandardDirs>
#include <KUrl>
@@ -73,6 +75,32 @@
// Defines
#define QL1S(x) QLatin1String(x)
+#define QL1C(x) QLatin1Char(x)
+
+
+// Returns true if the scheme and domain of the two urls match...
+static bool domainSchemeMatch(const QUrl& u1, const QUrl& u2)
+{
+ if (u1.scheme() != u2.scheme())
+ return false;
+
+ QStringList u1List = u1.host().split(QL1C('.'), QString::SkipEmptyParts);
+ QStringList u2List = u2.host().split(QL1C('.'), QString::SkipEmptyParts);
+
+ if (qMin(u1List.count(), u2List.count()) < 2)
+ return false; // better safe than sorry...
+
+ while (u1List.count() > 2)
+ u1List.removeFirst();
+
+ while (u2List.count() > 2)
+ u2List.removeFirst();
+
+ return (u1List == u2List);
+}
+
+
+// ---------------------------------------------------------------------------------
WebPage::WebPage(QWidget *parent)
@@ -92,6 +120,14 @@ WebPage::WebPage(QWidget *parent)
setNetworkAccessManager(manager);
+ // activate ssl warnings
+ setSessionMetaData("ssl_activate_warnings", "TRUE");
+
+ // Override the 'Accept' header sent by QtWebKit which favors XML over HTML!
+ // Setting the accept meta-data to null will force kio_http to use its own
+ // default settings for this header.
+ setSessionMetaData(QL1S("accept"), QString());
+
// ----- Web Plugin Factory
setPluginFactory(new WebPluginFactory(this));
@@ -100,7 +136,7 @@ WebPage::WebPage(QWidget *parent)
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
// protocol handler signals
- connect(&m_protHandler, SIGNAL(downloadUrl(const KUrl &)), this, SLOT(downloadUrl(const KUrl &)));
+ connect(&_protHandler, SIGNAL(downloadUrl(const KUrl &)), this, SLOT(downloadUrl(const KUrl &)));
}
@@ -112,21 +148,54 @@ WebPage::~WebPage()
bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
{
- // advise users on resubmitting data
- if(type == QWebPage::NavigationTypeFormResubmitted)
+ if(frame)
{
- int risp = KMessageBox::warningContinueCancel(view(),
- i18n("Are you sure you want to send your data again?"),
- i18n("Resend form data") );
- if(risp == KMessageBox::Cancel)
+ if ( _protHandler.preHandling(request, frame) )
+ {
return false;
+ }
+
+ switch (type)
+ {
+ case QWebPage::NavigationTypeLinkClicked:
+ if (_sslInfo.isValid() )
+ {
+ setRequestMetaData("ssl_was_in_use", "TRUE");
+ }
+ break;
+
+ case QWebPage::NavigationTypeFormSubmitted:
+ break;
+
+ case QWebPage::NavigationTypeFormResubmitted:
+ if( KMessageBox::warningContinueCancel(view(),
+ i18n("Are you sure you want to send your data again?"),
+ i18n("Resend form data")
+ )
+ == KMessageBox::Cancel)
+ {
+ return false;
+ }
+ break;
+
+ case QWebPage::NavigationTypeReload:
+ case QWebPage::NavigationTypeBackOrForward:
+ case QWebPage::NavigationTypeOther:
+ break;
+
+ default:
+ break;
+ }
+
+ if(frame == mainFrame())
+ {
+ setRequestMetaData("main_frame_request", "TRUE");
+ }
+ else
+ {
+ setRequestMetaData("main_frame_request", "FALSE");
+ }
}
-
- if ( frame && m_protHandler.preHandling(request, frame) )
- {
- return false;
- }
-
return KWebPage::acceptNavigationRequest(frame, request, type);
}
@@ -197,38 +266,67 @@ void WebPage::handleUnsupportedContent(QNetworkReply *reply)
}
-void WebPage::loadFinished(bool)
+void WebPage::loadFinished(bool ok)
{
+ if(!ok)
+ return;
+
Application::adblockManager()->applyHidingRules(this);
+ QStringList list = ReKonfig::walletBlackList();
+
// KWallet Integration
- // TODO: Add check for sites exempt from automatic form filling...
- if (wallet())
+ if ( wallet()
+ && !list.contains( mainFrame()->url().toString() )
+ )
{
wallet()->fillFormData(mainFrame());
}
+
+ // TODO: implement me!
+ if(_sslInfo.isValid())
+ {
+ // show an icon in the urlbar
+ }
+ else
+ {
+ // hide the icon in the urlbar
+ }
}
void WebPage::manageNetworkErrors(QNetworkReply *reply)
{
Q_ASSERT(reply);
-
- WebView *v = 0;
+ QWebFrame* frame = qobject_cast<QWebFrame *>(reply->request().originatingObject());
+ const bool isMainFrameRequest = (frame == mainFrame());
- // NOTE
- // These are not all networkreply errors,
+ if ( isMainFrameRequest
+ && _sslInfo.isValid()
+ && !domainSchemeMatch(reply->url(), _sslInfo.url())
+ )
+ {
+ //kDebug() << "Reseting cached SSL info...";
+ _sslInfo = WebSslInfo();
+ }
+
+ // NOTE: These are not all networkreply errors,
// but just that supported directly by KIO
-
switch( reply->error() )
{
- case QNetworkReply::NoError: // no error. Simple :)
+ case QNetworkReply::NoError: // no error. Simple :)
+ if ( isMainFrameRequest && !_sslInfo.isValid() )
+ {
+ // Obtain and set the SSL information if any...
+ _sslInfo.fromMetaData(reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)));
+ _sslInfo.setUrl(reply->url());
+ }
break;
case QNetworkReply::UnknownNetworkError: // unknown network-related error detected
- if( m_protHandler.postHandling(reply->request(), mainFrame()) )
+ if( _protHandler.postHandling(reply->request(), mainFrame()) )
break;
case QNetworkReply::ContentAccessDenied: // access to remote content denied (similar to HTTP error 401)
@@ -247,8 +345,7 @@ void WebPage::manageNetworkErrors(QNetworkReply *reply)
// don't bother on elements loading errors:
// we'll manage just main url page ones
- v = qobject_cast<WebView *>(view());
- if( reply->url() != v->url() )
+ if( !isMainFrameRequest )
break;
mainFrame()->setHtml( errorPage(reply), reply->url() );
@@ -398,3 +495,31 @@ void WebPage::downloadAllContentsWithKGet()
kget.call("importLinks", QVariant(contents.toList()));
}
}
+
+
+void WebPage::showSSLInfo()
+{
+ if (_sslInfo.isValid())
+ {
+ QPointer<KSslInfoDialog> dlg = new KSslInfoDialog ( view() );
+ dlg->setSslInfo( _sslInfo.certificateChain(),
+ _sslInfo.peerAddress().toString(),
+ mainFrame()->url().host(),
+ _sslInfo.protocol(),
+ _sslInfo.ciphers(),
+ _sslInfo.usedChiperBits(),
+ _sslInfo.supportedChiperBits(),
+ KSslInfoDialog::errorsFromString( _sslInfo.certificateErrors() )
+ );
+
+ dlg->open();
+ delete dlg;
+ }
+ else
+ {
+ KMessageBox::information( 0,
+ i18n("The SSL information for this site appears to be corrupt."),
+ i18nc("Secure Sockets Layer", "SSL")
+ );
+ }
+}
diff --git a/src/webpage.h b/src/webpage.h
index 76927725..42d5f586 100644
--- a/src/webpage.h
+++ b/src/webpage.h
@@ -37,6 +37,7 @@
#include "rekonqprivate_export.h"
#include "protocolhandler.h"
#include "newtabpage.h"
+#include "websslinfo.h"
// KDE Includes
#include <KWebPage>
@@ -57,6 +58,8 @@ public:
explicit WebPage(QWidget *parent = 0);
~WebPage();
+ void showSSLInfo();
+
public slots:
void manageNetworkErrors(QNetworkReply *reply);
virtual void downloadRequest(const QNetworkRequest &request);
@@ -78,7 +81,9 @@ private slots:
private:
QString errorPage(QNetworkReply *);
- ProtocolHandler m_protHandler;
+ ProtocolHandler _protHandler;
+
+ WebSslInfo _sslInfo;
};
#endif
diff --git a/src/websslinfo.cpp b/src/websslinfo.cpp
new file mode 100644
index 00000000..ffc4918f
--- /dev/null
+++ b/src/websslinfo.cpp
@@ -0,0 +1,211 @@
+/*
+ * This file is part of the KDE project.
+ *
+ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "websslinfo.h"
+
+#include <QtCore/QVariant>
+
+
+class WebSslInfo::WebSslInfoPrivate
+{
+public:
+ WebSslInfoPrivate()
+ : usedCipherBits(0), supportedCipherBits(0) {}
+
+ QUrl url;
+ QString ciphers;
+ QString protocol;
+ QString certErrors;
+ QHostAddress peerAddress;
+ QHostAddress parentAddress;
+ QList<QSslCertificate> certificateChain;
+
+ int usedCipherBits;
+ int supportedCipherBits;
+};
+
+WebSslInfo::WebSslInfo()
+ :d(new WebSslInfo::WebSslInfoPrivate)
+{
+}
+
+WebSslInfo::WebSslInfo(const WebSslInfo& other)
+ :d(new WebSslInfo::WebSslInfoPrivate)
+{
+ *this = other;
+}
+
+WebSslInfo::~WebSslInfo()
+{
+ delete d;
+ d = 0;
+}
+
+bool WebSslInfo::isValid() const
+{
+ return !d->peerAddress.isNull();
+}
+
+QUrl WebSslInfo::url() const
+{
+ return d->url;
+}
+
+QHostAddress WebSslInfo::parentAddress() const
+{
+ return d->parentAddress;
+}
+
+QHostAddress WebSslInfo::peerAddress() const
+{
+ return d->peerAddress;
+}
+
+QString WebSslInfo::protocol() const
+{
+ return d->protocol;
+}
+
+QString WebSslInfo::ciphers() const
+{
+ return d->ciphers;
+}
+
+QString WebSslInfo::certificateErrors() const
+{
+ return d->certErrors;
+}
+
+int WebSslInfo::supportedChiperBits () const
+{
+ return d->supportedCipherBits;
+}
+
+int WebSslInfo::usedChiperBits () const
+{
+ return d->usedCipherBits;
+}
+
+QList<QSslCertificate> WebSslInfo::certificateChain() const
+{
+ return d->certificateChain;
+}
+
+WebSslInfo& WebSslInfo::operator=(const WebSslInfo& other)
+{
+ d->ciphers = other.d->ciphers;
+ d->protocol = other.d->protocol;
+ d->certErrors = other.d->certErrors;
+ d->peerAddress = other.d->peerAddress;
+ d->parentAddress = other.d->parentAddress;
+ d->certificateChain = other.d->certificateChain;
+
+ d->usedCipherBits = other.d->usedCipherBits;
+ d->supportedCipherBits = other.d->supportedCipherBits;
+ d->url = other.d->url;
+
+ return *this;
+}
+
+QVariant WebSslInfo::toMetaData() const
+{
+ if (isValid()) {
+ QMap<QString, QVariant> data;
+ data.insert("ssl_in_use", true);
+ data.insert("ssl_peer_ip", d->peerAddress.toString());
+ data.insert("ssl_parent_ip", d->parentAddress.toString());
+ data.insert("ssl_protocol_version", d->protocol);
+ data.insert("ssl_cipher", d->ciphers);
+ data.insert("ssl_cert_errors", d->certErrors);
+ data.insert("ssl_cipher_used_bits", d->usedCipherBits);
+ data.insert("ssl_cipher_bits", d->supportedCipherBits);
+ QByteArray certChain;
+ Q_FOREACH(const QSslCertificate& cert, d->certificateChain)
+ certChain += cert.toPem();
+ data.insert("ssl_peer_chain", certChain);
+ return data;
+ }
+
+ return QVariant();
+}
+
+void WebSslInfo::fromMetaData(const QVariant& value)
+{
+ if (value.isValid() && value.type() == QVariant::Map) {
+ QMap<QString,QVariant> metaData = value.toMap();
+ if (metaData.value("ssl_in_use", false).toBool()) {
+ setCertificateChain(metaData.value("ssl_peer_chain").toByteArray());
+ setPeerAddress(metaData.value("ssl_peer_ip").toString());
+ setParentAddress(metaData.value("ssl_parent_ip").toString());
+ setProtocol(metaData.value("ssl_protocol_version").toString());
+ setCiphers(metaData.value("ssl_cipher").toString());
+ setCertificateErrors(metaData.value("ssl_cert_errors").toString());
+ setUsedCipherBits(metaData.value("ssl_cipher_used_bits").toString());
+ setSupportedCipherBits(metaData.value("ssl_cipher_bits").toString());
+ }
+ }
+}
+
+void WebSslInfo::setUrl (const QUrl &url)
+{
+ d->url = url;
+}
+
+void WebSslInfo::setPeerAddress(const QString& address)
+{
+ d->peerAddress = address;
+}
+
+void WebSslInfo::setParentAddress(const QString& address)
+{
+ d->parentAddress = address;
+}
+
+void WebSslInfo::setProtocol(const QString& protocol)
+{
+ d->protocol = protocol;
+}
+
+void WebSslInfo::setCertificateChain(const QByteArray& chain)
+{
+ d->certificateChain = QSslCertificate::fromData(chain);
+}
+
+void WebSslInfo::setCiphers(const QString& ciphers)
+{
+ d->ciphers = ciphers;
+}
+
+void WebSslInfo::setUsedCipherBits(const QString& bits)
+{
+ d->usedCipherBits = bits.toInt();
+}
+
+void WebSslInfo::setSupportedCipherBits(const QString& bits)
+{
+ d->supportedCipherBits = bits.toInt();
+}
+
+void WebSslInfo::setCertificateErrors(const QString& certErrors)
+{
+ d->certErrors = certErrors;
+}
diff --git a/src/websslinfo.h b/src/websslinfo.h
new file mode 100644
index 00000000..433cf053
--- /dev/null
+++ b/src/websslinfo.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the KDE project.
+ *
+ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef WEBSSLINFO_H
+#define WEBSSLINFO_H
+
+#include <kdemacros.h>
+
+#include <QtCore/QUrl>
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtNetwork/QHostAddress>
+#include <QtNetwork/QSslCertificate>
+
+
+class WebSslInfo
+{
+public:
+ WebSslInfo();
+ WebSslInfo(const WebSslInfo&);
+ virtual ~WebSslInfo();
+
+ bool isValid() const;
+ QUrl url() const;
+ QHostAddress peerAddress() const;
+ QHostAddress parentAddress() const;
+ QString ciphers() const;
+ QString protocol() const;
+ QString certificateErrors() const;
+ int supportedChiperBits () const;
+ int usedChiperBits () const;
+ QList<QSslCertificate> certificateChain() const;
+
+ QVariant toMetaData() const;
+ void fromMetaData (const QVariant &);
+
+ void setUrl (const QUrl &url);
+ WebSslInfo& operator = (const WebSslInfo&);
+
+protected:
+ void setCiphers(const QString& ciphers);
+ void setProtocol(const QString& protocol);
+ void setPeerAddress(const QString& address);
+ void setParentAddress(const QString& address);
+ void setCertificateChain(const QByteArray& chain);
+ void setCertificateErrors(const QString& certErrors);
+ void setUsedCipherBits(const QString& bits);
+ void setSupportedCipherBits(const QString& bits);
+
+private:
+ class WebSslInfoPrivate;
+ WebSslInfoPrivate* d;
+};
+
+#endif // WEBSSLINFO_H