Code for 'clean total'

Dirk Traulsen dirk.traulsen at lypso.de
Mon Oct 31 00:56:54 CET 2005


Hi David!

I'm the one who started the thread "Feature request: expand 'clean' 
to 'clean total'" at gnupg-users. Unfortunately you didn't comment on 
the issue, in spite being the one who wrote the clean options.
If you didn't see it, here is the main point again:

----snip----
> So here is my feature request: Please make an option to delete
> signatures, for which there is no corresponding signing key on
> the local keyring.
----snip----

As you can see in the thread, there are, me aside, other people who 
would appreciate a function 'clean total'.

Ok, what's the standard, if a users wants a feature and the 
developers don't react?
Right, it's show me the code...

So for me there were today a lot of first times:
Learning the basics of C, fetching source code from a version control 
system, trying to find my way through the jungle of files, trying to 
implement the wanted function and make diffs to trunk to send it to 
you.

I can tell you, this was a hard day! But very interesting, too!

I think, what I did could be the basis for the implementation of 
'clean total'. I really tried to understand how you implemented 
'clean' and now I hope that I got it right. As I'm an extreme 
beginner with C (until today only did scripts and naturally some 
BASIC at school a good time ago), I'm not in any way sure, that the 
code is correct or complete (or 'beautiful' :) ). 

My hope is, that you could take it and make something good from it.
As it is the first time for me, I was not sure, what is the correct 
way to send you the diffs. I decided to put them in here.

I'm really excited what you will say to this.
Dirk


Comments and diffs
===============

I fetched the relevant GnuPG trunk revision 3918 files as text: 
<filename>-<revisionnumber>.txt   and named my versions
<filename>-<revisionnumber>-Dirk.txt.
The diffs are called
diff_<filename>-<revisionnumber>.txt.

When I am correct, then the main function acting as 'clean sigs' is 
clean_sigs_from_uid() in trustdb.c, which is declared in trustdb.h.
Until now, mark_usable_uid_certs() would classify the signatures 
without a signing key with flag 12 and clean_sigs_from_uid() would 
keep them. This function is called directly and indirectly from 
keyedit.c, export.c and import.c.
My idea was to add a 'clean total' to the existing 'clean sigs' and 
'clean uids', which would do both like 'clean' alone, but 
additionally sort out the signatures with flag 12 from 
mark_usable_uid_certs().
Every time the 'clean' function is called, I made a test for 'clean 
total'. Mostly it is just an addition to 'clean sigs' everywhere 
necessary. To do this, I added a new variable clean-total and new 
(what is it called?) IMPORT_CLEAN_TOTAL and EXPORT_CLEAN_TOTAL to 
options.h and import.c and export.c. Is it correct, that this are 
'variables', where flags are set? I hope so or there is nonsense in 
import.c and export.c!
I do not know where is the best place to declare a normal integer 
variable like clean-total, which is used by several files. I decided 
to put it in trustdb.h, as every file included it. (If it is only 
declared, but gets no definitive value in the trustdb.h, do I need to 
set it to 0 in every file xxx.c, which uses the variable? I chose to 
set it to zero before and after using it.)
In export.c and import.c I changed texts, which seem to be send to 
the user. I don't know if I should have compensated for the changes 
at other places.
I also edited the man-page file and chose gpg.sgml, because I thought 
this to be the mother of all formats.

If you have some time could you please tell me what you think of my 
work. It may be really miserable, but I hope it convinces you to 
implement the function correctly.

Ok, here is the code:

##########################
--- options.h-3909.txt	2005-10-30 22:05:49.000000000 +0100
+++ options.h-3909-Dirk.txt	2005-10-30 22:05:49.000000000 +0100
@@ -267,6 +267,7 @@ struct {
 #define IMPORT_MERGE_ONLY                (1<<4)
 #define IMPORT_CLEAN_SIGS                (1<<5)
 #define IMPORT_CLEAN_UIDS                (1<<6)
+#define IMPORT_CLEAN_TOTAL               (1<<7)
 
 #define EXPORT_LOCAL_SIGS                (1<<0)
 #define EXPORT_ATTRIBUTES                (1<<1)
@@ -275,6 +276,7 @@ struct {
 #define EXPORT_CLEAN_SIGS                (1<<4)
 #define EXPORT_CLEAN_UIDS                (1<<5)
 #define EXPORT_RESET_SUBKEY_PASSWD       (1<<6)
+#define EXPORT_CLEAN_TOTAL               (1<<7)
 
 #define LIST_SHOW_PHOTOS                 (1<<0)
 #define LIST_SHOW_POLICY_URLS            (1<<1)
##########################

##########################
--- trustdb.h-3775.txt	2005-10-30 21:37:13.000000000 +0100
+++ trustdb.h-3775-Dirk.txt	2005-10-30 21:37:13.000000000 +0100
@@ -84,6 +84,7 @@ int clear_ownertrusts (PKT_public_key *p
 
 int clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy);
 int clean_uids_from_key(KBNODE keyblock,int noisy);
+int clean-total;
 
 /*-- tdbdump.c --*/
 void list_trustdb(const char *username);
##########################

##########################
--- trustdb.c-3841.txt	2005-10-30 21:37:13.000000000 +0100
+++ trustdb.c-3841-Dirk.txt	2005-10-30 21:37:12.000000000 +0100
@@ -1615,8 +1615,16 @@ clean_sigs_from_uid(KBNODE keyblock,KBNO
       if(node->flag & (1<<11))
 	continue;
 
-      /* ... and sigs from unavailable keys. */
-      if(node->flag & (1<<12))
+      /* ... but delete sigs from unavailable keys, 
+         if option 'clean-total' is set. */
+      if((node->flag & (1<<12)) && clean-total)
+      {if(noisy)
+	log_info("removing signature from %s on uid \"%s\": %s\n",
+		 keystr(node->pkt->pkt.signature->keyid),
+		 uidnode->pkt->pkt.user_id->name,"Key unavailable");
+       }
+      delete_kbnode(node);
+      deleted++;
 	continue;
 
       /* Everything else we delete */
##########################

##########################
--- import.c-3892.txt	2005-10-30 21:37:10.000000000 +0100
+++ import.c-3892-Dirk.txt	2005-10-30 21:37:10.000000000 +0100
@@ -102,11 +102,17 @@ parse_import_options(char *str,unsigned 
       {"merge-only",IMPORT_MERGE_ONLY,NULL,
        N_("only accept updates to existing keys")},
       {"import-clean-sigs",IMPORT_CLEAN_SIGS,NULL,
-       N_("remove unusable signatures after import")},
+       N_("remove only superceded or broken signatures after 
import")},
       {"import-clean-uids",IMPORT_CLEAN_UIDS,NULL,
        N_("remove unusable user IDs after import")},
       {"import-clean",IMPORT_CLEAN_SIGS|IMPORT_CLEAN_UIDS,NULL,
-       N_("all import-clean-* options from above")},
+       N_("combines import-clean-uid and import-clean-sigs")},
+
+   /*The following line should set IMPORT_CLEAN_SIGS and 
IMPORT_CLEAN_UIDS too.
+     Does it function like this?*/
+
+      {"import-clean-
total",IMPORT_CLEAN_TOTAL|IMPORT_CLEAN_SIGS|IMPORT_CLEAN_UIDS,NULL,
+       N_("remove unusable signatures and UIDs after import")},
       /* Aliases for backward compatibility */
       {"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL},
       {"repair-hkp-subkey-
bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL},
@@ -672,10 +678,15 @@ clean_sigs_from_all_uids(KBNODE keyblock
   KBNODE uidnode;
   int deleted=0;
 
+  if(options&IMPORT_CLEAN_TOTAL)
+    clean-total = 1;
+  else clean-total = 0; 
+
   for(uidnode=keyblock->next;uidnode;uidnode=uidnode->next)
     if(uidnode->pkt->pkttype==PKT_USER_ID)
       deleted+=clean_sigs_from_uid(keyblock,uidnode,opt.verbose);
 
+  clean-total = 0;
   return deleted;
 }
 
##########################

##########################
--- export.c-3912.txt	2005-10-30 21:37:09.000000000 +0100
+++ export.c-3912-Dirk.txt	2005-10-30 21:37:08.000000000 +0100
@@ -65,11 +65,17 @@ parse_export_options(char *str,unsigned 
       {"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
        N_("export revocation keys that are marked as 
\"sensitive\"")},
       {"export-clean-sigs",EXPORT_CLEAN_SIGS,NULL,
-       N_("remove unusable signatures during export")},
+       N_("remove only superceded and broken signatures during 
export")},
       {"export-clean-uids",EXPORT_CLEAN_UIDS,NULL,
        N_("remove unusable user IDs during export")},
       {"export-clean",EXPORT_CLEAN_SIGS|EXPORT_CLEAN_UIDS,NULL,
-       N_("all export-clean-* options from above")},
+       N_("combines export-clean-uid and export-clean-sigs")},
+
+   /*The following line should set EXPORT_CLEAN_SIGS and 
EXPORT_CLEAN_UIDS too.
+     Does it function like this?*/
+
+      {"export-clean-
total",EXPORT_CLEAN_TOTAL|EXPORT_CLEAN_SIGS|EXPORT_CLEAN_UIDS,NULL,
+       N_("remove unusable signatures and UIDs during export")},
       {"export-minimal",
        EXPORT_MINIMAL|EXPORT_CLEAN_SIGS|EXPORT_CLEAN_UIDS,NULL,
        N_("export the smallest key possible")},
@@ -466,8 +472,15 @@ do_export_stream( IOBUF out, STRLIST use
 		/* Run clean_sigs_from_uid against each uid if
 		   export-clean-sigs is on. */
 		if(options&EXPORT_CLEAN_SIGS)
-		  clean_sigs_from_uid(keyblock,node,opt.verbose);
+		  {
+            if(options&EXPORT_CLEAN_TOTAL)
+              clean-total = 1;
+            else clean-total = 0;
+
+            clean_sigs_from_uid(keyblock,node,opt.verbose);
+            clean-total = 0;
 	      }
+          }
 	    else if(node->pkt->pkttype==PKT_SIGNATURE)
 	      {
 		/* If we have export-minimal turned on, do not include
##########################

##########################
--- keyedit.c-3917.txt	2005-10-30 22:38:54.000000000 +0100
+++ keyedit.c-3917-Dirk.txt	2005-10-30 23:14:32.000000000 +0100
@@ -2176,7 +2176,13 @@ keyedit_menu( const char *username, STRL
 	    {
 	      if(*arg_string)
 		{
-		  if(ascii_strcasecmp(arg_string,"sigs")==0
+		  if(ascii_strcasecmp(arg_string,"total")==0
+           int clean-total = 1;
+           modified=menu_clean_sigs_from_uids(keyblock);
+		   clean-total = 0;
+           modified+=menu_clean_uids_from_key(keyblock);
+		   redisplay=modified;
+          else if(ascii_strcasecmp(arg_string,"sigs")==0
 		     || ascii_strcasecmp(arg_string,"signatures")==0
 		     || ascii_strcasecmp(arg_string,"certs")==0
 		     || ascii_strcasecmp(arg_string,"certificates")==0)
##########################

##########################
--- gpg.sgml-3918.txt	2005-10-30 21:56:38.000000000 +0100
+++ gpg.sgml-3918-Dirk.txt	2005-10-30 21:56:38.000000000 +0100
@@ -547,10 +547,10 @@ keep keys neat and clean, and it has no 
 <varlistentry>
 <term>sigs</term>
 <listitem><para>
-Remove any signatures that are not usable by the trust calculations.
-For example, this removes any signature that does not validate.  It
-also removes any signature that is superceded by a later signature, 
or
-signatures that were revoked.
+Remove signatures that are not usable by the trust calculations, but 
keep
+signatures which could not be verified because the signing key is 
missing.
+It removes any signature that is superceded by a later signature, 
broken
+or revoked.
 </para></listitem></varlistentry>
 
 <varlistentry>
@@ -560,9 +560,18 @@ Compact (by removing all signatures exce
 that is no longer usable (e.g. revoked, or expired).
 </para></listitem></varlistentry>
 
+<varlistentry>
+<term>total</term>
+<listitem><para>
+Remove like above any  unusable signature
+and UID,  but  also  remove any signature
+for which the signing key is not present.
+
 </variablelist>
 
-If invoked with no arguments, both `sigs' and `uids' are cleaned.
+If  invoked  with  no  arguments,  both `sigs' and `uids' are
+cleaned, but only signatures for which the signing key is 
+present can be evaluted.
 </para></listitem></varlistentry>
 
 <varlistentry>
##########################




More information about the Gnupg-devel mailing list