KIO

sslui.cpp
1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2009 Andreas Hartmetz <ahartmetz@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "sslui.h"
9
10#include <KLocalizedString>
11#include <KMessageBox>
12#include <ksslcertificatemanager.h>
13#include <ksslerroruidata_p.h>
14#include <ksslinfodialog.h>
15
17{
18 const KSslErrorUiData::Private *ud = KSslErrorUiData::Private::get(&uiData);
19 if (ud->sslErrors.isEmpty()) {
20 return true;
21 }
22
23 const QList<QSslError> fatalErrors = KSslCertificateManager::nonIgnorableErrors(ud->sslErrors);
24 if (!fatalErrors.isEmpty()) {
25 // TODO message "sorry, fatal error, you can't override it"
26 return false;
27 }
28 if (ud->certificateChain.isEmpty()) {
29 // SSL without certificates is quite useless and should never happen
30 KMessageBox::error(nullptr,
31 i18n("The remote host did not send any SSL certificates.\n"
32 "Aborting because the identity of the host cannot be established."));
33 return false;
34 }
35
36 KSslCertificateManager *const cm = KSslCertificateManager::self();
37 KSslCertificateRule rule(ud->certificateChain.first(), ud->host);
38 if (storedRules & RecallRules) {
39 rule = cm->rule(ud->certificateChain.first(), ud->host);
40 // remove previously seen and acknowledged errors
41 const QList<QSslError> remainingErrors = rule.filterErrors(ud->sslErrors);
42 if (remainingErrors.isEmpty()) {
43 // qDebug() << "Error list empty after removing errors to be ignored. Continuing.";
44 return true;
45 }
46 }
47
48 // ### We don't ask to permanently reject the certificate
49
50 QString message = i18n("The server failed the authenticity check (%1).\n\n", ud->host);
51 for (const QSslError &err : std::as_const(ud->sslErrors)) {
52 message.append(err.errorString() + QLatin1Char('\n'));
53 }
54 message = message.trimmed();
55
56 int msgResult;
57 do {
58 msgResult = KMessageBox::warningTwoActionsCancel(nullptr,
59 message,
60 i18n("Server Authentication"),
61 KGuiItem(i18n("&Details"), QStringLiteral("help-about")),
62 KGuiItem(i18n("Co&ntinue"), QStringLiteral("arrow-right")));
63 if (msgResult == KMessageBox::PrimaryAction) {
64 // Details was chosen - show the certificate and error details
65
66 QList<QList<QSslError::SslError>> meh; // parallel list to cert list :/
67
68 meh.reserve(ud->certificateChain.size());
69 for (const QSslCertificate &cert : std::as_const(ud->certificateChain)) {
71 for (const QSslError &error : std::as_const(ud->sslErrors)) {
72 if (error.certificate() == cert) {
73 // we keep only the error code enum here
74 errors.append(error.error());
75 }
76 }
77 meh.append(errors);
78 }
79
80 KSslInfoDialog *dialog = new KSslInfoDialog();
81 dialog->setSslInfo(ud->certificateChain, ud->ip, ud->host, ud->sslProtocol, ud->cipher, ud->usedBits, ud->bits, meh);
82 dialog->exec();
83 } else if (msgResult == KMessageBox::Cancel) {
84 return false;
85 }
86 // fall through on KMessageBox::SecondaryAction
87 } while (msgResult == KMessageBox::PrimaryAction);
88
89 if (storedRules & StoreRules) {
90 // Save the user's choice to ignore the SSL errors.
91
92 msgResult = KMessageBox::warningTwoActions(nullptr,
93 i18n("Would you like to accept this "
94 "certificate forever without "
95 "being prompted?"),
96 i18n("Server Authentication"),
97 KGuiItem(i18n("&Forever"), QStringLiteral("flag-green")),
98 KGuiItem(i18n("&Current Session only"), QStringLiteral("chronometer")));
100 if (msgResult == KMessageBox::PrimaryAction) {
101 // accept forever ("for a very long time")
102 ruleExpiry = ruleExpiry.addYears(1000);
103 } else {
104 // accept "for a short time", half an hour.
105 ruleExpiry = ruleExpiry.addSecs(30 * 60);
106 }
107
108 // TODO special cases for wildcard domain name in the certificate!
109 // rule = KSslCertificateRule(d->socket.peerCertificateChain().first(), whatever);
110
111 rule.setExpiryDateTime(ruleExpiry);
112 rule.setIgnoredErrors(ud->sslErrors);
113 cm->setRule(rule);
114 }
115
116 return true;
117}
static QList< QSslError > nonIgnorableErrors(const QList< QSslError > &errors)
Returns the subset of errors that cannot be ignored, ie.
void setIgnoredErrors(const QList< QSslError > &errors)
Set the ignored errors for this certificate.
QList< QSslError > filterErrors(const QList< QSslError > &errors) const
Filter out errors that are already ignored.
This class can hold all the necessary data from a QSslSocket or QNetworkReply to ask the user to cont...
KDE SSL Information Dialog.
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< QSslError::SslError > > &validationErrors)
Set information to display about the SSL connection.
QString i18n(const char *text, const TYPE &arg...)
RulesStorage
Error rule storage behavior.
Definition sslui.h:20
@ RecallRules
apply stored certificate rules (typically ignored errors)
Definition sslui.h:21
@ StoreRules
make new ignore rules from the user's choice and store them
Definition sslui.h:22
bool KIOWIDGETS_EXPORT askIgnoreSslErrors(const KSslErrorUiData &uiData, RulesStorage storedRules=RecallAndStoreRules)
If there are errors while establishing an SSL encrypted connection to a peer, usually due to certific...
Definition sslui.cpp:16
ButtonCode warningTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
ButtonCode warningTwoActionsCancel(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const KGuiItem &cancelAction=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
QDateTime addSecs(qint64 s) const const
QDateTime addYears(int nyears) const const
QDateTime currentDateTime()
virtual int exec()
void append(QList< T > &&value)
bool isEmpty() const const
void reserve(qsizetype size)
QString & append(QChar ch)
QString trimmed() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:52 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.