• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdeutils
  • Sitemap
  • Contact Us
 

kgpg

kgpginterface.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           kgpginterface.cpp  -  description
00003                              -------------------
00004     begin                : Mon Jul 8 2002
00005     copyright          : (C) 2002 by Jean-Baptiste Mardelle
00006     email                : bj@altern.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "kgpginterface.h"
00019 
00020 #include <QDir>
00021 #include <QTextStream>
00022 #include <QFile>
00023 
00024 #include <kio/netaccess.h>
00025 #include <KMessageBox>
00026 #include <KPasswordDialog>
00027 #include <knewpassworddialog.h>
00028 #include <KLocale>
00029 #include <KProcess>
00030 #include <KConfig>
00031 #include <KDebug>
00032 #include <KGlobal>
00033 #include <KStandardDirs>
00034 #include <KUrl>
00035 
00036 #include "detailedconsole.h"
00037 #include "emailvalidator.h"
00038 #include "kgpgsettings.h"
00039 #include "convert.h"
00040 #include "gpgproc.h"
00041 
00042 using namespace KgpgCore;
00043 
00044 KgpgInterface::KgpgInterface() : editprocess(0)
00045 {
00046 }
00047 
00048 KgpgInterface::~KgpgInterface()
00049 {
00050     if (editprocess != 0)
00051     {
00052         editprocess->kill();
00053         delete editprocess;
00054     }
00055 
00056     const QObjectList &list = children();
00057     // First, we block all signals
00058     for (int i = 0; i < list.size(); ++i)
00059         list.at(i)->blockSignals(true);
00060 
00061     // Then, we delete objects
00062     for (int i = 0; i < list.size(); ++i)
00063         delete list.at(i);
00064 }
00065 
00066 QString KgpgInterface::checkForUtf8(QString txt)
00067 {
00068     /* The string is not in UTF-8 */
00069     if (!txt.contains("\\x"))
00070         return txt;
00071 
00072     // if (!strchr (txt.toAscii(), 0xc3) || (txt.find("\\x")!=-1)) {
00073     for (int idx = 0; (idx = txt.indexOf( "\\x", idx )) >= 0 ; ++idx)
00074     {
00075         char str[2] = "x";
00076         str[0] = (char) QString(txt.mid(idx + 2, 2)).toShort(0, 16);
00077         txt.replace(idx, 4, str);
00078     }
00079 
00080     return QString::fromUtf8(txt.toAscii());
00081 }
00082 
00083 QString KgpgInterface::checkForUtf8bis(QString txt)
00084 {
00085     if (strchr(txt.toAscii(), 0xc3) || txt.contains("\\x"))
00086         txt = checkForUtf8(txt);
00087     else
00088     {
00089         txt = checkForUtf8(txt);
00090         txt = QString::fromUtf8(txt.toAscii());
00091     }
00092     return txt;
00093 }
00094 
00095 int KgpgInterface::gpgVersion(const QString &vstr)
00096 {
00097     if (vstr.isEmpty())
00098         return -1;
00099 
00100     QStringList values = vstr.split('.');
00101     if (values.count() < 3)
00102         return -2;
00103 
00104     return (0x10000 * values[0].toInt() + 0x100 * values[1].toInt() + values[2].toInt());
00105 }
00106 
00107 QString KgpgInterface::gpgVersionString(const QString &binary)
00108 {
00109     GPGProc process(0, binary);
00110     process << "--version";
00111     process.start();
00112     process.waitForFinished(-1);
00113 
00114     if (process.exitCode() == 255)
00115         return QString();
00116 
00117     QString line;
00118     if (process.readln(line) != -1)
00119         return line.simplified().section(' ', -1);
00120     else
00121         return QString();
00122 }
00123 
00124 QString KgpgInterface::getGpgProcessHome(const QString &binary)
00125 {
00126     GPGProc process(0, binary);
00127     process << "--version";
00128     process.start();
00129     process.waitForFinished(-1);
00130 
00131     if (process.exitCode() == 255) {
00132         return QString();
00133     }
00134 
00135     QString line;
00136     while (process.readln(line) != -1) {
00137         if (line.startsWith("Home: ")) {
00138             line.remove(0, 6);
00139             return line;
00140         }
00141     }
00142 
00143     return QString();
00144 }
00145 
00146 QString KgpgInterface::getGpgHome(const QString &binary)
00147 {
00148     // First try: if environment is set GnuPG will use that directory
00149     // We can use this directly without starting a new process
00150     QByteArray env = qgetenv("GNUPGHOME");
00151     QString gpgHome;
00152     if (!env.isEmpty()) {
00153         gpgHome = env;
00154     } else if (!binary.isEmpty()) {
00155         // Second try: start GnuPG and ask what it is
00156         gpgHome = getGpgProcessHome(binary);
00157     }
00158 
00159     // Third try: guess what it is.
00160     if (gpgHome.isEmpty()) {
00161 #ifdef Q_OS_WIN32
00162         gpgHome = qgetenv("APPDATA") + "/gnupg/";
00163         gpgHome.replace('\\', '/');
00164 #else
00165         gpgHome = QDir::homePath() + "/.gnupg/";
00166 #endif
00167     }
00168 
00169     gpgHome.replace("//", "/");
00170 
00171     if (!gpgHome.endsWith('/'))
00172         gpgHome.append('/');
00173 
00174     if (gpgHome.startsWith('~'))
00175         gpgHome.replace(0, 1, QDir::homePath());
00176 
00177     KStandardDirs::makeDir(gpgHome, 0700);
00178     return gpgHome;
00179 }
00180 
00181 QStringList KgpgInterface::getGpgGroupNames(const QString &configfile)
00182 {
00183     QStringList groups;
00184     QFile qfile(QFile::encodeName(configfile));
00185     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00186     {
00187         QTextStream t(&qfile);
00188         while (!t.atEnd())
00189         {
00190             QString result = t.readLine().simplified();
00191             if (result.startsWith("group "))
00192             {
00193                 result.remove(0, 6);
00194                 groups << result.section("=", 0, 0).simplified();
00195             }
00196         }
00197         qfile.close();
00198     }
00199     return groups;
00200 }
00201 
00202 QStringList KgpgInterface::getGpgGroupSetting(const QString &name, const QString &configfile)
00203 {
00204     QFile qfile(QFile::encodeName(configfile));
00205     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00206     {
00207         QTextStream t(&qfile);
00208         while (!t.atEnd())
00209         {
00210             QString result = t.readLine().simplified();
00211 
00212             if (result.startsWith("group "))
00213             {
00214                 kDebug(2100) << "Found 1 group" ;
00215                 result.remove(0, 6);
00216                 if (result.simplified().startsWith(name))
00217                 {
00218                     kDebug(2100) << "Found group: " << name ;
00219                     result = result.section('=', 1);
00220                     result = result.section('#', 0, 0);
00221                     return result.split(' ');
00222                 }
00223             }
00224         }
00225         qfile.close();
00226     }
00227     return QStringList();
00228 }
00229 
00230 void KgpgInterface::setGpgGroupSetting(const QString &name, const QStringList &values, const QString &configfile)
00231 {
00232     QString texttowrite;
00233     bool found = false;
00234     QFile qfile(QFile::encodeName(configfile));
00235 
00236     kDebug(2100) << "Changing group: " << name ;
00237     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00238     {
00239         QTextStream t(&qfile);
00240         while (!t.atEnd())
00241         {
00242         QString result = t.readLine();
00243             if (result.simplified().startsWith("group "))
00244             {
00245                 QString result2 = result.simplified();
00246                 result2.remove(0, 6);
00247                 result2 = result2.simplified();
00248                 if (result2.startsWith(name) && (result2.remove(0, name.length()).simplified().startsWith('=')))
00249                 {
00250                     // kDebug(2100) << "Found group: " << name ;
00251                     // kDebug(2100) << "New values: " << values ;
00252                     result = QString("group %1=%2").arg(name).arg(values.join(" "));
00253                     found = true;
00254                 }
00255             }
00256             texttowrite += result + '\n';
00257         }
00258         qfile.close();
00259 
00260         if (!found)
00261             texttowrite += '\n' + QString("group %1=%2").arg(name).arg(values.join(" "));
00262 
00263         if (qfile.open(QIODevice::WriteOnly))
00264         {
00265             QTextStream t(&qfile);
00266             t << texttowrite;
00267             qfile.close();
00268         }
00269     }
00270 }
00271 
00272 void KgpgInterface::delGpgGroup(const QString &name, const QString &configfile)
00273 {
00274     QString texttowrite;
00275     QFile qfile(QFile::encodeName(configfile));
00276     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00277     {
00278         QTextStream t(&qfile);
00279         while (!t.atEnd())
00280         {
00281         QString result = t.readLine();
00282             if (result.simplified().startsWith("group "))
00283             {
00284                 QString result2 = result.simplified();
00285                 result2.remove(0, 6);
00286                 result2 = result2.simplified();
00287                 if (result2.startsWith(name) && (result2.remove(0, name.length()).simplified().startsWith('=')))
00288                     result.clear();
00289             }
00290 
00291             texttowrite += result + '\n';
00292         }
00293 
00294         qfile.close();
00295         if (qfile.open(QIODevice::WriteOnly))
00296         {
00297             QTextStream t(&qfile);
00298             t << texttowrite;
00299             qfile.close();
00300         }
00301     }
00302 }
00303 
00304 QString KgpgInterface::getGpgSetting(QString name, const QString &configfile)
00305 {
00306     name = name.simplified() + ' ';
00307     QFile qfile(QFile::encodeName(configfile));
00308     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00309     {
00310         QTextStream t(&qfile);
00311         while (!t.atEnd())
00312         {
00313             QString result = t.readLine();
00314             if (result.simplified().startsWith(name))
00315             {
00316                 result = result.simplified();
00317                 result.remove(0, name.length());
00318                 result = result.simplified();
00319                 return result.section(" ", 0, 0);
00320             }
00321         }
00322         qfile.close();
00323     }
00324 
00325     return QString();
00326 }
00327 
00328 void KgpgInterface::setGpgSetting(const QString &name, const QString &value, const QString &url)
00329 {
00330     QString temp = name + ' ';
00331     QString texttowrite;
00332     bool found = false;
00333     QFile qfile(QFile::encodeName(url));
00334 
00335     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00336     {
00337         QTextStream t(&qfile);
00338         while (!t.atEnd())
00339         {
00340         QString result = t.readLine();
00341             if (result.simplified().startsWith(temp))
00342             {
00343                 if (!value.isEmpty())
00344                     result = temp + ' ' + value;
00345                 else
00346                     result.clear();
00347                 found = true;
00348             }
00349 
00350             texttowrite += result + '\n';
00351         }
00352 
00353         qfile.close();
00354         if ((!found) && (!value.isEmpty()))
00355             texttowrite += '\n' + temp + ' ' + value;
00356 
00357         if (qfile.open(QIODevice::WriteOnly))
00358         {
00359             QTextStream t(&qfile);
00360             t << texttowrite;
00361             qfile.close();
00362         }
00363     }
00364 }
00365 
00366 bool KgpgInterface::getGpgBoolSetting(const QString &name, const QString &configfile)
00367 {
00368     QFile qfile(QFile::encodeName(configfile));
00369     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00370     {
00371         QTextStream t(&qfile);
00372         while (!t.atEnd())
00373         {
00374             if (t.readLine().simplified().startsWith(name))
00375                 return true;
00376         }
00377         qfile.close();
00378     }
00379     return false;
00380 }
00381 
00382 void KgpgInterface::setGpgBoolSetting(const QString &name, const bool &enable, const QString &url)
00383 {
00384     QString texttowrite;
00385     bool found = false;
00386     QFile qfile(QFile::encodeName(url));
00387 
00388     if (qfile.open(QIODevice::ReadOnly) && (qfile.exists()))
00389     {
00390         QTextStream t(&qfile);
00391 
00392         while (!t.atEnd())
00393         {
00394         QString result = t.readLine();
00395 
00396             if (result.simplified().startsWith(name))
00397             {
00398                 if (enable)
00399                     result = name;
00400                 else
00401                     result.clear();
00402 
00403                 found = true;
00404             }
00405 
00406             texttowrite += result + '\n';
00407         }
00408         qfile.close();
00409 
00410         if ((!found) && (enable))
00411             texttowrite += name;
00412 
00413         if (qfile.open(QIODevice::WriteOnly))
00414         {
00415             QTextStream t(&qfile);
00416             t << texttowrite;
00417             qfile.close();
00418         }
00419     }
00420 }
00421 
00422 int KgpgInterface::sendPassphrase(const QString &text, KProcess *process, const bool isnew)
00423 {
00424     QByteArray passphrase;
00425     int code;
00426     if (isnew) {
00427         KNewPasswordDialog dlg;
00428         dlg.setPrompt(text);
00429         code = dlg.exec();
00430         passphrase = dlg.password().toLocal8Bit();
00431     } else {
00432         KPasswordDialog dlg;
00433         dlg.setPrompt(text);
00434         code = dlg.exec();
00435         passphrase = dlg.password().toLocal8Bit();
00436     }
00437 
00438     if (code != KPasswordDialog::Accepted)
00439         return 1;
00440 
00441     process->write(passphrase + '\n');
00442 
00443     return 0;
00444 }
00445 
00446 void KgpgInterface::updateIDs(QString txt)
00447 {
00448     int cut = txt.indexOf(' ', 22, Qt::CaseInsensitive);
00449     txt.remove(0, cut);
00450 
00451     if (txt.contains('(', Qt::CaseInsensitive))
00452         txt = txt.section('(', 0, 0) + txt.section(')', -1);
00453 
00454     txt.replace('<', "&lt;");
00455 
00456     if (!userIDs.contains(txt))
00457     {
00458         if (!userIDs.isEmpty())
00459             userIDs += i18n(" or ");
00460         userIDs += txt;
00461     }
00462 }
00463 
00464 KgpgKeyList KgpgInterface::readPublicKeys(const bool &block, const QStringList &ids, const bool &withsigs)
00465 {
00466     m_publiclistkeys = KgpgKeyList();
00467     m_publickey = KgpgKey();
00468     m_numberid = 1;
00469     cycle = "none";
00470 
00471     GPGProc *process = new GPGProc(this);
00472     *process << "--with-colons" << "--with-fingerprint";
00473     if (withsigs)
00474         *process << "--list-sigs";
00475     else
00476         *process << "--list-keys";
00477 
00478     *process << ids;
00479 
00480     if (!block)
00481     {
00482         connect(process, SIGNAL(readReady(GPGProc *)), this, SLOT(readPublicKeysProcess(GPGProc *)));
00483         connect(process, SIGNAL(processExited(GPGProc *)), this, SLOT(readPublicKeysFin(GPGProc *)));
00484         process->start();
00485         return KgpgKeyList();
00486     }
00487     else
00488     {
00489         process->start();
00490         process->waitForFinished(-1);
00491         readPublicKeysProcess(process);
00492         readPublicKeysFin(process, true);
00493         return m_publiclistkeys;
00494     }
00495 }
00496 
00497 void KgpgInterface::readPublicKeysProcess(GPGProc *p)
00498 {
00499     QStringList lsp;
00500     int items;
00501 
00502     while ((items = p->readln(lsp)) >= 0)
00503     {
00504         if ((lsp.at(0) == "pub") && (items >= 10))
00505         {
00506             if (cycle != "none")
00507             {
00508                 cycle = "none";
00509                 m_publiclistkeys << m_publickey;
00510             }
00511 
00512             m_publickey = KgpgKey();
00513 
00514             m_publickey.setTrust(Convert::toTrust(lsp.at(1)));
00515             m_publickey.setSize(lsp.at(2).toUInt());
00516             m_publickey.setAlgorithm(Convert::toAlgo(lsp.at(3).toInt()));
00517             m_publickey.setFingerprint(lsp.at(4));
00518             m_publickey.setCreation(QDate::fromString(lsp.at(5), Qt::ISODate));
00519             m_publickey.setOwnerTrust(Convert::toOwnerTrust(lsp.at(8)));
00520 
00521             if (lsp.at(6).isEmpty())
00522             {
00523                 m_publickey.setExpiration(QDate());
00524             }
00525             else
00526             {
00527                 m_publickey.setExpiration(QDate::fromString(lsp.at(6), Qt::ISODate));
00528             }
00529 
00530             if (lsp.at(11).contains("D", Qt::CaseSensitive))  // disabled key
00531                 m_publickey.setValid(false);
00532             else
00533                 m_publickey.setValid(true);
00534 
00535             QString fullname = lsp.at(9);
00536             if (fullname.contains("<"))
00537             {
00538                 QString kmail = fullname;
00539 
00540                 if (fullname.contains(')') )
00541                     kmail = kmail.section(')', 1);
00542 
00543                 kmail = kmail.section('<', 1);
00544                 kmail.truncate(kmail.length() - 1);
00545 
00546                 if (kmail.contains('<') ) // several email addresses in the same key
00547                 {
00548                     kmail = kmail.replace('>', ';');
00549                     kmail.remove('<');
00550                 }
00551 
00552                 m_publickey.setEmail(kmail);
00553             }
00554             else
00555                 m_publickey.setEmail(QString());
00556 
00557             QString kname = fullname.section(" <", 0, 0);
00558             if (fullname.contains('(') )
00559             {
00560                 kname = kname.section(" (", 0, 0);
00561                 QString comment = fullname.section('(', 1, 1);
00562                 comment = comment.section(')', 0, 0);
00563 
00564                 m_publickey.setComment(comment);
00565             }
00566             else
00567                 m_publickey.setComment(QString());
00568             m_publickey.setName(kname);
00569 
00570             cycle = "pub";
00571 
00572             // the first uid is merged into the public key
00573             m_numberid = 1;
00574         }
00575         else
00576         if ((lsp.at(0) == "fpr") && (items >= 10))
00577         {
00578             QString fingervalue = lsp.at(9);
00579 
00580             m_publickey.setFingerprint(fingervalue);
00581         }
00582         else
00583         if ((lsp.at(0) == "sub") && (items >= 7))
00584         {
00585             KgpgKeySub sub;
00586 
00587             sub.setId(lsp.at(4).right(8));
00588             sub.setTrust(Convert::toTrust(lsp.at(1)));
00589             sub.setSize(lsp.at(2).toUInt());
00590             sub.setAlgorithm(Convert::toAlgo(lsp.at(3).toInt()));
00591             sub.setCreation(QDate::fromString(lsp.at(5), Qt::ISODate));
00592 
00593             // FIXME: Please see kgpgkey.h, KgpgSubKey class
00594             if (lsp.at(11).contains('D'))
00595                 sub.setValid(false);
00596             else
00597                 sub.setValid(true);
00598 
00599             if (lsp.at(11).contains('s'))
00600                 sub.setType(SKT_SIGNATURE);
00601             else
00602             if (lsp.at(11).contains('e'))
00603                 sub.setType(SKT_ENCRYPTION);
00604 
00605             if (lsp.at(6).isEmpty())
00606             {
00607                 sub.setExpiration(QDate());
00608             }
00609             else
00610             {
00611                 sub.setExpiration(QDate::fromString(lsp.at(6), Qt::ISODate));
00612             }
00613 
00614             m_publickey.subList()->append(sub);
00615             cycle = "sub";
00616         }
00617         else
00618         if (lsp.at(0) == "uat")
00619         {
00620             m_numberid++;
00621             KgpgKeyUat uat;
00622             uat.setId(QString::number(m_numberid));
00623             uat.setCreation(QDate::fromString(lsp.at(5), Qt::ISODate));
00624             m_publickey.uatList()->append(uat);
00625 
00626             cycle = "uat";
00627         }
00628         else
00629         if ((lsp.at(0) == "uid") && (items >= 10))
00630         {
00631             KgpgKeyUid uid;
00632 
00633             uid.setTrust(Convert::toTrust(lsp.at(1)));
00634             if ((items > 11) && lsp.at(11).contains('D'))
00635                 uid.setValid(false);
00636             else
00637                 uid.setValid(true);
00638 
00639             uid.setIndex(++m_numberid);
00640             QString fullname = lsp.at(9);
00641             if (fullname.contains('<') )
00642             {
00643                 QString kmail = fullname;
00644 
00645                 if (fullname.contains(')') )
00646                     kmail = kmail.section(')', 1);
00647 
00648                 kmail = kmail.section('<', 1);
00649                 kmail.truncate(kmail.length() - 1);
00650 
00651                 if ( kmail.contains('<') ) // several email addresses in the same key
00652                 {
00653                     kmail = kmail.replace('>', ';');
00654                     kmail.remove('<');
00655                 }
00656 
00657                 uid.setEmail(kmail);
00658             }
00659             else
00660                 uid.setEmail(QString());
00661 
00662             QString kname = fullname.section(" <", 0, 0);
00663             if (fullname.contains('(') )
00664             {
00665                 kname = kname.section(" (", 0, 0);
00666                 QString comment = fullname.section('(', 1, 1);
00667                 comment = comment.section(')', 0, 0);
00668 
00669                 uid.setComment(comment);
00670             }
00671             else
00672                 uid.setComment(QString());
00673             uid.setName(kname);
00674 
00675             m_publickey.uidList()->append(uid);
00676 
00677             cycle = "uid";
00678         }
00679         else
00680         if (((lsp.at(0) == "sig") || (lsp.at(0) == "rev")) && (items >= 11))
00681         {
00682             KgpgKeySign signature;
00683 
00684             signature.setId(lsp.at(4));
00685             signature.setCreation(QDate::fromString(lsp.at(5), Qt::ISODate));
00686 
00687             if (lsp.at(6).isEmpty())
00688             {
00689                 signature.setExpiration(QDate());
00690             }
00691             else
00692             {
00693                 signature.setExpiration(QDate::fromString(lsp.at(6), Qt::ISODate));
00694             }
00695 
00696             QString fullname = lsp.at(9);
00697             if (fullname.contains('<') )
00698             {
00699                 QString kmail = fullname;
00700 
00701                 if (fullname.contains(')') )
00702                     kmail = kmail.section(')', 1);
00703 
00704                 kmail = kmail.section('<', 1);
00705                 kmail.truncate(kmail.length() - 1);
00706 
00707                 if (kmail.contains('<' )) // several email addresses in the same key
00708                 {
00709                     kmail = kmail.replace('>', ';');
00710                     kmail.remove('<');
00711                 }
00712 
00713                 signature.setEmail(kmail);
00714             }
00715             else
00716                 signature.setEmail(QString());
00717 
00718             QString kname = fullname.section(" <", 0, 0);
00719             if (fullname.contains('(' ))
00720             {
00721                 kname = kname.section(" (", 0, 0);
00722                 QString comment = fullname.section('(', 1, 1);
00723                 comment = comment.section(')', 0, 0);
00724 
00725                 signature.setComment(comment);
00726             }
00727             else
00728                 signature.setComment(QString());
00729             signature.setName(kname);
00730 
00731             if (lsp.at(10).endsWith('l'))
00732                 signature.setLocal(true);
00733 
00734             if (lsp.at(0) == "rev")
00735                 signature.setRevocation(true);
00736 
00737             if (cycle == "pub")
00738                 m_publickey.addSign(signature);
00739             else
00740             if (cycle == "uat")
00741                 m_publickey.uatList()->last().addSign(signature);
00742             else
00743             if (cycle == "uid")
00744                 m_publickey.uidList()->last().addSign(signature);
00745             else
00746             if (cycle == "sub")
00747                 m_publickey.subList()->last().addSign(signature);
00748         }
00749     }
00750 }
00751 
00752 void KgpgInterface::readPublicKeysFin(GPGProc *p, const bool &block)
00753 {
00754     // insert the last key
00755     if (cycle != "none")
00756         m_publiclistkeys << m_publickey;
00757 
00758     p->deleteLater();
00759     if (!block)
00760         emit readPublicKeysFinished(m_publiclistkeys, this);
00761 }
00762 
00763 
00764 KgpgKeyList KgpgInterface::readSecretKeys(const QStringList &ids)
00765 {
00766     m_partialline.clear();
00767     m_ispartial = false;
00768     m_secretlistkeys = KgpgKeyList();
00769     m_secretkey = KgpgKey();
00770     m_secretactivate = false;
00771 
00772         GPGProc *process = new GPGProc(this);
00773         *process << "--with-colons" << "--list-secret-keys" << "--with-fingerprint";
00774 
00775         *process << ids;
00776 
00777         process->start();
00778         process->waitForFinished(-1);
00779         readSecretKeysProcess(process);
00780 
00781     if (m_secretactivate)
00782         m_secretlistkeys << m_secretkey;
00783 
00784     delete process;
00785 
00786         return m_secretlistkeys;
00787 }
00788 
00789 void KgpgInterface::readSecretKeysProcess(GPGProc *p)
00790 {
00791     QStringList lsp;
00792     int items;
00793 
00794     while ( (items = p->readln(lsp)) >= 0 )
00795     {
00796             if ((lsp.at(0) == "sec") && (items >= 10))
00797             {
00798                 if (m_secretactivate)
00799                     m_secretlistkeys << m_secretkey;
00800 
00801                 m_secretactivate = true;
00802                 m_secretkey = KgpgKey();
00803 
00804                 m_secretkey.setTrust(Convert::toTrust(lsp.at(1)));
00805                 m_secretkey.setSize(lsp.at(2).toUInt());
00806                 m_secretkey.setAlgorithm(Convert::toAlgo(lsp.at(3).toInt()));
00807                 m_secretkey.setFingerprint(lsp.at(4));
00808                 m_secretkey.setCreation(QDate::fromString(lsp[5], Qt::ISODate));
00809                 m_secretkey.setSecret(true);
00810 
00811                 if (lsp.at(6).isEmpty())
00812                 {
00813                     m_secretkey.setExpiration(QDate());
00814                 }
00815                 else
00816                 {
00817                     m_secretkey.setExpiration(QDate::fromString(lsp.at(6), Qt::ISODate));
00818                 }
00819 
00820                 QString fullname = lsp.at(9);
00821                 if (fullname.contains('<' ))
00822                 {
00823                     QString kmail = fullname;
00824 
00825                     if (fullname.contains(')' ))
00826                         kmail = kmail.section(')', 1);
00827 
00828                     kmail = kmail.section('<', 1);
00829                     kmail.truncate(kmail.length() - 1);
00830 
00831                     if (kmail.contains('<' )) // several email addresses in the same key
00832                     {
00833                         kmail = kmail.replace('>', ';');
00834                         kmail.remove('<');
00835                     }
00836 
00837                     m_secretkey.setEmail(kmail);
00838                 }
00839                 else
00840                     m_secretkey.setEmail(QString());
00841 
00842                 QString kname = fullname.section(" <", 0, 0);
00843                 if (fullname.contains('(' ))
00844                 {
00845                     kname = kname.section(" (", 0, 0);
00846                     QString comment = fullname.section('(', 1, 1);
00847                     comment = comment.section(')', 0, 0);
00848 
00849                     m_secretkey.setComment(comment);
00850                 }
00851                 else
00852                     m_secretkey.setComment(QString());
00853                 m_secretkey.setName(kname);
00854             } else if ((lsp.at(0) == "fpr") && (items >= 10)) {
00855                 QString fingervalue = lsp.at(9);
00856 
00857                 m_secretkey.setFingerprint(fingervalue);
00858             }
00859     }
00860 }
00861 
00862 KgpgCore::KgpgKeyList
00863 KgpgInterface::readJoinedKeys(const KgpgKeyTrust &trust, const QStringList &ids)
00864 {
00865     KgpgKeyList secretkeys = readSecretKeys(ids);
00866     KgpgKeyList publickeys = readPublicKeys(true, ids, false);
00867     int i, j;
00868 
00869     for (i = publickeys.size() - 1; i >= 0; i--)
00870         if (publickeys.at(i).trust() < trust)
00871             publickeys.removeAt(i);
00872 
00873     for (i = 0; i < secretkeys.size(); i++) {
00874         for (j = 0; j < publickeys.size(); j++)
00875             if (secretkeys.at(i).fullId() == publickeys.at(j).fullId()) {
00876                 publickeys[j].setSecret(true);
00877                 break;
00878             }
00879     }
00880 
00881     // move the secret keys to the top of the list
00882     for (j = 1; j < publickeys.size(); j++)
00883         if (publickeys.at(j).secret())
00884             publickeys.move(j, 0);
00885 
00886     return publickeys;
00887 }
00888 
00889 QString KgpgInterface::getKeys(const QString *attributes, const QStringList &ids)
00890 {
00891     m_keystring.clear();
00892 
00893     GPGProc *gpgProcess = new GPGProc(this);
00894     *gpgProcess << "--export" << "--armor" << "--status-fd=1" << "--command-fd=0";
00895 
00896     if (attributes)
00897         *gpgProcess << "--export-options" << *attributes;
00898 
00899     *gpgProcess << ids;
00900 
00901     connect(gpgProcess, SIGNAL(readReady(GPGProc *)), this, SLOT(getKeysProcess(GPGProc *)));
00902     gpgProcess->start();
00903     gpgProcess->waitForFinished(-1);
00904     delete gpgProcess;
00905     return m_keystring;
00906 }
00907 
00908 void KgpgInterface::getKeysProcess(GPGProc *gpgProcess)
00909 {
00910     QString line;
00911 
00912     while (gpgProcess->readln(line, true) >= 0) {
00913         if (!line.startsWith("gpg:"))
00914             m_keystring += line + '\n';
00915     }
00916 }
00917 
00918 void KgpgInterface::getKeysFin(GPGProc *gpgProcess)
00919 {
00920     gpgProcess->deleteLater();
00921     emit getKeysFinished(m_keystring, this);
00922 }
00923 
00924 void KgpgInterface::signKey(const QString &keyid, const QString &signkeyid, const bool &local, const int &checking, const bool &terminal, const QString &uid)
00925 {
00926     m_partialline.clear();
00927     m_ispartial = false;
00928     log.clear();
00929     m_signkey = signkeyid;
00930     m_keyid = keyid;
00931     m_checking = checking;
00932     m_local = local;
00933     step = 3;
00934 
00935     if (terminal)
00936     {
00937         signKeyOpenConsole();
00938         return;
00939     }
00940 
00941     m_success = 0;
00942 
00943     m_workProcess = new KProcess(this);
00944     m_workProcess->setOutputChannelMode(KProcess::OnlyStdoutChannel);
00945     *m_workProcess << KGpgSettings::gpgBinaryPath();
00946     *m_workProcess << "--no-secmem-warning" << "--no-tty" << "--status-fd=1" << "--command-fd=0";
00947 
00948     *m_workProcess << "-u" << signkeyid;
00949     *m_workProcess << "--edit-key" << keyid;
00950 
00951     if (!uid.isEmpty())
00952         *m_workProcess << "uid" << uid;
00953 
00954     if (local)
00955         *m_workProcess << "lsign";
0095