#include <QStringList>
-#include "client.h"
+
#include "clientsettings.h"
+
+#include <QHostAddress>
+#ifdef HAVE_SSL
+#include <QSslSocket>
+#endif
+
+
+#include "client.h"
#include "quassel.h"
ClientSettings::ClientSettings(QString g) : Settings(g, Quassel::buildInfo().clientApplicationName) {
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
+}
#define CLIENTSETTINGS_H
#include "settings.h"
+
#include "types.h"
+class QHostAddress;
+class QSslSocket;
+
class ClientSettings : public Settings {
public:
virtual ~ClientSettings();
ClientSettings(QString group = "General");
};
+// ========================================
+// CoreAccountSettings
+// ========================================
+
// Deriving from CoreAccountSettings:
// MySettings() : CoreAccountSettings("MyGroup") {};
// Then use accountValue() / setAccountValue() to retrieve/store data associated to the currently
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
#include "networkmodel.h"
#include "quassel.h"
#include "signalproxy.h"
+#include "util.h"
ClientSyncer::ClientSyncer(QObject *parent)
: QObject(parent)
#ifdef HAVE_SSL
void ClientSyncer::ignoreSslWarnings(bool permanently) {
- QAbstractSocket *sock = qobject_cast<QAbstractSocket *>(socket);
+ QSslSocket *sock = qobject_cast<QSslSocket *>(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();
}
}
void ClientSyncer::sslErrors(const QList<QSslError> &errors) {
+ QByteArray knownDigest;
QSslSocket *socket = qobject_cast<QSslSocket *>(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);
}
}
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;
+}
return list;
}
+QByteArray prettyDigest(const QByteArray &digest);
+
#endif
#include "coreconfigwizard.h"
#include "iconloader.h"
#include "quassel.h"
+#include "util.h"
CoreConnectDlg::CoreConnectDlg(bool autoconnect, QWidget *parent)
: QDialog(parent),
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);