diff --git a/doc/sample.config b/doc/sample.config index bf69ef1e..532d3f5c 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -276,8 +276,8 @@ route = 192.168.5.0/255.255.255.0 # it is needed to switch between them. For these cases the client can # select prior to authentication. Add multiple entries for multiple groups. #select-group = group1 -#select-group = group2 -#select-group = tost +#select-group = group2[My group 2] +#select-group = tost[The tost group] # The name of the group that if selected it would allow to use # the assigned by default group. diff --git a/src/config.c b/src/config.c index f3c56b77..fce6f3be 100644 --- a/src/config.c +++ b/src/config.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -135,6 +136,8 @@ static struct cfg_options available_options[] = { { .name = "default-group-config", .type = OPTION_STRING, .mandatory = 0 }, }; +static char *get_brackets_string(void *pool, const char *str); + static const tOptionValue* get_option(const char* name, unsigned * mand) { unsigned j; @@ -156,6 +159,10 @@ unsigned j; if (s_name == NULL) { \ num = 0; \ s_name = talloc_size(config, sizeof(char*)*MAX_CONFIG_ENTRIES); \ + if (s_name == NULL) { \ + fprintf(stderr, "memory error\n"); \ + exit(1); \ + } \ } \ do { \ if (val && !strcmp(val->pzName, name)==0) \ @@ -171,6 +178,36 @@ unsigned j; exit(1); \ } +#define READ_MULTI_BRACKET_LINE(name, s_name, s_name2, num) \ + val = get_option(name, &mand); \ + if (val != NULL && val->valType == OPARG_TYPE_STRING) { \ + if (s_name == NULL || s_name2 == NULL) { \ + num = 0; \ + s_name = talloc_size(config, sizeof(char*)*MAX_CONFIG_ENTRIES); \ + s_name2 = talloc_size(config, sizeof(char*)*MAX_CONFIG_ENTRIES); \ + if (s_name == NULL || s_name2 == NULL) { \ + fprintf(stderr, "memory error\n"); \ + exit(1); \ + } \ + } \ + do { \ + char *xp; \ + if (val && !strcmp(val->pzName, name)==0) \ + 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); \ + num++; \ + if (num>=MAX_CONFIG_ENTRIES) \ + break; \ + } while((val = optionNextValue(pov, val)) != NULL); \ + s_name[num] = NULL; \ + s_name2[num] = NULL; \ + } else if (mand != 0) { \ + fprintf(stderr, "Configuration option %s is mandatory.\n", name); \ + exit(1); \ + } + #define READ_STRING(name, s_name) \ val = get_option(name, &mand); \ if (val != NULL && val->valType == OPARG_TYPE_STRING) \ @@ -256,6 +293,30 @@ unsigned j; } } +static char *get_brackets_string(void *pool, 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) { + fprintf(stderr, "error parsing %s\n", str); + exit(1); + } + + len = p2 - p; + + return talloc_strndup(pool, p, len); +} + static void parse_cfg_file(const char* file, struct cfg_st *config) { tOptionValue const * pov; @@ -306,21 +367,17 @@ unsigned force_cert_auth; fprintf(stderr, "PAM support is disabled\n"); exit(1); #endif - } else if (strncasecmp(auth[j], "plain[", 6) == 0) { - char* p; - + } else if (strncasecmp(auth[j], "plain", 5) == 0) { if ((config->auth_types & AUTH_TYPE_USERNAME_PASS) != 0) { fprintf(stderr, "You cannot mix multiple username/password authentication methods\n"); exit(1); } - config->plain_passwd = talloc_strdup(config, auth[j]+6); - p = strchr(config->plain_passwd, ']'); - if (p == NULL) { + config->plain_passwd = get_brackets_string(config, auth[j]+5); + if (config->plain_passwd == NULL) { fprintf(stderr, "Format error in %s\n", auth[j]); exit(1); } - *p = 0; amod = &plain_auth_funcs; config->auth_types |= AUTH_TYPE_PLAIN; } else if (c_strcasecmp(auth[j], "certificate") == 0) { @@ -506,7 +563,10 @@ unsigned force_cert_auth; if (auto_select_group != 0 && amod != NULL && amod->group_list != NULL) { amod->group_list(config, config->plain_passwd, &config->group_list, &config->group_list_size); } else { - READ_MULTI_LINE("select-group", config->group_list, config->group_list_size); + READ_MULTI_BRACKET_LINE("select-group", + config->group_list, + config->friendly_group_list, + config->group_list_size); } READ_MULTI_LINE("dns", config->network.dns, config->network.dns_size); diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 74805250..a8696f51 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -349,8 +349,9 @@ route = 192.168.5.0/255.255.255.0 # A client may belong in multiple groups, and in certain use-cases # it is needed to switch between them. For these cases the client can # select prior to authentication. Add multiple entries for multiple groups. +# The group may be followed by a user-friendly name in brackets. #select-group = group1 -#select-group = group2 +#select-group = group2[My special group] # The name of the group that if selected it would allow to use # the assigned by default group. diff --git a/src/vpn.h b/src/vpn.h index ac2a5319..68e908a1 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -201,6 +201,9 @@ struct cfg_st { char **group_list; /* select_group */ unsigned int group_list_size; + + char **friendly_group_list; /* the same size as group_list_size */ + char *default_select_group; char **custom_header; diff --git a/src/worker-auth.c b/src/worker-auth.c index 3552e9cf..90c00214 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -81,6 +81,25 @@ static const char login_msg_no_user_end[] = static int get_cert_info(worker_st * ws); +static int append_group_idx(worker_st * ws, str_st *str, unsigned i) +{ + char temp[128]; + const char *name; + const char *value; + + value = ws->config->group_list[i]; + if (ws->config->friendly_group_list[i] == NULL) + name = ws->config->group_list[i]; + else + name = ws->config->friendly_group_list[i]; + + snprintf(temp, sizeof(temp), "\n", value, name); + if (str_append_str(str, temp) < 0) + return -1; + + return 0; +} + int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) { int ret; @@ -192,6 +211,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) if (dup != 0) continue; + snprintf(temp, sizeof(temp), "\n", ws->cert_groups[i]); ret = str_append_str(&str, temp); if (ret < 0) { @@ -201,9 +221,9 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) } } + for (i=0;iconfig->group_list_size;i++) { - snprintf(temp, sizeof(temp), "\n", ws->config->group_list[i]); - ret = str_append_str(&str, temp); + ret = append_group_idx(ws, &str, i); if (ret < 0) { ret = -1; goto cleanup;