From a0d1c99184eeb07a6a7711e168c3db4b8c0937eb Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Tue, 9 Apr 2019 19:53:54 +0100 Subject: [PATCH] Use a set of policy flags to indicate what key cleaning to perform To decouple cleankeys.c from the keyserver config, and prepare for an extension of the policies available, use a set of flags to indicate what key cleaning to perform. --- add.c | 2 +- cleankey.c | 29 ++++++++++++++++++----------- cleankey.h | 14 ++++++++++---- keydb_stacked.c | 2 +- lookup.c | 2 +- onak-conf.c | 26 ++++++++++++++++++++------ onak-conf.h | 5 +++-- onak.c | 7 ++++--- stripkey.c | 2 +- 9 files changed, 59 insertions(+), 30 deletions(-) diff --git a/add.c b/add.c index 48dccf0..c3a54a7 100644 --- a/add.c +++ b/add.c @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) catchsignals(); dbctx = config.dbinit(config.backend, false); - count = cleankeys(keys); + count = cleankeys(&keys, config.clean_policies); logthing(LOGTHING_INFO, "%d keys cleaned.", count); diff --git a/cleankey.c b/cleankey.c index afe5a06..3ef76f9 100644 --- a/cleankey.c +++ b/cleankey.c @@ -181,26 +181,33 @@ int clean_key_sighashes(struct openpgp_publickey *key) /** * cleankeys - Apply all available cleaning options on a list of keys. - * @keys: The list of keys to clean. + * @policies: The cleaning policies to apply. * - * 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. + * Applies the requested cleaning policies to a list of keys. These are + * specified from the ONAK_CLEAN_* set of flags, or ONAK_CLEAN_ALL to + * apply all available cleaning options. Returns 0 if no changes were + * made, otherwise the number of keys cleaned. Note that some options + * may result in keys being removed entirely from the list. */ -int cleankeys(struct openpgp_publickey *keys) +int cleankeys(struct openpgp_publickey **keys, uint64_t policies) { + struct openpgp_publickey *curkey; int changed = 0, count; - while (keys != NULL) { - count = dedupuids(keys); - count += dedupsubkeys(keys); - if (config.check_sighash) { - count += clean_key_sighashes(keys); + if (keys == NULL) + return 0; + + curkey = *keys; + while (curkey != NULL) { + count = dedupuids(curkey); + count += dedupsubkeys(curkey); + if (policies & ONAK_CLEAN_CHECK_SIGHASH) { + count += clean_key_sighashes(curkey); } if (count > 0) { changed++; } - keys = keys->next; + curkey = curkey->next; } return changed; diff --git a/cleankey.h b/cleankey.h index 454dd4c..073ef66 100644 --- a/cleankey.h +++ b/cleankey.h @@ -21,14 +21,20 @@ #include "keystructs.h" +#define ONAK_CLEAN_CHECK_SIGHASH (1 << 0) +#define ONAK_CLEAN_ALL (uint64_t) -1 + /** * cleankeys - Apply all available cleaning options on a list of keys. * @publickey: The list of keys to clean. + * @policies: The cleaning policies to apply. * - * 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. + * Applies the requested cleaning policies to a list of keys. These are + * specified from the ONAK_CLEAN_* set of flags, or ONAK_CLEAN_ALL to + * apply all available cleaning options. Returns 0 if no changes were + * made, otherwise the number of keys cleaned. Note that some options + * may result in keys being removed entirely from the list. */ -int cleankeys(struct openpgp_publickey *keys); +int cleankeys(struct openpgp_publickey **keys, uint64_t policies); #endif diff --git a/keydb_stacked.c b/keydb_stacked.c index 06ee709..59c988d 100644 --- a/keydb_stacked.c +++ b/keydb_stacked.c @@ -113,7 +113,7 @@ static void store_on_fallback(struct onak_stacked_dbctx *privctx, (struct onak_dbctx *) privctx->backends->object; struct openpgp_publickey *curkey; - cleankeys(publickey); + cleankeys(&publickey, config.clean_policies); /* * If we walked the stack at all, store the key in the first * backend if configured to do so. It's not an update as we diff --git a/lookup.c b/lookup.c index fda1686..c9f94a9 100644 --- a/lookup.c +++ b/lookup.c @@ -239,7 +239,7 @@ int main(int argc, char *argv[]) result, search); puts("
");
-				cleankeys(publickey);
+				cleankeys(&publickey, config.clean_policies);
 				flatten_publickey(publickey,
 							&packets,
 							&list_end);
diff --git a/onak-conf.c b/onak-conf.c
index e4f0bc7..e6b645c 100644
--- a/onak-conf.c
+++ b/onak-conf.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 
+#include "cleankey.h"
 #include "ll.h"
 #include "log.h"
 #include "onak-conf.h"
@@ -52,7 +53,7 @@ struct onak_config config = {
 
 	.dbinit = DBINIT,
 
-	.check_sighash = true,
+	.clean_policies = ONAK_CLEAN_CHECK_SIGHASH,
 
 	.bin_dir = NULL,
 	.mail_dir = NULL,
@@ -169,8 +170,14 @@ static bool parseoldconfigline(char *line)
 	} else if (!strncmp("sock_dir ", line, 9)) {
 		config.sock_dir = strdup(&line[9]);
 	} else if (!strncmp("check_sighash ", line, 9)) {
-		config.check_sighash = parsebool(&line[9],
-					config.check_sighash);
+		if (parsebool(&line[9], config.clean_policies &
+					ONAK_CLEAN_CHECK_SIGHASH)) {
+			config.clean_policies |=
+				ONAK_CLEAN_CHECK_SIGHASH;
+		} else {
+			config.clean_policies &=
+				~ONAK_CLEAN_CHECK_SIGHASH;
+		}
 	} else {
 		return false;
 	}
@@ -273,8 +280,14 @@ static bool parseconfigline(char *line)
 				strdup(value));
 		/* [verification] section */
 		} else if (MATCH("verification", "check_sighash")) {
-			config.check_sighash = parsebool(value,
-					config.check_sighash);
+			if (parsebool(value, config.clean_policies &
+					ONAK_CLEAN_CHECK_SIGHASH)) {
+				config.clean_policies |=
+					ONAK_CLEAN_CHECK_SIGHASH;
+			} else {
+				config.clean_policies &=
+					~ONAK_CLEAN_CHECK_SIGHASH;
+			}
 		} else {
 			return false;
 		}
@@ -448,7 +461,8 @@ void writeconfig(const char *configfile)
 	fprintf(conffile, "\n");
 
 	fprintf(conffile, "[verification]\n");
-	WRITE_BOOL(config.check_sighash, "check_sighash");
+	WRITE_BOOL(config.clean_policies & ONAK_CLEAN_CHECK_SIGHASH,
+			"check_sighash");
 	fprintf(conffile, "\n");
 
 	fprintf(conffile, "[mail]\n");
diff --git a/onak-conf.h b/onak-conf.h
index 6d7500a..3e02b7a 100644
--- a/onak-conf.h
+++ b/onak-conf.h
@@ -21,6 +21,7 @@
 #define __ONAK_CONF_H_
 
 #include 
+#include 
 
 #include "ll.h"
 
@@ -88,8 +89,8 @@ struct onak_config {
 	/** Pointer to the initialisation function for our loaded DB backend */
 	struct onak_dbctx *(*dbinit)(struct onak_db_config *, bool);
 
-	/** Should we verify signature hashes match? */
-	bool check_sighash;
+	/** What policies should we use for cleaning keys? */
+	uint64_t clean_policies;
 
 	/*
 	 * Options used by the email handling script.
diff --git a/onak.c b/onak.c
index 89c2ec7..085a876 100644
--- a/onak.c
+++ b/onak.c
@@ -233,7 +233,7 @@ int main(int argc, char *argv[])
 			logthing(LOGTHING_INFO, "Finished reading %d keys.",
 					result);
 
-			result = cleankeys(keys);
+			result = cleankeys(&keys, config.clean_policies);
 			logthing(LOGTHING_INFO, "%d keys cleaned.",
 					result);
 
@@ -288,7 +288,8 @@ int main(int argc, char *argv[])
 					result);
 
 			if (keys != NULL) {
-				result = cleankeys(keys);
+				result = cleankeys(&keys,
+						config.clean_policies);
 				logthing(LOGTHING_INFO, "%d keys cleaned.",
 						result);
 
@@ -436,7 +437,7 @@ int main(int argc, char *argv[])
 			dbctx->starttrans(dbctx);
 			if (dbctx->fetch_key_id(dbctx, keyid, &keys, true)) {
 				dbctx->delete_key(dbctx, keyid, true);
-				cleankeys(keys);
+				cleankeys(&keys, config.clean_policies);
 				dbctx->store_key(dbctx, keys, true, false);
 			} else {
 				puts("Key not found");
diff --git a/stripkey.c b/stripkey.c
index f845f34..5579236 100644
--- a/stripkey.c
+++ b/stripkey.c
@@ -49,7 +49,7 @@ int main(int argc, char** argv) {
   parse_keys( packets, &keys );
   free_packet_list(packets);
   packets = NULL;
-  cleankeys( keys );
+  cleankeys(&keys, ONAK_CLEAN_ALL);
   /* Iterate over the keys... */
   for( key = keys; key; key = key->next ) {
     uint64_t keyid;
-- 
2.39.5