diff options
| author | Felix (xq) Queißner <git@mq32.de> | 2020-06-19 10:37:20 +0200 |
|---|---|---|
| committer | Felix (xq) Queißner <git@mq32.de> | 2020-06-19 10:37:20 +0200 |
| commit | 6a5198d23412a6d11f78cdef71850e578ca6f8c0 (patch) | |
| tree | 136afe4f0d78018a1ae97a35e770ae792ae66ebc /src | |
| parent | 9a5c0b8ba8595b9084ad8dc27884b0cbc691459c (diff) | |
| download | kristall-6a5198d23412a6d11f78cdef71850e578ca6f8c0.tar.gz | |
Allows user to skip over invalid TLS connections and fetch the content anyways.
Diffstat (limited to 'src')
| -rw-r--r-- | src/abouthandler.cpp | 3 | ||||
| -rw-r--r-- | src/abouthandler.hpp | 2 | ||||
| -rw-r--r-- | src/browsertab.cpp | 42 | ||||
| -rw-r--r-- | src/browsertab.hpp | 4 | ||||
| -rw-r--r-- | src/browsertab.ui | 17 | ||||
| -rw-r--r-- | src/error_page/TlsFailure.gemini | 2 | ||||
| -rw-r--r-- | src/filehandler.cpp | 4 | ||||
| -rw-r--r-- | src/filehandler.hpp | 2 | ||||
| -rw-r--r-- | src/fingerclient.cpp | 4 | ||||
| -rw-r--r-- | src/fingerclient.hpp | 2 | ||||
| -rw-r--r-- | src/geminiclient.cpp | 11 | ||||
| -rw-r--r-- | src/geminiclient.hpp | 3 | ||||
| -rw-r--r-- | src/geminirenderer.cpp | 6 | ||||
| -rw-r--r-- | src/gopherclient.cpp | 4 | ||||
| -rw-r--r-- | src/gopherclient.hpp | 2 | ||||
| -rw-r--r-- | src/protocolhandler.hpp | 8 | ||||
| -rw-r--r-- | src/webclient.cpp | 8 | ||||
| -rw-r--r-- | src/webclient.hpp | 3 |
18 files changed, 88 insertions, 39 deletions
diff --git a/src/abouthandler.cpp b/src/abouthandler.cpp index a836cf2..01eefff 100644 --- a/src/abouthandler.cpp +++ b/src/abouthandler.cpp @@ -14,8 +14,9 @@ bool AboutHandler::supportsScheme(const QString &scheme) const return (scheme == "about"); } -bool AboutHandler::startRequest(const QUrl &url) +bool AboutHandler::startRequest(const QUrl &url, ProtocolHandler::RequestOptions options) { + Q_UNUSED(options) if (url.path() == "blank") { emit this->requestComplete("", "text/gemini"); diff --git a/src/abouthandler.hpp b/src/abouthandler.hpp index b535d85..86b9180 100644 --- a/src/abouthandler.hpp +++ b/src/abouthandler.hpp @@ -13,7 +13,7 @@ public: bool supportsScheme(QString const & scheme) const override; - bool startRequest(QUrl const & url) override; + bool startRequest(QUrl const & url, ProtocolHandler::RequestOptions options) override; bool isInProgress() const override; diff --git a/src/browsertab.cpp b/src/browsertab.cpp index cd1ec4f..9b7f716 100644 --- a/src/browsertab.cpp +++ b/src/browsertab.cpp @@ -90,7 +90,7 @@ void BrowserTab::navigateTo(const QUrl &url, PushToHistory mode) this->successfully_loaded = false; this->timer.start(); - if(not this->startRequest(url)) { + if(not this->startRequest(url, ProtocolHandler::Default)) { QMessageBox::critical(this, "Kristall", QString("Failed to execute request to %1").arg(url.toString())); return; } @@ -212,6 +212,8 @@ void BrowserTab::on_networkError(ProtocolHandler::NetworkError error_code, const auto contents = QString::fromUtf8(file_src.readAll()).arg(reason).toUtf8(); + this->is_internal_location = true; + this->on_requestComplete( contents, "text/gemini"); @@ -568,7 +570,7 @@ void BrowserTab::on_redirected(const QUrl &uri, bool is_permanent) } } - if (this->startRequest(uri)) + if (this->startRequest(uri, ProtocolHandler::Default)) { redirection_count += 1; this->current_location = uri; @@ -584,7 +586,8 @@ void BrowserTab::on_redirected(const QUrl &uri, bool is_permanent) void BrowserTab::on_linkHovered(const QString &url) { - this->mainWindow->setUrlPreview(QUrl(url)); + if(not url.startsWith("kristall+ctrl:")) + this->mainWindow->setUrlPreview(QUrl(url)); } void BrowserTab::setErrorMessage(const QString &msg) @@ -613,6 +616,34 @@ void BrowserTab::on_text_browser_anchorClicked(const QUrl &url) { qDebug() << url; + if(url.scheme() == "kristall+ctrl") + { + if(this->is_internal_location) { + QString opt = url.path(); + qDebug() << "kristall control action" << opt; + if(opt == "ignore-tls") { + auto response = QMessageBox::question( + this, + "Kristall", + tr("This sites certificate could not be verified! This may be a man-in-the-middle attack on the server to send you malicious content (or the server admin made a configuration mistake).\r\nAre you sure you want to continue?"), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No + ); + if(response == QMessageBox::Yes) { + this->startRequest(this->current_location, ProtocolHandler::IgnoreTlsErrors); + } + + } + } else { + QMessageBox::critical( + this, + "Kristall", + tr("Malicious site detected! This site tries to use the Kristall control scheme!\r\nA trustworthy site does not do this!").arg(this->current_location.host()) + ); + } + return; + } + QUrl real_url = url; if (real_url.isRelative()) real_url = this->current_location.resolved(url); @@ -756,7 +787,7 @@ void BrowserTab::addProtocolHandler(std::unique_ptr<ProtocolHandler> &&handler) this->protocol_handlers.emplace_back(std::move(handler)); } -bool BrowserTab::startRequest(const QUrl &url) +bool BrowserTab::startRequest(const QUrl &url, ProtocolHandler::RequestOptions options) { this->current_handler = nullptr; for(auto & ptr : this->protocol_handlers) @@ -800,10 +831,11 @@ bool BrowserTab::startRequest(const QUrl &url) } } + this->is_internal_location = (url.scheme() == "about"); this->current_location = url; this->ui->url_bar->setText(url.toString(QUrl::FormattingOptions(QUrl::FullyEncoded))); - return this->current_handler->startRequest(url); + return this->current_handler->startRequest(url, options); } void BrowserTab::on_text_browser_customContextMenuRequested(const QPoint &pos) diff --git a/src/browsertab.hpp b/src/browsertab.hpp index 506584d..cc18d28 100644 --- a/src/browsertab.hpp +++ b/src/browsertab.hpp @@ -111,7 +111,7 @@ private: this->addProtocolHandler(std::make_unique<T>()); } - bool startRequest(QUrl const & url); + bool startRequest(QUrl const & url, ProtocolHandler::RequestOptions options); public: Ui::BrowserTab *ui; @@ -138,6 +138,8 @@ public: QElapsedTimer timer; CryptoIdentity current_identitiy; + + bool is_internal_location; }; #endif // BROWSERTAB_HPP diff --git a/src/browsertab.ui b/src/browsertab.ui index 6819707..fac9184 100644 --- a/src/browsertab.ui +++ b/src/browsertab.ui @@ -13,22 +13,7 @@ <property name="windowTitle"> <string>Form</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="spacing"> - <number>0</number> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="sizeConstraint"> diff --git a/src/error_page/TlsFailure.gemini b/src/error_page/TlsFailure.gemini index 4e7dc02..d8c447a 100644 --- a/src/error_page/TlsFailure.gemini +++ b/src/error_page/TlsFailure.gemini @@ -3,3 +3,5 @@ There was an error while negotiating the TLS encryption. > %1 + +=> kristall+ctrl:ignore-tls Continue to site diff --git a/src/filehandler.cpp b/src/filehandler.cpp index a8e2e24..d26cd57 100644 --- a/src/filehandler.cpp +++ b/src/filehandler.cpp @@ -14,8 +14,10 @@ bool FileHandler::supportsScheme(const QString &scheme) const return (scheme == "file"); } -bool FileHandler::startRequest(const QUrl &url) +bool FileHandler::startRequest(const QUrl &url, RequestOptions options) { + Q_UNUSED(options) + QFile file { url.path() }; if (file.open(QFile::ReadOnly)) diff --git a/src/filehandler.hpp b/src/filehandler.hpp index f7bbfff..55ac248 100644 --- a/src/filehandler.hpp +++ b/src/filehandler.hpp @@ -13,7 +13,7 @@ public: bool supportsScheme(QString const & scheme) const override; - bool startRequest(QUrl const & url) override; + bool startRequest(QUrl const & url, RequestOptions options) override; bool isInProgress() const override; diff --git a/src/fingerclient.cpp b/src/fingerclient.cpp index 13336b6..1c9a6a3 100644 --- a/src/fingerclient.cpp +++ b/src/fingerclient.cpp @@ -24,8 +24,10 @@ bool FingerClient::supportsScheme(const QString &scheme) const return (scheme == "finger"); } -bool FingerClient::startRequest(const QUrl &url) +bool FingerClient::startRequest(const QUrl &url, RequestOptions options) { + Q_UNUSED(options) + if(isInProgress()) return false; diff --git a/src/fingerclient.hpp b/src/fingerclient.hpp index c0b94e2..63d04fd 100644 --- a/src/fingerclient.hpp +++ b/src/fingerclient.hpp @@ -17,7 +17,7 @@ public: bool supportsScheme(QString const & scheme) const override; - bool startRequest(QUrl const & url) override; + bool startRequest(QUrl const & url, RequestOptions options) override; bool isInProgress() const override; diff --git a/src/geminiclient.cpp b/src/geminiclient.cpp index a1546d8..8bd8fe0 100644 --- a/src/geminiclient.cpp +++ b/src/geminiclient.cpp @@ -31,7 +31,7 @@ bool GeminiClient::supportsScheme(const QString &scheme) const return (scheme == "gemini"); } -bool GeminiClient::startRequest(const QUrl &url) +bool GeminiClient::startRequest(const QUrl &url, RequestOptions options) { if(url.scheme() != "gemini") return false; @@ -45,6 +45,8 @@ bool GeminiClient::startRequest(const QUrl &url) return false; } + this->options = options; + QSslConfiguration ssl_config = socket.sslConfiguration(); ssl_config.setProtocol(QSsl::TlsV1_2); if(not global_trust.enable_ca) @@ -239,7 +241,7 @@ void GeminiClient::socketReadyRead() { case 1: type = ResourceNotFound; break; case 2: type = ResourceNotFound; break; - case 3: type = BadRequest; break; + case 3: type = ProxyRequest; break; case 9: type = BadRequest; break; } emit networkError(type, meta); @@ -302,6 +304,11 @@ static bool isTrustRelated(QSslError::SslError err) void GeminiClient::sslErrors(QList<QSslError> const & errors) { + if(options & IgnoreTlsErrors) { + socket.ignoreSslErrors(errors); + return; + } + QList<QSslError> remaining_errors = errors; QList<QSslError> ignored_errors; diff --git a/src/geminiclient.hpp b/src/geminiclient.hpp index 5558200..980cb87 100644 --- a/src/geminiclient.hpp +++ b/src/geminiclient.hpp @@ -19,7 +19,7 @@ public: bool supportsScheme(QString const & scheme) const override; - bool startRequest(QUrl const & url) override; + bool startRequest(QUrl const & url, RequestOptions options) override; bool isInProgress() const override; @@ -47,6 +47,7 @@ private: QByteArray buffer; QByteArray body; QString mime_type; + RequestOptions options; }; #endif // GEMINICLIENT_HPP diff --git a/src/geminirenderer.cpp b/src/geminirenderer.cpp index fd628e5..ec00869 100644 --- a/src/geminirenderer.cpp +++ b/src/geminirenderer.cpp @@ -244,8 +244,10 @@ std::unique_ptr<GeminiDocument> GeminiRenderer::render( QString suffix = ""; if (absolute_url.scheme() != root_url.scheme()) { - suffix = " [" + absolute_url.scheme().toUpper() + "]"; - fmt = cross_protocol_link; + if(absolute_url.scheme() != "kristall+ctrl") { + suffix = " [" + absolute_url.scheme().toUpper() + "]"; + fmt = cross_protocol_link; + } } fmt.setAnchor(true); diff --git a/src/gopherclient.cpp b/src/gopherclient.cpp index 2f6f31d..49ef29d 100644 --- a/src/gopherclient.cpp +++ b/src/gopherclient.cpp @@ -24,8 +24,10 @@ bool GopherClient::supportsScheme(const QString &scheme) const return (scheme == "gopher"); } -bool GopherClient::startRequest(const QUrl &url) +bool GopherClient::startRequest(const QUrl &url, RequestOptions options) { + Q_UNUSED(options) + if(isInProgress()) return false; diff --git a/src/gopherclient.hpp b/src/gopherclient.hpp index f750d7b..888ebd8 100644 --- a/src/gopherclient.hpp +++ b/src/gopherclient.hpp @@ -17,7 +17,7 @@ public: bool supportsScheme(QString const & scheme) const override; - bool startRequest(QUrl const & url) override; + bool startRequest(QUrl const & url, RequestOptions options) override; bool isInProgress() const override; diff --git a/src/protocolhandler.hpp b/src/protocolhandler.hpp index f93ef87..2fc60db 100644 --- a/src/protocolhandler.hpp +++ b/src/protocolhandler.hpp @@ -17,7 +17,7 @@ public: ConnectionRefused, //!< The host refused connection on that port ResourceNotFound, //!< The requested resource was not found on the server BadRequest, //!< Our client misbehaved and did a request the server cannot understand - ProxyRequest, //!< We requested to + ProxyRequest, //!< We requested a proxy operation, but the server does not allow that InternalServerError, InvalidClientCertificate, UntrustedHost, //!< We don't know the host, and we don't trust it @@ -26,12 +26,16 @@ public: TlsFailure, //!< Unspecified TLS failure Timeout, //!< The network connection timed out. }; + enum RequestOptions { + Default = 0, + IgnoreTlsErrors = 1, + }; public: explicit ProtocolHandler(QObject *parent = nullptr); virtual bool supportsScheme(QString const & scheme) const = 0; - virtual bool startRequest(QUrl const & url) = 0; + virtual bool startRequest(QUrl const & url, RequestOptions options) = 0; virtual bool isInProgress() const = 0; diff --git a/src/webclient.cpp b/src/webclient.cpp index 4babb76..6d23ad3 100644 --- a/src/webclient.cpp +++ b/src/webclient.cpp @@ -21,7 +21,7 @@ bool WebClient::supportsScheme(const QString &scheme) const return (scheme == "https") or (scheme == "http"); } -bool WebClient::startRequest(const QUrl &url) +bool WebClient::startRequest(const QUrl &url, RequestOptions options) { if(url.scheme() != "http" and url.scheme() != "https") return false; @@ -29,6 +29,7 @@ bool WebClient::startRequest(const QUrl &url) if(this->current_reply != nullptr) return true; + this->options = options; this->body.clear(); QSslConfiguration ssl_config; @@ -135,6 +136,11 @@ void WebClient::on_finished() void WebClient::on_sslErrors(const QList<QSslError> &errors) { + if(options & IgnoreTlsErrors) { + this->current_reply->ignoreSslErrors(errors); + return; + } + qDebug() << "HTTP SSL Errors:"; for(auto const & err : errors) qDebug() << err; diff --git a/src/webclient.hpp b/src/webclient.hpp index 55439b9..53e7fad 100644 --- a/src/webclient.hpp +++ b/src/webclient.hpp @@ -18,7 +18,7 @@ public: bool supportsScheme(QString const & scheme) const override; - bool startRequest(QUrl const & url) override; + bool startRequest(QUrl const & url, RequestOptions options) override; bool isInProgress() const override; @@ -35,6 +35,7 @@ private: QNetworkReply * current_reply; QByteArray body; + RequestOptions options; }; #endif // WEBCLIENT_HPP |
