From 462b4e732f3c1a83fc1007feee086c8876ea26ee Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Wed, 17 May 2017 15:01:17 -0400 Subject: [PATCH] start of new protocol code. --- src/include/protocol.h | 26 ++++++++ src/main/virtual_servers.c | 79 +++++++++++++++++++----- src/modules/proto_radius/all.mk | 2 +- src/modules/proto_radius/proto_radius.c | 69 +++++++++++++++++++++ src/modules/proto_radius/proto_radius.mk | 9 +++ 5 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 src/modules/proto_radius/proto_radius.c create mode 100644 src/modules/proto_radius/proto_radius.mk diff --git a/src/include/protocol.h b/src/include/protocol.h index ce021bf786b5..fbc8369de71b 100644 --- a/src/include/protocol.h +++ b/src/include/protocol.h @@ -84,6 +84,32 @@ int common_socket_open(CONF_SECTION *cs, rad_listen_t *this); int common_socket_print(rad_listen_t const *this, char *buffer, size_t bufsize); void common_packet_debug(REQUEST *request, RADIUS_PACKET *packet, bool received); + +typedef int (*fr_app_bootstrap_t)(CONF_SECTION *); + +/* + * src/lib/io/transport.h + */ +typedef struct fr_transport_t fr_transport_t; + +typedef struct fr_app_io_t { + int fd; + void *ctx; + fr_transport_t *transport; +} fr_app_io_t; + +typedef fr_app_io_t *(*fr_app_compile_t)(CONF_SECTION *); + +/* + * Functions for new virtual servers and listeners + */ +typedef struct fr_app_t { + RAD_MODULE_COMMON; //!< Common fields to all loadable modules. + + fr_app_bootstrap_t bootstrap; + fr_app_compile_t compile; +} fr_app_t; + #ifdef __cplusplus } #endif diff --git a/src/main/virtual_servers.c b/src/main/virtual_servers.c index e4acf87a9d1a..3d908273f666 100644 --- a/src/main/virtual_servers.c +++ b/src/main/virtual_servers.c @@ -31,6 +31,7 @@ RCSID("$Id$") #include #include #include +#include static int default_component_results[MOD_COUNT] = { RLM_MODULE_REJECT, /* AUTH */ @@ -543,6 +544,7 @@ int virtual_servers_bootstrap(CONF_SECTION *config) cs = cf_subsection_find_next(config, cs, "server")) { CONF_ITEM *ci; CONF_SECTION *subcs; + CONF_PAIR *cp; server_name = cf_section_name2(cs); if (!server_name) { @@ -564,6 +566,43 @@ int virtual_servers_bootstrap(CONF_SECTION *config) return -1; } + /* + * New-style virtual servers are special. + */ + cp = cf_pair_find(cs, "namespace"); + if (cp) { + char const *value; + dl_t const *module; + fr_app_t const *app; + + value = cf_pair_value(cp); + if (!value) { + cf_log_err_cs(cs, "Cannot have empty namespace"); + return -1; + } + + if (strcmp(value, "radius") != 0) { + cf_log_err_cs(cs, "Unknown namespace '%s'", value); + return -1; + } + + module = dl_module(cs, NULL, value, DL_TYPE_PROTO); + if (!module) { + cf_log_err_cs(cs, "Failed to find library for 'namespace = %s'", value); + return -1; + } + + app = (fr_app_t const *) module->common; + + if (app->bootstrap && (app->bootstrap(cs) < 0)) { + cf_log_err_cs(cs, "Failed to bootstrap library for 'namespace = %s'", value); + return -1; + } + + cf_data_add(cs, module, "app", false); + continue; + } + for (ci = cf_item_find_next(cs, NULL); ci != NULL; ci = cf_item_find_next(cs, ci)) { @@ -571,19 +610,8 @@ int virtual_servers_bootstrap(CONF_SECTION *config) char const *name1; if (cf_item_is_pair(ci)) { - CONF_PAIR *cp; - - cp = cf_item_to_pair(ci); - name1 = cf_pair_attr(cp); - if (strcmp(name1, "namespace") != 0) { - cf_log_err(ci, "Cannot set variables inside of a virtual server."); - return -1; - } - - if (!cf_pair_value(cp)) { - cf_log_err(ci, "'namespace' cannot be empty"); - return -1; - } + cf_log_err(ci, "Cannot set variables inside of a virtual server."); + return -1; } if (!cf_item_is_section(ci)) continue; @@ -592,8 +620,6 @@ int virtual_servers_bootstrap(CONF_SECTION *config) name1 = cf_section_name1(subcs); if (strcmp(name1, "listen") == 0) { - if (cf_pair_find(cs, "namespace") != NULL) continue; - if (listen_bootstrap(cs, subcs, server_name) < 0) return -1; continue; } @@ -627,6 +653,29 @@ int virtual_servers_init(CONF_SECTION *config) for (cs = cf_subsection_find_next(config, NULL, "server"); cs != NULL; cs = cf_subsection_find_next(config, cs, "server")) { + /* + * Skip new-style virtual servers. + */ + if (cf_pair_find(cs, "namespace")) { + dl_t const *module; + fr_app_t const *app; + fr_app_io_t *io; + + module = cf_data_find(cs, dl_t, "app"); + if (!module) continue; + + app = (fr_app_t const *) module->common; + + if (app->compile) { + io = app->compile(cs); + if (!io) continue; + + DEBUG("Loaded Protocol %s", module->name); + } + + continue; + } + if (virtual_servers_compile(cs) < 0) { return -1; } diff --git a/src/modules/proto_radius/all.mk b/src/modules/proto_radius/all.mk index c42c44f9d855..2938e143df47 100644 --- a/src/modules/proto_radius/all.mk +++ b/src/modules/proto_radius/all.mk @@ -1 +1 @@ -SUBMAKEFILES := proto_radius_acct.mk proto_radius_auth.mk proto_radius_coa.mk proto_radius_status.mk +SUBMAKEFILES := proto_radius.mk proto_radius_acct.mk proto_radius_auth.mk proto_radius_coa.mk proto_radius_status.mk diff --git a/src/modules/proto_radius/proto_radius.c b/src/modules/proto_radius/proto_radius.c new file mode 100644 index 000000000000..5bbc29af1213 --- /dev/null +++ b/src/modules/proto_radius/proto_radius.c @@ -0,0 +1,69 @@ +/* + * proto_radius.c RADIUS master protocol handler + * + * Version: $Id$ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Copyright 2016 The FreeRADIUS server project + * Copyright 2016 Alan DeKok + */ + +#include +#include +#include +#include +#include +#include + +/** Load the RADIUS protocol + * + * Typically loads dictionaries, etc. + */ +static int proto_radius_load(void) +{ + /* + * @todo - load the RADIUS dictionaries + */ + + return 0; +} + +/** Bootstrap the RADIUS protocol in a particular virtual server. + * + */ +static int proto_radius_bootstrap(UNUSED CONF_SECTION *cs) +{ + return 0; +} + + +/** Compile the RADIUS protocol in a particular virtual server. + * + */ +static fr_app_io_t *proto_radius_compile(UNUSED CONF_SECTION *cs) +{ + + return NULL; +} + +extern fr_app_t proto_radius; +fr_app_t proto_radius = { + .magic = RLM_MODULE_INIT, + .name = "radius", + .load = proto_radius_load, + .bootstrap = proto_radius_bootstrap, + .compile = proto_radius_compile, +}; diff --git a/src/modules/proto_radius/proto_radius.mk b/src/modules/proto_radius/proto_radius.mk new file mode 100644 index 000000000000..24a03dd91f19 --- /dev/null +++ b/src/modules/proto_radius/proto_radius.mk @@ -0,0 +1,9 @@ +TARGETNAME := proto_radius + +ifneq "$(TARGETNAME)" "" +TARGET := $(TARGETNAME).a +endif + +SOURCES := proto_radius.c + +TGT_PREREQS := libfreeradius-util.a libfreeradius-radius.a