/* * Copyright (C) 2003-2008 Justin Karneges * Copyright (C) 2014 Ivan Romanov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "utils.h" #include "mykeystorelist.h" #include #include #include #ifdef Q_OS_WIN #include #endif using namespace QCA; namespace gpgQCAPlugin { void gpg_waitForFinished(GpgOp *gpg) { while (true) { GpgOp::Event e = gpg->waitForEvent(-1); if (e.type == GpgOp::Event::Finished) break; } } void gpg_keyStoreLog(const QString &str) { MyKeyStoreList *ksl = MyKeyStoreList::instance(); if (ksl) ksl->ext_keyStoreLog(str); } inline bool check_bin(const QString &bin) { QFileInfo fi(bin); return fi.exists(); } #ifdef Q_OS_WIN static bool get_reg_key(HKEY root, const char *path, QString &value) { HKEY hkey = 0; char szValue[256]; DWORD dwLen = 256; bool res = false; if (RegOpenKeyExA(root, path, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) { if (RegQueryValueExA(hkey, "Install Directory", NULL, NULL, (LPBYTE)szValue, &dwLen) == ERROR_SUCCESS) { value = QString::fromLocal8Bit(szValue); res = true; } RegCloseKey(hkey); } return res; } static QString find_reg_gpgProgram() { const QStringList bins = {QStringLiteral("gpg.exe"), QStringLiteral("gpg2.exe")}; HKEY root; root = HKEY_CURRENT_USER; const char *path = "Software\\GNU\\GnuPG"; const char *path2 = "Software\\Wow6432Node\\GNU\\GnuPG"; QString dir; // check list of possible places in registry get_reg_key(HKEY_CURRENT_USER, path, dir) || get_reg_key(HKEY_CURRENT_USER, path2, dir) || get_reg_key(HKEY_LOCAL_MACHINE, path, dir) || get_reg_key(HKEY_LOCAL_MACHINE, path2, dir); if (!dir.isEmpty()) { foreach (const QString &bin, bins) { if (check_bin(dir + QStringLiteral("\\") + bin)) { return dir + QStringLiteral("\\") + bin; } } } return QString(); } #endif QString find_bin() { // gpg and gpg2 has identical semantics // so any from them can be used QStringList bins; #ifdef Q_OS_WIN bins << QStringLiteral("gpg.exe") << QStringLiteral("gpg2.exe"); #else bins << QStringLiteral("gpg") << QStringLiteral("gpg2"); #endif // Prefer bundled gpg foreach (const QString &bin, bins) { if (check_bin(QCoreApplication::applicationDirPath() + QLatin1Char('/') + bin)) { return QCoreApplication::applicationDirPath() + QLatin1Char('/') + bin; } } #ifdef Q_OS_WIN // On Windows look up at registry QString bin = find_reg_gpgProgram(); if (!bin.isEmpty()) return bin; #endif // Look up at PATH environment #ifdef Q_OS_WIN const QString pathSep = QStringLiteral(";"); #else const QString pathSep = QStringLiteral(":"); #endif QStringList paths = QString::fromLocal8Bit(qgetenv("PATH")).split(pathSep, Qt::SkipEmptyParts); #ifdef Q_OS_MAC // On Mac OS bundled always uses system default PATH // so it need explicity add extra paths which can // contain gpg // Mac GPG and brew use /usr/local/bin // MacPorts uses /opt/local/bin paths << QStringLiteral("/usr/local/bin") << QStringLiteral("/opt/local/bin"); #endif paths.removeDuplicates(); foreach (const QString &path, paths) { foreach (const QString &bin, bins) { if (check_bin(path + QLatin1Char('/') + bin)) { return path + QLatin1Char('/') + bin; } } } // Return nothing if gpg not found return QString(); } QString escape_string(const QString &in) { QString out; for (const QChar &c : in) { if (c == QLatin1Char('\\')) out += QStringLiteral("\\\\"); else if (c == QLatin1Char(':')) out += QStringLiteral("\\c"); else out += c; } return out; } QString unescape_string(const QString &in) { QString out; for (int n = 0; n < in.length(); ++n) { if (in[n] == QLatin1Char('\\')) { if (n + 1 < in.length()) { if (in[n + 1] == QLatin1Char('\\')) out += QLatin1Char('\\'); else if (in[n + 1] == QLatin1Char('c')) out += QLatin1Char(':'); ++n; } } else out += in[n]; } return out; } PGPKey publicKeyFromId(const QString &id) { MyKeyStoreList *ksl = MyKeyStoreList::instance(); if (!ksl) return PGPKey(); return ksl->publicKeyFromId(id); } PGPKey secretKeyFromId(const QString &id) { MyKeyStoreList *ksl = MyKeyStoreList::instance(); if (!ksl) return PGPKey(); return ksl->secretKeyFromId(id); } } // end namespace gpgQCAPlugin