summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
Diffstat (limited to 'Swift')
-rw-r--r--Swift/Controllers/MainController.cpp6
-rw-r--r--Swift/Controllers/Storages/CertificateStorageTrustChecker.h12
-rw-r--r--Swift/Controllers/UIInterfaces/LoginWindow.h2
-rw-r--r--Swift/QtUI/QtLoginWindow.cpp21
-rw-r--r--Swift/QtUI/QtLoginWindow.h2
-rw-r--r--Swift/QtUI/QtMainWindow.cpp8
-rw-r--r--Swift/QtUI/QtMainWindow.h1
7 files changed, 31 insertions, 21 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 40b4ded..cb43057 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -559,9 +559,9 @@ void MainController::handleDisconnected(const boost::optional<ClientError>& erro
}
bool forceReconnectAfterCertificateTrust = false;
if (!certificateErrorMessage.empty()) {
- Certificate::ref certificate = certificateTrustChecker_->getLastCertificate();
- if (loginWindow_->askUserToTrustCertificatePermanently(certificateErrorMessage, certificate)) {
- certificateStorage_->addCertificate(certificate);
+ std::vector<Certificate::ref> certificates = certificateTrustChecker_->getLastCertificateChain();
+ if (!certificates.empty() && loginWindow_->askUserToTrustCertificatePermanently(certificateErrorMessage, certificates)) {
+ certificateStorage_->addCertificate(certificates[0]);
forceReconnectAfterCertificateTrust = true;
}
else {
diff --git a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
index 40838dd..a73590a 100644
--- a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
+++ b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
@@ -18,17 +18,17 @@ namespace Swift {
CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) {
}
- virtual bool isCertificateTrusted(Certificate::ref certificate) {
- lastCertificate = certificate;
- return storage->hasCertificate(certificate);
+ virtual bool isCertificateTrusted(Certificate::ref, const std::vector<Certificate::ref>& certificateChain) {
+ lastCertificateChain = std::vector<Certificate::ref>(certificateChain.begin(), certificateChain.end());
+ return certificateChain.empty() ? false : storage->hasCertificate(certificateChain[0]);
}
- Certificate::ref getLastCertificate() const {
- return lastCertificate;
+ const std::vector<Certificate::ref>& getLastCertificateChain() const {
+ return lastCertificateChain;
}
private:
CertificateStorage* storage;
- Certificate::ref lastCertificate;
+ std::vector<Certificate::ref> lastCertificateChain;
};
}
diff --git a/Swift/Controllers/UIInterfaces/LoginWindow.h b/Swift/Controllers/UIInterfaces/LoginWindow.h
index bbbbe35..f1c2ce1 100644
--- a/Swift/Controllers/UIInterfaces/LoginWindow.h
+++ b/Swift/Controllers/UIInterfaces/LoginWindow.h
@@ -31,7 +31,7 @@ namespace Swift {
virtual void setLoginAutomatically(bool loginAutomatically) = 0;
virtual void quit() = 0;
/** Blocking request whether a cert should be permanently trusted.*/
- virtual bool askUserToTrustCertificatePermanently(const std::string& message, Certificate::ref) = 0;
+ virtual bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificateChain) = 0;
boost::signal<void ()> onCancelLoginRequest;
boost::signal<void ()> onQuitRequest;
diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp
index 094f96c..42ebe39 100644
--- a/Swift/QtUI/QtLoginWindow.cpp
+++ b/Swift/QtUI/QtLoginWindow.cpp
@@ -506,20 +506,25 @@ void QtLoginWindow::moveEvent(QMoveEvent*) {
emit geometryChanged();
}
-bool QtLoginWindow::askUserToTrustCertificatePermanently(const std::string& message, Certificate::ref certificate) {
+bool QtLoginWindow::askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificates) {
QMessageBox dialog(this);
dialog.setText(tr("The certificate presented by the server is not valid."));
dialog.setInformativeText(P2QSTRING(message) + "\n\n" + tr("Would you like to permanently trust this certificate? This must only be done if you know it is correct."));
- QString detailedText = tr("Subject: %1").arg(P2QSTRING(certificate->getSubjectName())) + "\n";
- detailedText += tr("SHA-1 Fingerprint: %1").arg(P2QSTRING(certificate->getSHA1Fingerprint()));
- dialog.setDetailedText(detailedText);
-
- dialog.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ dialog.addButton("Show Certificate", QMessageBox::HelpRole);
+ dialog.addButton(QMessageBox::Yes);
+ dialog.addButton(QMessageBox::No);
dialog.setDefaultButton(QMessageBox::No);
-
- return dialog.exec() == QMessageBox::Yes;
+ while (true) {
+ int result = dialog.exec();
+ if (result == QMessageBox::Yes || result == QMessageBox::No) {
+ return result == QMessageBox::Yes;
+ }
+ // FIXME: This isn't very nice, because the dialog disappears every time. We actually need a real
+ // dialog with a custom button.
+ QtMainWindow::openCertificateDialog(certificates, &dialog);
+ }
}
}
diff --git a/Swift/QtUI/QtLoginWindow.h b/Swift/QtUI/QtLoginWindow.h
index 8f50a35..572902e 100644
--- a/Swift/QtUI/QtLoginWindow.h
+++ b/Swift/QtUI/QtLoginWindow.h
@@ -48,7 +48,7 @@ namespace Swift {
virtual void setLoginAutomatically(bool loginAutomatically);
virtual void setIsLoggingIn(bool loggingIn);
void selectUser(const std::string& user);
- bool askUserToTrustCertificatePermanently(const std::string& message, Certificate::ref certificate);
+ bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificate);
void hide();
QtMenus getMenus() const;
virtual void quit();
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index 547f22b..ec05684 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -273,10 +273,14 @@ void QtMainWindow::setStreamEncryptionStatus(bool tlsInPlaceAndValid) {
}
void QtMainWindow::openCertificateDialog(const std::vector<Certificate::ref>& chain) {
+ openCertificateDialog(chain, this);
+}
+
+void QtMainWindow::openCertificateDialog(const std::vector<Certificate::ref>& chain, QWidget* parent) {
#if defined(SWIFTEN_PLATFORM_MACOSX)
- CocoaUIHelpers::displayCertificateChainAsSheet(this, chain);
+ CocoaUIHelpers::displayCertificateChainAsSheet(parent, chain);
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
- WinUIHelpers::displayCertificateChainAsSheet(this,chain);
+ WinUIHelpers::displayCertificateChainAsSheet(parent, chain);
#else
#pragma message ("No certificate dialog available on this platform.")
#endif
diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h
index c725d08..25d9ace 100644
--- a/Swift/QtUI/QtMainWindow.h
+++ b/Swift/QtUI/QtMainWindow.h
@@ -47,6 +47,7 @@ namespace Swift {
void setConnecting();
void setStreamEncryptionStatus(bool tlsInPlaceAndValid);
void openCertificateDialog(const std::vector<Certificate::ref>& chain);
+ static void openCertificateDialog(const std::vector<Certificate::ref>& chain, QWidget* parent);
QtEventWindow* getEventWindow();
QtChatListWindow* getChatListWindow();
void setRosterModel(Roster* roster);