File indexing completed on 2024-05-12 05:36:19

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