aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix (xq) Queißner <git@mq32.de>2020-06-21 18:48:46 +0200
committerFelix (xq) Queißner <git@mq32.de>2020-06-21 18:48:46 +0200
commit75084776140610f31f28371a2c78191464577c40 (patch)
treec8967b31c5d64e7e4592ad62742a9cbd61304f64 /src
parent79a03469fc46ced070980a1446af94877dc8c466 (diff)
downloadkristall-75084776140610f31f28371a2c78191464577c40.tar.gz
Fixes a double-error-handlign with SSL trust. Error page is now more correct
Diffstat (limited to 'src')
-rw-r--r--src/geminiclient.cpp25
-rw-r--r--src/geminiclient.hpp1
-rw-r--r--src/ssltrust.cpp15
-rw-r--r--src/ssltrust.hpp8
-rw-r--r--src/webclient.cpp20
-rw-r--r--src/webclient.hpp2
6 files changed, 53 insertions, 18 deletions
diff --git a/src/geminiclient.cpp b/src/geminiclient.cpp
index 1f4acfb..12351ca 100644
--- a/src/geminiclient.cpp
+++ b/src/geminiclient.cpp
@@ -55,11 +55,13 @@ bool GeminiClient::startRequest(const QUrl &url, RequestOptions options)
ssl_config.setCaCertificates(QSslConfiguration::systemCaCertificates());
socket.setSslConfiguration(ssl_config);
+
socket.connectToHostEncrypted(url.host(), url.port(1965));
- buffer.clear();
- body.clear();
- is_receiving_body = false;
+ this->buffer.clear();
+ this->body.clear();
+ this->is_receiving_body = false;
+ this->suppress_socket_tls_error = true;
if(not socket.isOpen())
return false;
@@ -309,14 +311,19 @@ void GeminiClient::sslErrors(QList<QSslError> const & errors)
bool ignore = false;
if(SslTrust::isTrustRelated(err.error()))
{
- if(global_gemini_trust.isTrusted(target_url, socket.peerCertificate()))
+ switch(global_gemini_trust.getTrust(target_url, socket.peerCertificate()))
{
+ case SslTrust::Trusted:
ignore = true;
- }
- else
- {
+ break;
+ case SslTrust::Untrusted:
+ this->suppress_socket_tls_error = true;
emit this->networkError(UntrustedHost, "The requested host is not trusted.");
return;
+ case SslTrust::Mistrusted:
+ this->suppress_socket_tls_error = true;
+ emit this->networkError(MistrustedHost, "The requested host is in the trust store and its signature changed...");
+ return;
}
}
else if(err.error() == QSslError::UnableToVerifyFirstCertificate)
@@ -353,6 +360,8 @@ void GeminiClient::socketError(QAbstractSocket::SocketError socketError)
if(socketError == QAbstractSocket::RemoteHostClosedError) {
socket.close();
} else {
- this->emitNetworkError(socketError, socket.errorString());
+ if(not this->suppress_socket_tls_error) {
+ this->emitNetworkError(socketError, socket.errorString());
+ }
}
}
diff --git a/src/geminiclient.hpp b/src/geminiclient.hpp
index 980cb87..79514c0 100644
--- a/src/geminiclient.hpp
+++ b/src/geminiclient.hpp
@@ -41,6 +41,7 @@ private slots:
private:
bool is_receiving_body;
+ bool suppress_socket_tls_error;
QUrl target_url;
QSslSocket socket;
diff --git a/src/ssltrust.cpp b/src/ssltrust.cpp
index bbbc360..f35988e 100644
--- a/src/ssltrust.cpp
+++ b/src/ssltrust.cpp
@@ -49,15 +49,20 @@ void SslTrust::save(QSettings &settings) const
bool SslTrust::isTrusted(QUrl const & url, const QSslCertificate &certificate)
{
+ return (getTrust(url, certificate) == Trusted);
+}
+
+SslTrust::TrustStatus SslTrust::getTrust(const QUrl &url, const QSslCertificate &certificate)
+{
if(trust_level == TrustEverything)
- return true;
+ return Trusted;
if(auto host_or_none = trusted_hosts.get(url.host()); host_or_none)
{
if(host_or_none->public_key == certificate.publicKey())
- return true;
+ return Trusted;
qDebug() << "certificate mismatch for" << url;
- return false;
+ return Mistrusted;
}
else
{
@@ -70,9 +75,9 @@ bool SslTrust::isTrusted(QUrl const & url, const QSslCertificate &certificate)
bool ok = trusted_hosts.insert(host);
assert(ok);
- return true;
+ return Trusted;
}
- return false;
+ return Untrusted;
}
}
diff --git a/src/ssltrust.hpp b/src/ssltrust.hpp
index 15de44d..96a4d83 100644
--- a/src/ssltrust.hpp
+++ b/src/ssltrust.hpp
@@ -16,6 +16,12 @@ struct SslTrust
TrustNoOne = 2, // approve every fingerprint by hand
};
+ enum TrustStatus {
+ Untrusted = 0,
+ Trusted = 1,
+ Mistrusted = 2,
+ };
+
SslTrust() = default;
SslTrust(SslTrust const &) = default;
SslTrust(SslTrust &&) = default;
@@ -34,6 +40,8 @@ struct SslTrust
bool isTrusted(QUrl const & url, QSslCertificate const & certificate);
+ TrustStatus getTrust(QUrl const & url, QSslCertificate const & certificate);
+
static bool isTrustRelated(QSslError::SslError err);
};
diff --git a/src/webclient.cpp b/src/webclient.cpp
index b50d508..ecbcfef 100644
--- a/src/webclient.cpp
+++ b/src/webclient.cpp
@@ -54,6 +54,8 @@ bool WebClient::startRequest(const QUrl &url, RequestOptions options)
if(this->current_reply == nullptr)
return false;
+ this->suppress_socket_tls_error = true;
+
connect(this->current_reply, &QNetworkReply::readyRead, this, &WebClient::on_data);
connect(this->current_reply, &QNetworkReply::finished, this, &WebClient::on_finished);
connect(this->current_reply, &QNetworkReply::sslErrors, this, &WebClient::on_sslErrors);
@@ -129,7 +131,10 @@ void WebClient::on_finished()
qDebug() << "web network error" << reply->errorString();
qDebug() << this->body;
- emit this->networkError(error, reply->errorString());
+
+ if(not this->suppress_socket_tls_error) {
+ emit this->networkError(error, reply->errorString());
+ }
}
else
{
@@ -170,14 +175,19 @@ void WebClient::on_sslErrors(const QList<QSslError> &errors)
bool ignore = false;
if(SslTrust::isTrustRelated(err.error()))
{
- if(global_https_trust.isTrusted(current_reply->url(), current_reply->sslConfiguration().peerCertificate()))
+ switch(global_https_trust.getTrust(this->current_reply->url(), this->current_reply->sslConfiguration().peerCertificate()))
{
+ case SslTrust::Trusted:
ignore = true;
- }
- else
- {
+ break;
+ case SslTrust::Untrusted:
+ this->suppress_socket_tls_error = true;
emit this->networkError(UntrustedHost, "The requested host is not trusted.");
return;
+ case SslTrust::Mistrusted:
+ this->suppress_socket_tls_error = true;
+ emit this->networkError(MistrustedHost, "The requested is in the trust store and its signature changed..");
+ return;
}
}
else if(err.error() == QSslError::UnableToVerifyFirstCertificate)
diff --git a/src/webclient.hpp b/src/webclient.hpp
index 8c3e2ba..58ae029 100644
--- a/src/webclient.hpp
+++ b/src/webclient.hpp
@@ -41,6 +41,8 @@ private:
RequestOptions options;
CryptoIdentity current_identity;
+
+ bool suppress_socket_tls_error;
};
#endif // WEBCLIENT_HPP