diff options
Diffstat (limited to 'knetworkmanager-0.8/src/knetworkmanager-storage.cpp')
-rw-r--r-- | knetworkmanager-0.8/src/knetworkmanager-storage.cpp | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/knetworkmanager-0.8/src/knetworkmanager-storage.cpp b/knetworkmanager-0.8/src/knetworkmanager-storage.cpp new file mode 100644 index 0000000..553bd1f --- /dev/null +++ b/knetworkmanager-0.8/src/knetworkmanager-storage.cpp @@ -0,0 +1,634 @@ +/*************************************************************************** + * + * knetworkmanager-storage.cpp - A NetworkManager frontend for KDE + * + * Copyright (C) 2005, 2006 Novell, Inc. + * + * Author: Helmut Schaa <[email protected]>, <[email protected]> + * Author: Timothy Pearson <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + **************************************************************************/ + +#include <tqtimer.h> + +#include <kglobal.h> +#include <kconfig.h> +#include <kstaticdeleter.h> +#include <kdebug.h> + +#include "knetworkmanager-storage.h" +#include "knetworkmanager-connection_store.h" +#include "knetworkmanager-wireless_connection.h" +#include "knetworkmanager-wired_connection.h" +#include "knetworkmanager-cdma_connection.h" +#include "knetworkmanager-gsm_connection.h" +#include "knetworkmanager-vpn_connection.h" +#include "knetworkmanager-connection.h" +#include "knetworkmanager-connection_setting.h" +#include "xmlmarshaller.h" +#include "knetworkmanager-connection_setting_info.h" +#include "knetworkmanager-connection_setting_wired.h" +#include "knetworkmanager-connection_setting_wireless.h" +#include "knetworkmanager-connection_setting_wireless_security.h" +#include "knetworkmanager-connection_setting_ipv4.h" + +using namespace ConnectionSettings; + +static KStaticDeleter<Storage> sd2; + +// private stuff +class StoragePrivate +{ + public: + StoragePrivate() {}; + ~StoragePrivate() {}; + + static Storage* _instance; +}; + +Storage* StoragePrivate::_instance = NULL; + +Storage* +Storage::getInstance() +{ + if (StoragePrivate::_instance) + return StoragePrivate::_instance; + return sd2.setObject(StoragePrivate::_instance, new Storage()); +} + +Storage::Storage() +{ + d = new StoragePrivate(); + + // defer the connection init a bit + TQTimer::singleShot(0, this, TQT_SLOT(slotInit())); +} + +Storage::~Storage() +{ + delete d; +} + +void +Storage::slotInit() +{ + ConnectionStore* cstore = ConnectionStore::getInstance(); + + // we want to get notified whenever a new connection is created, edited or deleted + connect(cstore, TQT_SIGNAL(signalConnectionAdded(ConnectionSettings::Connection*)), this, TQT_SLOT(slotConnectionAdded(ConnectionSettings::Connection*))); + connect(cstore, TQT_SIGNAL(signalConnectionRemoved(ConnectionSettings::Connection*)), this, TQT_SLOT(slotConnectionRemoved(ConnectionSettings::Connection*))); +} + +void +Storage::slotConnectionAdded(Connection* con) +{ + // connection added, save it + saveConnection(con); + KGlobal::config()->sync(); +} + +void +Storage::slotConnectionRemoved(Connection* con) +{ + // find the appropriate connection and delete it from the storage + deleteConnection(con); + KGlobal::config()->sync(); +} + +Connection* +Storage::createConnectionByType(const TQString& cType) +{ + // TODO: use a factory class here + if (cType == NM_SETTING_WIRELESS_SETTING_NAME) + return new WirelessConnection(); + else if (cType == NM_SETTING_WIRED_SETTING_NAME) + return new WiredConnection(); + else if(cType == NM_SETTING_CDMA_SETTING_NAME) + return new CDMAConnection(); + else if(cType == NM_SETTING_GSM_SETTING_NAME) + return new GSMConnection(); + else if (cType == NM_SETTING_VPN_SETTING_NAME) + return new VPNConnection(); + else + return NULL; +} + +void +Storage::restoreConnections() +{ + kdDebug() << k_funcinfo << endl; + // let's read all connections from the config-file and add them to the connection-store + ConnectionStore* store = ConnectionStore::getInstance(); + TQStringList groups = KGlobal::config()->groupList(); + const TQStringList::Iterator end = groups.end(); + for ( TQStringList::Iterator it = groups.begin(); it != end; ++it ) + { + if ( !(*it).startsWith( "Connection_" ) ) + continue; + + // restore that connection + Connection* conn = NULL; + if ( (conn = restoreConnection(*it)) != NULL) + { + // add the connection to the store + store->addConnection(conn); + } + } + +} + +Connection* +Storage::restoreConnection(const TQString& grpname) +{ + Connection* conn = NULL; + kdDebug() << k_funcinfo << " " << grpname << endl; + + // we have a connection to restore + KConfigGroup grp( KGlobal::config(), grpname); + TQString id = grp.readEntry("Id"); + TQString cType = grp.readEntry("Type"); + + // ID is needed! + if (id.isEmpty() || cType.isEmpty()) + return NULL; + + // create a new connection object by its type + conn = createConnectionByType(cType); + + // check if the connection was successfully created + if (!conn) + return NULL; + + // set the connection ID + conn->setID(id); + + // restore all appropriate settings + TQStringList settings = grp.readListEntry("Settings"); + + for (TQStringList::ConstIterator it = settings.begin(); it != settings.end(); ++it) + { + if ( !restoreSetting(conn, *it) ) + { + // setting could not be restored -> Error + kdDebug() << " Connection " << id.ascii() << " could not be restored." << endl; + kdError() << k_funcinfo << " Connection " << id << " could not be restored." << endl; + delete conn; + conn = NULL; + return NULL; + } + } + + // restore all appropriate secrets + TQStringList secrets = grp.readListEntry("Secrets"); + + for (TQStringList::ConstIterator it = secrets.begin(); it != secrets.end(); ++it) + { + if ( !restoreSecrets(conn, *it) ) + { + // setting could not be restored -> Error + kdDebug() << " Connection " << id.ascii() << " could not be restored." << endl; + kdError() << k_funcinfo << " Connection " << id << " could not be restored." << endl; + delete conn; + conn = NULL; + return NULL; + } + } + + return conn; +} + +bool +Storage::restoreSetting(Connection* conn, const TQString& setting_grp_name) +{ + kdDebug() << k_funcinfo << " " << setting_grp_name << endl; + kdDebug() << "restore setting: " << setting_grp_name.ascii() << endl; + + KConfigGroup setting_grp(KGlobal::config(), setting_grp_name); + TQMap<TQString, TQString> config_map = KGlobal::config()->entryMap(setting_grp_name); + TQString type = setting_grp.readEntry("Type"); + + // get the appropriate setting from the connection + ConnectionSetting* setting = conn->getSetting(type); + if (!setting) + { + kdWarning() << k_funcinfo << "Connection " << conn->getID() << ": Setting " << type << " could not be restored" << endl; + return false; + } + + // read the SettingsMap from kconfig + SettingsMap map; + for(TQMap<TQString, TQString>::ConstIterator it = config_map.begin(); it != config_map.end(); ++it) + { + if (!it.key().startsWith("Value_")) + continue; + + TQString key = it.key(); + // get the original name + key.replace("Value_", ""); + + TQString xmldata = it.data(); + TQT_DBusData dbusdata = XMLMarshaller::toTQT_DBusData(xmldata); + + map.insert(key, dbusdata); + } + + // restore the setting from the generated map + setting->fromMap(map); + return true; +} + +bool +Storage::restoreSecrets(Connection* conn, const TQString& secrets_grp_name) +{ + kdDebug() << k_funcinfo << " " << secrets_grp_name << endl; + kdDebug() << "restore secret: " << secrets_grp_name.ascii() << endl; + + KConfigGroup secrets_grp(KGlobal::config(), secrets_grp_name); + TQMap<TQString, TQString> config_map = KGlobal::config()->entryMap(secrets_grp_name); + TQString type = secrets_grp.readEntry("Type"); + + // get the appropriate setting from the connection + ConnectionSetting* setting = conn->getSetting(type); + if (!setting) + { + kdWarning() << k_funcinfo << "Connection " << conn->getID() << ": Secrets for setting " << type << " could not be restored" << endl; + return false; + } + + // read the SettingsMap from kconfig + SettingsMap map; + for(TQMap<TQString, TQString>::ConstIterator it = config_map.begin(); it != config_map.end(); ++it) + { + if (!it.key().startsWith("Value_")) + continue; + + TQString key = it.key(); + // get the original name + key.replace("Value_", ""); + + TQString xmldata = it.data(); + TQT_DBusData dbusdata = XMLMarshaller::toTQT_DBusData(xmldata); + + map.insert(key, dbusdata); + } + + // restore the setting from the generated map + setting->fromSecretsMap(map); + return true; +} + +bool +Storage::restoreVPNSecrets(Connection* conn, const TQString& secrets_grp_name) +{ + kdDebug() << k_funcinfo << " " << secrets_grp_name << endl; + kdDebug() << "restore secret: " << secrets_grp_name.ascii() << endl; + + KConfigGroup secrets_grp(KGlobal::config(), secrets_grp_name); + TQMap<TQString, TQString> config_map = KGlobal::config()->entryMap(secrets_grp_name); + TQString type = secrets_grp.readEntry("Type"); + + // get the appropriate setting from the connection + ConnectionSetting* setting = conn->getSetting(type); + if (!setting) + { + kdWarning() << k_funcinfo << "Connection " << conn->getID() << ": Secrets for setting " << type << " could not be restored" << endl; + return false; + } + + // read the SettingsMap from kconfig + SettingsMap map; + for(TQMap<TQString, TQString>::ConstIterator it = config_map.begin(); it != config_map.end(); ++it) + { + if (!it.key().startsWith("Value_")) + continue; + + TQString key = it.key(); + // get the original name + key.replace("Value_", ""); + + TQString xmldata = it.data(); + TQT_DBusData dbusdata = XMLMarshaller::toTQT_DBusData(xmldata); + + map.insert(key, dbusdata); + } + + // restore the setting from the generated map + setting->fromSecretsMap(map); + return true; +} + +void +Storage::saveConnections() +{ + kdDebug() << k_funcinfo << endl; + kdDebug() << "Storage::saveConnections" << endl; + printf("Storage::saveConnections\n\r"); + // write all connections we get from the connection-store to disk + ConnectionStore* store = ConnectionStore::getInstance(); + TQValueList<ConnectionSettings::Connection*> connections = store->getConnections(); + + for (TQValueList<ConnectionSettings::Connection*>::ConstIterator it = connections.begin(); it != connections.end(); ++it) + { + // save this connection + saveConnection(*it); + } + KGlobal::config()->sync(); +} + +bool +Storage::saveConnection(Connection* conn) +{ + KConfig* config = KGlobal::config(); + TQString id = conn->getID(); + TQString cType = conn->getType(); + + kdDebug() << k_funcinfo << " <" << id << ">" << endl; + kdDebug() << "Storage::saveConnection " << id.ascii() << endl; + + // connections without id are evil + if (id.isEmpty() || cType.isEmpty()) + return false; + + // let's get the config group for this connection + KConfigGroup grp(config, TQString("Connection_%1").tqarg(id)); + TQStringList settings_grps; + TQStringList secrets_grps; + + // save the connections settings to the configfile + if (saveConnectionSettings(conn, settings_grps, secrets_grps)) + { + grp.writeEntry("Type", cType); + grp.writeEntry("Id", id); + // save the list of settings groups + grp.writeEntry("Settings", settings_grps); + grp.writeEntry("Secrets", secrets_grps); + } + return false; +} + +bool +Storage::saveConnectionSettings(Connection* conn, TQStringList& settings_grps, TQStringList& secrets_grps) +{ + TQString id = conn->getID(); + + // connections without id are evil + if (id.isEmpty()) + return false; + + // iterate over all settings + TQValueList<ConnectionSetting*> settings = conn->getSettings(); + TQString setting_grp; + TQString secrets_grp; + + // save all settings + for (TQValueList<ConnectionSetting*>::ConstIterator it = settings.begin(); it != settings.end(); ++it) + { + if (!saveConnectionSetting(conn, *it, setting_grp)) + return false; + + if ((*it)->hasSecrets()) + { + if (!saveConnectionSecrets(conn, *it, secrets_grp)) + return false; + secrets_grps.append(secrets_grp); + } + + settings_grps.append(setting_grp); + } + + return true; +} + +bool +Storage::saveConnectionSetting(Connection* conn, ConnectionSetting* setting, TQString& setting_grp) +{ + KConfig* config = KGlobal::config(); + TQString id = conn->getID(); + TQString type = setting->getType(); + + kdDebug() << k_funcinfo << " <" << id << "> <" << type << ">" << endl; + + // ID is necessary + if (id.isEmpty()) + return false; + + // get a group for this setting + setting_grp = TQString("ConnectionSetting_%1_%2").tqarg(id).tqarg(type); + KConfigGroup grp(config, setting_grp); + + // write the type + grp.writeEntry("Type", type); + + // write the values + SettingsMap map = setting->toMap(); + for (SettingsMap::ConstIterator it = map.begin(); it != map.end(); ++it) + { + kdDebug() << k_funcinfo << " " << TQString("Value_%1").tqarg(it.key()) << " = " << XMLMarshaller::fromTQT_DBusData( it.data() )<< endl; + grp.writeEntry(TQString("Value_%1").tqarg(it.key()), XMLMarshaller::fromTQT_DBusData( it.data() )); + } + return true; +} + +bool +Storage::saveConnectionSecrets(Connection* conn, ConnectionSetting* setting, TQString& setting_grp) +{ + KConfig* config = KGlobal::config(); + TQString id = conn->getID(); + TQString type = setting->getType(); + bool storage_requested; + + kdDebug() << k_funcinfo << " <" << id << "> <" << type << ">" << endl; + + // ID is necessary + if (id.isEmpty()) + return false; + + // see if permanent storage was requested by the user + SettingsMap setting_map = setting->toMap(); + storage_requested = true; + for (SettingsMap::ConstIterator it = setting_map.begin(); it != setting_map.end(); ++it) + { + if (it.key() == "Commit to disk") { + if (XMLMarshaller::fromTQT_DBusData(it.data()) == TQString("true")) { + storage_requested = true; + } + if (XMLMarshaller::fromTQT_DBusData(it.data()) == TQString("false")) { + storage_requested = false; + } + } + } + printf("Secrets storage requested: %d\n\r", storage_requested); + + // get a group for this setting + setting_grp = TQString("ConnectionSecrets_%1_%2").tqarg(id).tqarg(type); + KConfigGroup grp(config, setting_grp); + + // write the type + grp.writeEntry("Type", type); + + // write the values + SettingsMap map = setting->toSecretsMap(false); + for (SettingsMap::ConstIterator it = map.begin(); it != map.end(); ++it) + { + kdDebug() << k_funcinfo << " " << TQString("Value_%1").tqarg(it.key()) << " = " << XMLMarshaller::fromTQT_DBusData( it.data() )<< endl; + if (storage_requested == true) { + grp.writeEntry(TQString("Value_%1").tqarg(it.key()), XMLMarshaller::fromTQT_DBusData( it.data() )); + } + else { + grp.writeEntry(TQString("Value_%1").tqarg(it.key()), TQString("") ); + } + } + return true; +} + +bool +Storage::hasSecretsStored(Connection* connection) +{ + TQString id = connection->getID(); + + // ID is necessary + if (id.isEmpty()) + return false; + + TQValueList<ConnectionSetting*> settings = connection->getSettings(); + for (TQValueList<ConnectionSetting*>::Iterator it = settings.begin(); it != settings.end(); ++it) + { + if (hasSecretsStored(connection, *it)) + return true; + } + return false; +} + + +bool +Storage::hasSecretsStored(Connection* connection, ConnectionSetting* setting) +{ + TQString id = connection->getID(); + TQString type = setting->getType(); + + kdDebug() << "Storage::hasSecretsStored" << endl; + + // ID is necessary + if (id.isEmpty()) + return false; + + // get a group for this setting + TQString setting_grp_name = TQString("ConnectionSecrets_%1_%2").tqarg(id).tqarg(type); + + TQMap<TQString, TQString> config_map = KGlobal::config()->entryMap(setting_grp_name); + + return !(config_map.isEmpty()); +} + +bool +Storage::restoreAllSecrets(Connection* connection) +{ + TQString id = connection->getID(); + bool retval = true; + + if (id.isEmpty()) + return false; + + TQValueList<ConnectionSetting*> settings = connection->getSettings(); + for (TQValueList<ConnectionSetting*>::Iterator it = settings.begin(); it != settings.end(); ++it) + { + if (hasSecretsStored(connection, *it)) + if (!restoreSecrets(connection, *it)) + retval = false; + } + return retval; +} + +bool +Storage::restoreSecrets(Connection* connection, ConnectionSetting* setting) +{ + TQString id = connection->getID(); + TQString type = setting->getType(); + + kdDebug() << "Storage::restoreSecrets" << endl; + // ID is necessary + if (id.isEmpty()) + return false; + + // get a group for this setting + TQString setting_grp = TQString("ConnectionSecrets_%1_%2").tqarg(id).tqarg(type); + + // restore the setting + return restoreSecrets(connection, setting_grp); +} + +bool +Storage::restoreVPNSecrets(Connection* connection, ConnectionSetting* setting) +{ + TQString id = connection->getID(); + TQString type = setting->getType(); + + printf("Storage::restoreVPNSecrets\n\r"); + kdDebug() << "Storage::restoreVPNSecrets" << endl; + // ID is necessary + if (id.isEmpty()) + return false; + + // get a group for this setting + TQString setting_grp = TQString("ConnectionSecrets_%1_%2").tqarg(id).tqarg(type); + + // restore the setting + return restoreVPNSecrets(connection, setting_grp); +} + +bool +Storage::deleteConnection(Connection* conn) +{ + KConfig* config = KGlobal::config(); + TQString id = conn->getID(); + TQString cType = conn->getType(); + + kdDebug() << k_funcinfo << " <" << id << ">" << endl; + kdDebug() << "Storage::deleteConnection " << id.ascii() << endl; + + // connections without id are evil + if (id.isEmpty() || cType.isEmpty()) + return false; + + // let's get the config group for this connection + KConfigGroup grp(config, TQString("Connection_%1").tqarg(id)); + + + // delete all associated settings + TQStringList settings = grp.readListEntry("Settings"); + + for (TQStringList::ConstIterator it = settings.begin(); it != settings.end(); ++it) + { + KConfigGroup setting(config, *it); + setting.deleteGroup(); + } + + // delete all associated secrets + TQStringList secrets = grp.readListEntry("Secrets"); + + for (TQStringList::ConstIterator it = secrets.begin(); it != secrets.end(); ++it) + { + KConfigGroup setting(config, *it); + setting.deleteGroup(); + } + + grp.deleteGroup(); + + return true; +} + +#include "knetworkmanager-storage.moc" |