From 556f51f104fbbb5bd0d51b61a18d7e5af2759079 Mon Sep 17 00:00:00 2001
From: Jonathan McDowell <noodles@earth.li>
Date: Mon, 31 May 2004 23:47:10 +0000
Subject: [PATCH] cscvs to tla changeset 32 Author: noodles Date: 2002/11/13
 19:41:39 Bidirectional syncing support for both mail and HKP received keys.

---
 Makefile     |  9 +++---
 add.c        |  9 +++++-
 merge.c      |  8 ++++--
 onak-mail.pl | 58 ++++++++++++++++++++++++++++++++++----
 onak.c       | 18 +++++++++++-
 sendsync.c   | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 sendsync.h   | 22 +++++++++++++++
 7 files changed, 189 insertions(+), 13 deletions(-)
 create mode 100644 sendsync.c
 create mode 100644 sendsync.h

diff --git a/Makefile b/Makefile
index 2d6cfee..f48b710 100644
--- a/Makefile
+++ b/Makefile
@@ -11,10 +11,11 @@ LIBS = -L/usr/local/lib -ldb3
 
 PROGS = add lookup gpgwww onak
 OBJS = armor.o parsekey.o keydb_$(DBTYPE).o merge.o keyid.o md5.o sha.o \
-	getcgi.o keyindex.o mem.o stats.o ll.o hash.o onak-conf.o charfuncs.o
+	getcgi.o keyindex.o mem.o stats.o ll.o hash.o onak-conf.o charfuncs.o \
+	sendsync.o
 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
+	gpgwww.c onak-conf.c charfuncs.c sendsync.c
 
 all: $(PROGS) testparse maxpath
 
@@ -34,10 +35,10 @@ lookup: lookup.o getcgi.o keyindex.o keydb_$(DBTYPE).o keyid.o sha.o \
 		charfuncs.o $(LIBS)
 
 add: add.o getcgi.o armor.o parsekey.o keydb_$(DBTYPE).o keyid.o sha.o mem.o \
-		keyindex.o ll.o hash.o merge.o onak-conf.o charfuncs.o
+	keyindex.o ll.o hash.o merge.o onak-conf.o charfuncs.o sendsync.o
 	$(CC) -o add add.o getcgi.o armor.o parsekey.o keydb_$(DBTYPE).o \
 		keyid.o sha.o mem.o keyindex.o ll.o hash.o merge.o onak-conf.o \
-		charfuncs.o $(LIBS)
+		charfuncs.o sendsync.o $(LIBS)
 
 onak: onak.o merge.o keyid.o sha.o armor.o parsekey.o ll.o charfuncs.o \
 		keydb_$(DBTYPE).o mem.o keyindex.o hash.o getcgi.o onak-conf.o
diff --git a/add.c b/add.c
index bb12e05..f65203c 100644
--- a/add.c
+++ b/add.c
@@ -16,9 +16,11 @@
 #include "getcgi.h"
 #include "keydb.h"
 #include "keystructs.h"
+#include "mem.h"
+#include "merge.h"
 #include "onak-conf.h"
 #include "parsekey.h"
-#include "merge.h"
+#include "sendsync.h"
 
 int main(int argc, char *argv[])
 {
@@ -60,6 +62,11 @@ int main(int argc, char *argv[])
 			initdb();
 			printf("Got %d new keys.\n",
 					update_keys(&keys, false));
+			if (keys != NULL) {
+				sendkeysync(keys);
+				free_publickey(keys);
+				keys = NULL;
+			}
 			cleanupdb();
 		} else {
 			puts("No OpenPGP packets found in input.");
diff --git a/merge.c b/merge.c
index 6954337..cfe2d97 100644
--- a/merge.c
+++ b/merge.c
@@ -395,11 +395,14 @@ int update_keys(struct openpgp_publickey **keys, bool verbose)
 				} else {
 					prev->next = curkey->next;
 					prev = curkey->next;
+					curkey->next = NULL;
+					free_publickey(curkey);
 				}
 			} else {
 				prev = curkey;
 				if (verbose) {
-					fprintf(stderr, "Merged key; storing updated key.\n");
+					fprintf(stderr,
+					"Merged key; storing updated key.\n");
 				}
 				store_key(oldkey, intrans, true);
 			}
