[Swan-dev] pluto: Fix bogus "no RSA public key known for '%fromcert'"

Herbert Xu herbert at gondor.apana.org.au
Fri May 1 00:59:22 EEST 2015


When refine_host_connection tests against a %fromcert RW connection
followed by other right=%any connections with fixed IDs (e.g.,
@hostname), it will lose the fromcert setting.  So when it does
eventually return with the %fromcert RW connection fromcert will
be set to false and therefore the actual certificate ID won't be
copied into spd.that.id, resulting in a bogus "no RSA public key
known for '%fromcert'".
    
This error won't happen if the order of matching is reversed and
the %fromcert connection gets tested last.  So that's why the
conencton sometimes works but often fails with an authentication
error.
    
This patch fixes it by keeping the fromcert setting of the best
match.
    
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>

diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c
index 292b3b1..9140673 100644
--- a/programs/pluto/connections.c
+++ b/programs/pluto/connections.c
@@ -2621,6 +2621,7 @@ struct connection *refine_host_connection(const struct state *st,
 	d = c->host_pair->connections;
 	for (wcpip = FALSE;; wcpip = TRUE) {
 		for (; d != NULL; d = d->hp_next) {
+			bool d_fromcert = FALSE;
 			bool match1 = match_id(peer_id, &d->spd.that.id,
 					&wildcards);
 			bool match2 = trusted_ca_nss(peer_ca, d->spd.that.ca,
@@ -2659,9 +2660,10 @@ struct connection *refine_host_connection(const struct state *st,
 			 * the %fromcert + peer id match result. - matt
 			 */
 			if (!match1) {
-			    *fromcert = id_kind(&d->spd.that.id) == ID_FROMCERT;
-			    if (!*fromcert)
-				continue;
+				d_fromcert = id_kind(&d->spd.that.id) ==
+					     ID_FROMCERT;
+				if (!d_fromcert)
+					continue;
 			}
 
 			/* if initiator, our ID must match exactly */
@@ -2764,8 +2766,10 @@ struct connection *refine_host_connection(const struct state *st,
 			 * We'll go with it if the Peer ID was an exact match.
 			 */
 			if (match1 && wildcards == 0 &&
-			    peer_pathlen == 0 && our_pathlen == 0)
+			    peer_pathlen == 0 && our_pathlen == 0) {
+				*fromcert = d_fromcert;
 				return d;
+			}
 
 			/*
 			 * If it was a non-exact (wildcard) match, we'll
@@ -2786,6 +2790,7 @@ struct connection *refine_host_connection(const struct state *st,
 						d->name,
 						wildcards, peer_pathlen,
 						our_pathlen));
+				*fromcert = d_fromcert;
 				best_found = d;
 				best_wildcards = wildcards;
 				best_peer_pathlen = peer_pathlen;
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


More information about the Swan-dev mailing list