mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-03-16 14:57:48 +08:00
radius: replace experimental Group-Name with Class attribute
The current format allows to handle multiple groups and is used by several radius servers. Suggested by Yick Xie.
This commit is contained in:
committed by
Nikos Mavrogiannopoulos
parent
0b4333d7ee
commit
ade786a0f1
@@ -82,6 +82,11 @@ ATTRIBUTE Framed-IP-Netmask 9 ipaddr
|
||||
# a CIDR string)
|
||||
ATTRIBUTE Framed-Route 22 string
|
||||
|
||||
# Sets group name using format "OU=group1;group2"
|
||||
# Note that the groups sent by the server must be made known
|
||||
# to ocserv, via the select-group variable.
|
||||
ATTRIBUTE Class 25 string
|
||||
|
||||
# sets DNS servers
|
||||
VENDOR Microsoft 311
|
||||
|
||||
@@ -112,14 +117,4 @@ ATTRIBUTE DNS-Server-IPv6-Address 169 ipv6addr
|
||||
# Sets IPv6 routes
|
||||
ATTRIBUTE Framed-IPv6-Prefix 97 ipv6prefix
|
||||
ATTRIBUTE Route-IPv6-Information 170 ipv6prefix
|
||||
|
||||
|
||||
|
||||
############################
|
||||
# Experimental attributes #
|
||||
############################
|
||||
|
||||
# Experimental Non Protocol Attributes used by Cistron-Radiusd
|
||||
#
|
||||
ATTRIBUTE Group-Name 1030 string
|
||||
```
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
* Copyright (C) 2014-2016 Red Hat, Inc.
|
||||
* Copyright (C) 2016 Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This file is part of ocserv.
|
||||
*
|
||||
@@ -28,6 +29,7 @@
|
||||
#include <arpa/inet.h> /* inet_ntop */
|
||||
#include "radius.h"
|
||||
#include "auth/common.h"
|
||||
#include "str.h"
|
||||
|
||||
#ifdef HAVE_RADIUS
|
||||
|
||||
@@ -39,7 +41,7 @@
|
||||
# include <radcli/radcli.h>
|
||||
#endif
|
||||
|
||||
#define RAD_GROUP_NAME 1030
|
||||
#define RAD_GROUP_NAME PW_CLASS
|
||||
#define RAD_IPV4_DNS1 ((311<<16)|(28))
|
||||
#define RAD_IPV4_DNS2 ((311<<16)|(29))
|
||||
|
||||
@@ -134,13 +136,16 @@ static int radius_auth_init(void **ctx, void *pool, const common_auth_init_st *i
|
||||
static int radius_auth_group(void *ctx, const char *suggested, char *groupname, int groupname_size)
|
||||
{
|
||||
struct radius_ctx_st *pctx = ctx;
|
||||
unsigned i;
|
||||
|
||||
groupname[0] = 0;
|
||||
|
||||
if (suggested != NULL) {
|
||||
if (strcmp(suggested, pctx->groupname) == 0) {
|
||||
strlcpy(groupname, pctx->groupname, groupname_size);
|
||||
return 0;
|
||||
for (i=0;i<pctx->groupnames_size;i++) {
|
||||
if (strcmp(suggested, pctx->groupnames[i]) == 0) {
|
||||
strlcpy(groupname, pctx->groupnames[i], groupname_size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
syslog(LOG_AUTH,
|
||||
@@ -149,9 +154,10 @@ static int radius_auth_group(void *ctx, const char *suggested, char *groupname,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pctx->groupname[0] != 0 && groupname[0] == 0) {
|
||||
strlcpy(groupname, pctx->groupname, groupname_size);
|
||||
if (pctx->groupnames_size > 0 && groupname[0] == 0) {
|
||||
strlcpy(groupname, pctx->groupnames[0], groupname_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -190,6 +196,39 @@ static void append_route(struct radius_ctx_st *pctx, const char *route, unsigned
|
||||
}
|
||||
}
|
||||
|
||||
/* Parses group of format "OU=group1;group2;group3" */
|
||||
static void parse_groupnames(struct radius_ctx_st *pctx, const char *full)
|
||||
{
|
||||
char *p, *p2;
|
||||
unsigned i;
|
||||
|
||||
pctx->groupnames_size = 0;
|
||||
|
||||
if (strncmp(full, "OU=", 3) == 0) {
|
||||
full += 3;
|
||||
|
||||
p = talloc_strdup(pctx, full);
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
i = 0;
|
||||
p2 = strsep(&p, ";");
|
||||
while(p2 != NULL) {
|
||||
pctx->groupnames[i++] = p2;
|
||||
pctx->groupnames_size = i;
|
||||
|
||||
trim_trailing_whitespace(p2);
|
||||
|
||||
p2 = strsep(&p, ";");
|
||||
}
|
||||
} else {
|
||||
pctx->groupnames[0] = talloc_strdup(pctx, full);
|
||||
if (pctx->groupnames[0] == NULL)
|
||||
return;
|
||||
pctx->groupnames_size = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 0 if the user is successfully authenticated, and sets the appropriate group name.
|
||||
*/
|
||||
static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
|
||||
@@ -290,7 +329,7 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
|
||||
goto fail;
|
||||
} else if (vp->attribute == RAD_GROUP_NAME && vp->type == PW_TYPE_STRING) {
|
||||
/* Group-Name */
|
||||
strlcpy(pctx->groupname, vp->strvalue, sizeof(pctx->groupname));
|
||||
parse_groupnames(pctx, vp->strvalue);
|
||||
} else if (vp->attribute == PW_FRAMED_IPV6_ADDRESS && vp->type == PW_TYPE_IPV6ADDR) {
|
||||
/* Framed-IPv6-Address */
|
||||
if (inet_ntop(AF_INET6, vp->strvalue, pctx->ipv6, sizeof(pctx->ipv6)) != NULL) {
|
||||
|
||||
@@ -25,9 +25,11 @@
|
||||
|
||||
struct radius_ctx_st {
|
||||
char username[MAX_USERNAME_SIZE*2];
|
||||
char groupname[MAX_GROUPNAME_SIZE];
|
||||
char user_agent[MAX_AGENT_NAME];
|
||||
|
||||
char *groupnames[MAX_GROUPS];
|
||||
unsigned groupnames_size;
|
||||
|
||||
char remote_ip[MAX_IP_STR];
|
||||
char our_ip[MAX_IP_STR];
|
||||
unsigned interim_interval_secs;
|
||||
|
||||
14
src/str.c
14
src/str.c
@@ -30,6 +30,20 @@
|
||||
#include <main.h>
|
||||
#include "vasprintf.h"
|
||||
|
||||
void trim_trailing_whitespace(char *str)
|
||||
{
|
||||
unsigned len = strlen(str);
|
||||
char *p;
|
||||
|
||||
if (len > 0) {
|
||||
p = str+len-1;
|
||||
while (c_isspace(*p) && p >= str) {
|
||||
*p = 0;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
|
||||
|
||||
void str_clear(str_st * str)
|
||||
|
||||
@@ -77,6 +77,8 @@ inline static void str_reset(str_st * buf)
|
||||
buf->length = 0;
|
||||
}
|
||||
|
||||
void trim_trailing_whitespace(char *str);
|
||||
|
||||
int str_append_printf(str_st *dest, const char *fmt, ...);
|
||||
int str_append_str(str_st *, const char *str);
|
||||
int str_replace_str(str_st *, const str_rep_tab *tab);
|
||||
|
||||
Reference in New Issue
Block a user