File indexing completed on 2024-03-24 05:53:38
0001 /* 0002 SPDX-FileCopyrightText: 2002 Jean-Baptiste Mardelle <bj@altern.org> 0003 SPDX-FileCopyrightText: 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Rolf Eike Beer <kde@opensource.sf-tec.de> 0004 SPDX-FileCopyrightText: 2016 Andrius Štikonas <andrius@stikonas.eu> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kgpg.h" 0009 0010 #include "gpgproc.h" 0011 #include "kgpgsettings.h" 0012 #include "keysmanager.h" 0013 #include "kgpg_interface.h" 0014 #include "kgpgexternalactions.h" 0015 #include "kgpginterface.h" 0016 #include "core/images.h" 0017 #include "editor/kgpgeditor.h" 0018 #include "transactions/kgpgimport.h" 0019 0020 #include <QCommandLineOption> 0021 #include <QCommandLineParser> 0022 #include <QFile> 0023 #include <QMimeDatabase> 0024 #include <QMimeType> 0025 #include <QTextStream> 0026 0027 #include <KMessageBox> 0028 #include <KWindowSystem> 0029 0030 using namespace KgpgCore; 0031 0032 KGpgApp::KGpgApp(int &argc, char **argv) 0033 : QApplication(argc, argv), 0034 w(nullptr), 0035 s_keyManager(nullptr) 0036 { 0037 } 0038 0039 KGpgApp::~KGpgApp() 0040 { 0041 delete s_keyManager; 0042 } 0043 0044 void KGpgApp::slotHandleQuit() 0045 { 0046 s_keyManager->saveToggleOpts(); 0047 quit(); 0048 } 0049 0050 void KGpgApp::assistantOver(const QString &defaultKeyId) 0051 { 0052 if (!defaultKeyId.isEmpty()) 0053 s_keyManager->slotSetDefaultKey(defaultKeyId); 0054 0055 s_keyManager->show(); 0056 s_keyManager->raise(); 0057 } 0058 0059 bool KGpgApp::newInstance() 0060 { 0061 const QString gpgError = GPGProc::getGpgStartupError(KGpgSettings::gpgBinaryPath()); 0062 if (!gpgError.isEmpty()) { 0063 KMessageBox::detailedError(nullptr, i18n("GnuPG failed to start.<br />You must fix the GnuPG error first before running KGpg."), gpgError, i18n("GnuPG error")); 0064 QApplication::quit(); 0065 return false; 0066 } 0067 0068 s_keyManager = new KeysManager(); 0069 0070 w = new KGpgExternalActions(s_keyManager, s_keyManager->getModel()); 0071 0072 connect(s_keyManager, &KeysManager::readAgainOptions, w, &KGpgExternalActions::readOptions); 0073 connect(w, &KGpgExternalActions::updateDefault, this, &KGpgApp::assistantOver); 0074 connect(w, &KGpgExternalActions::createNewKey, s_keyManager, &KeysManager::slotGenerateKey); 0075 0076 const QString gpgPath = KGpgSettings::gpgConfigPath(); 0077 0078 if (!gpgPath.isEmpty()) { 0079 const int gpgver = GPGProc::gpgVersion(GPGProc::gpgVersionString(KGpgSettings::gpgBinaryPath())); 0080 0081 // Warn if sign of a properly running gpg-agent cannot be determined 0082 // The environment variable has been removed in GnuPG 2.1, the agent is started internally by 0083 // any program part of GnuPG that needs it, so simply assume everything is fine. 0084 if ((gpgver < 0x20100) && KgpgInterface::getGpgBoolSetting(QLatin1String("use-agent"), gpgPath) && 0085 qEnvironmentVariableIsEmpty("GPG_AGENT_INFO")) 0086 KMessageBox::error(nullptr, i18n("<qt>The use of <b>GnuPG Agent</b> is enabled in GnuPG's configuration file (%1).<br />" 0087 "However, the agent does not seem to be running. This could result in problems with signing/decryption.<br />" 0088 "Please disable GnuPG Agent from KGpg settings, or fix the agent.</qt>", gpgPath)); 0089 } 0090 0091 return true; 0092 } 0093 0094 void KGpgApp::handleArguments(const QCommandLineParser &parser, const QDir &workingDirectory) 0095 { 0096 // parsing of command line args 0097 if (parser.isSet(QStringLiteral("k")) || (!KGpgSettings::showSystray() && parser.positionalArguments().isEmpty() && !parser.isSet(QStringLiteral("d")))) { 0098 s_keyManager->show(); 0099 s_keyManager->raise(); // set on top 0100 } else if (parser.isSet(QStringLiteral("d"))) { 0101 s_keyManager->slotOpenEditor(); 0102 s_keyManager->hide(); 0103 } else { 0104 QList<QUrl> urlList; 0105 0106 const QStringList positionalArguments = parser.positionalArguments(); 0107 for (const QString &arg : positionalArguments) 0108 urlList.append(QUrl::fromLocalFile(workingDirectory.absoluteFilePath(arg))); 0109 0110 bool directoryInside = false; 0111 for (const QUrl &url : std::as_const(urlList)) { 0112 QMimeDatabase db; 0113 if (db.mimeTypeForUrl(url).name() == QLatin1String( "inode/directory" )) { 0114 directoryInside = true; 0115 break; 0116 } 0117 } 0118 0119 if (parser.isSet(QStringLiteral("e"))) { 0120 if (urlList.isEmpty()) 0121 KMessageBox::error(nullptr, i18n("No files given.")); 0122 else if (!directoryInside) 0123 KGpgExternalActions::encryptFiles(s_keyManager, urlList); 0124 else 0125 KGpgExternalActions::encryptFolders(s_keyManager, urlList); 0126 } else if (parser.isSet(QStringLiteral("s"))) { 0127 if (urlList.isEmpty()) 0128 KMessageBox::error(nullptr, i18n("No files given.")); 0129 else if (!directoryInside) 0130 w->showDroppedFile(urlList.first()); 0131 else 0132 KMessageBox::error(nullptr, i18n("Cannot decrypt and show folder.")); 0133 } else if (parser.isSet(QStringLiteral("S"))) { 0134 if (urlList.isEmpty()) 0135 KMessageBox::error(nullptr, i18n("No files given.")); 0136 else if (!directoryInside) 0137 KGpgExternalActions::signFiles(s_keyManager, urlList); 0138 else 0139 KMessageBox::error(nullptr, i18n("Cannot sign folder.")); 0140 } else if (parser.isSet(QStringLiteral("V")) != 0) { 0141 if (urlList.isEmpty()) 0142 KMessageBox::error(nullptr, i18n("No files given.")); 0143 else if (!directoryInside) 0144 w->verifyFile(urlList.first()); 0145 else 0146 KMessageBox::error(nullptr, i18n("Cannot verify folder.")); 0147 } else { 0148 if (directoryInside && (urlList.count() > 1)) { 0149 KMessageBox::error(nullptr, i18n("Unable to perform requested operation.\nPlease select only one folder, or several files, but do not mix files and folders.")); 0150 return; 0151 } 0152 0153 if (urlList.isEmpty()) { 0154 /* do nothing */ 0155 } else if (urlList.first().fileName().endsWith(QLatin1String(".sig"))) { 0156 w->verifyFile(urlList.first()); 0157 } else { 0158 bool haskeys = false; 0159 bool hastext = false; 0160 for (const QUrl &url : std::as_const(urlList)) { 0161 QFile qfile(url.path()); 0162 if (qfile.open(QIODevice::ReadOnly)) { 0163 const int probelen = 4096; 0164 QTextStream t(&qfile); 0165 QString probetext(t.read(probelen)); 0166 qfile.close(); 0167 0168 if (KGpgImport::isKey(probetext, probetext.length() == probelen)) 0169 haskeys = true; 0170 else 0171 hastext = true; 0172 } 0173 } 0174 0175 if (hastext) { 0176 KGpgExternalActions::decryptFiles(s_keyManager, urlList); 0177 } else if (haskeys) { 0178 s_keyManager->slotImport(urlList); 0179 } 0180 } 0181 } 0182 } 0183 } 0184 0185 void KGpgApp::setupCmdlineParser(QCommandLineParser& parser) 0186 { 0187 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("e"), i18n("Encrypt file"))); 0188 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("k"), i18n("Open key manager"))); 0189 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("d"), i18n("Open editor"))); 0190 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("s"), i18n("Show encrypted file"))); 0191 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("S"), i18n("Sign File"))); 0192 parser.addOption(QCommandLineOption(QStringList() << QLatin1String("V"), i18n("Verify signature"))); 0193 parser.addPositionalArgument(QLatin1String("[File]"), i18n("File to open")); 0194 } 0195 0196 void KGpgApp::slotDBusActivation(const QStringList &arguments, const QString &workingDirectory) 0197 { 0198 QCommandLineParser parser; 0199 0200 setupCmdlineParser(parser); 0201 0202 parser.parse(arguments); 0203 0204 handleArguments(parser, QDir(workingDirectory)); 0205 }