[SCM] ktp-auth-handler packaging branch, master, updated. debian/15.12.1-2-282-g080758e
Maximiliano Curia
maxy at moszumanska.debian.org
Fri May 27 23:58:55 UTC 2016
Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-auth-handler.git;a=commitdiff;h=b553543
The following commit has been merged in the master branch:
commit b55354344d4dd3078a340da78f761c34770552d0
Author: Dan Vrátil <dvratil at redhat.com>
Date: Tue Feb 5 12:39:34 2013 +0100
Support TLS channels
Certificates are verified against user's CAs and rules stored
in KSslCertificateManager.
---
CMakeLists.txt | 19 ++--
kssl/kssl.h | 169 +++++++++++++++++++++++++++++++++++
kssl/ksslcertificatemanager.h | 99 +++++++++++++++++++++
kssl/ksslinfodialog.h | 101 +++++++++++++++++++++
kssl/ksslsettings.h | 169 +++++++++++++++++++++++++++++++++++
main.cpp | 3 -
tls-cert-verifier-op.cpp | 199 ++++++++++++++++++++++++++++++++++++------
tls-cert-verifier-op.h | 12 +++
8 files changed, 730 insertions(+), 41 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 417554a..a12225a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,19 +13,19 @@ find_package (KDE4 4.4.75 REQUIRED)
find_package (TelepathyQt4 0.8.9 REQUIRED)
find_package (KTp REQUIRED)
find_package (QJSON REQUIRED)
+find_package (QCA2 REQUIRED)
include (KDE4Defaults)
include (MacroLibrary)
-add_definitions (${KDE4_DEFINITIONS}
- -DQT_NO_CAST_FROM_ASCII
- -DQT_NO_KEYWORDS
-)
+add_definitions (${KDE4_DEFINITIONS})
include_directories (${KDE4_INCLUDES}
${TELEPATHY_QT4_INCLUDE_DIR}
${KTP_INCLUDE_DIR}
${QJSON_INCLUDE_DIR}
+ ${QCA2_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/kssl
)
set(ktp_auth_handler_SRCS
@@ -61,12 +61,13 @@ target_link_libraries(ktp-auth-handler
${KDE4_KDEUI_LIBS}
${KDE4_KDEWEBKIT_LIBS}
${QJSON_LIBRARIES}
+ ${QCA2_LIBRARIES}
)
configure_file(org.freedesktop.Telepathy.Client.KTp.SASLHandler.service.in
${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.SASLHandler.service)
-#configure_file(org.freedesktop.Telepathy.Client.KTp.TLSHandler.service.in
-# ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.TLSHandler.service)
+configure_file(org.freedesktop.Telepathy.Client.KTp.TLSHandler.service.in
+ ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.TLSHandler.service)
configure_file(org.freedesktop.Telepathy.Client.KTp.ConfAuthObserver.service.in
${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.ConfAuthObserver.service)
@@ -75,8 +76,8 @@ install(TARGETS ktp-auth-handler DESTINATION ${LIBEXEC_INSTALL_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.SASLHandler.service
${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.ConfAuthObserver.service
DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
-#install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.TLSHandler.service
-# DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.TLSHandler.service
+ DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
install(FILES KTp.SASLHandler.client DESTINATION ${SHARE_INSTALL_PREFIX}/telepathy/clients/)
-#install(FILES KTp.TLSHandler.client DESTINATION ${SHARE_INSTALL_PREFIX}/telepathy/clients/)
+install(FILES KTp.TLSHandler.client DESTINATION ${SHARE_INSTALL_PREFIX}/telepathy/clients/)
install(FILES KTp.ConfAuthObserver.client DESTINATION ${SHARE_INSTALL_PREFIX}/telepathy/clients/)
diff --git a/kssl/kssl.h b/kssl/kssl.h
new file mode 100644
index 0000000..0d3d294
--- /dev/null
+++ b/kssl/kssl.h
@@ -0,0 +1,169 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2000-2005 George Staikos <staikos at kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _KSSL_H
+#define _KSSL_H
+
+#include <ksslsettings.h>
+
+class QIODevice;
+class KSSLPrivate;
+class KSSLSession;
+
+/**
+ * KDE SSL Wrapper Class
+ *
+ * This class implements KDE's SSL support by wrapping OpenSSL.
+ *
+ * @author George Staikos <staikos at kde.org>
+ * @see KExtendedSocket, TCPSlaveBase
+ * @short KDE SSL Class
+ */
+class KIO_EXPORT KSSL {
+public:
+ /**
+ * Construct a KSSL object
+ *
+ * @param init Set this to false if you do not want this class to
+ * immediately initialize OpenSSL.
+ */
+ KSSL(bool init = true);
+
+ /**
+ * Destroy this KSSL object
+ *
+ * Does not close any socket.
+ */
+ ~KSSL();
+
+ /**
+ * Determine if SSL is available and works.
+ *
+ * @return true is SSL is available and usable
+ */
+ static bool doesSSLWork();
+
+ /**
+ * Initialize OpenSSL.
+ *
+ * @return true on success
+ *
+ * This will do nothing if it is already initialized.
+ * @see reInitialize
+ */
+ bool initialize();
+
+ /**
+ * This is used for applicationss which do STARTTLS or something
+ * similar. It creates a TLS method regardless of the user's settings.
+ *
+ * @return true if TLS is successfully initialized
+ */
+ bool TLSInit();
+
+ /**
+ * Set an SSL session to use. This deep copies the session so it
+ * doesn't have to remain valid. You need to call it after calling
+ * initialize or reInitialize. The ID is cleared in close().
+ *
+ * @param session A valid session to reuse. If 0L, it will clear the
+ * session ID in memory.
+ *
+ * @return true on success
+ */
+ bool setSession(const KSSLSession *session);
+
+ /**
+ * Close the SSL session.
+ */
+ void close();
+
+ /**
+ * Reinitialize OpenSSL.
+ *
+ * @return true on success
+ *
+ * This is not generally needed unless you are reusing the KSSL object
+ * for a new session.
+ * @see initialize
+ */
+ bool reInitialize();
+
+ /**
+ * Trigger a reread of KSSL configuration and reInitialize() KSSL.
+ *
+ * @return true on successful reinitalizations
+ *
+ * If you setAutoReconfig() to false, then this will simply
+ * reInitialize() and not read in the new configuration.
+ * @see setAutoReconfig
+ */
+ bool reconfig();
+
+ /**
+ * Enable or disable automatic reconfiguration on initialize().
+ *
+ * @param ar Set to false in order to disable auto-reloading of the
+ * KSSL configuration during initialize().
+ *
+ * By default, KSSL will read its configuration on initialize(). You
+ * might want to disable this for performance reasons.
+ */
+ void setAutoReconfig(bool ar);
+
+ /**
+ * This will reseed the pseudo-random number generator with the EGD
+ * (entropy gathering daemon) if the EGD is configured and enabled.
+ * You don't need to call this yourself normally.
+ *
+ * @return 0 on success
+ */
+ int seedWithEGD();
+
+ /**
+ * Set a new KSSLSettings instance as the settings. This deletes the
+ * current instance of KSSLSettings.
+ *
+ * @param settings A new, valid settings object.
+ *
+ * @return true on success
+ */
+ bool setSettings(KSSLSettings *settings);
+
+ /**
+ * One is built by the constructor, so this will only return a NULL
+ * pointer if you set one with setSettings().
+ *
+ * @return the current settings instance
+ */
+ KSSLSettings * settings();
+
+private:
+ static bool m_bSSLWorks;
+ bool m_bInit;
+ bool m_bAutoReconfig;
+ KSSLSettings *m_cfg;
+
+ KSSLPrivate *d;
+};
+
+
+#endif
+
diff --git a/kssl/ksslcertificatemanager.h b/kssl/ksslcertificatemanager.h
new file mode 100644
index 0000000..4942203
--- /dev/null
+++ b/kssl/ksslcertificatemanager.h
@@ -0,0 +1,99 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2007, 2008, 2010 Andreas Hartmetz <ahartmetz at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _INCLUDE_KSSLCERTIFICATEMANAGER_H
+#define _INCLUDE_KSSLCERTIFICATEMANAGER_H
+
+#include "ktcpsocket.h"
+
+#include <QtNetwork/QSslCertificate>
+#include <QtNetwork/QSslError>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QDate>
+
+class QSslCertificate;
+class KSslCertificateRulePrivate;
+class KSslCertificateManagerPrivate;
+
+//### document this... :/
+class KDECORE_EXPORT KSslCertificateRule
+{
+public:
+ KSslCertificateRule(const QSslCertificate &cert = QSslCertificate(),
+ const QString &hostName = QString());
+ KSslCertificateRule(const KSslCertificateRule &other);
+ ~KSslCertificateRule();
+ KSslCertificateRule &operator=(const KSslCertificateRule &other);
+
+ QSslCertificate certificate() const;
+ QString hostName() const;
+ void setExpiryDateTime(const QDateTime &dateTime);
+ QDateTime expiryDateTime() const;
+ void setRejected(bool rejected);
+ bool isRejected() const;
+ bool isErrorIgnored(KSslError::Error error) const;
+ void setIgnoredErrors(const QList<KSslError::Error> &errors);
+ void setIgnoredErrors(const QList<KSslError> &errors);
+ QList<KSslError::Error> ignoredErrors() const;
+ QList<KSslError::Error> filterErrors(const QList<KSslError::Error> &errors) const;
+ QList<KSslError> filterErrors(const QList<KSslError> &errors) const;
+private:
+ KSslCertificateRulePrivate *const d;
+};
+
+
+//### document this too... :/
+class KDECORE_EXPORT KSslCertificateManager
+{
+public:
+ static KSslCertificateManager *self();
+ void setRule(const KSslCertificateRule &rule);
+ void clearRule(const KSslCertificateRule &rule);
+ void clearRule(const QSslCertificate &cert, const QString &hostName);
+ KSslCertificateRule rule(const QSslCertificate &cert, const QString &hostName) const;
+
+ // do not use, it does nothing!
+#ifndef KDE_NO_DEPRECATED
+ KDE_DEPRECATED void setRootCertificates(const QList<QSslCertificate> &rootCertificates)
+ { Q_UNUSED(rootCertificates) }
+#endif
+ // use caCertificates() instead
+#ifndef KDE_NO_DEPRECATED
+ KDE_DEPRECATED QList<QSslCertificate> rootCertificates() const
+ { return caCertificates(); }
+#endif
+
+ QList<QSslCertificate> caCertificates() const;
+
+ static QList<KSslError> nonIgnorableErrors(const QList<KSslError> &);
+ static QList<KSslError::Error> nonIgnorableErrors(const QList<KSslError::Error> &);
+
+private:
+ friend class KSslCertificateManagerContainer;
+ friend class KSslCertificateManagerPrivate;
+ KSslCertificateManager();
+ ~KSslCertificateManager();
+
+ KSslCertificateManagerPrivate *const d;
+};
+
+
+#endif
diff --git a/kssl/ksslinfodialog.h b/kssl/ksslinfodialog.h
new file mode 100644
index 0000000..b65c225
--- /dev/null
+++ b/kssl/ksslinfodialog.h
@@ -0,0 +1,101 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2000-2003 George Staikos <staikos at kde.org>
+ * Copyright (C) 2000 Malte Starostik <malte at kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _KSSLINFODIALOG_H
+#define _KSSLINFODIALOG_H
+
+#include <kssl.h>
+#include <kdialog.h>
+
+#include "ktcpsocket.h"
+
+/**
+ * KDE SSL Information Dialog
+ *
+ * This class creates a dialog that can be used to display information about
+ * an SSL session.
+ *
+ * There are NO GUARANTEES that KSslInfoDialog will remain binary compatible/
+ * Contact staikos at kde.org for details if needed.
+ *
+ * @author George Staikos <staikos at kde.org>
+ * @see KSSL
+ * @short KDE SSL Information Dialog
+ */
+class KIO_EXPORT KSslInfoDialog : public KDialog {
+ Q_OBJECT
+public:
+ /**
+ * Construct a KSSL Information Dialog
+ *
+ * @param parent the parent widget
+ */
+ explicit KSslInfoDialog(QWidget *parent = 0);
+
+ /**
+ * Destroy this dialog
+ */
+ virtual ~KSslInfoDialog();
+
+ /**
+ * Tell the dialog if the connection has portions that may not be
+ * secure (ie. a mixture of secure and insecure frames)
+ *
+ * @param isIt true if security is in question
+ */
+ void setSecurityInQuestion(bool isIt);
+
+ /**
+ * Set information to display about the SSL connection.
+ *
+ * @param certificateChain the certificate chain leading from the certificate
+ * authority to the peer.
+ * @param ip the ip of the remote host
+ * @param host the remote hostname
+ * @param sslProtocol the version of SSL in use (SSLv2, SSLv3, TLSv1)
+ * @param cipher the cipher in use
+ * @param usedBits the used bits of the key
+ * @param bits the key size of the cipher in use
+ * @param validationErrors errors validating the certificates, if any
+ */
+ 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<KSslError::Error> > &validationErrors);
+
+ void setMainPartEncrypted(bool);
+ void setAuxiliaryPartsEncrypted(bool);
+
+ static QList<QList<KSslError::Error> > errorsFromString(const QString &s);
+
+private:
+ void updateWhichPartsEncrypted();
+
+ class KSslInfoDialogPrivate;
+ KSslInfoDialogPrivate* const d;
+
+private Q_SLOTS:
+ void launchConfig();
+ void displayFromChain(int);
+};
+
+#endif
diff --git a/kssl/ksslsettings.h b/kssl/ksslsettings.h
new file mode 100644
index 0000000..d4af1d0
--- /dev/null
+++ b/kssl/ksslsettings.h
@@ -0,0 +1,169 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2000-2003 George Staikos <staikos at kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _KSSLSETTINGS_H
+#define _KSSLSETTINGS_H
+
+#include <kio/kio_export.h>
+
+#include <QtCore/QString>
+
+#include <kconfig.h>
+
+class KSSLSettingsPrivate;
+
+/**
+ * KDE SSL Settings
+ *
+ * This class contains some of the SSL settings for easy use.
+ *
+ * @author George Staikos <staikos at kde.org>
+ * @see KSSL
+ * @short KDE SSL Settings
+ */
+class KIO_EXPORT KSSLSettings {
+public:
+ /**
+ * Construct a KSSL Settings object
+ *
+ * @param readConfig read in the configuration immediately if true
+ */
+ KSSLSettings(bool readConfig = true);
+
+ /**
+ * Destroy this KSSL Settings object
+ */
+ ~KSSLSettings();
+
+ /**
+ * Does the user want to be warned on entering SSL mode
+ * @return true if the user wants to be warned
+ */
+ bool warnOnEnter() const;
+
+ /**
+ * Change the user's warnOnEnter() setting
+ * @param x true if the user is to be warned
+ * @see warnOnEnter
+ */
+ void setWarnOnEnter(bool x);
+
+ /**
+ * Does the user want to be warned on sending unencrypted data
+ * @return true if the user wants to be warned
+ * @see setWarnOnUnencrypted
+ */
+ bool warnOnUnencrypted() const;
+
+ /**
+ * Change the user's warnOnUnencrypted() setting
+ * @param x true if the user is to be warned
+ * @see warnOnUnencrypted
+ */
+ void setWarnOnUnencrypted(bool x);
+
+ /**
+ * Does the user want to be warned on leaving SSL mode
+ * @return true if the user wants to be warned
+ */
+ bool warnOnLeave() const;
+
+ /**
+ * Change the user's warnOnLeave() setting
+ * @param x true if the user is to be warned
+ * @see warnOnLeave
+ */
+ void setWarnOnLeave(bool x);
+
+ /**
+ * Does the user want to be warned during mixed SSL/non-SSL mode
+ * @return true if the user wants to be warned
+ */
+ bool warnOnMixed() const;
+
+ /**
+ * Does the user want to use the Entropy Gathering Daemon?
+ * @return true if the user wants to use EGD
+ */
+ bool useEGD() const;
+
+ /**
+ * Does the user want to use an entropy file?
+ * @return true if the user wants to use an entropy file
+ */
+ bool useEFile() const;
+
+ /**
+ * Does the user want X.509 client certificates to always be sent when
+ * possible?
+ * @return true if the user always wants a certificate sent
+ */
+ bool autoSendX509() const;
+
+ /**
+ * Does the user want to be prompted to send X.509 client certificates
+ * when possible?
+ * @return true if the user wants to be prompted
+ */
+ bool promptSendX509() const;
+
+ /**
+ * Get the OpenSSL cipher list for selecting the list of ciphers to
+ * use in a connection.
+ * @return the cipher list
+ */
+ QString getCipherList();
+
+ /**
+ * Get the configured path to the entropy gathering daemon or entropy
+ * file.
+ * @return the path
+ */
+ QString& getEGDPath();
+
+ /**
+ * Load the user's settings.
+ */
+ void load();
+
+ /**
+ * Revert to default settings.
+ */
+ void defaults();
+
+ /**
+ * Save the current settings.
+ */
+ void save();
+
+private:
+ KConfig *m_cfg;
+ bool m_bWarnOnEnter, m_bWarnOnUnencrypted, m_bWarnOnLeave, m_bWarnOnMixed;
+ bool m_bWarnSelfSigned, m_bWarnRevoked, m_bWarnExpired;
+
+ QList<QString> v3ciphers, v3selectedciphers;
+ QList<int> v3bits;
+
+ KSSLSettingsPrivate* const d;
+};
+
+
+#endif
+
diff --git a/main.cpp b/main.cpp
index 3350658..01e2235 100644
--- a/main.cpp
+++ b/main.cpp
@@ -83,14 +83,11 @@ int main(int argc, char *argv[])
kWarning() << "Could not register the room auth observer!";
}
-
-#if 0
Tp::SharedPtr<TlsHandler> tlsHandler = Tp::SharedPtr<TlsHandler>(new TlsHandler);
if (!clientRegistrar->registerClient(
Tp::AbstractClientPtr(tlsHandler), QLatin1String("KTp.TLSHandler"))) {
handlers -= 1;
}
-#endif
if (!handlers) {
kDebug() << "No handlers registered. Exiting";
diff --git a/tls-cert-verifier-op.cpp b/tls-cert-verifier-op.cpp
index c94999e..eccfd69 100644
--- a/tls-cert-verifier-op.cpp
+++ b/tls-cert-verifier-op.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
* @author Andre Moreira Magalhaes <andre.magalhaes at collabora.co.uk>
+ * Copyright (C) 2013 Dan Vrátil <dvratil at redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +28,12 @@
#include <QSslCertificate>
#include <QSslKey>
+#include <QSslCipher>
+
+#include "kssl/ksslcertificatemanager.h"
+#include "kssl/ksslinfodialog.h"
+
+#include <QtCrypto/QtCrypto>
TlsCertVerifierOp::TlsCertVerifierOp(const Tp::AccountPtr &account,
const Tp::ConnectionPtr &connection,
@@ -76,42 +83,20 @@ void TlsCertVerifierOp::gotProperties(Tp::PendingOperation *op)
kWarning() << "This is not an x509 certificate";
}
+ // Initialize QCA module
+ QCA::Initializer initializer;
+
+ QCA::CertificateChain chain;
Q_FOREACH (const QByteArray &data, m_certData) {
- // FIXME How to chech if it is QSsl::Pem or QSsl::Der? QSsl::Der works for kdetalk
- QList<QSslCertificate> certs = QSslCertificate::fromData(data, QSsl::Der);
- Q_FOREACH (const QSslCertificate &cert, certs) {
- kDebug() << cert;
- kDebug() << "Issuer Organization:" << cert.issuerInfo(QSslCertificate::Organization);
- kDebug() << "Issuer Common Name:" << cert.issuerInfo(QSslCertificate::CommonName);
- kDebug() << "Issuer Locality Name:" << cert.issuerInfo(QSslCertificate::LocalityName);
- kDebug() << "Issuer Organizational Unit Name:" << cert.issuerInfo(QSslCertificate::OrganizationalUnitName);
- kDebug() << "Issuer Country Name:" << cert.issuerInfo(QSslCertificate::CountryName);
- kDebug() << "Issuer State or Province Name:" << cert.issuerInfo(QSslCertificate::StateOrProvinceName);
- kDebug() << "Subject Organization:" << cert.subjectInfo(QSslCertificate::Organization);
- kDebug() << "Subject Common Name:" << cert.subjectInfo(QSslCertificate::CommonName);
- kDebug() << "Subject Locality Name:" << cert.subjectInfo(QSslCertificate::LocalityName);
- kDebug() << "Subject Organizational Unit Name:" << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
- kDebug() << "Subject Country Name:" << cert.subjectInfo(QSslCertificate::CountryName);
- kDebug() << "Subject State Or Province Name:" << cert.subjectInfo(QSslCertificate::StateOrProvinceName);
- kDebug() << "Effective Date:" << cert.effectiveDate();
- kDebug() << "Expiry Date:" << cert.expiryDate();
- kDebug() << "Public Key:" << cert.publicKey();
- kDebug() << "Serial Number:" << cert.serialNumber();
- kDebug() << "Version" << cert.version();
- kDebug() << "Is Valid?" << cert.isValid();
- }
+ // FIXME How to check if it is QSsl::Pem or QSsl::Der? QSsl::Der works for kdetalk
+ chain << QCA::Certificate::fromDER(data);
}
- //TODO Show a nice dialog
- if (KMessageBox::questionYesNo(0,
- i18n("Accept this certificate from <b>%1?</b><br />%2<br />", m_hostname, QString::fromLatin1(m_certData.first().toHex())),
- i18n("Untrusted certificate")) == KMessageBox::Yes) {
- // TODO Remember value
+ if (verifyCertChain(chain)) {
m_authTLSCertificateIface->Accept().waitForFinished();
setFinished();
} else {
Tp::TLSCertificateRejectionList rejections;
- // TODO Add reason
m_authTLSCertificateIface->Reject(rejections);
m_channel->requestClose();
setFinishedWithError(QLatin1String("Cert.Untrusted"),
@@ -119,4 +104,160 @@ void TlsCertVerifierOp::gotProperties(Tp::PendingOperation *op)
}
}
+bool TlsCertVerifierOp::verifyCertChain(const QCA::CertificateChain& chain)
+{
+ const QList<QSslCertificate> primary = QSslCertificate::fromData(chain.primary().toDER(), QSsl::Der);
+ KSslCertificateManager *const cm = KSslCertificateManager::self();
+ KSslCertificateRule rule = cm->rule(primary.first(), m_hostname);
+
+ // Find all errors then are not ignored by the rule
+ QList<KSslError> errors;
+ Q_FOREACH(const QCA::Certificate &cert, chain) {
+ QCA::Validity validity = cert.validate(CACollection(), QCA::CertificateCollection(), QCA::UsageTLSClient, QCA::ValidateAll);
+ if (validity == QCA::ValidityGood) {
+ continue;
+ }
+
+ KSslError::Error error = validityToError(validity);
+ if (!rule.ignoredErrors().contains(error)) {
+ errors << KSslError(error);
+ }
+ }
+
+ // If all errors are ignored, just accept
+ if (errors.isEmpty()) {
+ return true;
+ }
+
+ QString message = i18n("The server failed the authenticity check (%1).
", m_hostname);
+ Q_FOREACH(const KSslError &error, errors) {
+ message.append(error.errorString());
+ message.append(QLatin1Char('
'));
+ }
+
+ int msgResult;
+ do {
+ msgResult = KMessageBox::warningYesNoCancel(0,
+ message,
+ i18n("Server Authentication"),
+ KGuiItem(i18n("&Details"), QLatin1String("dialog-information")), // yes
+ KGuiItem(i18n("Co&ntinue"), QLatin1String("arrow-right")), // no
+ KGuiItem(i18n("&Cancel"), QLatin1String("dialog-cancel")));
+ if (msgResult == KMessageBox::Yes) {
+ showSslDialog(chain, errors);
+ } else if (msgResult == KMessageBox::Cancel) {
+ return false; // reject
+ }
+ // Fall through on KMessageBox::No
+ } while (msgResult == KMessageBox::Yes);
+
+ // Save the user's choice to ignore the SSL errors.
+ msgResult = KMessageBox::warningYesNo(
+ 0,
+ i18n("Would you like to accept this "
+ "certificate forever without "
+ "being prompted?"),
+ i18n("Server Authentication"),
+ KGuiItem(i18n("&Forever"), QLatin1String("flag-green")),
+ KGuiItem(i18n("&Current Session only"), QLatin1String("chronometer")));
+ QDateTime ruleExpiry = QDateTime::currentDateTime();
+ if (msgResult == KMessageBox::Yes) {
+ // Accept forever ("for a very long time")
+ ruleExpiry = ruleExpiry.addYears(1000);
+ } else {
+ // Accept "for a short time", half an hour.
+ ruleExpiry = ruleExpiry.addSecs(30*60);
+ }
+
+ rule.setExpiryDateTime(ruleExpiry);
+ rule.setIgnoredErrors(errors);
+ cm->setRule(rule);
+
+ return true;
+}
+
+void TlsCertVerifierOp::showSslDialog(const QCA::CertificateChain &chain, const QList<KSslError> &errors) const
+{
+ QString errorStr;
+ Q_FOREACH (const KSslError &error, errors) {
+ errorStr += QString::number(static_cast<int>(error.error())) + QLatin1Char(' ');
+ errorStr += QLatin1Char('
');
+ }
+ errorStr.chop(1);
+
+ // No way to tell whether QSsl::TlsV1 or QSsl::TlsV1Ssl3
+ KSslCipher cipher = QSslCipher(QLatin1String("TLS"), QSsl::TlsV1);
+ QString sslCipher = cipher.encryptionMethod() + QLatin1Char('
');
+ sslCipher += cipher.authenticationMethod() + QLatin1Char('
');
+ sslCipher += cipher.keyExchangeMethod() + QLatin1Char('
');
+ sslCipher += cipher.digestMethod();
+
+ const QList<QSslCertificate> qchain = chainToList(chain);
+ QPointer<KSslInfoDialog> dialog(new KSslInfoDialog(0));
+ dialog->setSslInfo(qchain,
+ QString(), // we don't know the IP
+ m_hostname, // the URL
+ QLatin1String("TLS"),
+ sslCipher,
+ cipher.usedBits(),
+ cipher.supportedBits(),
+ KSslInfoDialog::errorsFromString(errorStr));
+
+ dialog->exec();
+ delete dialog;
+}
+
+KSslError::Error TlsCertVerifierOp::validityToError(QCA::Validity validity) const
+{
+ switch (validity) {
+ case QCA::ValidityGood:
+ return KSslError::NoError;
+ case QCA::ErrorRejected:
+ return KSslError::RejectedCertificate;
+ case QCA::ErrorUntrusted:
+ return KSslError::UntrustedCertificate;
+ case QCA::ErrorSignatureFailed:
+ return KSslError::CertificateSignatureFailed;
+ case QCA::ErrorInvalidCA:
+ return KSslError::InvalidCertificateAuthorityCertificate;
+ case QCA::ErrorInvalidPurpose:
+ return KSslError::InvalidCertificatePurpose;
+ case QCA::ErrorSelfSigned:
+ return KSslError::SelfSignedCertificate;
+ case QCA::ErrorRevoked:
+ return KSslError::RevokedCertificate;
+ case QCA::ErrorPathLengthExceeded:
+ return KSslError::PathLengthExceeded;
+ case QCA::ErrorExpired: // fall-through
+ case QCA::ErrorExpiredCA:
+ return KSslError::ExpiredCertificate;
+ case QCA::ErrorValidityUnknown:
+ return KSslError::UnknownError;
+ }
+
+ return KSslError::UnknownError;
+}
+
+QCA::CertificateCollection TlsCertVerifierOp::CACollection() const
+{
+ QList<QSslCertificate> certs = KSslCertificateManager::self()->caCertificates();
+ QCA::CertificateCollection collection;
+
+ Q_FOREACH(const QSslCertificate &cert, certs) {
+ collection.addCertificate(QCA::Certificate::fromDER(cert.toDer()));
+ }
+
+ return collection;
+}
+
+QList< QSslCertificate > TlsCertVerifierOp::chainToList(const QCA::CertificateChain& chain) const
+{
+ QList<QSslCertificate> certs;
+ Q_FOREACH(const QCA::Certificate &cert, chain) {
+ certs << QSslCertificate::fromData(cert.toDER(), QSsl::Der);
+ }
+
+ return certs;
+}
+
#include "tls-cert-verifier-op.moc"
diff --git a/tls-cert-verifier-op.h b/tls-cert-verifier-op.h
index 121cf41..35f2fb0 100644
--- a/tls-cert-verifier-op.h
+++ b/tls-cert-verifier-op.h
@@ -31,6 +31,11 @@
// FIXME: Move this to tp-qt4 itself
#include "types.h"
+#include <QtCrypto/QtCrypto>
+#include <QSslError>
+#include <ktcpsocket.h>
+
+class QSslCertificate;
class TlsCertVerifierOp : public Tp::PendingOperation
{
Q_OBJECT
@@ -48,6 +53,13 @@ private Q_SLOTS:
void gotProperties(Tp::PendingOperation *op);
private:
+ bool verifyCertChain(const QCA::CertificateChain &chain);
+ void showSslDialog(const QCA::CertificateChain &chain, const QList<KSslError> &errors) const;
+ KSslError::Error validityToError(QCA::Validity validity) const;
+
+ QCA::CertificateCollection CACollection() const;
+ QList<QSslCertificate> chainToList(const QCA::CertificateChain &chain) const;
+
Tp::AccountPtr m_account;
Tp::ConnectionPtr m_connection;
Tp::ChannelPtr m_channel;
--
ktp-auth-handler packaging
More information about the pkg-kde-commits
mailing list