/* * Copyright (C) 2008,2009,2010,2012 Rolf Eike Beer */ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "kgpgimport.h" #include "model/kgpgitemmodel.h" #include "core/KGpgKeyNode.h" #include #include KGpgImport::KGpgImport(QObject *parent, const QString &text) : KGpgTextOrFileTransaction(parent, text, true) { } KGpgImport::KGpgImport(QObject *parent, const KUrl::List &files) : KGpgTextOrFileTransaction(parent, files, true) { } KGpgImport::~KGpgImport() { } QStringList KGpgImport::command() const { QStringList ret; ret << QLatin1String( "--import" ) << QLatin1String( "--allow-secret-key-import" ); return ret; } QStringList KGpgImport::getImportedKeys() const { QStringList res; foreach (const QString &str, getMessages()) if (str.startsWith(QLatin1String("[GNUPG:] IMPORTED "))) res << str.mid(18); return res; } QStringList KGpgImport::getImportedIds(const QStringList &log, const int reason) { QStringList res; foreach (const QString &str, log) { if (!str.startsWith(QLatin1String("[GNUPG:] IMPORT_OK "))) continue; QString tmpstr(str.mid(19).simplified()); int space = tmpstr.indexOf(QLatin1Char( ' ' )); if (space <= 0) { kDebug(2100) << __LINE__ << "invalid format:" << str; continue; } bool ok; unsigned char code = tmpstr.left(space).toUInt(&ok); if (!ok) { kDebug(2100) << __LINE__ << "invalid format:" << str << space << tmpstr.left(space - 1); continue; } if ((reason == -1) || ((reason == 0) && (code == 0)) || ((reason & code) != 0)) res << tmpstr.mid(space + 1); } return res; } QStringList KGpgImport::getImportedIds(const int reason) const { return getImportedIds(getMessages(), reason); } QString KGpgImport::getImportMessage() const { return getImportMessage(getMessages()); } QString KGpgImport::getImportMessage(const QStringList &log) { #define RESULT_PARTS 14 unsigned long rcode[RESULT_PARTS]; unsigned int i = 0; int line = 0; bool fine; memset(rcode, 0, sizeof(rcode)); foreach (const QString &str, log) { line++; if (!str.startsWith(QLatin1String("[GNUPG:] IMPORT_RES "))) continue; const QStringList rstr(str.mid(20).simplified().split(QLatin1Char( ' ' ))); fine = (rstr.count() == RESULT_PARTS); i = 0; while (fine && (i < RESULT_PARTS)) { rcode[i] += rstr.at(i).toULong(&fine); i++; } if (!fine) return i18n("The import result string has an unsupported format in line %1.
Please see the detailed log for more information.", line); } fine = false; i = 0; while (!fine && (i < RESULT_PARTS)) { fine = (rcode[i] != 0); i++; } if (!fine) return i18n("No key imported.
Please see the detailed log for more information."); QString resultMessage(i18np("%1 key processed.", "%1 keys processed.", rcode[0])); if (rcode[1]) resultMessage += i18np("
One key without ID.
", "
%1 keys without ID.
", rcode[1]); if (rcode[2]) resultMessage += i18np("
One key imported:
", "
%1 keys imported:
", rcode[2]); if (rcode[3]) resultMessage += i18np("
One RSA key imported.
", "
%1 RSA keys imported.
", rcode[3]); if (rcode[4]) resultMessage += i18np("
One key unchanged.
", "
%1 keys unchanged.
", rcode[4]); if (rcode[5]) resultMessage += i18np("
One user ID imported.
", "
%1 user IDs imported.
", rcode[5]); if (rcode[6]) resultMessage += i18np("
One subkey imported.
", "
%1 subkeys imported.
", rcode[6]); if (rcode[7]) resultMessage += i18np("
One signature imported.
", "
%1 signatures imported.
", rcode[7]); if (rcode[8]) resultMessage += i18np("
One revocation certificate imported.
", "
%1 revocation certificates imported.
", rcode[8]); if (rcode[9]) resultMessage += i18np("
One secret key processed.
", "
%1 secret keys processed.
", rcode[9]); if (rcode[10]) resultMessage += i18np("
One secret key imported.
", "
%1 secret keys imported.
", rcode[10]); if (rcode[11]) resultMessage += i18np("
One secret key unchanged.
", "
%1 secret keys unchanged.
", rcode[11]); if (rcode[12]) resultMessage += i18np("
One secret key not imported.
", "
%1 secret keys not imported.
", rcode[12]); if (rcode[9]) resultMessage += i18n("
You have imported a secret key.
" "Please note that imported secret keys are not trusted by default.
" "To fully use this secret key for signing and encryption, you must edit the key (double click on it) and set its trust to Full or Ultimate.
"); return resultMessage; } static QString beautifyKeyList(const QStringList &keyIds, const KGpgItemModel *model) { QString result; result.append(QLatin1String("\n")); if (model == NULL) { result.append(QLatin1String(" ") + keyIds.join(QLatin1String("\n "))); } else { foreach (const QString &changed, keyIds) { const KGpgKeyNode *node = model->findKeyNode(changed); QString line; if (node == NULL) { line = changed; } else { if (node->getEmail().isEmpty()) line = i18nc("ID: Name", "%1: %2", node->getFingerprint(), node->getName()); else line = i18nc("ID: Name ", "%1: %2 <%3>", node->getFingerprint(), node->getName(), node->getEmail()); } result.append(QLatin1String(" ") + line + QLatin1String("\n")); } } return result; } QString KGpgImport::getDetailedImportMessage(const QStringList &log, const KGpgItemModel *model) { QString result; QMap resultcodes; foreach (const QString &keyresult, log) { if (!keyresult.startsWith(QLatin1String("[GNUPG:] IMPORT_OK "))) continue; QStringList rc(keyresult.mid(19).split(QLatin1Char( ' ' ))); if (rc.count() < 2) { kDebug(2100) << "unexpected syntax:" << keyresult; continue; } resultcodes[rc.at(1)] = rc.at(0).toUInt(); } QMap::const_iterator iterend = resultcodes.constEnd(); for (unsigned int flag = 1; flag <= 16; flag <<= 1) { QStringList thischanged; for (QMap::const_iterator iter = resultcodes.constBegin(); iter != iterend; ++iter) { if (iter.value() & flag) thischanged << iter.key(); } if (thischanged.isEmpty()) continue; switch (flag) { case 1: result.append(i18np("New Key", "New Keys", thischanged.count())); break; case 2: result.append(i18np("Key with new User Id", "Keys with new User Ids", thischanged.count())); break; case 4: result.append(i18np("Key with new Signatures", "Keys with new Signatures", thischanged.count())); break; case 8: result.append(i18np("Key with new Subkeys", "Keys with new Subkeys", thischanged.count())); break; case 16: result.append(i18np("New Private Key", "New Private Keys", thischanged.count())); break; default: Q_ASSERT(flag == 1); } result.append(beautifyKeyList(thischanged, model)); result.append(QLatin1String("\n\n")); } QStringList unchanged(resultcodes.keys(0)); if (unchanged.isEmpty()) { // remove empty line at end result.chop(1); } else { result.append(i18np("Unchanged Key", "Unchanged Keys", unchanged.count())); result.append(beautifyKeyList(unchanged, model)); result.append(QLatin1String("\n")); } return result; } int KGpgImport::isKey(const QString &text, const bool incomplete) { int markpos = text.indexOf(QLatin1String("-----BEGIN PGP PUBLIC KEY BLOCK-----")); if (markpos >= 0) { markpos = text.indexOf(QLatin1String("-----END PGP PUBLIC KEY BLOCK-----"), markpos); return ((markpos > 0) || incomplete) ? 1 : 0; } markpos = text.indexOf(QLatin1String("-----BEGIN PGP PRIVATE KEY BLOCK-----")); if (markpos < 0) return 0; markpos = text.indexOf(QLatin1String("-----END PGP PRIVATE KEY BLOCK-----"), markpos); if ((markpos < 0) && !incomplete) return 0; return 2; } #include "kgpgimport.moc"