summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2012-09-02 12:30:24 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-09-02 17:32:02 (GMT)
commit10e368538ec36b6a5f0c115196fb1177d547a64a (patch)
tree3adf47ff4d72dcd80306e4f556aa1444357fa3c0
parentabf10a2c0200819f6bb99366220f4c7566c01028 (diff)
downloadswift-10e368538ec36b6a5f0c115196fb1177d547a64a.zip
swift-10e368538ec36b6a5f0c115196fb1177d547a64a.tar.bz2
Adding Qt based certificate viewer as fallback for Linux.
License: This patch is BSD-licensed, see http://www.opensource.org/licenses/bsd-license.php
-rw-r--r--Swift/QtUI/QtCertificateViewerDialog.cpp133
-rw-r--r--Swift/QtUI/QtCertificateViewerDialog.h44
-rw-r--r--Swift/QtUI/QtCertificateViewerDialog.ui131
-rw-r--r--Swift/QtUI/QtMainWindow.cpp4
-rw-r--r--Swift/QtUI/SConscript5
5 files changed, 316 insertions, 1 deletions
diff --git a/Swift/QtUI/QtCertificateViewerDialog.cpp b/Swift/QtUI/QtCertificateViewerDialog.cpp
new file mode 100644
index 0000000..2a1e32a
--- /dev/null
+++ b/Swift/QtUI/QtCertificateViewerDialog.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtCertificateViewerDialog.h"
+#include "ui_QtCertificateViewerDialog.h"
+
+#include <Swiften/Base/foreach.h>
+
+#include <QTreeWidgetItem>
+#include <QLabel>
+#include <QDateTime>
+
+namespace Swift {
+
+QtCertificateViewerDialog::QtCertificateViewerDialog(QWidget *parent) : QDialog(parent), ui(new Ui::QtCertificateViewerDialog) {
+ ui->setupUi(this);
+ connect(ui->certChainTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
+
+ setAttribute(Qt::WA_DeleteOnClose);
+}
+
+QtCertificateViewerDialog::~QtCertificateViewerDialog() {
+ delete ui;
+}
+
+void QtCertificateViewerDialog::setCertificateChain(const std::vector<Certificate::ref> &chain) {
+ // clean widgets
+ ui->certChainTreeWidget->clear();
+
+ if (chain.empty()) return;
+
+ // convert Swift certificate chain to qt certificate chain (root goes first)
+ currentChain.clear();
+ foreach(Certificate::ref cert, chain) {
+ ByteArray certAsDer = cert->toDER();
+ QByteArray dataArray(reinterpret_cast<const char*>(certAsDer.data()), certAsDer.size());
+ currentChain.push_front(QSslCertificate(dataArray, QSsl::Der));
+ }
+
+ // fill treeWidget
+ QTreeWidgetItem* root = new QTreeWidgetItem(ui->certChainTreeWidget, QStringList(currentChain.at(0).subjectInfo(QSslCertificate::CommonName)));
+ root->setData(0, Qt::UserRole, QVariant(0));
+ root->setExpanded(true);
+ ui->certChainTreeWidget->addTopLevelItem(root);
+ if (currentChain.size() > 1) {
+ QTreeWidgetItem* parent = root;
+ for (int n = 1; n < currentChain.size(); n++) {
+ QTreeWidgetItem* link = new QTreeWidgetItem(parent, QStringList(QString("↳ ") + currentChain.at(n).subjectInfo(QSslCertificate::CommonName)));
+ link->setExpanded(true);
+ link->setData(0, Qt::UserRole, QVariant(n));
+ parent = link;
+ }
+ ui->certChainTreeWidget->setCurrentItem(parent);
+ } else {
+ ui->certChainTreeWidget->setCurrentItem(root);
+ }
+}
+
+void QtCertificateViewerDialog::displayCertificateChainAsSheet(QWidget *parent, const std::vector<Certificate::ref> &chain) {
+ QtCertificateViewerDialog* dialog = new QtCertificateViewerDialog(parent);
+ dialog->setCertificateChain(chain);
+ dialog->show();
+}
+
+void QtCertificateViewerDialog::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem*) {
+ setCertificateDetails(currentChain.at(current->data(0, Qt::UserRole).toInt()));
+}
+
+#define ADD_SECTION( TITLE ) \
+ ui->certGridLayout->addWidget(new QLabel("<strong>" + TITLE + "</strong>"), rowCount++, 0, 1, 2);
+
+#define ADD_FIELD( TITLE, VALUE) \
+ ui->certGridLayout->addWidget(new QLabel(TITLE), rowCount, 0, 1, 1, Qt::AlignRight); \
+ valueLabel = new QLabel(VALUE); \
+ valueLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); \
+ ui->certGridLayout->addWidget(valueLabel, rowCount++, 1, 1, 1, Qt::AlignLeft);
+
+void QtCertificateViewerDialog::setCertificateDetails(const QSslCertificate &cert) {
+ QLayoutItem* item;
+ while ((item = ui->certGridLayout->takeAt(0)) != NULL ) {
+ delete item->widget();
+ delete item;
+ }
+
+ int rowCount = 0;
+
+ ui->certGridLayout->setColumnStretch(2, 1);
+
+ QLabel* valueLabel = 0;
+
+ ADD_SECTION(tr("General"));
+ ADD_FIELD(tr("Valid From"), cert.effectiveDate().toString(Qt::TextDate));
+ ADD_FIELD(tr("Valid To"), cert.expiryDate().toString(Qt::TextDate));
+ ADD_FIELD(tr("Serial Number"), QString(cert.serialNumber().toHex()));
+ ADD_FIELD(tr("Version"), QString(cert.version()));
+
+ ADD_SECTION(tr("Subject"));
+ ADD_FIELD(tr("Organization"), cert.subjectInfo(QSslCertificate::Organization));
+ ADD_FIELD(tr("Common Name"), cert.subjectInfo(QSslCertificate::CommonName));
+ ADD_FIELD(tr("Locality"), cert.subjectInfo(QSslCertificate::LocalityName));
+ ADD_FIELD(tr("Organizational Unit"), cert.subjectInfo(QSslCertificate::OrganizationalUnitName));
+ ADD_FIELD(tr("Country"), cert.subjectInfo(QSslCertificate::CountryName));
+ ADD_FIELD(tr("State"), cert.subjectInfo(QSslCertificate::StateOrProvinceName));
+
+ if (!cert.alternateSubjectNames().empty()) {
+ ADD_SECTION(tr("Alternate Subject Names"));
+ QMultiMap<QSsl::AlternateNameEntryType, QString> altNames = cert.alternateSubjectNames();
+ foreach (const QSsl::AlternateNameEntryType &type, altNames.uniqueKeys()) {
+ foreach (QString name, altNames.values(type)) {
+ if (type == QSsl::EmailEntry) {
+ ADD_FIELD(tr("E-mail Address"), name);
+ } else {
+ ADD_FIELD(tr("DNS Name"), name);
+ }
+ }
+ }
+ }
+
+ ADD_SECTION(tr("Issuer"));
+ ADD_FIELD(tr("Organization"), cert.issuerInfo(QSslCertificate::Organization));
+ ADD_FIELD(tr("Common Name"), cert.issuerInfo(QSslCertificate::CommonName));
+ ADD_FIELD(tr("Locality"), cert.issuerInfo(QSslCertificate::LocalityName));
+ ADD_FIELD(tr("Organizational Unit"), cert.issuerInfo(QSslCertificate::OrganizationalUnitName));
+ ADD_FIELD(tr("Country"), cert.issuerInfo(QSslCertificate::CountryName));
+ ADD_FIELD(tr("State"), cert.issuerInfo(QSslCertificate::StateOrProvinceName));
+
+ ui->certGridLayout->setRowStretch(rowCount + 1, 1);
+}
+
+}
diff --git a/Swift/QtUI/QtCertificateViewerDialog.h b/Swift/QtUI/QtCertificateViewerDialog.h
new file mode 100644
index 0000000..9475a83
--- /dev/null
+++ b/Swift/QtUI/QtCertificateViewerDialog.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QDialog>
+#include <QList>
+#include <QSslCertificate>
+#include <QTreeWidgetItem>
+
+#include <Swiften/TLS/Certificate.h>
+
+namespace Ui {
+class QtCertificateViewerDialog;
+}
+
+namespace Swift {
+
+class QtCertificateViewerDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit QtCertificateViewerDialog(QWidget* parent = 0);
+ ~QtCertificateViewerDialog();
+
+ void setCertificateChain(const std::vector<Certificate::ref>& chain);
+
+ static void displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain);
+
+ private slots:
+ void currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
+
+ private:
+ void setCertificateDetails(const QSslCertificate& cert);
+
+ private:
+ Ui::QtCertificateViewerDialog *ui;
+ QList<QSslCertificate> currentChain;
+};
+
+}
diff --git a/Swift/QtUI/QtCertificateViewerDialog.ui b/Swift/QtUI/QtCertificateViewerDialog.ui
new file mode 100644
index 0000000..63a96bf
--- /dev/null
+++ b/Swift/QtUI/QtCertificateViewerDialog.ui
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtCertificateViewerDialog</class>
+ <widget class="QDialog" name="QtCertificateViewerDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>655</width>
+ <height>514</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Certificate Viewer</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0">
+ <item row="3" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>629</width>
+ <height>368</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="certGridLayout"/>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QTreeWidget" name="certChainTreeWidget">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>70</height>
+ </size>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="dragEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ <property name="expandsOnDoubleClick">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtCertificateViewerDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtCertificateViewerDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index ced375f..5d50c1e 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -41,6 +41,8 @@
#include <Swift/QtUI/CocoaUIHelpers.h>
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
#include <Swift/QtUI/WinUIHelpers.h>
+#else
+#include <Swift/QtUI/QtCertificateViewerDialog.h>
#endif
namespace Swift {
@@ -309,7 +311,7 @@ void QtMainWindow::openCertificateDialog(const std::vector<Certificate::ref>& ch
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
WinUIHelpers::displayCertificateChainAsSheet(parent, chain);
#else
-#pragma message ("No certificate dialog available on this platform.")
+ QtCertificateViewerDialog::displayCertificateChainAsSheet(parent, chain);
#endif
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 27ff237..a8a87de 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -51,6 +51,9 @@ myenv.Tool("textfile", toolpath = ["#/BuildTools/SCons/Tools"])
qt4modules = ['QtCore', 'QtGui', 'QtWebKit']
if env["PLATFORM"] == "posix" :
qt4modules += ["QtDBus"]
+if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" :
+ qt4modules += ["QtNetwork"]
+
myenv.EnableQt4Modules(qt4modules, debug = False)
myenv.Append(CPPPATH = ["."])
@@ -185,6 +188,8 @@ if env["PLATFORM"] == "darwin" or env["PLATFORM"] == "win32" :
swiftProgram = myenv.Program("Swift", sources)
else :
swiftProgram = myenv.Program("swift-im", sources)
+ sources += ["QtCertificateViewerDialog.cpp"];
+ myenv.Uic4("QtCertificateViewerDialog.ui");
if env["PLATFORM"] != "darwin" and env["PLATFORM"] != "win32" :
openURIProgram = myenv.Program("swift-open-uri", "swift-open-uri.cpp")