File indexing completed on 2024-10-06 13:24:51

0001 /*
0002     SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "wifisettings.h"
0008 
0009 #include <KAboutData>
0010 #include <KLocalizedString>
0011 #include <KPluginFactory>
0012 
0013 #include <NetworkManagerQt/AccessPoint>
0014 #include <NetworkManagerQt/ActiveConnection>
0015 #include <NetworkManagerQt/Connection>
0016 #include <NetworkManagerQt/ConnectionSettings>
0017 #include <NetworkManagerQt/GsmSetting>
0018 #include <NetworkManagerQt/Ipv4Setting>
0019 #include <NetworkManagerQt/Manager>
0020 #include <NetworkManagerQt/Settings>
0021 #include <NetworkManagerQt/Utils>
0022 #include <NetworkManagerQt/WiredDevice>
0023 #include <NetworkManagerQt/WiredSetting>
0024 #include <NetworkManagerQt/WirelessDevice>
0025 #include <NetworkManagerQt/WirelessSetting>
0026 
0027 K_PLUGIN_CLASS_WITH_JSON(WifiSettings, "wifisettings.json")
0028 
0029 WifiSettings::WifiSettings(QObject *parent, const QVariantList &args)
0030     : KQuickAddons::ConfigModule(parent, args)
0031 {
0032     KAboutData *about = new KAboutData("kcm_mobile_wifi", i18n("Wi-Fi networks"), "0.1", QString(), KAboutLicense::LGPL);
0033     about->addAuthor(i18n("Martin Kacej"), QString(), "m.kacej@atlas.sk");
0034     setAboutData(about);
0035 }
0036 
0037 WifiSettings::~WifiSettings()
0038 {
0039 }
0040 
0041 QVariantMap WifiSettings::getConnectionSettings(const QString &connection, const QString &type)
0042 {
0043     if (type.isEmpty())
0044         return QVariantMap();
0045 
0046     NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection);
0047     if (!con)
0048         return QVariantMap();
0049 
0050     if (type == "secrets")
0051         return con->secrets(QLatin1String("802-11-wireless-security")).value().value(QLatin1String("802-11-wireless-security"));
0052 
0053     QVariantMap map = con->settings()->toMap().value(type);
0054     if (type == "ipv4") {
0055         NetworkManager::Ipv4Setting::Ptr ipSettings = NetworkManager::Ipv4Setting::Ptr(new NetworkManager::Ipv4Setting());
0056         ipSettings->fromMap(map);
0057         map.clear();
0058         if (ipSettings->method() == NetworkManager::Ipv4Setting::Automatic) {
0059             map.insert(QLatin1String("method"), QVariant(QLatin1String("auto")));
0060         }
0061 
0062         if (ipSettings->method() == NetworkManager::Ipv4Setting::Manual) {
0063             map.insert(QLatin1String("method"), QVariant(QLatin1String("manual")));
0064             map.insert(QLatin1String("address"), QVariant(ipSettings->addresses().first().ip().toString()));
0065             map.insert(QLatin1String("prefix"), QVariant(ipSettings->addresses().first().prefixLength()));
0066             map.insert(QLatin1String("gateway"), QVariant(ipSettings->addresses().first().gateway().toString()));
0067             map.insert(QLatin1String("dns"), QVariant(ipSettings->dns().first().toString()));
0068         }
0069     }
0070     return map;
0071 }
0072 
0073 QVariantMap WifiSettings::getActiveConnectionInfo(const QString &connection)
0074 {
0075     if (connection.isEmpty())
0076         return QVariantMap();
0077 
0078     NetworkManager::ActiveConnection::Ptr activeCon;
0079     NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection);
0080     foreach (const NetworkManager::ActiveConnection::Ptr &active, NetworkManager::activeConnections()) {
0081         if (active->uuid() == con->uuid())
0082             activeCon = active;
0083     }
0084 
0085     if (!activeCon) {
0086         qWarning() << "Active" << connection << "not found";
0087         return QVariantMap();
0088     }
0089 
0090     QVariantMap map;
0091     if (activeCon->ipV4Config().addresses().count() > 0) {
0092         map.insert("address", QVariant(activeCon->ipV4Config().addresses().first().ip().toString()));
0093         map.insert("prefix", QVariant(activeCon->ipV4Config().addresses().first().netmask().toString()));
0094     }
0095     map.insert("gateway", QVariant(activeCon->ipV4Config().gateway()));
0096     if (activeCon->ipV4Config().nameservers().count() > 0)
0097         map.insert("dns", QVariant(activeCon->ipV4Config().nameservers().first().toString()));
0098     // qWarning() << map;
0099     return map;
0100 }
0101 
0102 void WifiSettings::addConnectionFromQML(const QVariantMap &QMLmap)
0103 {
0104     if (QMLmap.isEmpty())
0105         return;
0106 
0107     NetworkManager::ConnectionSettings::Ptr connectionSettings =
0108         NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless));
0109     connectionSettings->setId(QMLmap.value(QLatin1String("id")).toString());
0110     connectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid());
0111 
0112     NetworkManager::WirelessSetting::Ptr wirelessSettings = NetworkManager::WirelessSetting::Ptr(new NetworkManager::WirelessSetting());
0113     wirelessSettings->setSsid(QMLmap.value(QLatin1String("id")).toString().toUtf8());
0114     if (QMLmap["mode"].toString() == "infrastructure") {
0115         wirelessSettings->setMode(NetworkManager::WirelessSetting::Infrastructure);
0116         connectionSettings->setAutoconnect(true);
0117     }
0118     if (QMLmap["mode"].toString() == "ap") {
0119         wirelessSettings->setMode(NetworkManager::WirelessSetting::Ap);
0120         connectionSettings->setAutoconnect(false);
0121     }
0122     if (QMLmap.contains("hidden")) {
0123         wirelessSettings->setHidden(QMLmap.value("hidden").toBool());
0124     }
0125 
0126     NetworkManager::Ipv4Setting::Ptr ipSettings = NetworkManager::Ipv4Setting::Ptr(new NetworkManager::Ipv4Setting());
0127     if (QMLmap["method"] == QLatin1String("auto")) {
0128         ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Automatic);
0129     }
0130     if (QMLmap["method"] == QLatin1String("shared")) {
0131         ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Shared);
0132     }
0133     if (QMLmap["method"] == QLatin1String("manual")) {
0134         ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Manual);
0135         NetworkManager::IpAddress ipaddr;
0136         ipaddr.setIp(QHostAddress(QMLmap["address"].toString()));
0137         ipaddr.setPrefixLength(QMLmap["prefix"].toInt());
0138         ipaddr.setGateway(QHostAddress(QMLmap["gateway"].toString()));
0139         ipSettings->setAddresses(QList<NetworkManager::IpAddress>({ipaddr}));
0140         ipSettings->setDns(QList<QHostAddress>({QHostAddress(QMLmap["dns"].toString())}));
0141     }
0142 
0143     NMVariantMapMap map = connectionSettings->toMap();
0144     map.insert("802-11-wireless", wirelessSettings->toMap());
0145     map.insert("ipv4", ipSettings->toMap());
0146 
0147     // TODO can't set password for AP
0148     // needs further inspection
0149 
0150     if (QMLmap.contains("802-11-wireless-security")) {
0151         QVariantMap securMap = QMLmap["802-11-wireless-security"].toMap();
0152         int type = securMap["type"].toInt();
0153         if (!type == NetworkManager::NoneSecurity) {
0154             NetworkManager::WirelessSecuritySetting::Ptr securitySettings =
0155                 NetworkManager::WirelessSecuritySetting::Ptr(new NetworkManager::WirelessSecuritySetting());
0156             if (type == NetworkManager::Wpa2Psk) {
0157                 if (QMLmap["mode"].toString() == "ap") {
0158                     securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaNone);
0159                 } else {
0160                     securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaPsk);
0161                 }
0162                 securitySettings->setAuthAlg(NetworkManager::WirelessSecuritySetting::AuthAlg::Open);
0163                 securitySettings->setPskFlags(NetworkManager::Setting::SecretFlagType::AgentOwned);
0164                 securitySettings->setPsk(securMap["password"].toString());
0165             }
0166             if (type == NetworkManager::StaticWep) {
0167                 securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::Wep);
0168                 securitySettings->setAuthAlg(NetworkManager::WirelessSecuritySetting::AuthAlg::Open);
0169                 securitySettings->setWepKeyType(NetworkManager::WirelessSecuritySetting::WepKeyType::Hex);
0170                 securitySettings->setWepKeyFlags(NetworkManager::Setting::SecretFlagType::AgentOwned);
0171                 securitySettings->setWepKey0(securMap["password"].toString());
0172             }
0173             map.insert("802-11-wireless-security", securitySettings->toMap());
0174         }
0175     }
0176     // qWarning() << map;
0177     NetworkManager::addConnection(map);
0178 }
0179 
0180 void WifiSettings::updateConnectionFromQML(const QString &path, const QVariantMap &map)
0181 {
0182     NetworkManager::Connection::Ptr con = NetworkManager::findConnection(path);
0183     if (!con)
0184         return;
0185 
0186     // qWarning() << map;
0187     if (map.contains("id"))
0188         con->settings()->setId(map.value("id").toString());
0189 
0190     NMVariantMapMap toUpdateMap = con->settings()->toMap();
0191 
0192     NetworkManager::Ipv4Setting::Ptr ipSetting = con->settings()->setting(NetworkManager::Setting::Ipv4).staticCast<NetworkManager::Ipv4Setting>();
0193     if (ipSetting->method() == NetworkManager::Ipv4Setting::Automatic || ipSetting->method() == NetworkManager::Ipv4Setting::Manual) {
0194         if (map.value("method") == "auto") {
0195             ipSetting->setMethod(NetworkManager::Ipv4Setting::Automatic);
0196         }
0197 
0198         if (map.value("method") == "manual") {
0199             ipSetting->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Manual);
0200             NetworkManager::IpAddress ipaddr;
0201             ipaddr.setIp(QHostAddress(map["address"].toString()));
0202             ipaddr.setPrefixLength(map["prefix"].toInt());
0203             ipaddr.setGateway(QHostAddress(map["gateway"].toString()));
0204             ipSetting->setAddresses(QList<NetworkManager::IpAddress>({ipaddr}));
0205             ipSetting->setDns(QList<QHostAddress>({QHostAddress(map["dns"].toString())}));
0206         }
0207         toUpdateMap.insert("ipv4", ipSetting->toMap());
0208     }
0209 
0210     NetworkManager::WirelessSetting::Ptr wirelessSetting =
0211         con->settings()->setting(NetworkManager::Setting::Wireless).staticCast<NetworkManager::WirelessSetting>();
0212     if (map.contains("hidden")) {
0213         wirelessSetting->setHidden(map.value("hidden").toBool());
0214     }
0215     if (map.contains("id")) {
0216         wirelessSetting->setSsid(map.value("id").toByteArray());
0217     }
0218     toUpdateMap.insert("802-11-wireless", wirelessSetting->toMap());
0219 
0220     if (map.contains("802-11-wireless-security")) {
0221         QVariantMap secMap = map.value("802-11-wireless-security").toMap();
0222         // qWarning() << secMap;
0223         NetworkManager::WirelessSecuritySetting::Ptr securitySetting =
0224             con->settings()->setting(NetworkManager::Setting::WirelessSecurity).staticCast<NetworkManager::WirelessSecuritySetting>();
0225         if ((securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::Wep) && (secMap.value("type") == NetworkManager::StaticWep)) {
0226             securitySetting->setWepKey0(secMap["password"].toString());
0227         }
0228 
0229         if ((securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaPsk) && (secMap.value("type") == NetworkManager::Wpa2Psk)) {
0230             securitySetting->setPsk(secMap["password"].toString());
0231         }
0232 
0233         // TODO can't set password for AP
0234         // needs further inspection
0235         if (wirelessSetting->mode() == NetworkManager::WirelessSetting::Ap) {
0236             if (securitySetting->toMap().empty()) { // no security
0237                 if (secMap.value("type") == NetworkManager::Wpa2Psk) {
0238                     securitySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone);
0239                     securitySetting->setPsk(secMap.value("password").toString());
0240                 }
0241             }
0242             if (securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaNone) {
0243                 if (secMap.empty()) {
0244                     securitySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Unknown);
0245                 }
0246                 if (secMap.value("type") == NetworkManager::Wpa2Psk) {
0247                     securitySetting->setPsk(secMap.value("password").toString());
0248                 }
0249             }
0250         }
0251 
0252         toUpdateMap.insert("802-11-wireless-security", securitySetting->toMap());
0253     }
0254     qWarning() << toUpdateMap;
0255     con->update(toUpdateMap);
0256 }
0257 
0258 QString WifiSettings::getAccessPointDevice()
0259 {
0260     NetworkManager::WirelessDevice::Ptr device;
0261     foreach (const NetworkManager::Device::Ptr &dev, NetworkManager::networkInterfaces()) {
0262         if (dev->type() == NetworkManager::Device::Wifi) {
0263             device = dev.staticCast<NetworkManager::WirelessDevice>();
0264             if (device->wirelessCapabilities().testFlag(NetworkManager::WirelessDevice::ApCap))
0265                 break; // we have wireless device with access point capability
0266         }
0267     }
0268     if (device) {
0269         return device->uni();
0270     } else {
0271         qWarning() << "No wireless device found";
0272     }
0273     return QString();
0274 }
0275 
0276 QString WifiSettings::getAccessPointConnection()
0277 {
0278     foreach (const NetworkManager::Connection::Ptr &con, NetworkManager::listConnections()) {
0279         NetworkManager::Setting::Ptr d = con->settings()->setting(NetworkManager::Setting::Wireless);
0280         if (!d.isNull()) {
0281             if (d.staticCast<NetworkManager::WirelessSetting>()->mode() == NetworkManager::WirelessSetting::Ap) {
0282                 return con->path();
0283             }
0284         }
0285     }
0286     return QString();
0287 }
0288 
0289 #include "wifisettings.moc"