changeset 332:e624fa5f85ca

Attempt to fix a bug reported by Alexey Berdnikov (CER without ISI AVP)
author Sebastien Decugis <sdecugis@nict.go.jp>
date Mon, 31 May 2010 19:09:24 +0900
parents ac6e9cc9c3ba
children 3baabc0da588
files extensions/acl_wl/acl_wl.c freeDiameter/p_ce.c
diffstat 2 files changed, 43 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/acl_wl/acl_wl.c	Mon May 31 16:43:11 2010 +0900
+++ b/extensions/acl_wl/acl_wl.c	Mon May 31 19:09:24 2010 +0900
@@ -76,22 +76,13 @@
 		return 0;
 	}
 	
-	/* Check the Inband-Security-Id value */
-	res &= info->runtime.pir_isi;
-	if (res == 0) {
-		TRACE_DEBUG(INFO, "Peer '%s' rejected, remotely advertised Inband-Security-Id is not compatible with whitelist flags.", info->pi_diamid);
-		/* We don't actually set *auth = -1, leave space for a further extension to validate the peer */
-		return 0;
-	}
-	
-	/* Ok, the peer is whitelisted */
+	/* Otherwise, just set the configured flags for the peer, and authorize it */
 	*auth = 1;
 	
-	/* Now, configure the peer for the authorized mechanism */
+	/* Save information about the security mechanism to use after CER/CEA exchange */
 	if ((res & PI_SEC_NONE) && (res & PI_SEC_TLS_OLD))
 		res = PI_SEC_NONE; /* If we authorized it, we must have an IPsec tunnel setup, no need for TLS in this case */
 	
-	/* Save information about the security mechanism to use after CER/CEA exchange */
 	info->config.pic_flags.sec = res;
 	return 0;
 }
--- a/freeDiameter/p_ce.c	Mon May 31 16:43:11 2010 +0900
+++ b/freeDiameter/p_ce.c	Mon May 31 19:09:24 2010 +0900
@@ -793,22 +793,45 @@
 	
 	/* Do we agree on ISI ? */
 	if ( ! fd_cnx_getTLS(peer->p_cnxctx) ) {
+		
 		/* In case of responder, the validate callback must have set the config.pic_flags.sec value already */
-		if (!peer->p_hdr.info.config.pic_flags.sec) {
-			/* The peer did not send the Inband-Security-Id AVP, reject */
-			TRACE_DEBUG(INFO, "No security mechanism advertised by peer '%s', sending DIAMETER_NO_COMMON_SECURITY", peer->p_hdr.info.pi_diamid);
-			ec = "DIAMETER_NO_COMMON_SECURITY";
-			fatal = 1;
-			goto error_abort;
+	
+		/* First case: we are not using old mechanism: ISI are deprecated, we ignore it. */
+		if ( ! (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD)) {
+			/* Just check then that the peer configuration allows for IPsec protection */
+			if (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE) {
+				isi = PI_SEC_NONE;
+			} else {
+				/* otherwise, we should have already been protected. Reject */
+				TRACE_DEBUG(INFO, "Non TLS-protected CER/CEA exchanges are not allowed with this peer, rejecting.");
+			}
+		} else {
+			/* The old mechanism is allowed with this peer. Now, look into the ISI AVP values */
+			
+			/* In case no ISI was present anyway: */
+			if (!peer->p_hdr.info.runtime.pir_isi) {
+				TRACE_DEBUG(INFO, "Inband-Security-Id AVP is missing in received CER.");
+				if (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE) {
+					isi = PI_SEC_NONE;
+					TRACE_DEBUG(INFO, "IPsec protection allowed by configuration, allowing this mechanism to be used.");
+				} else {
+					/* otherwise, we should have already been protected. Reject */
+					TRACE_DEBUG(INFO, "Rejecting the peer connection (please allow IPsec here or configure TLS in the remote peer).");
+				}
+			} else {
+				/* OK, the remote peer did send the ISI AVP. */
+				if ((peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE) && (peer->p_hdr.info.runtime.pir_isi & PI_SEC_NONE)) {
+					/* We have allowed IPsec */
+					isi = PI_SEC_NONE;
+				} else if (peer->p_hdr.info.runtime.pir_isi & PI_SEC_TLS_OLD) {
+					/* We can agree on TLS */
+					isi = PI_SEC_TLS_OLD;
+				} else {
+					TRACE_DEBUG(INFO, "Remote peer requested IPsec protection, but local configuration forbids it.");
+				}
+			}
 		}
-		
-		/* Now, check if we agree on the value IPsec */
-		if ((peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE) && (peer->p_hdr.info.runtime.pir_isi & PI_SEC_NONE)) {
-			isi = PI_SEC_NONE;
-		} else if ((peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD) && (peer->p_hdr.info.runtime.pir_isi & PI_SEC_TLS_OLD)) {
-			isi = PI_SEC_TLS_OLD;
-		}
-		
+	
 		/* If we did not find an agreement */
 		if (!isi) {
 			TRACE_DEBUG(INFO, "No common security mechanism with '%s', sending DIAMETER_NO_COMMON_SECURITY", peer->p_hdr.info.pi_diamid);
@@ -816,6 +839,10 @@
 			fatal = 1;
 			goto error_abort;
 		}
+		
+		/* Do not send the ISI IPsec if we are using the new mechanism */
+		if ((isi == PI_SEC_NONE) && (! (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD)))
+			isi = 0;
 	}
 	
 	/* Reply a CEA */
"Welcome to our mercurial repository"