Index: autotests/settings/CMakeLists.txt =================================================================== --- autotests/settings/CMakeLists.txt +++ autotests/settings/CMakeLists.txt @@ -19,6 +19,7 @@ ipv4settingtest ipv6settingtest matchsettingtest + macsecsettingtest olpcmeshsettingtest ovsbridgesettingtest ovsinterfacesettingtest Index: autotests/settings/macsecsettingtest.h =================================================================== --- /dev/null +++ autotests/settings/macsecsettingtest.h @@ -0,0 +1,36 @@ +/* + Copyright 2018 Pranav Gade + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef NETWORKMANAGERQT_MACSECSETTING_TEST_H +#define NETWORKMANAGERQT_MACSECSETTING_TEST_H + +#include + +class MacsecSettingTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testSetting_data(); + void testSetting(); +}; + +#endif // NETWORKMANAGERQT_MACSECSETTING_TEST_H + Index: autotests/settings/macsecsettingtest.cpp =================================================================== --- /dev/null +++ autotests/settings/macsecsettingtest.cpp @@ -0,0 +1,103 @@ +/* + Copyright 2018 Pranav Gade + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "macsecsettingtest.h" + +#include "settings/macsecsetting.h" + +#include + +#include + +#if !NM_CHECK_VERSION(1, 12, 0) +#define NM_SETTING_MACSEC_PARENT "parent" +#define NM_SETTING_MACSEC_MODE "mode" +#define NM_SETTING_MACSEC_ENCRYPT "encrypt" +#define NM_SETTING_MACSEC_MKA_CAK "mka-cak" +#define NM_SETTING_MACSEC_MKA_CAK_FLAGS "mka-cak-flags" +#define NM_SETTING_MACSEC_MKA_CKN "mka-ckn" +#define NM_SETTING_MACSEC_PORT "port" +#define NM_SETTING_MACSEC_VALIDATION "validation" +#define NM_SETTING_MACSEC_SEND_SCI "send-sci" +#endif + +void MacsecSettingTest::testSetting_data() +{ + QTest::addColumn("encrypt"); + QTest::addColumn("mkaCak"); + QTest::addColumn("mkaCkn"); + QTest::addColumn("mode"); + QTest::addColumn("parent"); + QTest::addColumn("port"); + QTest::addColumn("sendSci"); + QTest::addColumn("validation"); + QTest::addColumn("mkaCakFlags"); + + QTest::newRow("setting1") + << false // encrypt + << QString("abc") // mkaCak + << QString("abc") // mkaCkn + << (qint32) 1 // mode + << QString("abc") // parent + << (qint32) 666 // port + << false // sendSci + << (qint32) 4 // validation + << (quint32) 6; // mkaCakFlags + +} + +void MacsecSettingTest::testSetting() +{ + QFETCH(bool, encrypt); + QFETCH(QString, mkaCak); + QFETCH(QString, mkaCkn); + QFETCH(qint32, mode); + QFETCH(QString, parent); + QFETCH(qint32, port); + QFETCH(bool, sendSci); + QFETCH(qint32, validation); + QFETCH(quint32, mkaCakFlags); + + QVariantMap map; + + map.insert(QLatin1String(NM_SETTING_MACSEC_ENCRYPT), encrypt); + map.insert(QLatin1String(NM_SETTING_MACSEC_MKA_CAK), mkaCak); + map.insert(QLatin1String(NM_SETTING_MACSEC_MKA_CKN), mkaCkn); + map.insert(QLatin1String(NM_SETTING_MACSEC_MODE), mode); + map.insert(QLatin1String(NM_SETTING_MACSEC_PARENT), parent); + map.insert(QLatin1String(NM_SETTING_MACSEC_PORT), port); + map.insert(QLatin1String(NM_SETTING_MACSEC_SEND_SCI), sendSci); + map.insert(QLatin1String(NM_SETTING_MACSEC_VALIDATION), validation); + map.insert(QLatin1String(NM_SETTING_MACSEC_MKA_CAK_FLAGS), mkaCakFlags); + + NetworkManager::MacsecSetting setting; + setting.fromMap(map); + + QVariantMap map1 = setting.toMap(); + + // Will fail if set some default values, because they are skipped in toMap() method + QVariantMap::const_iterator it = map.constBegin(); + while (it != map.constEnd()) { + QCOMPARE(it.value(), map1.value(it.key())); + ++it; + } +} + +QTEST_MAIN(MacsecSettingTest) Index: src/CMakeLists.txt =================================================================== --- src/CMakeLists.txt +++ src/CMakeLists.txt @@ -63,6 +63,7 @@ settings/ipv4setting.cpp settings/ipv6setting.cpp settings/infinibandsetting.cpp + settings/macsecsetting.cpp settings/matchsetting.cpp settings/olpcmeshsetting.cpp settings/ovsbridgesetting.cpp Index: src/settings/macsecsetting.h =================================================================== --- /dev/null +++ src/settings/macsecsetting.h @@ -0,0 +1,109 @@ +/* + Copyright 2018 Pranav Gade + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef NETWORKMANAGERQT_MACSECSETTING_H +#define NETWORKMANAGERQT_MACSECSETTING_H + +#include +#include "setting.h" + +#include + +namespace NetworkManager +{ + +class MacsecSettingPrivate; + +/** + * Represents Macsec setting + */ +class NETWORKMANAGERQT_EXPORT MacsecSetting : public Setting +{ +public: + typedef QSharedPointer Ptr; + typedef QList List; + + enum Mode{ + Psk = NM_SETTING_MACSEC_MODE_PSK, + Eap = NM_SETTING_MACSEC_MODE_EAP + }; + + enum Validation { + Disable = NM_SETTING_MACSEC_VALIDATION_DISABLE, + Check = NM_SETTING_MACSEC_VALIDATION_CHECK, + Strict = NM_SETTING_MACSEC_VALIDATION_STRICT + }; + + MacsecSetting(); + explicit MacsecSetting(const Ptr &other); + ~MacsecSetting() override; + + QString name() const override; + + void setEncrypt(bool encrypt); + bool encrypt() const; + + void setMkaCak(QString mkaCak); + QString mkaCak() const; + + void setMkaCkn(QString mkaCkn); + QString mkaCkn() const; + + void setMode(Mode mode); + Mode mode() const; + + void setParent(QString parent); + QString parent() const; + + void setPort(qint32 port); + qint32 port() const; + + void setSendSci(bool sendSci); + bool sendSci() const; + + void setValidation(Validation validation); + Validation validation() const; + + void setMkaCakFlags(Setting::SecretFlags flags); + Setting::SecretFlags mkaCakFlags() const; + + QStringList needSecrets(bool requestNew = false) const override; + + void secretsFromMap(const QVariantMap &secrets) override; + + QVariantMap secretsToMap() const override; + + void fromMap(const QVariantMap &setting) override; + + QVariantMap toMap() const override; + +protected: + MacsecSettingPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(MacsecSetting) +}; + +NETWORKMANAGERQT_EXPORT QDebug operator<<(QDebug dbg, const MacsecSetting &setting); + +} + +#endif // NETWORKMANAGERQT_MACSECSETTING_H + Index: src/settings/macsecsetting.cpp =================================================================== --- /dev/null +++ src/settings/macsecsetting.cpp @@ -0,0 +1,333 @@ +/* + Copyright Pranav Gade + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "macsecsetting.h" +#include "macsecsetting_p.h" + +#include + +#if !NM_CHECK_VERSION(1, 12, 0) +#define NM_SETTING_MACSEC_SETTING_NAME "macsec" + +#define NM_SETTING_MACSEC_PARENT "parent" +#define NM_SETTING_MACSEC_MODE "mode" +#define NM_SETTING_MACSEC_ENCRYPT "encrypt" +#define NM_SETTING_MACSEC_MKA_CAK "mka-cak" +#define NM_SETTING_MACSEC_MKA_CAK_FLAGS "mka-cak-flags" +#define NM_SETTING_MACSEC_MKA_CKN "mka-ckn" +#define NM_SETTING_MACSEC_PORT "port" +#define NM_SETTING_MACSEC_VALIDATION "validation" +#define NM_SETTING_MACSEC_SEND_SCI "send-sci" +#endif + +NetworkManager::MacsecSettingPrivate::MacsecSettingPrivate() + : name(NM_SETTING_MACSEC_SETTING_NAME) + , encrypt(true) + , mode(NetworkManager::MacsecSetting::Psk) + , port(1) + , sendSci(true) + , validation(NetworkManager::MacsecSetting::Disable) +{ } + +NetworkManager::MacsecSetting::MacsecSetting() + : Setting(Setting::Macsec) + , d_ptr(new MacsecSettingPrivate()) +{ } + +NetworkManager::MacsecSetting::MacsecSetting(const Ptr &other) + : Setting(other) + , d_ptr(new MacsecSettingPrivate()) +{ + setEncrypt(other->encrypt()); + setMkaCak(other->mkaCak()); + setMkaCkn(other->mkaCkn()); + setMode(other->mode()); + setParent(other->parent()); + setPort(other->port()); + setSendSci(other->sendSci()); + setValidation(other->validation()); + setMkaCakFlags(other->mkaCakFlags()); +} + +NetworkManager::MacsecSetting::~MacsecSetting() +{ + delete d_ptr; +} + +QString NetworkManager::MacsecSetting::name() const +{ + Q_D(const MacsecSetting); + + return d->name; +} + +void NetworkManager::MacsecSetting::setEncrypt(bool encrypt) +{ + Q_D(MacsecSetting); + + d->encrypt = encrypt; +} + +bool NetworkManager::MacsecSetting::encrypt() const +{ + Q_D(const MacsecSetting); + + return d->encrypt; +} + +void NetworkManager::MacsecSetting::setMkaCak(QString mkaCak) +{ + Q_D(MacsecSetting); + + d->mkaCak = mkaCak; +} + +QString NetworkManager::MacsecSetting::mkaCak() const +{ + Q_D(const MacsecSetting); + + return d->mkaCak; +} + +void NetworkManager::MacsecSetting::setMkaCkn(QString mkaCkn) +{ + Q_D(MacsecSetting); + + d->mkaCkn = mkaCkn; +} + +QString NetworkManager::MacsecSetting::mkaCkn() const +{ + Q_D(const MacsecSetting); + + return d->mkaCkn; +} + +void NetworkManager::MacsecSetting::setMode(Mode mode) +{ + Q_D(MacsecSetting); + + d->mode = mode; +} + +NetworkManager::MacsecSetting::Mode NetworkManager::MacsecSetting::mode() const +{ + Q_D(const MacsecSetting); + + return d->mode; +} + +void NetworkManager::MacsecSetting::setParent(QString parent) +{ + Q_D(MacsecSetting); + + d->parent = parent; +} + +QString NetworkManager::MacsecSetting::parent() const +{ + Q_D(const MacsecSetting); + + return d->parent; +} + +void NetworkManager::MacsecSetting::setPort(qint32 port) +{ + Q_D(MacsecSetting); + + d->port = port; +} + +qint32 NetworkManager::MacsecSetting::port() const +{ + Q_D(const MacsecSetting); + + return d->port; +} + +void NetworkManager::MacsecSetting::setSendSci(bool sendSci) +{ + Q_D(MacsecSetting); + + d->sendSci = sendSci; +} + +bool NetworkManager::MacsecSetting::sendSci() const +{ + Q_D(const MacsecSetting); + + return d->sendSci; +} + +void NetworkManager::MacsecSetting::setValidation(Validation validation) +{ + Q_D(MacsecSetting); + + d->validation = validation; +} + +NetworkManager::MacsecSetting::Validation NetworkManager::MacsecSetting::validation() const +{ + Q_D(const MacsecSetting); + + return d->validation; +} + +void NetworkManager::MacsecSetting::setMkaCakFlags(NetworkManager::Setting::SecretFlags flags) +{ + Q_D(MacsecSetting); + + d->mkaCakFlags = flags; +} + +NetworkManager::Setting::SecretFlags NetworkManager::MacsecSetting::mkaCakFlags() const +{ + Q_D(const MacsecSetting); + + return d->mkaCakFlags; +} + +QStringList NetworkManager::MacsecSetting::needSecrets(bool requestNew) const +{ + QStringList secrets; + + if ((mkaCak().isEmpty() || requestNew) && !mkaCakFlags().testFlag(Setting::NotRequired)) { + secrets << QLatin1String(NM_SETTING_MACSEC_MKA_CAK); + } + + return secrets; +} + +void NetworkManager::MacsecSetting::secretsFromMap(const QVariantMap &secrets) +{ + if (secrets.contains(QLatin1String(NM_SETTING_MACSEC_MKA_CAK))) { + setMkaCak(secrets.value(QLatin1String(NM_SETTING_MACSEC_MKA_CAK)).toString()); + } +} + +QVariantMap NetworkManager::MacsecSetting::secretsToMap() const +{ + QVariantMap secrets; + + if (!mkaCak().isEmpty()) { + secrets.insert(QLatin1String(NM_SETTING_MACSEC_MKA_CAK), mkaCak()); + } + + return secrets; +} + +void NetworkManager::MacsecSetting::fromMap(const QVariantMap &setting) +{ + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_ENCRYPT))) { + setEncrypt(setting.value(QLatin1String(NM_SETTING_MACSEC_ENCRYPT)).toBool()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_MKA_CAK))) { + setMkaCak(setting.value(QLatin1String(NM_SETTING_MACSEC_MKA_CAK)).toString()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_MKA_CKN))) { + setMkaCkn(setting.value(QLatin1String(NM_SETTING_MACSEC_MKA_CKN)).toString()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_MODE))) { + setMode((Mode)setting.value(QLatin1String(NM_SETTING_MACSEC_MODE)).toInt()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_PARENT))) { + setParent(setting.value(QLatin1String(NM_SETTING_MACSEC_PARENT)).toString()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_PORT))) { + setPort(setting.value(QLatin1String(NM_SETTING_MACSEC_PORT)).toInt()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_SEND_SCI))) { + setSendSci(setting.value(QLatin1String(NM_SETTING_MACSEC_SEND_SCI)).toBool()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_VALIDATION))) { + setValidation((Validation)setting.value(QLatin1String(NM_SETTING_MACSEC_VALIDATION)).toInt()); + } + + if (setting.contains(QLatin1String(NM_SETTING_MACSEC_MKA_CAK_FLAGS))) { + setMkaCakFlags((Setting::SecretFlags)setting.value(QLatin1String(NM_SETTING_MACSEC_MKA_CAK_FLAGS)).toUInt()); + } +} + +QVariantMap NetworkManager::MacsecSetting::toMap() const +{ + QVariantMap setting; + + if (!encrypt()) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_ENCRYPT), encrypt()); + } + + if (!mkaCak().isEmpty()) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_MKA_CAK), mkaCak()); + } + + if (!mkaCkn().isEmpty()) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_MKA_CKN), mkaCkn()); + } + + if (mode() > 0) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_MODE), (int)mode()); + } + + if (!parent().isEmpty()) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_PARENT), parent()); + } + + if (port() > 1) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_PORT), port()); + } + + if (!sendSci()) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_SEND_SCI), sendSci()); + } + + if (validation() >= 0) { + setting.insert(QLatin1String(NM_SETTING_MACSEC_VALIDATION), (int)validation()); + } + + setting.insert(QLatin1String(NM_SETTING_MACSEC_MKA_CAK_FLAGS), (int)mkaCakFlags()); + + return setting; +} + +QDebug NetworkManager::operator <<(QDebug dbg, const NetworkManager::MacsecSetting &setting) +{ + dbg.nospace() << "type: " << setting.typeAsString(setting.type()) << '\n'; + dbg.nospace() << "initialized: " << !setting.isNull() << '\n'; + + dbg.nospace() << NM_SETTING_MACSEC_ENCRYPT << ": " << setting.encrypt() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_MKA_CAK << ": " << setting.mkaCak() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_MKA_CKN << ": " << setting.mkaCkn() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_MODE << ": " << setting.mode() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_PARENT << ": " << setting.parent() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_PORT << ": " << setting.port() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_SEND_SCI << ": " << setting.sendSci() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_VALIDATION << ": " << setting.validation() << '\n'; + dbg.nospace() << NM_SETTING_MACSEC_MKA_CAK_FLAGS << ": " << setting.mkaCakFlags() << '\n'; + + return dbg.maybeSpace(); +} + Index: src/settings/macsecsetting_p.h =================================================================== --- /dev/null +++ src/settings/macsecsetting_p.h @@ -0,0 +1,50 @@ +/* + Copyright 2018 Pranav Gade + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef NETWORKMANAGERQT_MACSECSETTING_P_H +#define NETWORKMANAGERQT_MACSECSETTING_P_H + +#include + +namespace NetworkManager +{ + +class MacsecSettingPrivate +{ +public: + MacsecSettingPrivate(); + + QString name; + + bool encrypt; + QString mkaCak; + QString mkaCkn; + NetworkManager::MacsecSetting::Mode mode; + QString parent; + qint32 port; + bool sendSci; + NetworkManager::MacsecSetting::Validation validation; + NetworkManager::Setting::SecretFlags mkaCakFlags; +}; + +} + +#endif // NETWORKMANAGERQT_MACSECSETTING_P_H + Index: src/settings/setting.h =================================================================== --- src/settings/setting.h +++ src/settings/setting.h @@ -82,7 +82,8 @@ OvsPort, Match, Tc, - TeamPort + TeamPort, + Macsec }; enum SecretFlagType { Index: src/settings/setting.cpp =================================================================== --- src/settings/setting.cpp +++ src/settings/setting.cpp @@ -31,6 +31,10 @@ #define NM_SETTING_MATCH_SETTING_NAME "match" #endif +#if !NM_CHECK_VERSION(1, 12, 0) +#define NM_SETTING_MACSEC_SETTING_NAME "macsec" +#endif + #if !NM_CHECK_VERSION(1, 10, 0) #define NM_SETTING_OVS_BRIDGE_SETTING_NAME "ovs-bridge" #define NM_SETTING_OVS_INTERFACE_SETTING_NAME "ovs-interface" @@ -169,6 +173,9 @@ case TeamPort: typeString = QLatin1String(NM_SETTING_TEAM_PORT_SETTING_NAME); break; + case Macsec: + typeString = QLatin1String(NM_SETTING_MACSEC_SETTING_NAME); + break; case NetworkManager::Setting::Generic: typeString = QLatin1String(NM_SETTING_GENERIC_SETTING_NAME); break; @@ -245,6 +252,8 @@ type = Tc; } else if (typeString == QLatin1String(NM_SETTING_TEAM_PORT_SETTING_NAME)) { type = TeamPort; + } else if (typeString == QLatin1String(NM_SETTING_MACSEC_SETTING_NAME)) { + type = Macsec; } return type;