Module Name:    src
Committed By:   agc
Date:           Mon Dec  7 16:17:17 UTC 2009

Modified Files:
        src/crypto/external/bsd/netpgp/dist/src/lib: keyring.c keyring.h
            netpgp.c reader.c validate.c

Log Message:
+ When using ssh keys, use the first key as the default userid, unless
specified.

+ The internal variable "sshetcdir" has been renamed to "sshkeydir"

+ When matching the text fields in the username, use an ICASE, NOSUB, EXTENDED
regular expression. This allows more advanced ways of searching, such as:

% netpgpkeys --list-keys '\.de\>'

to find all the keys in the default keyring which have an email address
in Germany. This is actually surprisingly useful.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 \
    src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c \
    src/crypto/external/bsd/netpgp/dist/src/lib/validate.c
cvs rdiff -u -r1.18 -r1.19 \
    src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h
cvs rdiff -u -r1.31 -r1.32 \
    src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c
cvs rdiff -u -r1.26 -r1.27 \
    src/crypto/external/bsd/netpgp/dist/src/lib/reader.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c:1.23 src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c:1.24
--- src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c:1.23	Sat Dec  5 07:08:18 2009
+++ src/crypto/external/bsd/netpgp/dist/src/lib/keyring.c	Mon Dec  7 16:17:17 2009
@@ -57,13 +57,14 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: keyring.c,v 1.23 2009/12/05 07:08:18 agc Exp $");
+__RCSID("$NetBSD: keyring.c,v 1.24 2009/12/07 16:17:17 agc Exp $");
 #endif
 
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
 
+#include <regex.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -764,11 +765,9 @@
 */
 const __ops_key_t *
 __ops_getkeybyid(__ops_io_t *io, const __ops_keyring_t *keyring,
-			   const unsigned char keyid[OPS_KEY_ID_SIZE])
+			   const unsigned char *keyid, unsigned *from)
 {
-	unsigned	 n;
-
-	for (n = 0; keyring && n < keyring->keyc; n++) {
+	for ( ; keyring && *from < keyring->keyc; *from += 1) {
 		if (__ops_get_debug_level(__FILE__)) {
 			int	i;
 
@@ -776,7 +775,7 @@
 				"__ops_getkeybyid: keyring keyid ");
 			for (i = 0 ; i < OPS_KEY_ID_SIZE ; i++) {
 				(void) fprintf(io->errs, "%02x",
-					keyring->keys[n].key_id[i]);
+					keyring->keys[*from].key_id[i]);
 			}
 			(void) fprintf(io->errs, ", keyid ");
 			for (i = 0 ; i < OPS_KEY_ID_SIZE ; i++) {
@@ -784,13 +783,13 @@
 			}
 			(void) fprintf(io->errs, "\n");
 		}
-		if (memcmp(keyring->keys[n].key_id, keyid,
+		if (memcmp(keyring->keys[*from].key_id, keyid,
 				OPS_KEY_ID_SIZE) == 0) {
-			return &keyring->keys[n];
+			return &keyring->keys[*from];
 		}
-		if (memcmp(&keyring->keys[n].key_id[OPS_KEY_ID_SIZE / 2],
+		if (memcmp(&keyring->keys[*from].key_id[OPS_KEY_ID_SIZE / 2],
 				keyid, OPS_KEY_ID_SIZE / 2) == 0) {
-			return &keyring->keys[n];
+			return &keyring->keys[*from];
 		}
 	}
 	return NULL;
@@ -831,117 +830,105 @@
 	keyid[j] = 0x0;
 }
 
-/**
-   \ingroup HighLevel_KeyringFind
-
-   \brief Finds key from its User ID
-
-   \param keyring Keyring to be searched
-   \param userid User ID of required key
-
-   \return Pointer to Key, if found; NULL, if not found
-
-   \note This returns a pointer to the key inside the keyring, not a
-   copy.  Do not free it.
-
-*/
-const __ops_key_t *
-__ops_getkeybyname(__ops_io_t *io,
+/* return the next key which matches, starting searching at *from */
+static const __ops_key_t *
+getkeybyname(__ops_io_t *io,
 			const __ops_keyring_t *keyring,
-			const char *name)
+			const char *name,
+			unsigned *from)
 {
 	const __ops_key_t	*kp;
 	__ops_key_t		*keyp;
 	__ops_userid_t		*uidp;
 	unsigned char		 keyid[OPS_KEY_ID_SIZE + 1];
 	unsigned int    	 i = 0;
+	unsigned		 savedstart;
+	regex_t			 r;
 	size_t          	 len;
-	char	                *cp;
-	unsigned             	 n;
 
 	if (!keyring) {
 		return NULL;
 	}
 	len = strlen(name);
-	n = 0;
-	for (keyp = &keyring->keys[n]; n < keyring->keyc; ++n, keyp++) {
-		for (i = 0, uidp = keyp->uids; i < keyp->uidc; i++, uidp++) {
+	if (__ops_get_debug_level(__FILE__)) {
+		(void) fprintf(io->outs, "[%u] name '%s', len %u\n",
+			*from, name, len);
+	}
+	/* first try name as a keyid */
+	(void) memset(keyid, 0x0, sizeof(keyid));
+	str2keyid(name, keyid, sizeof(keyid));
+	if (__ops_get_debug_level(__FILE__)) {
+		(void) fprintf(io->outs,
+			"name \"%s\", keyid %02x%02x%02x%02x\n",
+			name,
+			keyid[0], keyid[1], keyid[2], keyid[3]);
+	}
+	savedstart = *from;
+	if ((kp = __ops_getkeybyid(io, keyring, keyid, from)) != NULL) {
+		return kp;
+	}
+	*from = savedstart;
+	if (__ops_get_debug_level(__FILE__)) {
+		(void) fprintf(io->outs, "regex match '%s' from %u\n",
+			name, *from);
+	}
+	/* match on full name or email address as a NOSUB, ICASE regexp */
+	(void) regcomp(&r, name, REG_EXTENDED | REG_ICASE);
+	for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
+		uidp = keyp->uids;
+		for (i = 0 ; i < keyp->uidc; i++, uidp++) {
 			if (__ops_get_debug_level(__FILE__)) {
 				(void) fprintf(io->outs,
-					"[%u][%u] name %s, last '%d'\n",
-					n, i, uidp->userid,
-					uidp->userid[len]);
+					"keyid \"%s\" len %"
+					PRIsize "u, keyid[len] '%c'\n",
+				       (char *) uidp->userid,
+				       len, uidp->userid[len]);
 			}
-			if (strncmp((char *) uidp->userid, name, len) == 0 &&
-			    uidp->userid[len] == ' ') {
+			if (regexec(&r, (char *)uidp->userid, 0, NULL, 0) == 0) {
+				regfree(&r);
 				return keyp;
 			}
 		}
 	}
-
-	if (strchr(name, '@') == NULL) {
-		/* no '@' sign */
-		/* first try name as a keyid */
-		(void) memset(keyid, 0x0, sizeof(keyid));
-		str2keyid(name, keyid, sizeof(keyid));
-		if (__ops_get_debug_level(__FILE__)) {
-			(void) fprintf(io->outs,
-				"name \"%s\", keyid %02x%02x%02x%02x\n",
-				name,
-				keyid[0], keyid[1], keyid[2], keyid[3]);
-		}
-		if ((kp = __ops_getkeybyid(io, keyring, keyid)) != NULL) {
-			return kp;
-		}
-		/* match on full name */
-		keyp = keyring->keys;
-		for (n = 0; n < keyring->keyc; ++n, keyp++) {
-			uidp = keyp->uids;
-			for (i = 0 ; i < keyp->uidc; i++, uidp++) {
-				if (__ops_get_debug_level(__FILE__)) {
-					(void) fprintf(io->outs,
-						"keyid \"%s\" len %"
-						PRIsize "u, keyid[len] '%c'\n",
-					       (char *) uidp->userid,
-					       len, uidp->userid[len]);
-				}
-				if (strncasecmp((char *) uidp->userid, name,
-					len) == 0 && uidp->userid[len] == ' ') {
-					return keyp;
-				}
-			}
-		}
-	}
-	/* match on <em...@address> */
-	keyp = keyring->keys;
-	for (n = 0; n < keyring->keyc; ++n, keyp++) {
-		for (i = 0, uidp = keyp->uids; i < keyp->uidc; i++, uidp++) {
-			/*
-			 * look for the rightmost '<', in case there is one
-			 * in the comment field
-			 */
-			cp = strrchr((char *) uidp->userid, '<');
-			if (cp != NULL) {
-				if (__ops_get_debug_level(__FILE__)) {
-					(void) fprintf(io->errs,
-						"cp ,%s, name ,%s, len %"
-						PRIsize "u ,%c,\n",
-						cp + 1,
-						name,
-						len,
-						*(cp + len + 1));
-				}
-				if (strncasecmp(cp + 1, name, len) == 0 &&
-				    *(cp + len + 1) == '>') {
-					return keyp;
-				}
-			}
-		}
-	}
+	regfree(&r);
 	return NULL;
 }
 
 /**
+   \ingroup HighLevel_KeyringFind
+
+   \brief Finds key from its User ID
+
+   \param keyring Keyring to be searched
+   \param userid User ID of required key
+
+   \return Pointer to Key, if found; NULL, if not found
+
+   \note This returns a pointer to the key inside the keyring, not a
+   copy.  Do not free it.
+
+*/
+const __ops_key_t *
+__ops_getkeybyname(__ops_io_t *io,
+			const __ops_keyring_t *keyring,
+			const char *name)
+{
+	unsigned	from;
+
+	from = 0;
+	return getkeybyname(io, keyring, name, &from);
+}
+
+const __ops_key_t *
+__ops_getnextkeybyname(__ops_io_t *io,
+			const __ops_keyring_t *keyring,
+			const char *name,
+			unsigned *n)
+{
+	return getkeybyname(io, keyring, name, n);
+}
+
+/**
    \ingroup HighLevel_KeyringList
 
    \brief Prints all keys in keyring to stdout.
Index: src/crypto/external/bsd/netpgp/dist/src/lib/validate.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/validate.c:1.23 src/crypto/external/bsd/netpgp/dist/src/lib/validate.c:1.24
--- src/crypto/external/bsd/netpgp/dist/src/lib/validate.c:1.23	Fri Nov 20 07:17:07 2009
+++ src/crypto/external/bsd/netpgp/dist/src/lib/validate.c	Mon Dec  7 16:17:17 2009
@@ -54,7 +54,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: validate.c,v 1.23 2009/11/20 07:17:07 agc Exp $");
+__RCSID("$NetBSD: validate.c,v 1.24 2009/12/07 16:17:17 agc Exp $");
 #endif
 
 #include <sys/types.h>
@@ -228,6 +228,7 @@
 	validate_key_cb_t	 *key;
 	__ops_error_t		**errors;
 	__ops_io_t		 *io;
+	unsigned		  from;
 	unsigned		  valid = 0;
 
 	io = cbinfo->io;
@@ -284,9 +285,10 @@
 
 	case OPS_PTAG_CT_SIGNATURE:	/* V3 sigs */
 	case OPS_PTAG_CT_SIGNATURE_FOOTER:	/* V4 sigs */
-
+		from = 0;
 		signer = __ops_getkeybyid(io, key->keyring,
-					 content->sig.info.signer_id);
+					 content->sig.info.signer_id,
+					 &from);
 		if (!signer) {
 			if (!add_sig_to_list(&content->sig.info,
 				&key->result->unknown_sigs,
@@ -401,6 +403,7 @@
 	validate_data_cb_t	 *data;
 	__ops_error_t		**errors;
 	__ops_io_t		 *io;
+	unsigned		  from;
 	unsigned		  valid = 0;
 
 	io = cbinfo->io;
@@ -453,8 +456,9 @@
 				sizeof(content->sig.info.signer_id), "");
 			(void) fprintf(io->outs, "\n");
 		}
+		from = 0;
 		signer = __ops_getkeybyid(io, data->keyring,
-					 content->sig.info.signer_id);
+					 content->sig.info.signer_id, &from);
 		if (!signer) {
 			OPS_ERROR(errors, OPS_E_V_UNKNOWN_SIGNER,
 					"Unknown Signer");

Index: src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.18 src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.19
--- src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.18	Sat Dec  5 07:08:18 2009
+++ src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h	Mon Dec  7 16:17:17 2009
@@ -72,10 +72,15 @@
 
 const __ops_key_t *__ops_getkeybyid(__ops_io_t *,
 					const __ops_keyring_t *,
-					const unsigned char *);
+					const unsigned char *,
+					unsigned *);
 const __ops_key_t *__ops_getkeybyname(__ops_io_t *,
 					const __ops_keyring_t *,
 					const char *);
+const __ops_key_t *__ops_getnextkeybyname(__ops_io_t *,
+					const __ops_keyring_t *,
+					const char *,
+					unsigned *);
 void __ops_keydata_free(__ops_key_t *);
 void __ops_keyring_free(__ops_keyring_t *);
 void __ops_dump_keyring(const __ops_keyring_t *);

Index: src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c:1.31 src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c:1.32
--- src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c:1.31	Sat Dec  5 07:08:19 2009
+++ src/crypto/external/bsd/netpgp/dist/src/lib/netpgp.c	Mon Dec  7 16:17:17 2009
@@ -34,7 +34,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: netpgp.c,v 1.31 2009/12/05 07:08:19 agc Exp $");
+__RCSID("$NetBSD: netpgp.c,v 1.32 2009/12/07 16:17:17 agc Exp $");
 #endif
 
 #include <sys/types.h>
@@ -138,6 +138,7 @@
 	__ops_keyring_t *ring)
 {
 	const __ops_key_t	*pubkey;
+	unsigned		 from;
 	unsigned		 i;
 	char			 id[MAX_ID_LENGTH + 1];
 
@@ -148,8 +149,10 @@
 			ctime(&res->valid_sigs[i].birthtime),
 			__ops_show_pka(res->valid_sigs[i].key_alg),
 			userid_to_id(res->valid_sigs[i].signer_id, id));
+		from = 0;
 		pubkey = __ops_getkeybyid(io, ring,
-			(const unsigned char *) res->valid_sigs[i].signer_id);
+			(const unsigned char *) res->valid_sigs[i].signer_id,
+			&from);
 		__ops_print_keydata(io, pubkey, "pub", &pubkey->key.pubkey);
 	}
 }
