Accumulative patch from commit f5f37d3a4fc2df2a24676b4f95afca15ed793cba

Author: Jouni Malinen <j@w1.fi>
Date:   Sun Nov 25 22:05:32 2012 +0200

   Fix REAUTHENTICATE command after PMKSA caching

   The current PMKSA cache entry needs to be clear to allow EAPOL
   reauthentication to be started in case this association used PMKSA
   caching.

 - Remove old WPS_OOB NCF
 - WPS: Add preliminary NFC connection handover support for Enrollee
 - WPS: Reenable the networks disabled during wpa_wpas_reassoc
 - P2P: Avoid multi-channel scans when they are not needed
 - P2P: Allow discoverable interval for p2p_find to be configured
 - P2P: Allow all channels with multi-channel concurrency
 - Bonjour changes
 - Remove disassociate
 - HS 2.0 changes
 - Add preliminary support for using SQLite for eap_user database
 - Add SAE support
 - Add disallow_aps parameter to disallow BSSIDs/SSIDs

Change-Id: I85358a05b39d46b8db49acdad667e771c580b05c
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/radius/radius.c b/src/radius/radius.c
index d5edfd8..d1feec9 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -1406,11 +1406,12 @@
  * @secret: RADIUS shared secret
  * @secret_len: Length of secret
  * @sent_msg: Sent RADIUS message
- * Returns: pointer to password (free with os_free) or %NULL
+ * @n: Number of password attribute to return (starting with 0)
+ * Returns: Pointer to n-th password (free with os_free) or %NULL
  */
 char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
 				      const u8 *secret, size_t secret_len,
-				      struct radius_msg *sent_msg)
+				      struct radius_msg *sent_msg, size_t n)
 {
 	u8 *buf = NULL;
 	size_t buflen;
@@ -1420,7 +1421,7 @@
 	size_t len[3];
 	u8 hash[16];
 	u8 *pos;
-	size_t i;
+	size_t i, j = 0;
 	struct radius_attr_hdr *attr;
 	const u8 *data;
 	size_t dlen;
@@ -1428,7 +1429,7 @@
 	size_t fdlen = -1;
 	char *ret = NULL;
 
-	/* find attribute with lowest tag and check it */
+	/* find n-th valid Tunnel-Password attribute */
 	for (i = 0; i < msg->attr_used; i++) {
 		attr = radius_get_attr_hdr(msg, i);
 		if (attr == NULL ||
@@ -1441,11 +1442,13 @@
 		dlen = attr->length - sizeof(*attr);
 		if (dlen <= 3 || dlen % 16 != 3)
 			continue;
-		if (fdata != NULL && fdata[0] <= data[0])
+		j++;
+		if (j <= n)
 			continue;
 
 		fdata = data;
 		fdlen = dlen;
+		break;
 	}
 	if (fdata == NULL)
 		goto out;