From: Marcus Eggenberger Date: Thu, 29 Jan 2009 00:02:45 +0000 (+0100) Subject: You can now add a core to the known hosts. X-Git-Tag: 0.4.0~166 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=e06ce3bfa98752cb9e87586477dfaf31e7e1ab0a You can now add a core to the known hosts. This will supress future warnings about issues with that specific ssl certificate in combination with the connected host until the cert changes. --- diff --git a/src/client/clientsettings.cpp b/src/client/clientsettings.cpp index cc8e2099..62812fc7 100644 --- a/src/client/clientsettings.cpp +++ b/src/client/clientsettings.cpp @@ -20,8 +20,16 @@ #include -#include "client.h" + #include "clientsettings.h" + +#include +#ifdef HAVE_SSL +#include +#endif + + +#include "client.h" #include "quassel.h" ClientSettings::ClientSettings(QString g) : Settings(g, Quassel::buildInfo().clientApplicationName) { @@ -140,3 +148,40 @@ void NotificationSettings::setNicksCaseSensitive(bool cs) { bool NotificationSettings::nicksCaseSensitive() { return localValue("Highlights/NicksCaseSensitive", false).toBool(); } + + +// ======================================== +// KnownHostsSettings +// ======================================== +KnownHostsSettings::KnownHostsSettings() + : ClientSettings("KnownHosts") +{ +} + +QByteArray KnownHostsSettings::knownDigest(const QHostAddress &address) { + return localValue(address.toString(), QByteArray()).toByteArray(); +} + +void KnownHostsSettings::saveKnownHost(const QHostAddress &address, const QByteArray &certDigest) { + setLocalValue(address.toString(), certDigest); +} + +bool KnownHostsSettings::isKnownHost(const QHostAddress &address, const QByteArray &certDigest) { + return certDigest == localValue(address.toString(), QByteArray()).toByteArray(); +} + +#ifdef HAVE_SSL +QByteArray KnownHostsSettings::knownDigest(const QSslSocket *socket) { + return knownDigest(socket->peerAddress()); +} + +void KnownHostsSettings::saveKnownHost(const QSslSocket *socket) { + Q_ASSERT(socket); + saveKnownHost(socket->peerAddress(), socket->peerCertificate().digest()); +} + +bool KnownHostsSettings::isKnownHost(const QSslSocket *socket) { + Q_ASSERT(socket); + return isKnownHost(socket->peerAddress(), socket->peerCertificate().digest()); +#endif +} diff --git a/src/client/clientsettings.h b/src/client/clientsettings.h index c927250c..aa0f0d67 100644 --- a/src/client/clientsettings.h +++ b/src/client/clientsettings.h @@ -22,8 +22,12 @@ #define CLIENTSETTINGS_H #include "settings.h" + #include "types.h" +class QHostAddress; +class QSslSocket; + class ClientSettings : public Settings { public: virtual ~ClientSettings(); @@ -32,6 +36,10 @@ protected: ClientSettings(QString group = "General"); }; +// ======================================== +// CoreAccountSettings +// ======================================== + // Deriving from CoreAccountSettings: // MySettings() : CoreAccountSettings("MyGroup") {}; // Then use accountValue() / setAccountValue() to retrieve/store data associated to the currently @@ -67,29 +75,50 @@ private: QString _subgroup; }; +// ======================================== +// NotificationSettings +// ======================================== class NotificationSettings : public ClientSettings { +public: + enum HighlightNickType { + NoNick = 0x00, + CurrentNick= 0x01, + AllNicks = 0x02 + }; + + NotificationSettings(); - public: - enum HighlightNickType { - NoNick = 0x00, - CurrentNick= 0x01, - AllNicks = 0x02 - }; + inline void setValue(const QString &key, const QVariant &data) { setLocalValue(key, data); } + inline QVariant value(const QString &key, const QVariant &def = QVariant()) { return localValue(key, def); } + inline void remove(const QString &key) { removeLocalKey(key); } - NotificationSettings(); + void setHighlightList(const QVariantList &highlightList); + QVariantList highlightList(); - inline void setValue(const QString &key, const QVariant &data) { setLocalValue(key, data); } - inline QVariant value(const QString &key, const QVariant &def = QVariant()) { return localValue(key, def); } - inline void remove(const QString &key) { removeLocalKey(key); } + void setHighlightNick(HighlightNickType); + HighlightNickType highlightNick(); + + void setNicksCaseSensitive(bool); + bool nicksCaseSensitive(); +}; - void setHighlightList(const QVariantList &highlightList); - QVariantList highlightList(); - void setHighlightNick(HighlightNickType); - HighlightNickType highlightNick(); +// ======================================== +// KnownHostsSettings +// ======================================== +class KnownHostsSettings : public ClientSettings { +public: + KnownHostsSettings(); - void setNicksCaseSensitive(bool); - bool nicksCaseSensitive(); + QByteArray knownDigest(const QHostAddress &address); + void saveKnownHost(const QHostAddress &address, const QByteArray &certDigest); + bool isKnownHost(const QHostAddress &address, const QByteArray &certDigest); +#ifdef HAVE_SSL + QByteArray knownDigest(const QSslSocket *socket); + void saveKnownHost(const QSslSocket *socket); + bool isKnownHost(const QSslSocket *socket); +#endif }; + #endif diff --git a/src/client/clientsyncer.cpp b/src/client/clientsyncer.cpp index e9d64f32..3b68b5c0 100644 --- a/src/client/clientsyncer.cpp +++ b/src/client/clientsyncer.cpp @@ -30,6 +30,7 @@ #include "networkmodel.h" #include "quassel.h" #include "signalproxy.h" +#include "util.h" ClientSyncer::ClientSyncer(QObject *parent) : QObject(parent) @@ -349,11 +350,17 @@ void ClientSyncer::resetWarningsHandler() { #ifdef HAVE_SSL void ClientSyncer::ignoreSslWarnings(bool permanently) { - QAbstractSocket *sock = qobject_cast(socket); + QSslSocket *sock = qobject_cast(socket); if(sock) { // ensure that a proper state is displayed and no longer a warning emit socketStateChanged(sock->state()); } + if(permanently) { + if(!sock) + qWarning() << Q_FUNC_INFO << "unable to save cert digest! Socket is either a nullptr or not a QSslSocket"; + else + KnownHostsSettings().saveKnownHost(sock); + } emit connectionMsg(_coreMsgBuffer["CoreInfo"].toString()); connectionReady(); } @@ -366,15 +373,26 @@ void ClientSyncer::sslSocketEncrypted() { } void ClientSyncer::sslErrors(const QList &errors) { + QByteArray knownDigest; QSslSocket *socket = qobject_cast(sender()); if(socket) { socket->ignoreSslErrors(); + knownDigest = KnownHostsSettings().knownDigest(socket); + if(knownDigest == socket->peerCertificate().digest()) { + connectionReady(); + return; + } } QStringList warnings; + foreach(QSslError err, errors) warnings << err.errorString(); + if(!knownDigest.isEmpty()) { + warnings << tr("Cert Digest changed! was: %1").arg(QString(prettyDigest(knownDigest))); + } + setWarningsHandler(SLOT(ignoreSslWarnings(bool))); emit connectionWarnings(warnings); } diff --git a/src/common/util.cpp b/src/common/util.cpp index 9bc24bc1..817790f8 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -142,3 +142,14 @@ QString secondsToString(int timeInSeconds) { } return returnString.join(", "); } + +QByteArray prettyDigest(const QByteArray &digest) { + QByteArray hexDigest = digest.toHex(); + QByteArray prettyDigest; + prettyDigest.fill(':', hexDigest.count() + (hexDigest.count() / 2) - 1); + + for(int i = 0; i * 2 < hexDigest.count(); i++) { + prettyDigest.replace(i * 3, 2, hexDigest.mid(i * 2, 2)); + } + return prettyDigest; +} diff --git a/src/common/util.h b/src/common/util.h index 99032e99..0e205fd8 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -67,4 +67,6 @@ QList fromVariantList(const QVariantList &variants) { return list; } +QByteArray prettyDigest(const QByteArray &digest); + #endif diff --git a/src/qtui/coreconnectdlg.cpp b/src/qtui/coreconnectdlg.cpp index 16655ffd..e60d4d69 100644 --- a/src/qtui/coreconnectdlg.cpp +++ b/src/qtui/coreconnectdlg.cpp @@ -36,6 +36,7 @@ #include "coreconfigwizard.h" #include "iconloader.h" #include "quassel.h" +#include "util.h" CoreConnectDlg::CoreConnectDlg(bool autoconnect, QWidget *parent) : QDialog(parent), @@ -600,6 +601,7 @@ SslCertDisplayDialog::SslCertDisplayDialog(const QString &host, const QSslCertif for(int i = 0; i < mailaddresses.count(); i++) { additionalLayout->addRow(tr("E-Mail Address %1:").arg(i + 1), new QLabel(mailaddresses[i], this)); } + additionalLayout->addRow(tr("Digest:"), new QLabel(QString(prettyDigest(cert.digest())))); mainLayout->addWidget(additionalBox);