From: Alan T. DeKok Date: Wed, 31 Mar 2021 13:52:41 +0000 (-0400) Subject: add WITH_COA_TUNNEL definition X-Git-Tag: release_3_0_24~171 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e26cc1ac7e63be08c6a775240e517e56a4e4a34b;p=thirdparty%2Ffreeradius-server.git add WITH_COA_TUNNEL definition along with recv_coa functionality in the home server definition. and parse / verify the home server configuration for recv coa --- diff --git a/src/include/features-h b/src/include/features-h index f24a52d20ed..ce28e9c5197 100644 --- a/src/include/features-h +++ b/src/include/features-h @@ -64,4 +64,16 @@ # endif # endif # endif + +# ifdef WITH_COA +# ifndef WITHOUT_COA_TUNNEL +# define WITH_COA_TUNNEL (1) +# endif +# endif +#endif + +#ifdef WITH_COA_TUNNEL +# ifdef WITHOUT_TLS +# error Reverse CoA requests requires TLS +# endif #endif diff --git a/src/include/realms.h b/src/include/realms.h index 90ee6ada2d3..c0747643e6b 100644 --- a/src/include/realms.h +++ b/src/include/realms.h @@ -21,10 +21,15 @@ typedef enum { HOME_TYPE_INVALID = 0, HOME_TYPE_AUTH, //!< Authentication server HOME_TYPE_ACCT, //!< Accounting server - HOME_TYPE_AUTH_ACCT //!< Authentication and accounting server + HOME_TYPE_AUTH_ACCT, //!< Authentication and accounting server #ifdef WITH_COA - ,HOME_TYPE_COA //!< CoA destination (NAS or Proxy) + HOME_TYPE_COA, //!< CoA destination (NAS or Proxy) + +#ifdef WITH_COA_TUNNEL + HOME_TYPE_AUTH_COA, //!< auth + coa + HOME_TYPE_AUTH_ACCT_COA, //!< auth + acct + coa +#endif #endif } home_type_t; @@ -61,6 +66,9 @@ typedef struct home_server { bool dual; //!< One of a pair of homeservers on consecutive ports. bool dynamic; //!< is this a dynamically added home server? +#ifdef WITH_COA_TUNNEL + bool recv_coa; //!< receive CoA packets, too +#endif char const *server; //!< For internal proxying char const *parent_server; @@ -121,6 +129,9 @@ typedef struct home_server { uint32_t coa_mrc; uint32_t coa_mrt; uint32_t coa_mrd; +#ifdef WITH_COA_TUNNEL + char const *coa_server; //!< for accepting incoming CoA requests +#endif #endif #ifdef WITH_TLS fr_tls_server_conf_t *tls; diff --git a/src/main/realms.c b/src/main/realms.c index 4a6dafb7419..d04f708ce93 100644 --- a/src/main/realms.c +++ b/src/main/realms.c @@ -73,6 +73,10 @@ static const FR_NAME_NUMBER home_server_types[] = { { "acct", HOME_TYPE_ACCT }, { "auth+acct", HOME_TYPE_AUTH_ACCT }, { "coa", HOME_TYPE_COA }, +#ifdef WITH_COA_TUNNEL + { "auth+coa", HOME_TYPE_AUTH_COA }, + { "auth+acct+coa", HOME_TYPE_AUTH_ACCT_COA }, +#endif { NULL, 0 } }; @@ -433,6 +437,16 @@ static CONF_PARSER home_server_coa[] = { { "mrd", FR_CONF_OFFSET(PW_TYPE_INTEGER, home_server_t, coa_mrd), STRINGIFY(30) }, CONF_PARSER_TERMINATOR }; + + + +#ifdef WITH_COA_TUNNEL +static CONF_PARSER home_server_recv_coa[] = { + { "virtual_server", FR_CONF_OFFSET(PW_TYPE_STRING, home_server_t, coa_server), NULL }, + CONF_PARSER_TERMINATOR +}; +#endif + #endif static CONF_PARSER home_server_config[] = { @@ -482,6 +496,9 @@ static CONF_PARSER home_server_config[] = { #ifdef WITH_COA { "coa", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) home_server_coa }, +#ifdef WITH_COA_TUNNEL + { "recv_coa", FR_CONF_POINTER(PW_TYPE_SUBSECTION, NULL), (void const *) home_server_recv_coa }, +#endif #endif CONF_PARSER_TERMINATOR @@ -681,6 +698,20 @@ bool realm_home_server_add(home_server_t *home) } } +#ifdef WITH_COA_TUNNEL + if (home->recv_coa) { + if (!home->tls) { + ERROR("TLS is required in order to accept CoA requests from a home server"); + return false; + } + + if (!home->coa_server) { + ERROR("A 'virtual_server' configuration is required in order to accept CoA requests from a home server"); + return false; + } + } +#endif + /* * Mark it as already processed */ @@ -745,7 +776,7 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, realm_config_t *rc, CONF_SE } /* - * Try and find a 'server' section off the root of + * Try and find a "server" section off the root of * the config with a name that matches the * virtual_server. */ @@ -793,6 +824,17 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, realm_config_t *rc, CONF_SE goto error; } break; + +#ifdef WITH_COA_TUNNEL + case HOME_TYPE_AUTH_ACCT_COA: + home->dual = true; + home->recv_coa = true; + break; + + case HOME_TYPE_AUTH_COA: + home->recv_coa = true; + break; +#endif #endif case HOME_TYPE_INVALID: @@ -819,6 +861,10 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, realm_config_t *rc, CONF_SE } if (((home->type == HOME_TYPE_AUTH) || +#ifdef WITH_COA_TUNNEL + (home->type == HOME_TYPE_AUTH_COA) || + (home->type == HOME_TYPE_AUTH_ACCT_COA) || +#endif (home->type == HOME_TYPE_AUTH_ACCT)) && !home->ping_user_password) { cf_log_err_cs(cs, "You must supply a 'password' to enable status_check=request"); goto error; @@ -883,6 +929,38 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, realm_config_t *rc, CONF_SE } #endif + /* + * Check the reverse CoA configuration. + */ +#ifdef WITH_COA_TUNNEL + if (home->recv_coa) { + if (!tls) { + ERROR("TLS is required in order to accept CoA requests from a home server"); + goto error; + } + + if (!home->coa_server) { + ERROR("A 'virtual_server' configuration is required in order to accept CoA requests from a home server"); + goto error; + } + + /* + * Try and find a 'server' section off the root of + * the config with a name that matches the coa + * virtual_server. + */ + if (!rc) { + ERROR("Dynamic home servers cannot accept CoA requests"); + goto error; + } + + if (!cf_section_sub_find_name2(rc->cs, "server", home->coa_server)) { + cf_log_err_cs(cs, "No such coa server %s", home->coa_server); + goto error; + } + } +#endif + /* * If were doing RADSEC (tls+tcp) the secret should default * to radsec, else a secret must be set. @@ -1127,6 +1205,16 @@ static int pool_check_home_server(UNUSED realm_config_t *rc, CONF_PAIR *cp, case HOME_TYPE_ACCT: myhome.type = HOME_TYPE_AUTH_ACCT; home = rbtree_finddata(home_servers_byname, &myhome); +#ifdef WITH_COA_TUNNEL + if (!home) { + myhome.type = HOME_TYPE_AUTH_COA; + home = rbtree_finddata(home_servers_byname, &myhome); + if(!home) { + myhome.type = HOME_TYPE_AUTH_ACCT_COA; + home = rbtree_finddata(home_servers_byname, &myhome); + } + } +#endif if (home) { *phome = home; return 1; @@ -1418,6 +1506,16 @@ static int server_pool_add(realm_config_t *rc, case HOME_TYPE_ACCT: myhome.type = HOME_TYPE_AUTH_ACCT; home = rbtree_finddata(home_servers_byname, &myhome); +#ifdef WITH_COA_TUNNEL + if (!home) { + myhome.type = HOME_TYPE_AUTH_COA; + home = rbtree_finddata(home_servers_byname, &myhome); + if (!home) { + myhome.type = HOME_TYPE_AUTH_ACCT_COA; + home = rbtree_finddata(home_servers_byname, &myhome); + } + } +#endif break; default: @@ -2987,6 +3085,14 @@ int home_server_afrom_file(char const *filename) goto error; } +#ifdef COA_TUNNEL + if (home->recv_coa) { + fr_strerror_printf("Dynamic home_server '%s' cannot receive CoA requests'", p); + talloc_free(home); + goto error; + } +#endif + if (!realm_home_server_add(home)) { fr_strerror_printf("Failed adding home_server to the internal data structures"); talloc_free(home);