diff --git a/sddmauthhelper.cpp b/sddmauthhelper.cpp index c256513..336c154 100644 --- a/sddmauthhelper.cpp +++ b/sddmauthhelper.cpp @@ -1,231 +1,231 @@ /* Copyright 2013 by Reza Fatahilah Shah Copyright 2011, 2012 David Edmundson 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, see . */ #include "sddmauthhelper.h" #include #include #include #include #include #include #include #include #include #include #include #include #include static QSharedPointer openConfig(const QString &filePath) { QFile file(filePath); if(!file.exists()) { // If we are creating the config file, ensure it is world-readable: if // we don't do that, KConfig will create a file which is only readable // by root file.open(QIODevice::WriteOnly); file.close(); file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther); } return QSharedPointer(new KConfig(file.fileName(), KConfig::SimpleConfig)); } ActionReply SddmAuthHelper::save(const QVariantMap &args) { ActionReply reply = ActionReply::HelperErrorReply(); QSharedPointer sddmConfig = openConfig(args[QStringLiteral("sddm.conf")].toString()); QSharedPointer themeConfig; QString themeConfigFile = args[QStringLiteral("theme.conf.user")].toString(); if (!themeConfigFile.isEmpty()) { themeConfig = openConfig(themeConfigFile); } QMap::const_iterator iterator; for (iterator = args.constBegin() ; iterator != args.constEnd() ; ++iterator) { if (iterator.key() == QLatin1String("sddm.conf") || iterator.key() == QLatin1String("theme.conf.user")) continue; QStringList configFields = iterator.key().split(QLatin1Char('/')); if (configFields.size() != 3) { continue; } QSharedPointer config; QString fileName = configFields[0]; QString groupName = configFields[1]; QString keyName = configFields[2]; if (fileName == QLatin1String("sddm.conf")) { sddmConfig->group(groupName).writeEntry(keyName, iterator.value()); } else if (fileName == QLatin1String("theme.conf.user") && !themeConfig.isNull()) { QFileInfo themeConfigFileInfo(themeConfigFile); QDir configRootDirectory = themeConfigFileInfo.absoluteDir(); if (keyName == QLatin1String("background")) { QFileInfo newBackgroundFileInfo(iterator.value().toString()); QString previousBackground = themeConfig->group(groupName).readEntry(keyName); bool backgroundChanged = newBackgroundFileInfo.fileName() != previousBackground; if (backgroundChanged) { if (!previousBackground.isEmpty()) { QString previousBackgroundPath = configRootDirectory.filePath(previousBackground); if (QFile::remove(previousBackgroundPath)) { qDebug() << "Removed previous background " << previousBackgroundPath; } } if (newBackgroundFileInfo.exists()) { QString newBackgroundPath = configRootDirectory.filePath(newBackgroundFileInfo.fileName()); qDebug() << "Copying background from " << newBackgroundFileInfo.absoluteFilePath() << " to " << newBackgroundPath; if (QFile::copy(newBackgroundFileInfo.absoluteFilePath(), newBackgroundPath)) { QFile::setPermissions(newBackgroundPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther); themeConfig->group(groupName).writeEntry(keyName, newBackgroundFileInfo.fileName()); } } else { themeConfig->group(groupName).deleteEntry(keyName); } } } else { themeConfig->group(groupName).writeEntry(keyName, iterator.value()); } } } sddmConfig->sync(); if (!themeConfig.isNull()) themeConfig->sync(); return ActionReply::SuccessReply(); } ActionReply SddmAuthHelper::installtheme(const QVariantMap &args) { const QString filePath = args[QStringLiteral("filePath")].toString(); if (filePath.isEmpty()) { return ActionReply::HelperErrorReply(); } const QString themesBaseDir = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("sddm/themes"), QStandardPaths::LocateDirectory); QDir dir(themesBaseDir); if (!dir.exists()) { return ActionReply::HelperErrorReply(); } qDebug() << "Installing " << filePath << " into " << themesBaseDir; if (!QFile::exists(filePath)) { return ActionReply::HelperErrorReply(); } QMimeDatabase db; QMimeType mimeType = db.mimeTypeForFile(filePath); qWarning() << "Postinstallation: uncompress the file"; QScopedPointer archive; //there must be a better way to do this? If not, make a static bool KZip::supportsMimeType(const QMimeType &type); ? //or even a factory class in KArchive if (mimeType.inherits(QStringLiteral("application/zip"))) { archive.reset(new KZip(filePath)); } else if (mimeType.inherits(QStringLiteral("application/tar")) || mimeType.inherits(QStringLiteral("application/x-gzip")) || mimeType.inherits(QStringLiteral("application/x-bzip")) || mimeType.inherits(QStringLiteral("application/x-lzma")) || mimeType.inherits(QStringLiteral("application/x-xz")) || mimeType.inherits(QStringLiteral("application/x-bzip-compressed-tar")) || mimeType.inherits(QStringLiteral("application/x-compressed-tar"))) { archive.reset(new KTar(filePath)); } else { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Invalid theme package")); return e; } if (!archive->open(QIODevice::ReadOnly)) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Could not open file")); return e; } auto directory = archive->directory(); QStringList installedPaths; //some basic validation //the top level should only have folders, and those folders should contain a valid metadata.desktop file //if we get anything else, abort everything before copying for(const QString &name: directory->entries()) { auto entry = directory->entry(name); if (!entry->isDirectory()) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Invalid theme package")); return e; } auto subDirectory = static_cast(entry); auto metadataFile = subDirectory->file(QStringLiteral("metadata.desktop")); if(!metadataFile || !metadataFile->data().contains("[SddmGreeterTheme]")) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Invalid theme package")); return e; } installedPaths.append(themesBaseDir + QLatin1Char('/') + name); } if (!directory->copyTo(themesBaseDir)) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Could not decompress archive")); return e; } auto rc = ActionReply::SuccessReply(); rc.addData(QStringLiteral("installedPaths"), installedPaths); return rc; } ActionReply SddmAuthHelper::uninstalltheme(const QVariantMap &args) { const QString themePath = args[QStringLiteral("filePath")].toString(); const QString themesBaseDir = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("sddm/themes"), QStandardPaths::LocateDirectory); QDir dir(themePath); if (!dir.exists()) { return ActionReply::HelperErrorReply(); } //validate the themePath is directly inside the themesBaseDir QDir baseDir(themesBaseDir); if(baseDir.absoluteFilePath(dir.dirName()) != dir.absolutePath()) { return ActionReply::HelperErrorReply(); } if (!dir.removeRecursively()) { return ActionReply::HelperErrorReply(); } return ActionReply::SuccessReply(); } -KAUTH_HELPER_MAIN("org.kde.kcontrol.kcmsddm", SddmAuthHelper); +KAUTH_HELPER_MAIN("org.kde.kcontrol.kcmsddm", SddmAuthHelper) #include "moc_sddmauthhelper.cpp"