Bug 68470 - generated key not in key list
Summary: generated key not in key list
Status: RESOLVED WORKSFORME
Alias: None
Product: kgpg
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources FreeBSD
: NOR normal
Target Milestone: ---
Assignee: bj
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-11-18 04:29 UTC by brad
Modified: 2007-09-11 11:24 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description brad 2003-11-18 04:29:35 UTC
Version:            (using KDE KDE 3.1.93)
Installed from:    Compiled From Sources
Compiler:          gcc3.2 
OS:          FreeBSD

KDE Version: 3.1.93 (kde3.2 beta)
Kgpg Version: 1.0.99

Problem Description:
Generating key pair does not show up in key list

Reproduce:
Start with empty key list. Generate a key pair, go through normal motions of generating a key. When the key is generated, it does not show up in the list.
Comment 1 bj 2003-12-09 12:36:07 UTC
Subject: Re: generated key not in key list

Hello !
I cannot reproduce the bug. Could you update your cvs and see if it still 
happens ?

Does it only happen if there is no key in the list ?

regards
Comment 2 brad 2003-12-09 16:36:45 UTC
I'm running kde 3.2 beta 2. 
If i do a 'gpg --list-keys' i get a list of a few keys, but when i start kgpg, zero keys show up. I mentioned an empty keylist above because that's all that i have seen so far, but i don't think that's a factor. So i guess a better description of the bug is that 'gpg --list-keys' does not populate kgpg's display.

I'm using gpg (GnuPG) 1.2.2 if that makes any difference.

Is there a verbose flag i can execute kgpg with to see what it is trying to do?
Comment 3 bj 2003-12-10 19:04:48 UTC
Subject: Re:  generated key not in key list

> If i do a 'gpg --list-keys' i get a list of a few keys, but when i start
> kgpg, zero keys show up. I mentioned an empty keylist above because that's
> all that i have seen so far, but i don't think that's a factor. So i guess
> a better description of the bug is that 'gpg --list-keys' does not populate
> kgpg's display.

Could you please send me the output the following command:
gpg --with-colon --list-keys

You can also try to start KGpg from a console, it may give you some output in 
the console view.

Are you sure the gpg binary is in your path (executable from your home 
directory ?)

Nobody ever reported such a problem. Thanks to give me all informations, It 
would be really nice to find & fix the problem before the final release.

regards
Comment 4 brad 2003-12-26 05:31:33 UTC
More specs on my system FreeBSD 5.1.

After talking with the developer it seems that the problem is with the fgets() function calls in listkeys.cpp in the function KeyView::refreshkeylist(). Here is some output with added debugging code (the intersting output is the last three lines).


  FreeBSD| brad@lou > ./kgpg --nofork
  QSettings::sync: filename is null/empty
  kgpg: New instance
  kgpg: Starting KGpg
  kdecore (KConfigSkeleton): Creating KConfigSkeleton (0x8238c00)
  kdecore (KConfigSkeleton): KConfigSkeleton::readConfig()
  kdecore (KAccel): WARNING: KKeySequence::init( seq ): key[0] is null.
  kdecore (KAccel): WARNING: KKeySequence::init( seq ): key[0] is null.
  QMetaObject::findSignal:KeyView: Conflict with  
  QListView::doubleClicked(QListViewItem*,const QPoint&,int)
  kgpg: Fgets error no is : 35
  kgpg: Error is : Resource temporarily unavailable
  kgpg: Last line read is : p??0

Comment 5 groot 2004-01-04 19:57:13 UTC
Using popen() with gpg is nasty; the pty stuff hard to understand (I have a great example showing resource unavailable bugs, BTW). kgpg would need KProcess if it weren't in much bigger need of a complete rewrite using gpgme and the rest of the improved crypto stuff Mutz is working on.
Comment 6 groot 2004-01-09 10:51:23 UTC
Again, misunderstood.
Comment 7 Nicolas L. 2005-08-19 14:31:18 UTC
can't reproduce this bug with kde 3.4.2
Comment 8 Martin Seekatz 2005-12-01 22:44:07 UTC
This may be the result of an bug of the settings. KGPG do not find the gpg configuration file. On Linux / Unix per default ~/.gnupg/gpg.conf.
If you open the setup dialog and change the "GnuPG" settings (to show the hidden .gnupg directory the right mouse buttom have to be used over the listing!!!!!!) so that the gnupg configuration is shown, you get your secret keys displayed.
Comment 9 brad 2005-12-07 14:01:24 UTC
I think the much greater problem is that kgpg is not using gpgme but
rather it's using the gpg command line interface directly through system calls such as popen(), for example,

kgpg/listkeys.cpp:249
   fp = popen("gpg --no-tty --with-colon --list-secret-keys", "r");

