[Qt] Implement SSL error handling QML API.

https://bugs.webkit.org/show_bug.cgi?id=76793

Patch by Alexander Færøy <alexander.faeroy@nokia.com> on 2012-01-23
Reviewed by Simon Hausmann.

This patch implements support for accepting or rejecting invalid SSL
certificates from the QML API.

* UIProcess/API/qt/qquickwebview.cpp:
(QQuickWebViewPrivate::QQuickWebViewPrivate):
(QQuickWebViewPrivate::handleCertificateVerificationRequest):
(QQuickWebViewExperimental::certificateVerificationDialog):
(QQuickWebViewExperimental::setCertificateVerificationDialog):
* UIProcess/API/qt/qquickwebview_p.h:
* UIProcess/API/qt/qquickwebview_p_p.h:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::certificateVerificationRequest):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/qt/QtDialogRunner.cpp:
(CertificateVerificationDialogContextObject::CertificateVerificationDialogContextObject):
(CertificateVerificationDialogContextObject::hostname):
(CertificateVerificationDialogContextObject::accept):
(CertificateVerificationDialogContextObject::reject):
(QtDialogRunner::initForCertificateVerification):
* UIProcess/qt/QtDialogRunner.h:
* UIProcess/qt/QtPageClient.cpp:
(QtPageClient::handleCertificateVerificationRequest):
* UIProcess/qt/QtPageClient.h:
* WebProcess/qt/QtNetworkAccessManager.cpp:
(WebKit::QtNetworkAccessManager::QtNetworkAccessManager):
(WebKit::QtNetworkAccessManager::onSslErrors):
* WebProcess/qt/QtNetworkAccessManager.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105670 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e88fc125
2012-01-23 Alexander Færøy <alexander.faeroy@nokia.com>
[Qt] Implement SSL error handling QML API.
https://bugs.webkit.org/show_bug.cgi?id=76793
Reviewed by Simon Hausmann.
This patch implements support for accepting or rejecting invalid SSL
certificates from the QML API.
* UIProcess/API/qt/qquickwebview.cpp:
(QQuickWebViewPrivate::QQuickWebViewPrivate):
(QQuickWebViewPrivate::handleCertificateVerificationRequest):
(QQuickWebViewExperimental::certificateVerificationDialog):
(QQuickWebViewExperimental::setCertificateVerificationDialog):
* UIProcess/API/qt/qquickwebview_p.h:
* UIProcess/API/qt/qquickwebview_p_p.h:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::certificateVerificationRequest):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/qt/QtDialogRunner.cpp:
(CertificateVerificationDialogContextObject::CertificateVerificationDialogContextObject):
(CertificateVerificationDialogContextObject::hostname):
(CertificateVerificationDialogContextObject::accept):
(CertificateVerificationDialogContextObject::reject):
(QtDialogRunner::initForCertificateVerification):
* UIProcess/qt/QtDialogRunner.h:
* UIProcess/qt/QtPageClient.cpp:
(QtPageClient::handleCertificateVerificationRequest):
* UIProcess/qt/QtPageClient.h:
* WebProcess/qt/QtNetworkAccessManager.cpp:
(WebKit::QtNetworkAccessManager::QtNetworkAccessManager):
(WebKit::QtNetworkAccessManager::onSslErrors):
* WebProcess/qt/QtNetworkAccessManager.h:
2012-01-23 David Levin <levin@chromium.org>
[windows] Convert usages of GetDC to HWndDC Part 2.
......@@ -60,6 +60,7 @@ QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
, confirmDialog(0)
, promptDialog(0)
, authenticationDialog(0)
, certificateVerificationDialog(0)
, itemSelector(0)
, postTransitionState(adoptPtr(new PostTransitionState(this)))
, isTransitioningToNewPage(false)
......@@ -479,6 +480,25 @@ void QQuickWebViewPrivate::handleAuthenticationRequiredRequest(const QString& ho
password = dialogRunner.password();
}
bool QQuickWebViewPrivate::handleCertificateVerificationRequest(const QString& hostname)
{
if (!certificateVerificationDialog)
return false;
Q_Q(QQuickWebView);
QtDialogRunner dialogRunner;
if (!dialogRunner.initForCertificateVerification(certificateVerificationDialog, q, hostname))
return false;
setViewInAttachedProperties(dialogRunner.dialog());
disableMouseEvents();
dialogRunner.exec();
enableMouseEvents();
return dialogRunner.wasAccepted();
}
void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type)
{
#ifndef QT_NO_FILEDIALOG
......@@ -725,6 +745,21 @@ void QQuickWebViewExperimental::setAuthenticationDialog(QDeclarativeComponent* a
emit authenticationDialogChanged();
}
QDeclarativeComponent* QQuickWebViewExperimental::certificateVerificationDialog() const
{
Q_D(const QQuickWebView);
return d->certificateVerificationDialog;
}
void QQuickWebViewExperimental::setCertificateVerificationDialog(QDeclarativeComponent* certificateVerificationDialog)
{
Q_D(QQuickWebView);
if (d->certificateVerificationDialog == certificateVerificationDialog)
return;
d->certificateVerificationDialog = certificateVerificationDialog;
emit certificateVerificationDialogChanged();
}
QDeclarativeComponent* QQuickWebViewExperimental::itemSelector() const
{
Q_D(const QQuickWebView);
......
......@@ -209,6 +209,7 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject {
Q_PROPERTY(QDeclarativeComponent* confirmDialog READ confirmDialog WRITE setConfirmDialog NOTIFY confirmDialogChanged)
Q_PROPERTY(QDeclarativeComponent* promptDialog READ promptDialog WRITE setPromptDialog NOTIFY promptDialogChanged)
Q_PROPERTY(QDeclarativeComponent* authenticationDialog READ authenticationDialog WRITE setAuthenticationDialog NOTIFY authenticationDialogChanged)
Q_PROPERTY(QDeclarativeComponent* certificateVerificationDialog READ certificateVerificationDialog WRITE setCertificateVerificationDialog NOTIFY certificateVerificationDialogChanged)
Q_PROPERTY(QDeclarativeComponent* itemSelector READ itemSelector WRITE setItemSelector NOTIFY itemSelectorChanged)
Q_PROPERTY(QWebPreferences* preferences READ preferences CONSTANT FINAL)
Q_PROPERTY(bool useTraditionalDesktopBehaviour READ useTraditionalDesktopBehaviour WRITE setUseTraditionalDesktopBehaviour)
......@@ -232,6 +233,8 @@ public:
void setPromptDialog(QDeclarativeComponent*);
QDeclarativeComponent* authenticationDialog() const;
void setAuthenticationDialog(QDeclarativeComponent*);
QDeclarativeComponent* certificateVerificationDialog() const;
void setCertificateVerificationDialog(QDeclarativeComponent*);
QDeclarativeComponent* itemSelector() const;
void setItemSelector(QDeclarativeComponent*);
......@@ -261,6 +264,7 @@ Q_SIGNALS:
void confirmDialogChanged();
void promptDialogChanged();
void authenticationDialogChanged();
void certificateVerificationDialogChanged();
void itemSelectorChanged();
void downloadRequested(QWebDownloadItem* downloadItem);
void permissionRequested(QWebPermissionRequest* permission);
......
......@@ -98,6 +98,7 @@ public:
QString runJavaScriptPrompt(const QString&, const QString& defaultValue, bool& ok);
void handleAuthenticationRequiredRequest(const QString& hostname, const QString& realm, const QString& prefilledUsername, QString& username, QString& password);
bool handleCertificateVerificationRequest(const QString& hostname);
void setUseTraditionalDesktopBehaviour(bool enable);
void setViewInAttachedProperties(QObject*);
......@@ -154,6 +155,7 @@ private:
QDeclarativeComponent* confirmDialog;
QDeclarativeComponent* promptDialog;
QDeclarativeComponent* authenticationDialog;
QDeclarativeComponent* certificateVerificationDialog;
QDeclarativeComponent* itemSelector;
WebCore::ViewportArguments viewportArguments;
......
......@@ -110,7 +110,8 @@ public:
virtual void handleDownloadRequest(DownloadProxy*) = 0;
virtual void updateTextInputState() = 0;
virtual void handleAuthenticationRequiredRequest(const String& hostname, const String& realm, const String& prefilledUsername, String& username, String& password) = 0;
#endif
virtual void handleCertificateVerificationRequest(const String& hostname, bool& ignoreErrors) = 0;
#endif // PLATFORM(QT).
#if PLATFORM(QT) || PLATFORM(GTK)
virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage) = 0;
......
......@@ -2367,6 +2367,11 @@ void WebPageProxy::authenticationRequiredRequest(const String& hostname, const S
{
m_pageClient->handleAuthenticationRequiredRequest(hostname, realm, prefilledUsername, username, password);
}
void WebPageProxy::certificateVerificationRequest(const String& hostname, bool& ignoreErrors)
{
m_pageClient->handleCertificateVerificationRequest(hostname, ignoreErrors);
}
#endif // PLATFORM(QT).
#if ENABLE(TOUCH_EVENTS)
......
......@@ -321,7 +321,8 @@ public:
void resolveApplicationSchemeRequest(QtNetworkRequestData);
void sendApplicationSchemeReply(const QQuickNetworkReply*);
void authenticationRequiredRequest(const String& hostname, const String& realm, const String& prefilledUsername, String& username, String& password);
#endif
void certificateVerificationRequest(const String& hostname, bool& ignoreErrors);
#endif // PLATFORM(QT).
#if PLATFORM(QT)
void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd);
......
......@@ -75,6 +75,7 @@ messages -> WebPageProxy {
DidChangeContentsSize(WebCore::IntSize newSize)
DidFindZoomableArea(WebCore::IntPoint target, WebCore::IntRect area)
AuthenticationRequiredRequest(WTF::String hostname, WTF::String realm, WTF::String prefilledUsername) -> (WTF::String username, WTF::String password)
CertificateVerificationRequest(WTF::String hostname) -> (bool ignoreErrors)
#endif
#if ENABLE(TOUCH_EVENTS)
NeedTouchEvents(bool needTouchEvents)
......
......@@ -102,6 +102,31 @@ private:
QString m_prefilledUsername;
};
class CertificateVerificationDialogContextObject : public QObject {
Q_OBJECT
Q_PROPERTY(QString hostname READ hostname CONSTANT)
public:
CertificateVerificationDialogContextObject(const QString& hostname)
: QObject()
, m_hostname(hostname)
{
}
QString hostname() const { return m_hostname; }
public slots:
void accept() { emit accepted(); }
void reject() { emit rejected(); }
signals:
void accepted();
void rejected();
private:
QString m_hostname;
};
bool QtDialogRunner::initForAlert(QDeclarativeComponent* component, QQuickItem* dialogParent, const QString& message)
{
DialogContextObject* contextObject = new DialogContextObject(message);
......@@ -149,6 +174,19 @@ bool QtDialogRunner::initForAuthentication(QDeclarativeComponent* component, QQu
return true;
}
bool QtDialogRunner::initForCertificateVerification(QDeclarativeComponent* component, QQuickItem* dialogParent, const QString& hostname)
{
CertificateVerificationDialogContextObject* contextObject = new CertificateVerificationDialogContextObject(hostname);
if (!createDialog(component, dialogParent, contextObject))
return false;
connect(contextObject, SIGNAL(accepted()), SLOT(onAccepted()));
connect(contextObject, SIGNAL(accepted()), SLOT(quit()));
connect(contextObject, SIGNAL(rejected()), SLOT(quit()));
return true;
}
bool QtDialogRunner::createDialog(QDeclarativeComponent* component, QQuickItem* dialogParent, QObject* contextObject)
{
QDeclarativeContext* baseContext = component->creationContext();
......
......@@ -39,6 +39,7 @@ public:
bool initForConfirm(QDeclarativeComponent*, QQuickItem* dialogParent, const QString& message);
bool initForPrompt(QDeclarativeComponent*, QQuickItem* dialogParent, const QString& message, const QString& defaultValue);
bool initForAuthentication(QDeclarativeComponent*, QQuickItem* dialogParent, const QString& hostname, const QString& realm, const QString& prefilledUsername);
bool initForCertificateVerification(QDeclarativeComponent*, QQuickItem*, const QString& hostname);
QQuickItem* dialog() const { return m_dialog.get(); }
......
......@@ -118,6 +118,11 @@ void QtPageClient::handleAuthenticationRequiredRequest(const String& hostname, c
password = qPassword;
}
void QtPageClient::handleCertificateVerificationRequest(const String& hostname, bool& ignoreErrors)
{
ignoreErrors = QQuickWebViewPrivate::get(m_webView)->handleCertificateVerificationRequest(hostname);
}
void QtPageClient::setCursor(const WebCore::Cursor& cursor)
{
// FIXME: This is a temporary fix until we get cursor support in QML items.
......
......@@ -55,6 +55,7 @@ public:
virtual void handleDownloadRequest(DownloadProxy*);
virtual void handleApplicationSchemeRequest(PassRefPtr<QtNetworkRequestData>);
virtual void handleAuthenticationRequiredRequest(const String& hostname, const String& realm, const String& prefilledUsername, String& username, String& password);
virtual void handleCertificateVerificationRequest(const String& hostname, bool& ignoreErrors);
virtual void displayView();
virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset);
......
......@@ -43,6 +43,7 @@ QtNetworkAccessManager::QtNetworkAccessManager(WebProcess* webProcess)
, m_webProcess(webProcess)
{
connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), SLOT(onAuthenticationRequired(QNetworkReply*, QAuthenticator*)));
connect(this, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)), SLOT(onSslErrors(QNetworkReply*, QList<QSslError>)));
}
WebPage* QtNetworkAccessManager::obtainOriginatingWebPage(const QNetworkRequest& request)
......@@ -96,6 +97,25 @@ void QtNetworkAccessManager::onAuthenticationRequired(QNetworkReply* reply, QAut
}
}
void QtNetworkAccessManager::onSslErrors(QNetworkReply* reply, const QList<QSslError>& qSslErrors)
{
WebPage* webPage = obtainOriginatingWebPage(reply->request());
// FIXME: This check can go away once our Qt version is up-to-date. See: QTBUG-23512.
if (!webPage)
return;
String hostname = reply->url().host();
bool ignoreErrors = false;
if (webPage->sendSync(
Messages::WebPageProxy::CertificateVerificationRequest(hostname),
Messages::WebPageProxy::CertificateVerificationRequest::Reply(ignoreErrors))) {
if (ignoreErrors)
reply->ignoreSslErrors(qSslErrors);
}
}
}
#include "moc_QtNetworkAccessManager.cpp"
......@@ -47,6 +47,7 @@ protected:
private Q_SLOTS:
void onAuthenticationRequired(QNetworkReply *, QAuthenticator *);
void onSslErrors(QNetworkReply*, const QList<QSslError>&);
private:
WebPage* obtainOriginatingWebPage(const QNetworkRequest&);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment