Mercurial > hg > freeDiameter
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 */