diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/sslinfodialog_p.h | 107 | ||||
| -rw-r--r-- | src/webpage.cpp | 175 | ||||
| -rw-r--r-- | src/webpage.h | 7 | ||||
| -rw-r--r-- | src/websslinfo.cpp | 211 | ||||
| -rw-r--r-- | src/websslinfo.h | 73 | 
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 | 