@@ -407,7 +410,8 @@ int update_keys(struct openpgp_publickey **keys, bool verbose)
 			oldkey = NULL;
 		} else {
 			if (verbose) {
-				fprintf(stderr, "Storing completely new key.\n");
+				fprintf(stderr,
+					"Storing completely new key.\n");
 			}
 			store_key(curkey, intrans, false);
 			newkeys++;
diff --git a/onak-mail.pl b/onak-mail.pl
index 0e3c2b5..46763f3 100755
--- a/onak-mail.pl
+++ b/onak-mail.pl
@@ -55,7 +55,7 @@ sub submitupdate {
 	my (@errors, @mergedata);
 
 	open3(\*MERGEIN, \*MERGEOUT, \*MERGEERR,
-		"/home/noodles/onak-0.0.3/onak", "add");
+		"/home/noodles/onak-0.0.3/onak", "-u", "add");
 
 	print MERGEIN @data;
 	close MERGEIN;
@@ -63,13 +63,13 @@ sub submitupdate {
 	@mergedata = <MERGEOUT>;
 
 	open (LOG, ">>/home/noodles/onak-0.0.3/keyadd.log");
-	print LOG @errors;
+	print LOG "[".localtime(time)."] ", @errors;
 	close LOG;
 
 	return @mergedata;
 }
 
-my ($inheader, %syncsites, $subject, $from, $replyto, @body, @syncmail);
+my ($inheader, %seenby, $subject, $from, $replyto, @body, @syncmail);
 
 $inheader = 1;
 $subject = "";
@@ -80,7 +80,7 @@ while (<>) {
 		if (/^Subject:\s*(.*)\s*$/i) {
 			$subject = $1;
 		} elsif (/^X-KeyServer-Sent:\s*(.*)\s*$/i) {
-			$syncsites{$1} = 1;
+			$seenby{$1} = 1;
 		} elsif (/^From:\s*(.*)\s*$/i) {
 			$from = $1;
 		} elsif (/^Reply-To:\s*(.*)\s*$/i) {
@@ -98,5 +98,53 @@ while (<>) {
 # LAST <days>
 
 if ($subject =~ /^INCREMENTAL$/i) {
-	submitupdate(@body);
+	my $site;
+	my $count;
+	my $i;
+	my @newupdate = submitupdate(@body);
+
+	$count = 0;
+	foreach $i (@{$config{'syncsites'}}) {
+		if (! defined($seenby{$i})) {
+			$count++;
+		}
+	}
+
+	open (LOG, ">>/home/noodles/logs/keyadd.log");
+	print LOG "[".localtime(time)."] Syncing with $count sites.\n";
+	close LOG;
+
+	if ($newupdate[0] eq '') {
+		open (LOG, ">>/home/noodles/logs/keyadd.log");
+		print LOG "[".localtime(time)."] Nothing to sync.\n";
+		close LOG;
+		$count = 0;
+	}
+
+	if ($count > 0) {
+		open(MAIL, "|$config{mta}");
+		print MAIL "From: $config{adminemail}\n";
+		print MAIL "To: ";
+		foreach $i (@{$config{'syncsites'}}) {
+			if (! defined($seenby{$i})) {
+				print MAIL "$i";
+				$count--;
+				if ($count > 0) {
+					print MAIL ", ";
+				}
+			}
+		}
+		print MAIL "\n";
+		print MAIL "Subject: incremental\n";
+		foreach $site (keys %seenby) {
+			print MAIL "X-KeyServer-Sent: $site\n";
+		}
+		print MAIL "X-KeyServer-Sent: $config{thissite}\n";
+		print MAIL "Precedence: list\n";
+		print MAIL "MIME-Version: 1.0\n";
+		print MAIL "Content-Type: application/pgp-keys\n";
+		print MAIL "\n";
+		print @newupdate;
+		close MAIL;
+	}
 }
diff --git a/onak.c b/onak.c
index 8eccc9c..7a50d7a 100644
--- a/onak.c
+++ b/onak.c
@@ -92,15 +92,19 @@ int main(int argc, char *argv[])
 	uint64_t			 keyid = 0;
 	bool				 ishex = false;
 	bool				 verbose = false;
+	bool				 update = false;
 	bool				 binary = false;
 	int				 optchar;
 
 
-	while ((optchar = getopt(argc, argv, "bv")) != -1 ) {
+	while ((optchar = getopt(argc, argv, "buv")) != -1 ) {
 		switch (optchar) {
 		case 'b': 
 			binary = true;
 			break;
+		case 'u': 
+			update = true;
+			break;
 		case 'v': 
 			verbose = true;
 			break;
@@ -128,6 +132,16 @@ int main(int argc, char *argv[])
 			initdb();
 			fprintf(stderr, "Got %d new keys.\n",
 					update_keys(&keys, verbose));
+			if (keys != NULL && update) {
+				flatten_publickey(keys,
+					&packets,
+					&list_end);
+				armor_openpgp_stream(stdout_putchar,
+					NULL,
+					packets);
+				free_packet_list(packets);
+				packets = NULL;
+			}
 			cleanupdb();
 		} else {
 			rc = 1;
@@ -169,6 +183,8 @@ int main(int argc, char *argv[])
 				armor_openpgp_stream(stdout_putchar,
 						NULL,
 						packets);
+				free_packet_list(packets);
+				packets = NULL;
 			} else {
 				puts("Key not found");
 			}
diff --git a/sendsync.c b/sendsync.c
new file mode 100644
index 0000000..6afec8b
--- /dev/null
+++ b/sendsync.c
@@ -0,0 +1,78 @@
+/*
+ * sendsync.c - Routines to send a key sync mail.
+ *
+ * Jonathan McDowell <noodles@earth.li>
+ *
+ * Copyright 1999, 2002 Project Purple
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "armor.h"
+#include "keystructs.h"
+#include "ll.h"
+#include "mem.h"
+#include "onak-conf.h"
+#include "parsekey.h"
+#include "sendsync.h"
+
+int fd_putchar(void *ctx, size_t count, unsigned char *c)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		fputc(c[i], ctx);
+	}
+	return 0;
+}
+
+/**
+ *	sendkeysync - Send a key sync mail to our peers.
+ *	keys: The list of keys to send.
+ *
+ *	Takes a list of keys and sends out a keysync mail to all our peers.
+ */
+int sendkeysync(struct openpgp_publickey *keys)
+{
+	FILE                       *fd = NULL;
+	struct ll                  *cursite = NULL;
+	struct openpgp_packet_list *packets = NULL;
+	struct openpgp_packet_list *list_end = NULL;
+
+	if (config.syncsites != NULL &&
+			(fd=popen("sendmail -t", "w")) != NULL) {
+		fprintf(fd, "From: %s\n", config.adminemail);
+
+		fprintf(fd, "To: ");
+		for (cursite = config.syncsites; cursite != NULL;
+				cursite = cursite->next) {
+			fprintf(fd, "%s", (char *) cursite->object);
+			if (cursite->next != NULL) {
+				fprintf(fd, ", ");
+			}
+		}
+		fprintf(fd, "\n");
+
+		fprintf(fd, "Subject: incremental\n");
+		fprintf(fd, "X-Keyserver-Sent: %s\n", config.thissite);
+		fprintf(fd, "Precedence: list\n");
+		fprintf(fd, "MIME-Version: 1.0\n");
+		fprintf(fd, "Content-Type: application/pgp-keys\n\n");
+
+		flatten_publickey(keys,
+				&packets,
+				&list_end);
+		armor_openpgp_stream(fd_putchar,
+				fd,
+				packets);
+		free_packet_list(packets);
+		packets = NULL;
+
+		pclose(fd);
+	} else return 0;
+
+	return 1;
+}
diff --git a/sendsync.h b/sendsync.h
new file mode 100644
index 0000000..dca5f9b
--- /dev/null
+++ b/sendsync.h
@@ -0,0 +1,22 @@
+/*
+ * sendsync.c - Routines to send a key sync mail.
+ *
+ * Jonathan McDowell <noodles@earth.li>
+ *
+ * Copyright 1999, 2002 Project Purple
+*/
+
+#ifndef __SENDSYNC_H_
+#define __SENDSYNC_H_
+
+#include "keystructs.h"
+
+/**
+ *	sendkeysync - Send a key sync mail to our peers.
+ *	keys: The list of keys to send.
+ *
+ *	Takes a list of keys and sends out a keysync mail to all our peers.
+ */
+int sendkeysync(struct openpgp_publickey *keys);
+
+#endif /* __SENDSYNC_H */
-- 
2.39.5