Commit 21f5f783 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Completed whitelist extension

parent 658c6183
......@@ -15,4 +15,5 @@
# ALLOW_IPSEC : we accept implicitly protected connection with with peer (Inband-Security-Id = IPSec)
# It is specified for example as:
# ALLOW_IPSEC vpn.example.net vpn2.example.net *.vpn.example.net
# These flag take effect from their position, until the end of the line.
......@@ -7,7 +7,7 @@ FLEX_FILE(aw_conf.l)
SET_SOURCE_FILES_PROPERTIES(lex.aw_conf.c aw_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
# List of source files
SET( APP_TEST_SRC
SET( ACL_WL_SRC
acl_wl.h
acl_wl.c
aw_tree.c
......@@ -17,4 +17,4 @@ SET( APP_TEST_SRC
)
# Compile as a module
FD_ADD_EXTENSION(acl_wl ${APP_TEST_SRC})
FD_ADD_EXTENSION(acl_wl ${ACL_WL_SRC})
......@@ -70,35 +70,57 @@ static int aw_validate(struct peer_info * info, int * auth, int (**cb2)(struct p
}
/* Now, if we did not specify any flag, reject */
if (res == 0) {
TRACE_DEBUG(INFO, "Peer '%s' rejected, only TLS-protected connection is whitelisted.", info->pi_diamid);
/* We don't actually set *auth = -1, leave space for a further extension to validate the peer */
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 */
*auth = 1;
/* Now, configure the peer for the authorized mechanism */
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;
}
/* entry point */
static int aw_entry(char * conffile)
{
TRACE_ENTRY("%p", conffile);
CHECK_PARAMS(conffile);
/* Parse configuration file */
CHECK_FCT( aw_conf_handle(conffile) );
TRACE_DEBUG(INFO, "Extension ACL_wl initialized with configuration: '%s'", conffile);
aw_tree_dump();
if (TRACE_BOOL(ANNOYING)) {
aw_tree_dump();
}
/* Register the validator function */
CHECK_FCT( fd_peer_validate_register ( aw_validate ) );
return 0;
}
/* Unload */
void fd_ext_fini(void)
{
/* Unregister the validator function */
/* Destroy the tree */
aw_tree_destroy();
}
EXTENSION_ENTRY("acl_wl", aw_entry);
......@@ -229,7 +229,7 @@ int aw_tree_add(char * name, int flags)
/* Check if we have a '*' element already that overlapses */
ti = (struct tree_item *)(senti->next);
if (ti->str == NULL) {
fd_log_debug("[acl_wl] Warning: entry '%s' is superseeded by a generic entry at level %d, ignoring.\n", name, lbl);
fd_log_debug("[acl_wl] Warning: entry '%s' is superseeded by a generic entry at label %d, ignoring.\n", name, lbl + 1);
return 0;
}
......@@ -286,7 +286,7 @@ int aw_tree_add(char * name, int flags)
/* Check we don't have a '*' entry already */
ti = (struct tree_item *)(senti->next);
if (ti->str == NULL) {
fd_log_debug("[acl_wl] Warning: entry '%s' is superseeded by a generic entry at level 0, ignoring.\n", name);
fd_log_debug("[acl_wl] Warning: entry '%s' is superseeded by a generic entry at label 1, ignoring.\n", name);
return 0;
}
......@@ -366,7 +366,7 @@ int aw_tree_lookup(char * name, int * result)
/* Check if we have a '*' element */
ti = (struct tree_item *)(senti->next);
if (ti->str == NULL) {
TRACE_DEBUG(FULL, "[acl_wl] %s matched at level %d with a generic entry.", name, lbl);
TRACE_DEBUG(ANNOYING, "[acl_wl] %s matched at label %d with a generic entry.", name, lbl + 1);
*result = ti->flags;
return 0;
}
......@@ -406,7 +406,7 @@ int aw_tree_lookup(char * name, int * result)
if (!ti->leaf)
return 0;
TRACE_DEBUG(FULL, "[acl_wl] %s matched exactly.", name);
TRACE_DEBUG(ANNOYING, "[acl_wl] %s matched exactly.", name);
*result = ti->flags;
return 0;
}
......@@ -781,12 +781,31 @@ int fd_p_ce_process_receiver(struct fd_peer * peer)
}
}
/* Do we send ISI back ? */
/* Do we agree on ISI ? */
if ( ! fd_cnx_getTLS(peer->p_cnxctx) ) {
if (peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE)
isi = PI_SEC_NONE; /* Maybe we should also look at peer->p_hdr.info.runtime.pir_isi here ? */
else
/* 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;
}
/* 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);
ec = "DIAMETER_NO_COMMON_SECURITY";
fatal = 1;
goto error_abort;
}
}
/* Reply a CEA */
......
......@@ -302,7 +302,7 @@ int fd_peer_add ( struct peer_info * info, char * orig_dbg, void (*cb)(struct pe
int fd_peer_getbyid( char * diamid, struct peer_hdr ** peer );
/*
* FUNCTION: peer_validate_register
* FUNCTION: fd_peer_validate_register
*
* PARAMETERS:
* peer_validate : Callback as defined bellow.
......@@ -341,6 +341,8 @@ int fd_peer_validate_register ( int (*peer_validate)(struct peer_info * /* info
* structure as parameter (with pir_cert_list set) and returns 0 if the credentials are correct,
* or an error code otherwise. If the error code is received, the connection is closed and the
* peer is destroyed.
* Note that freeDiameter already achieves some usual checks. The callback may be used to enforce
* additional restrictions.
*
* RETURN VALUE:
* 0 : The authorization decision has been written in the location pointed by auth.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment