From: Jonathan McDowell Date: Mon, 31 May 2004 23:48:29 +0000 (+0000) Subject: cscvs to tla changeset 138 X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/commitdiff_plain/cfbbd6655346497ab28d50d2b5c34f0c5d9ce5ce cscvs to tla changeset 138 Author: noodles Date: 2004/05/31 14:16:49 Initial key cleaning routines; de-dupe key uids. --- diff --git a/Makefile b/Makefile index fee9fde..1991552 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # # Makefile for onak. # -# $Id: Makefile,v 1.21 2004/05/27 22:02:05 noodles Exp $ +# $Id: Makefile,v 1.22 2004/05/31 14:16:49 noodles Exp $ # CC = gcc @@ -19,10 +19,11 @@ PROGS = add lookup gpgwww onak splitkeys CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o keydb_$(DBTYPE).o \ keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha.o md5.o \ log.o photoid.o wordlist.o -OBJS = merge.o stats.o sendsync.o $(CORE_OBJS) +OBJS = merge.o stats.o sendsync.o cleankey.o $(CORE_OBJS) SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha.c main.c getcgi.c stats.c \ keyindex.c mem.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \ - gpgwww.c onak-conf.c charfuncs.c sendsync.c log.c photoid.c wordlist.c + gpgwww.c onak-conf.c charfuncs.c sendsync.c log.c photoid.c \ + wordlist.c cleankey.c all: .depend $(PROGS) testparse maxpath sixdegrees splitkeys @@ -41,14 +42,15 @@ sixdegrees: sixdegrees.o $(OBJS) gpgwww: gpgwww.o $(OBJS) $(LINK) -o gpgwww gpgwww.o $(OBJS) $(LIBS) -lookup: lookup.o $(CORE_OBJS) - $(LINK) -o lookup lookup.o $(CORE_OBJS) $(LIBS) +lookup: lookup.o cleankey.o merge.o $(CORE_OBJS) + $(LINK) -o lookup lookup.o cleankey.o merge.o $(CORE_OBJS) $(LIBS) -add: add.o merge.o sendsync.o $(CORE_OBJS) - $(LINK) -o add add.o merge.o sendsync.o $(CORE_OBJS) $(LIBS) +add: add.o cleankey.o merge.o sendsync.o $(CORE_OBJS) + $(LINK) -o add add.o cleankey.o merge.o sendsync.o $(CORE_OBJS) $(LIBS) -onak: onak.o merge.o $(CORE_OBJS) - $(LINK) $(LDFLAGS) -o onak onak.o merge.o $(CORE_OBJS) $(LIBS) +onak: onak.o merge.o cleankey.o $(CORE_OBJS) + $(LINK) $(LDFLAGS) -o onak onak.o merge.o cleankey.o $(CORE_OBJS) \ + $(LIBS) clean: rm -f $(PROGS) $(OBJS) Makefile.bak testparse maxpath *.core core \ diff --git a/add.c b/add.c index 32016b5..f15a145 100644 --- a/add.c +++ b/add.c @@ -5,7 +5,7 @@ * * Copyright 2002 Project Purple * - * $Id: add.c,v 1.14 2004/05/26 21:20:05 noodles Exp $ + * $Id: add.c,v 1.15 2004/05/31 14:16:49 noodles Exp $ */ #include @@ -14,6 +14,7 @@ #include #include "armor.h" +#include "cleankey.h" #include "charfuncs.h" #include "getcgi.h" #include "keydb.h" @@ -70,6 +71,11 @@ int main(int argc, char *argv[]) fclose(stdout); fclose(stderr); initdb(false); + + count = cleankeys(keys); + logthing(LOGTHING_INFO, "%d keys cleaned.", + count); + count = update_keys(&keys); printf("Got %d new keys.\n", count); logthing(LOGTHING_NOTICE, "Got %d new keys.", diff --git a/cleankey.c b/cleankey.c new file mode 100644 index 0000000..b236fa3 --- /dev/null +++ b/cleankey.c @@ -0,0 +1,86 @@ +/* + * cleankey.c - Routines to look for common key problems and clean them up. + * + * Jonathan McDowell + * + * Copyright 2004 Project Purple + * + * $Id: cleankey.c,v 1.1 2004/05/31 14:16:49 noodles Exp $ + */ + +#include +#include +#include +#include + +#include "cleankey.h" +#include "keystructs.h" +#include "mem.h" +#include "merge.h" +#include "log.h" + +/** + * dedupuids - Merge duplicate uids on a key. + * @key: The key to de-dup uids on. + * + * This function attempts to merge duplicate IDs on a key. It returns 0 + * if the key is unchanged, otherwise the number of dups merged. + */ +int dedupuids(struct openpgp_publickey *key) +{ + struct openpgp_signedpacket_list *curuid = NULL; + struct openpgp_signedpacket_list *dup = NULL; + struct openpgp_signedpacket_list *tmp = NULL; + int merged = 0; + + assert(key != NULL); + curuid = key->uids; + while (curuid != NULL) { + dup = find_signed_packet(curuid->next, curuid->packet); + while (dup != NULL) { + logthing(LOGTHING_INFO, "Found duplicate uid: %.*s", + curuid->packet->length, + curuid->packet->data); + merged++; + merge_packet_sigs(curuid, dup); + /* + * Remove the duplicate uid. + */ + tmp = curuid; + while (tmp != NULL && tmp->next != dup) { + tmp = tmp->next; + } + assert(tmp != NULL); + tmp->next = dup->next; + dup->next = NULL; + free_signedpacket_list(dup); + + dup = find_signed_packet(curuid->next, curuid->packet); + } + curuid = curuid->next; + } + + return merged; +} + +/** + * cleankeys - Apply all available cleaning options on a list of keys. + * @keys: The list of keys to clean. + * + * Applies all the cleaning options we can (eg duplicate key ids) to a + * list of keys. Returns 0 if no changes were made, otherwise the number + * of keys cleaned. + */ +int cleankeys(struct openpgp_publickey *keys) +{ + int changed = 0; + + while (keys != NULL) { + if (dedupuids(keys) > 0) { + changed++; + } + keys = keys->next; + } + + return changed; +} diff --git a/cleankey.h b/cleankey.h new file mode 100644 index 0000000..2b9d8ec --- /dev/null +++ b/cleankey.h @@ -0,0 +1,26 @@ +/* + * cleankey.h - Routines to look for common key problems and clean them up. + * + * Jonathan McDowell + * + * Copyright 2004 Project Purple + * + * $Id: cleankey.h,v 1.1 2004/05/31 14:16:49 noodles Exp $ + */ + +#ifndef __CLEANKEY_H__ +#define __CLEANKEY_H__ + +#include "keystructs.h" + +/** + * cleankeys - Apply all available cleaning options on a list of keys. + * @publickey: The list of keys to clean. + * + * Applies all the cleaning options we can (eg duplicate key ids) to a + * list of keys. Returns 0 if no changes were made, otherwise the number + * of keys cleaned. + */ +int cleankeys(struct openpgp_publickey *keys); + +#endif diff --git a/lookup.c b/lookup.c index 123ec5f..5042600 100644 --- a/lookup.c +++ b/lookup.c @@ -5,7 +5,7 @@ * * Copyright 2002 Project Purple * - * $Id: lookup.c,v 1.16 2004/05/27 21:58:18 noodles Exp $ + * $Id: lookup.c,v 1.17 2004/05/31 14:16:49 noodles Exp $ */ #include @@ -17,6 +17,7 @@ #include "armor.h" #include "charfuncs.h" +#include "cleankey.h" #include "getcgi.h" #include "keydb.h" #include "keyindex.h" @@ -164,6 +165,7 @@ int main(int argc, char *argv[]) keyid); if (fetch_key(keyid, &publickey, false)) { puts("
");
+				cleankeys(publickey);
 				flatten_publickey(publickey,
 							&packets,
 							&list_end);