The behavior of these calls is not portable at all. The think the use
gpgme will greatly improve the portability of kgpg.
Comment 10 Rolf Eike Beer 2007-09-05 23:53:36 UTC
SVN commit 708873 by dakon:

Clean up scanning for possible default keys in KGpg wizard

If the wizard comes up it does it's own scanning for secret keys. It uses the 
popen() function reported as unportable. In fact it's not really needed at all 
as the actions performed here are already implemented in the KgpgInterface 
class.

CCBUG:68470


 M  +22 -34    kgpg.cpp  


--- trunk/KDE/kdeutils/kgpg/kgpg.cpp #708872:708873
@@ -767,46 +767,34 @@
     wiz->kURLRequester2->setURL(KGlobalSettings::desktopPath());
         wiz->kURLRequester2->setMode(2);*/
 
-    FILE *fp,*fp2;
-    QString tst;
-    QString tst2;
-    QString name;
-    QString trustedvals = "idre-";
     QString firstKey = QString();
-    char line[300];
-    bool counter = false;
 
-    fp = popen("gpg --no-tty --with-colon --list-secret-keys", "r");
-    while (fgets(line, sizeof(line), fp))
-    {
-        tst = line;
-        if (tst.startsWith("sec"))
-        {
-            name = KgpgInterface::checkForUtf8(tst.section(':', 9, 9));
-            if (!name.isEmpty())
-            {
-                fp2 = popen("gpg --no-tty --with-colon --list-keys " + QFile::encodeName(tst.section(':',4,4)), "r");
-                while (fgets( line, sizeof(line), fp2))
-                {
-                    tst2 = line;
-                    if (tst2.startsWith("pub") && !trustedvals.contains(tst2.section(':',1,1)))
-                    {
-                        counter = true;
-                        wiz->CBdefault->addItem(tst.section(':', 4, 4).right(8) + ": " + name);
-                        if (firstKey.isEmpty())
-                            firstKey=tst.section(':',4,4).right(8)+": "+name;
-                        break;
-                    }
-                }
-                pclose(fp2);
-            }
+    KgpgInterface *interface = new KgpgInterface();
+    KgpgKeyList secretlist = interface->readSecretKeys();
+
+    QStringList issec;
+    int i;
+    for (i = 0; i < secretlist.size(); ++i)
+        issec << secretlist.at(i).fullId();
+
+    KgpgKeyList publiclist = interface->readPublicKeys(true, issec);
+    delete interface;
+
+    for (i = 0; i < publiclist.size(); ++i)
+        if (publiclist.at(i).trust() >= TRUST_FULL) {
+            KgpgKey k = publiclist.at(i);
+
+            QString s = k.fullId().right(8) + ": " + k.name() + " <" + k.email() + '>';
+
+            wiz->CBdefault->addItem(s);
+            if (firstKey.isEmpty())
+                firstKey = s;
         }
-    }
-    pclose(fp);
+
     wiz->CBdefault->setCurrentItem(firstKey);
 
     //connect(wiz->pushButton4,SIGNAL(clicked()),this,SLOT(slotGenKey()));
-    if (!counter)
+    if (!firstKey.isEmpty())
         connect(wiz->finishButton(),SIGNAL(clicked()),this,SLOT(slotGenKey()));
     else
     {
Comment 11 Rolf Eike Beer 2007-09-06 18:17:55 UTC
SVN commit 709135 by dakon:

Remove another instance of the unportable popen()

The newly introduced function can work with more than one signature at once. 
Currently this is not supported by the rest of the program but I don't see 
any benefit in introducing a new function with another limitation.

Deletion of multiple signatures at once will come when the feature freeze is 
lifted.

CCBUG:68470


 M  +30 -21    kgpginterface.cpp  
 M  +5 -0      kgpginterface.h  


--- trunk/KDE/kdeutils/kgpg/kgpginterface.cpp #709134:709135
@@ -2959,33 +2959,21 @@
 // delete signature
 void KgpgInterface::KgpgDelSignature(const QString &keyID, const QString &uid, QString signKeyID)
 {
-    message = signKeyID.remove(0, 2);
     deleteSuccess = false;
     step = 0;
 
-    FILE *fp;
     QString encResult;
-    char buffer[200];
     signb = 0;
     sigsearch = 0;
-    int curuid = 1;
-    int tgtuid = uid.toInt();
+    QList<int> signoff;
 
-    QString gpgcmd = "gpg --no-tty --no-secmem-warning --with-colon --list-sigs " + keyID;
-    fp = popen(QFile::encodeName(gpgcmd), "r");
-    while (fgets( buffer, sizeof(buffer), fp))
-    {
-        encResult = buffer;
-                if (encResult.startsWith("uid"))
-                        curuid++;
-                else if (encResult.startsWith("sig") && (curuid == tgtuid)) {
-                        if (encResult.contains(message))
-                                break;
-                        signb++;
-                } else if (encResult.startsWith("rev"))
-                        signb++;
-        }
-        pclose(fp);
+    findSigns(keyID, QStringList(signKeyID), uid, &signoff);
+
+    if (signoff.count() == 0)
+        return;
+
+    signb = signoff.at(0);
+
         K3ProcIO *conprocess = gpgProc(2, 0);
         *conprocess << "--edit-key" << keyID << "uid" << uid << "delsig";
         connect(conprocess,SIGNAL(readReady(K3ProcIO *)),this,SLOT(delsigprocess(K3ProcIO *)));
@@ -2993,7 +2981,6 @@
         conprocess->start(K3Process::NotifyOnExit,true);
 }
 
-
 void KgpgInterface::delsigprocess(K3ProcIO *p)//ess *p,char *buf, int buflen)
 {
 
@@ -3130,4 +3117,26 @@
 	return process;
 }
 
+void KgpgInterface::findSigns(const QString &keyID, const QStringList &ids, const QString &uid, QList<int> *res)
+{
+	K3ProcIO* listproc = gpgProc(1);
+	*listproc << "--with-colons" << "--list-sigs" << keyID;
+	listproc->start(K3Process::Block, false);
+
+	QString line;
+	int curuid = 1;
+	int signs = 0;
+	int tgtuid = uid.toInt();
+
+	while (listproc->readln(line, true) != -1) {
+		if (line.startsWith("sig:") && (tgtuid == curuid)) {
+			if (ids.contains(line.section(':', 4, 4), Qt::CaseInsensitive))
+				*res << signs;
+			signs++;
+		} else if (line.startsWith("uid:")) {
+			curuid++;
+		}
+	}
+}
+
 #include "kgpginterface.moc"
--- trunk/KDE/kdeutils/kgpg/kgpginterface.h #709134:709135
@@ -698,6 +698,11 @@
     void delsignover(K3Process *p);
 
     /**
+     * Finds the offset of the given signatures to a uid
+     */
+    void findSigns(const QString &keyID, const QStringList &ids, const QString &uid, QList<int> *res);
+
+    /**
      * Checks output of the import process
      */
     void importURLover(K3Process *p);
Comment 12 Rolf Eike Beer 2007-09-11 09:46:20 UTC
SVN commit 711028 by dakon:

Remove another instance of popen()

Again KgpgInterface already has was we need.

CCBUG:68470


 M  +16 -17    kgpg.cpp  


--- trunk/KDE/kdeutils/kgpg/kgpg.cpp #711027:711028
@@ -784,7 +784,7 @@
         if (publiclist.at(i).trust() >= TRUST_FULL) {
             KgpgKey k = publiclist.at(i);
 
-            QString s = k.fullId().right(8) + ": " + k.name() + " <" + k.email() + '>';
+            QString s = k.id() + ": " + k.name() + " <" + k.email() + '>';
 
             wiz->CBdefault->addItem(s);
             if (firstKey.isEmpty())
@@ -813,26 +813,25 @@
 
 void MyView::slotWizardChange()
 {
-    QString tst,name;
-    char line[300];
-    FILE *fp;
-
     if (wiz->indexOf(wiz->currentPage()) == 2)
     {
-        QString defaultID = KgpgInterface::getGpgSetting("default-key", wiz->kURLRequester1->url().path());
-        if (defaultID.isEmpty())
+        QString tst,name;
+        KgpgInterface *iface = new KgpgInterface();
+        QString defaultID = iface->getGpgSetting("default-key", wiz->kURLRequester1->url().path());
+
+        if (defaultID.isEmpty()) {
+            delete iface;
             return;
-        fp = popen("gpg --no-tty --with-colon --list-secret-keys " + QFile::encodeName(defaultID), "r");
-        while (fgets( line, sizeof(line), fp))
-        {
-            tst = line;
-            if (tst.startsWith("sec"))
-            {
-                name = KgpgInterface::checkForUtf8(tst.section(':', 9, 9));
-                wiz->CBdefault->setCurrentItem(tst.section(':', 4, 4).right(8) + ": " + name);
-            }
         }
-        pclose(fp);
+        KgpgKeyList secl = iface->readSecretKeys(QStringList(defaultID));
+        delete iface;
+
+        if (secl.isEmpty())
+            return;
+
+        KgpgKey k = secl.at(0);
+
+        wiz->CBdefault->setCurrentItem(k.id() + ": " + k.name() + " <" + k.email() + '>');
     }
 }
 
Comment 13 Rolf Eike Beer 2007-09-11 11:24:56 UTC
Seems to work. There is only one instance of popen() left, used for the seldom needed operation of public key regeneration. Once I find a better way this will also go away.