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