diff --git a/merge.h b/merge.h
index 3ec64f3..da8534f 100644
--- a/merge.h
+++ b/merge.h
@@ -5,7 +5,7 @@
  *
  * Copyright 2002 Project Purple
  *
- * $Id: merge.h,v 1.5 2003/06/04 20:57:11 noodles Exp $
+ * $Id: merge.h,v 1.6 2004/05/31 14:16:49 noodles Exp $
  */
 
 #ifndef __MERGE_H__
@@ -39,4 +39,29 @@ int merge_keys(struct openpgp_publickey *a, struct openpgp_publickey *b);
  */
 int update_keys(struct openpgp_publickey **keys);
 
+/**
+ *	get_signed_packet - Gets a signed packet from a list.
+ *	@packet_list: The list of packets to look in.
+ *	@packet: The packet to look for.
+ *
+ *	Walks through the signedpacket_list looking for the supplied packet and
+ *	returns it if found. Otherwise returns NULL.
+ */
+struct openpgp_signedpacket_list *find_signed_packet(
+		struct openpgp_signedpacket_list *packet_list,
+		struct openpgp_packet *packet);
+
+/**
+ *	merge_packet_sigs - Takes 2 signed packets and merges their sigs.
+ *	@old: The old signed packet.
+ *	@new: The new signed packet.
+ *
+ *	Takes 2 signed packet list structures and the sigs of the packets on
+ *	the head of these structures. These packets must both be the same and
+ *	the fully merged structure is returned in old and the minimal
+ *	difference to get from old to new in new.
+ */
+int merge_packet_sigs(struct openpgp_signedpacket_list *old,
+			struct openpgp_signedpacket_list *new);
+
 #endif
