From: Alan T. DeKok Date: Wed, 31 Mar 2021 13:52:41 +0000 (-0400) Subject: add WITH_COA_TUNNEL definition X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84d35c273cc0528d0c3ecf1328eb5d5a5379b142;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 f24a52d20e..ce28e9c519 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 dcb420371e..be4998ec08 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; @@ -60,6 +65,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; @@ -120,6 +128,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 682c58f351..a8a88669a1 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 } }; @@ -429,6 +433,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[] = { @@ -478,6 +492,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 @@ -677,6 +694,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 */ @@ -741,7 +772,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. */ @@ -789,6 +820,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: @@ -815,6 +857,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; @@ -879,6 +925,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. @@ -1123,6 +1201,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; @@ -1414,6 +1502,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: @@ -2983,6 +3081,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);