@@ -230,7 +233,7 @@
 	return keyring;
 }
 
-/* read keys from ssh host key files */
+/* read keys from ssh key files */
 static int
 readsshkeys(netpgp_t *netpgp, const char *pubname, const char *secname)
 {
@@ -241,7 +244,7 @@
 	char		*etcdir;
 
 	__OPS_USED(secname);
-	etcdir = netpgp_getvar(netpgp, "sshetcdir");
+	etcdir = netpgp_getvar(netpgp, "sshkeydir");
 	if ((filename = netpgp_getvar(netpgp, pubname)) == NULL) {
 		(void) snprintf(f, sizeof(f), "%s/ssh_host_rsa_key.pub", etcdir);
 		filename = f;
@@ -336,23 +339,23 @@
 		(void) fprintf(io->errs, "netpgp: bad homedir\n");
 		return 0;
 	}
-	if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) {
-		(void) memset(id, 0x0, sizeof(id));
-		(void) conffile(netpgp, homedir, id, sizeof(id));
-		if (id[0] != 0x0) {
-			netpgp_setvar(netpgp, "userid", userid = id);
+	/* read from either gpg files or ssh keys */
+	if (netpgp_getvar(netpgp, "ssh keys") == NULL) {
+		if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) {
+			(void) memset(id, 0x0, sizeof(id));
+			(void) conffile(netpgp, homedir, id, sizeof(id));
+			if (id[0] != 0x0) {
+				netpgp_setvar(netpgp, "userid", userid = id);
+			}
 		}
-	}
-	if (userid == NULL) {
-		if (netpgp_getvar(netpgp, "need userid") != NULL) {
-			(void) fprintf(io->errs, "Cannot find user id\n");
-			return 0;
+		if (userid == NULL) {
+			if (netpgp_getvar(netpgp, "need userid") != NULL) {
+				(void) fprintf(io->errs, "Cannot find user id\n");
+				return 0;
+			}
+		} else {
+			(void) netpgp_setvar(netpgp, "userid", userid);
 		}
-	} else {
-		(void) netpgp_setvar(netpgp, "userid", userid);
-	}
-	/* read from either gpg files or ssh host keys */
-	if (netpgp_getvar(netpgp, "ssh keys") == NULL) {
 		if ((netpgp->pubring = readkeyring(netpgp, "pubring")) == NULL) {
 			(void) fprintf(io->errs, "Can't read pub keyring\n");
 			return 0;
@@ -363,9 +366,33 @@
 		}
 	} else {
 		if (!readsshkeys(netpgp, "ssh pub key", "ssh sec file")) {
-			(void) fprintf(io->errs, "Can't read ssh host pub key\n");
+			(void) fprintf(io->errs, "Can't read ssh pub key\n");
 			return 0;
 		}
+		if ((userid = netpgp_getvar(netpgp, "userid")) == NULL) {
+			/* set ssh uid to first one in ring */
+			__ops_keyring_t	*pubring;
+			unsigned char	*src;
+			int		 i;
+			int		 n;
+
+			pubring = netpgp->pubring;
+			(void) memset(id, 0x0, sizeof(id));
+			src = pubring->keys[0].key_id;
+			for (i = 0, n = 0 ; i < OPS_KEY_ID_SIZE ; i += 2) {
+				n += snprintf(&id[n], sizeof(id) - n, "%02x%02x", src[i], src[i + 1]);
+			}
+			id[n] = 0x0;
+			netpgp_setvar(netpgp, "userid", userid = id);
+		}
+		if (userid == NULL) {
+			if (netpgp_getvar(netpgp, "need userid") != NULL) {
+				(void) fprintf(io->errs, "Cannot find user id\n");
+				return 0;
+			}
+		} else {
+			(void) netpgp_setvar(netpgp, "userid", userid);
+		}
 	}
 	if ((passfd = netpgp_getvar(netpgp, "pass-fd")) != NULL &&
 	    (netpgp->passfp = fdopen(atoi(passfd), "r")) == NULL) {
@@ -413,6 +440,29 @@
 	return __ops_keyring_list(netpgp->io, netpgp->pubring);
 }
 
+/* find and list some keys in a keyring */
+int
+netpgp_match_list_keys(netpgp_t *netpgp, char *name)
+{
+	const __ops_key_t	*key;
+	unsigned		 found;
+	unsigned		 k;
+	char			*data;
+
+	found = k = 0;
+	do {
+		if ((key = __ops_getnextkeybyname(netpgp->io, netpgp->pubring, name, &k)) != NULL) {
+			__ops_sprint_keydata(key, &data, "pub", &key->key.pubkey);
+			printf("%s\n", data);
+			free(data);
+			found += 1;
+			k += 1;
+		}
+	} while (key != NULL);
+	printf("Found %u key%s\n", found, (found == 1) ? "" : "s");
+	return (found > 0);
+}
+
 /* find a key in a keyring */
 int
 netpgp_find_key(netpgp_t *netpgp, char *id)

Index: src/crypto/external/bsd/netpgp/dist/src/lib/reader.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/reader.c:1.26 src/crypto/external/bsd/netpgp/dist/src/lib/reader.c:1.27
--- src/crypto/external/bsd/netpgp/dist/src/lib/reader.c:1.26	Sat Dec  5 07:08:19 2009
+++ src/crypto/external/bsd/netpgp/dist/src/lib/reader.c	Mon Dec  7 16:17:17 2009
@@ -54,7 +54,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: reader.c,v 1.26 2009/12/05 07:08:19 agc Exp $");
+__RCSID("$NetBSD: reader.c,v 1.27 2009/12/07 16:17:17 agc Exp $");
 #endif
 
 #include <sys/types.h>
@@ -2162,6 +2162,7 @@
 pk_sesskey_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo)
 {
 	const __ops_contents_t	*content = &pkt->u;
+	unsigned		 from;
 	__ops_io_t		*io;
 
 	io = cbinfo->io;
@@ -2179,9 +2180,10 @@
 				"pk_sesskey_cb: bad keyring\n");
 			return (__ops_cb_ret_t)0;
 		}
+		from = 0;
 		cbinfo->cryptinfo.keydata =
 			__ops_getkeybyid(io, cbinfo->cryptinfo.keyring,
-				content->pk_sesskey.key_id);
+				content->pk_sesskey.key_id, &from);
 		if (!cbinfo->cryptinfo.keydata) {
 			break;
 		}
@@ -2214,6 +2216,7 @@
 	const __ops_contents_t	*content = &pkt->u;
 	const __ops_seckey_t	*secret;
 	const __ops_key_t	*keypair;
+	unsigned		 from;
 	__ops_io_t		*io;
 
 	io = cbinfo->io;
@@ -2222,9 +2225,11 @@
 	}
 	switch (pkt->tag) {
 	case OPS_GET_SECKEY:
+		from = 0;
 		cbinfo->cryptinfo.keydata =
 			__ops_getkeybyid(io, cbinfo->cryptinfo.keyring,
-				content->get_seckey.pk_sesskey->key_id);
+				content->get_seckey.pk_sesskey->key_id,
+				&from);
 		if (!cbinfo->cryptinfo.keydata ||
 		    !__ops_is_key_secret(cbinfo->cryptinfo.keydata)) {
 			return (__ops_cb_ret_t)0;

Reply via email to