From 43caa1be14101d075974192b50f6af5f5850967e Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 24 Feb 2015 12:05:38 +0100 Subject: [PATCH] radius will use the new sub-config format --- doc/sample.config | 8 +-- src/acct/radius.c | 5 +- src/auth/radius.c | 5 +- src/cfg.h | 8 ++- src/config.c | 94 ++---------------------------------- src/ocserv-args.def | 8 +-- src/subconfig.c | 115 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 142 insertions(+), 101 deletions(-) diff --git a/doc/sample.config b/doc/sample.config index 5e453d6e..bf08836c 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -1,7 +1,7 @@ # User authentication method. Could be set multiple times and in # that case all should succeed. To enable multiple methods use # multiple auth directives. Available options: certificate, -# plain, pam, radius[configfile,groupconfig], gssapi. +# plain, pam, radius[config=configfile,groupconfig=trueval], gssapi. # # Note that authentication methods cannot be changed with reload. @@ -19,7 +19,7 @@ # One entry must be listed per line, and 'ocpasswd' should be used # to generate password entries. # -# radius[/etc/radiusclient/radiusclient.conf,groupconfig]: +# radius[config=/etc/radiusclient/radiusclient.conf,groupconfig=true]: # The radius option requires specifying freeradius-client configuration # file. If the groupconfig option is set, then config-per-user will be overriden, # and all configuration will be read from radius. The supported atributes for @@ -31,7 +31,7 @@ #auth = "pam[gid-min=1000]" auth = "plain[./sample.passwd]" #auth = "certificate" -#auth = "radius[/etc/radiusclient/radiusclient.conf,groupconfig]" +#auth = "radius[config=/etc/radiusclient/radiusclient.conf,groupconfig=true]" # Specify alternative authentication methods that are sufficient # for authentication. That is, if set, any of the methods enabled @@ -49,7 +49,7 @@ auth = "plain[./sample.passwd]" # # Only one accounting method can be specified. #acct = "pam" -#acct = "radius[/etc/radiusclient/radiusclient.conf]" +#acct = "radius[config=/etc/radiusclient/radiusclient.conf]" # Whether to enable seccomp/Linux namespaces worker isolation. That restricts the number of # system calls allowed to a worker process, in order to reduce damage from a diff --git a/src/acct/radius.c b/src/acct/radius.c index 378c8b20..32dd1f7e 100644 --- a/src/acct/radius.c +++ b/src/acct/radius.c @@ -35,13 +35,16 @@ #include #include "auth/radius.h" #include "acct/radius.h" +#include "cfg.h" static rc_handle *rh = NULL; static char nas_identifier[64]; static void acct_radius_global_init(void *pool, const char *server_name, void *additional) { - rh = rc_read_config(additional); + radius_cfg_st *config = additional; + + rh = rc_read_config(config->config); if (rh == NULL) { fprintf(stderr, "radius initialization error\n"); exit(1); diff --git a/src/auth/radius.c b/src/auth/radius.c index 5a17329a..7aa89d00 100644 --- a/src/auth/radius.c +++ b/src/auth/radius.c @@ -31,6 +31,7 @@ #ifdef HAVE_RADIUS +#include "cfg.h" #include #define RAD_GROUP_NAME 1030 @@ -42,7 +43,9 @@ static char nas_identifier[64]; static void radius_global_init(void *pool, const char *server_name, void *additional) { - rh = rc_read_config(additional); + radius_cfg_st *config = additional; + + rh = rc_read_config(config->config); if (rh == NULL) { fprintf(stderr, "radius initialization error\n"); exit(1); diff --git a/src/cfg.h b/src/cfg.h index 625de863..dcb29bb0 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -33,6 +33,10 @@ typedef struct gssapi_cfg_st { unsigned no_local_map; } gssapi_cfg_st; +typedef struct radius_cfg_st { + char *config; +} radius_cfg_st; + unsigned expand_brackets_string(struct cfg_st *config, const char *str, subcfg_val_st out[MAX_SUBOPTIONS]); inline static void free_expanded_brackets_string(subcfg_val_st out[MAX_SUBOPTIONS], unsigned size) { @@ -43,8 +47,10 @@ inline static void free_expanded_brackets_string(subcfg_val_st out[MAX_SUBOPTION } } -#define CHECK_TRUE(str) (c_strcasecmp(str, "true") == 0 || c_strcasecmp(str, "yes") == 0)?1:0 +#define CHECK_TRUE(str) (str != NULL && (c_strcasecmp(str, "true") == 0 || c_strcasecmp(str, "yes") == 0))?1:0 +void *get_brackets_string1(struct cfg_st *config, const char *str); void *gssapi_get_brackets_string(struct cfg_st *config, const char *str); +void *radius_get_brackets_string(struct cfg_st *config, const char *str); #endif diff --git a/src/config.c b/src/config.c index 7fea9288..9f9c7eb2 100644 --- a/src/config.c +++ b/src/config.c @@ -167,66 +167,6 @@ static struct cfg_options available_options[] = { { .name = "default-group-config", .type = OPTION_STRING, .mandatory = 0 }, }; -#define get_brackets_string get_brackets_string1 -static void *get_brackets_string1(struct cfg_st *config, const char *str); - -#ifdef HAVE_RADIUS -static void *get_brackets_string2(struct cfg_st *config, const char *str) -{ - char *p, *p2; - unsigned len; - - p = strchr(str, '['); - if (p == NULL) { - return NULL; - } - p++; - - p = strchr(p, ','); - if (p == NULL) { - return NULL; - } - p++; - - while (c_isspace(*p)) - p++; - - p2 = strchr(p, ','); - if (p2 == NULL) { - p2 = strchr(p, ']'); - if (p2 == NULL) { - fprintf(stderr, "error parsing %s\n", str); - exit(1); - } - } - - len = p2 - p; - - return talloc_strndup(config, p, len); -} - -static void *radius_get_brackets_string(struct cfg_st *config, const char *str) -{ - char *ret, *p; - - ret = get_brackets_string1(config, str); - if (ret == NULL) { - fprintf(stderr, "No radius configuration specified: %s\n", str); - exit(1); - } - - p = get_brackets_string2(config, str); - if (p != NULL) { - if (strcasecmp(p, "groupconfig") != 0) { - fprintf(stderr, "No known configuration option: %s\n", p); - exit(1); - } - config->sup_config_type = SUP_CONFIG_RADIUS; - } - return ret; -} -#endif - static const tOptionValue* get_option(const char* name, unsigned * mand) { unsigned j; @@ -285,7 +225,7 @@ unsigned j; continue; \ s_name[num] = talloc_strdup(config, val->v.strVal); \ xp = strchr(s_name[num], '['); if (xp != NULL) *xp = 0; \ - s_name2[num] = get_brackets_string(config, val->v.strVal); \ + s_name2[num] = get_brackets_string1(config, val->v.strVal); \ num++; \ if (num>=MAX_CONFIG_ENTRIES) \ break; \ @@ -382,32 +322,6 @@ unsigned j; } } -static void *get_brackets_string1(struct cfg_st *config, const char *str) -{ - char *p, *p2; - unsigned len; - - p = strchr(str, '['); - if (p == NULL) { - return NULL; - } - p++; - while (c_isspace(*p)) - p++; - - p2 = strchr(p, ','); - if (p2 == NULL) { - p2 = strchr(p, ']'); - if (p2 == NULL) { - fprintf(stderr, "error parsing %s\n", str); - exit(1); - } - } - - len = p2 - p; - - return talloc_strndup(config, p, len); -} /* Parses the string ::1/prefix, to return prefix * and modify the string to contain the network only. @@ -443,7 +357,7 @@ typedef struct auth_types_st { static auth_types_st avail_auth_types[] = { #ifdef HAVE_PAM - {NAME("pam"), &pam_auth_funcs, AUTH_TYPE_PAM, get_brackets_string}, + {NAME("pam"), &pam_auth_funcs, AUTH_TYPE_PAM, get_brackets_string1}, #endif #ifdef HAVE_GSSAPI {NAME("gssapi"), &gssapi_auth_funcs, AUTH_TYPE_GSSAPI, gssapi_get_brackets_string}, @@ -451,7 +365,7 @@ static auth_types_st avail_auth_types[] = #ifdef HAVE_RADIUS {NAME("radius"), &radius_auth_funcs, AUTH_TYPE_RADIUS, radius_get_brackets_string}, #endif - {NAME("plain"), &plain_auth_funcs, AUTH_TYPE_PLAIN, get_brackets_string}, + {NAME("plain"), &plain_auth_funcs, AUTH_TYPE_PLAIN, get_brackets_string1}, {NAME("certificate"), NULL, AUTH_TYPE_CERTIFICATE, NULL}, }; @@ -549,7 +463,7 @@ static acct_types_st avail_acct_types[] = { {NAME("pam"), &pam_acct_funcs, NULL}, #ifdef HAVE_RADIUS - {NAME("radius"), &radius_acct_funcs, get_brackets_string1}, + {NAME("radius"), &radius_acct_funcs, radius_get_brackets_string}, #endif }; diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 86fe518c..8a6ece9a 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -76,7 +76,7 @@ An example configuration file follows. # User authentication method. Could be set multiple times and in # that case all should succeed. To enable multiple methods use # multiple auth directives. Available options: certificate, -# plain, pam, radius[configfile,groupconfig], gssapi. +# plain, pam, radius[config=configfile,groupconfig=trueval], gssapi. # # Note that authentication methods cannot be changed with reload. @@ -94,7 +94,7 @@ An example configuration file follows. # One entry must be listed per line, and 'ocpasswd' should be used # to generate password entries. # -# radius[/etc/radiusclient/radiusclient.conf,groupconfig]: +# radius[config=/etc/radiusclient/radiusclient.conf,groupconfig=true]: # The radius option requires specifying freeradius-client configuration # file. If the groupconfig option is set, then config-per-user will be overriden, # and all configuration will be read from radius. The supported atributes for @@ -106,7 +106,7 @@ An example configuration file follows. #auth = "pam" #auth = "pam[gid-min=1000]" #auth = "plain[/etc/ocserv/ocpasswd]" -#auth = "radius[/etc/radiusclient/radiusclient.conf,groupconfig]" +#auth = "radius[config=/etc/radiusclient/radiusclient.conf,groupconfig=true]" # Specify alternative authentication methods that are sufficient # for authentication. That is, if set, any of the methods enabled @@ -124,7 +124,7 @@ An example configuration file follows. # # Only one accounting method can be specified. #acct = "pam" -#acct = "radius[/etc/radiusclient/radiusclient.conf]" +#acct = "radius[config=/etc/radiusclient/radiusclient.conf]" # Whether to enable seccomp/Linux namespaces worker isolation. That restricts the number of # system calls allowed to a worker process, in order to reduce damage from a diff --git a/src/subconfig.c b/src/subconfig.c index 4dc58481..f1d15879 100644 --- a/src/subconfig.c +++ b/src/subconfig.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include "cfg.h" @@ -112,3 +113,117 @@ void *gssapi_get_brackets_string(struct cfg_st *config, const char *str) return additional; } #endif + +void *get_brackets_string1(struct cfg_st *config, const char *str) +{ + char *p, *p2; + unsigned len; + + p = strchr(str, '['); + if (p == NULL) { + return NULL; + } + p++; + while (c_isspace(*p)) + p++; + + p2 = strchr(p, ','); + if (p2 == NULL) { + p2 = strchr(p, ']'); + if (p2 == NULL) { + fprintf(stderr, "error parsing %s\n", str); + exit(1); + } + } + + len = p2 - p; + + return talloc_strndup(config, p, len); +} + +#ifdef HAVE_RADIUS +static void *get_brackets_string2(struct cfg_st *config, const char *str) +{ + char *p, *p2; + unsigned len; + + p = strchr(str, '['); + if (p == NULL) { + return NULL; + } + p++; + + p = strchr(p, ','); + if (p == NULL) { + return NULL; + } + p++; + + while (c_isspace(*p)) + p++; + + p2 = strchr(p, ','); + if (p2 == NULL) { + p2 = strchr(p, ']'); + if (p2 == NULL) { + fprintf(stderr, "error parsing %s\n", str); + exit(1); + } + } + + len = p2 - p; + + return talloc_strndup(config, p, len); +} + +void *radius_get_brackets_string(struct cfg_st *config, const char *str) +{ + char *p; + subcfg_val_st vals[MAX_SUBOPTIONS]; + unsigned vals_size, i; + radius_cfg_st *additional; + + additional = talloc_zero(config, radius_cfg_st); + if (additional == NULL) { + return NULL; + } + + if (str && str[0] == '[' && str[1] == '/') { /* legacy format */ + fprintf(stderr, "Parsing radius auth method subconfig using legacy format\n"); + + additional->config = get_brackets_string1(config, str); + if (additional->config == NULL) { + fprintf(stderr, "No radius configuration specified: %s\n", str); + exit(1); + } + + p = get_brackets_string2(config, str); + if (p != NULL) { + if (strcasecmp(p, "groupconfig") != 0) { + fprintf(stderr, "No known configuration option: %s\n", p); + exit(1); + } + config->sup_config_type = SUP_CONFIG_RADIUS; + } + } else { + /* new format */ + vals_size = expand_brackets_string(config, str, vals); + for (i=0;iconfig = talloc_strdup(config, vals[i].value); + vals[i].value = NULL; + } else if (c_strcasecmp(vals[i].name, "groupconfig") == 0) { + if (CHECK_TRUE(vals[i].value)) + config->sup_config_type = SUP_CONFIG_RADIUS; + } else { + fprintf(stderr, "unknown option '%s'\n", vals[i].name); + exit(1); + } + } + free_expanded_brackets_string(vals, vals_size); + return additional; + + } + return additional; +} +#endif