diff --git a/onak.c b/onak.c
index 2a0376e..15154c4 100644
--- a/onak.c
+++ b/onak.c
@@ -7,7 +7,7 @@
  * 
  * Copyright 2002 Project Purple
  *
- * $Id: onak.c,v 1.21 2004/05/27 21:58:18 noodles Exp $
+ * $Id: onak.c,v 1.22 2004/05/31 14:16:49 noodles Exp $
  */
 
 #include 
@@ -17,6 +17,7 @@
 
 #include "armor.h"
 #include "charfuncs.h"
+#include "cleankey.h"
 #include "keydb.h"
 #include "keyid.h"
 #include "keyindex.h"
@@ -57,14 +58,19 @@ void usage(void) {
 	puts("Usage:\n");
 	puts("\tonak [options]  \n");
 	puts("\tCommands:\n");
-	puts("\tadd    - read armored OpenPGP keys from stdin and add to the"
+	puts("\tadd      - read armored OpenPGP keys from stdin and add to the"
 		" keyserver");
-	puts("\tdelete - delete a given key from the keyserver");
-	puts("\tdump   - dump all the keys from the keyserver to a file or"
-		" files\n\t         starting keydump*");
-	puts("\tget    - retrieves the key requested from the keyserver");
-	puts("\tindex  - search for a key and list it");
-	puts("\tvindex - search for a key and list it and its signatures");
+	puts("\tclean    - read armored OpenPGP keys from stdin, run the "
+		" cleaning\n\t       	   routines against them and dump to"
+		" stdout");
+	puts("\tdelete   - delete a given key from the keyserver");
+	puts("\tdump     - dump all the keys from the keyserver to a file or"
+		" files\n\t           starting keydump*");
+	puts("\tget      - retrieves the key requested from the keyserver");
+	puts("\tgetphoto - retrieves the first photoid on the given key and"
+		" dumps to\n\t           stdout");
+	puts("\tindex    - search for a key and list it");
+	puts("\tvindex   - search for a key and list it and its signatures");
 }
 
 int main(int argc, char *argv[])
@@ -131,6 +137,10 @@ int main(int argc, char *argv[])
 			logthing(LOGTHING_INFO, "Finished reading %d keys.",
 					result);
 
+			result = cleankeys(keys);
+			logthing(LOGTHING_INFO, "%d keys cleaned.",
+					result);
+
 			initdb(false);
 			logthing(LOGTHING_NOTICE, "Got %d new keys.",
 					update_keys(&keys));
@@ -138,9 +148,15 @@ int main(int argc, char *argv[])
 				flatten_publickey(keys,
 					&packets,
 					&list_end);
-				armor_openpgp_stream(stdout_putchar,
-					NULL,
-					packets);
+				if (binary) {
+					write_openpgp_stream(stdout_putchar,
+							NULL,
+						 	packets);
+				} else {
+					armor_openpgp_stream(stdout_putchar,
+						NULL,
+						packets);
+				}
 				free_packet_list(packets);
 				packets = NULL;
 			}
@@ -157,6 +173,53 @@ int main(int argc, char *argv[])
 			rc = 1;
 			logthing(LOGTHING_NOTICE, "No changes.");
 		}
+	} else if (!strcmp("clean", argv[optind])) {
+		if (binary) {
+			result = read_openpgp_stream(stdin_getchar, NULL,
+				 &packets, 0);
+			logthing(LOGTHING_INFO,
+					"read_openpgp_stream: %d", result);
+		} else {
+			dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
+		}
+
+		if (packets != NULL) {
+			result = parse_keys(packets, &keys);
+			free_packet_list(packets);
+			packets = NULL;
+			logthing(LOGTHING_INFO, "Finished reading %d keys.",
+					result);
+
+			if (keys != NULL) {
+				result = cleankeys(keys);
+				logthing(LOGTHING_INFO, "%d keys cleaned.",
+						result);
+
+				flatten_publickey(keys,
+					&packets,
+					&list_end);
+
+				if (binary) {
+					write_openpgp_stream(stdout_putchar,
+							NULL,
+						 	packets);
+				} else {
+					armor_openpgp_stream(stdout_putchar,
+						NULL,
+						packets);
+				}
+				free_packet_list(packets);
+				packets = NULL;
+			}
+		} else {
+			rc = 1;
+			logthing(LOGTHING_NOTICE, "No keys read.");
+		}
+		
+		if (keys != NULL) {
+			free_publickey(keys);
+			keys = NULL;
+		}
 	} else if ((argc - optind) == 2) {
 		search = argv[optind+1];
 		if (search != NULL) {