diff mbox

[1/8] mka: fix multiple key server election bugs

Message ID 39f28a0fcb835e2c3b4e7a2916f9e5c253cc434c.1467374899.git.sd@queasysnail.net
State Accepted
Headers show

Commit Message

Sabrina Dubroca July 19, 2016, 9:56 a.m. UTC
1. The comparison between SCI's of two servers with identical priority
   is broken, and would always return TRUE. Just use os_memcmp, which
   provides the ordering we need.

2. If no peer can be key server but this instance can, then become the
   key server.

3. The ordering of blocks between peer as key server and ourself as key
   server overwrites settings. Simple reordering fixes this.

4. Default to being the key server, so that we advertise our ability in
   the MKPDUs we send. That's the only way peers can know we can be key
   server. Cleared automatically as soon as we find a better peer.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
 src/pae/ieee802_1x_kay.c | 34 ++++++++++++----------------------
 1 file changed, 12 insertions(+), 22 deletions(-)
diff mbox

Patch

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 6980b094e3a9..15b235fba49b 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -2097,7 +2097,6 @@  ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
 	struct ieee802_1x_kay_peer *key_server = NULL;
 	struct ieee802_1x_kay *kay = participant->kay;
 	Boolean i_is_key_server;
-	int i;
 
 	if (participant->is_obliged_key_server) {
 		participant->new_sak = TRUE;
@@ -2122,11 +2121,8 @@  ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
 			key_server = peer;
 		} else if (peer->key_server_priority ==
 			   key_server->key_server_priority) {
-			for (i = 0; i < 6; i++) {
-				if (peer->sci.addr[i] <
-				    key_server->sci.addr[i])
-					key_server = peer;
-			}
+			if (os_memcmp(peer->sci.addr, key_server->sci.addr, 6) < 0)
+				key_server = peer;
 		}
 	}
 
@@ -2138,20 +2134,12 @@  ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
 			i_is_key_server = TRUE;
 		} else if (kay->actor_priority
 					== key_server->key_server_priority) {
-			for (i = 0; i < 6; i++) {
-				if (kay->actor_sci.addr[i]
-					< key_server->sci.addr[i]) {
-					i_is_key_server = TRUE;
-				}
+			if (os_memcmp(kay->actor_sci.addr, key_server->sci.addr, 6) < 0) {
+				i_is_key_server = TRUE;
 			}
 		}
-	}
-
-	if (!key_server && !i_is_key_server) {
-		participant->principal = FALSE;
-		participant->is_key_server = FALSE;
-		participant->is_elected = FALSE;
-		return 0;
+	} else if (participant->can_be_key_server) {
+		i_is_key_server = TRUE;
 	}
 
 	if (i_is_key_server) {
@@ -2172,9 +2160,7 @@  ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
 		os_memcpy(&kay->key_server_sci, &kay->actor_sci,
 			  sizeof(kay->key_server_sci));
 		kay->key_server_priority = kay->actor_priority;
-	}
-
-	if (key_server) {
+	} else if (key_server) {
 		ieee802_1x_cp_set_electedself(kay->cp, FALSE);
 		if (os_memcmp(&kay->key_server_sci, &key_server->sci,
 			      sizeof(kay->key_server_sci))) {
@@ -2189,6 +2175,10 @@  ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
 		os_memcpy(&kay->key_server_sci, &key_server->sci,
 			  sizeof(kay->key_server_sci));
 		kay->key_server_priority = key_server->key_server_priority;
+	} else {
+		participant->principal = FALSE;
+		participant->is_key_server = FALSE;
+		participant->is_elected = FALSE;
 	}
 
 	return 0;
@@ -3320,7 +3310,7 @@  ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn,
 	default:
 		participant->is_obliged_key_server = FALSE;
 		participant->can_be_key_server = TRUE;
-		participant->is_key_server = FALSE;
+		participant->is_key_server = TRUE;
 		participant->is_elected = FALSE;
 		break;
 	}