Commit 94bb9292 authored by venaas's avatar venaas Committed by venaas
Browse files

added initial ttl support, need testing

git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@430 e88ac4ed-0b26-0410-9574-a7f39faa03bf
parent d31e6fdb
......@@ -110,7 +110,6 @@ static const struct protodefs protodefs[] = {
60, /* retryintervalmax */
DUPLICATE_INTERVAL, /* duplicateintervaldefault */
udpserverrd, /* listener */
&options.sourceudp, /* srcaddrport */
NULL, /* connecter */
NULL, /* clientconnreader */
clientradputudp, /* clientradput */
......@@ -129,7 +128,6 @@ static const struct protodefs protodefs[] = {
60, /* retryintervalmax */
DUPLICATE_INTERVAL, /* duplicateintervaldefault */
tlslistener, /* listener */
&options.sourcetls, /* srcaddrport */
tlsconnect, /* connecter */
tlsclientrd, /* clientconnreader */
clientradputtls, /* clientradput */
......@@ -148,7 +146,6 @@ static const struct protodefs protodefs[] = {
60, /* retryintervalmax */
DUPLICATE_INTERVAL, /* duplicateintervaldefault */
tcplistener, /* listener */
&options.sourcetcp, /* srcaddrport */
tcpconnect, /* connecter */
tcpclientrd, /* clientconnreader */
clientradputtcp, /* clientradput */
......@@ -167,7 +164,6 @@ static const struct protodefs protodefs[] = {
60, /* retryintervalmax */
DUPLICATE_INTERVAL, /* duplicateintervaldefault */
udpdtlsserverrd, /* listener */
&options.sourcedtls, /* srcaddrport */
dtlsconnect, /* connecter */
dtlsclientrd, /* clientconnreader */
clientradputdtls, /* clientradput */
......@@ -668,7 +664,7 @@ int addserver(struct clsrvconf *conf) {
conf->servers->rbios = newqueue();
if (!srcprotores[type]) {
res = resolve_hostport(type, *conf->pdef->srcaddrport, NULL);
res = resolve_hostport(type, options.sourcearg[type], NULL);
srcprotores[type] = res->addrinfo;
res->addrinfo = NULL;
freeclsrvres(res);
......@@ -1610,6 +1606,100 @@ int rewriteusername(struct request *rq, struct tlv *attr) {
return 1;
}
int addvendorattr(struct radmsg *msg, uint32_t vendor, struct tlv *attr) {
struct tlv *vattr;
uint8_t l, *v;
l = attr->l + 6;
v = malloc(l);
if (v) {
vendor = htonl(vendor);
memcpy(v, &vendor, 4);
tlv2buf(v + 4, attr);
vattr = maketlv(RAD_Attr_Vendor_Specific, l, v);
if (vattr && radmsg_add(msg, vattr))
return 1;
freetlv(vattr);
}
return 0;
}
void addttlattr(struct radmsg *msg, uint32_t *attrtype, uint8_t addttl) {
uint8_t ttl[4];
struct tlv *attr;
memset(ttl, 0, 4);
ttl[3] = addttl;
if (attrtype[1] == -1) { /* not vendor */
attr = maketlv(attrtype[0], 4, ttl);
if (attr && !radmsg_add(msg, attr))
freetlv(attr);
} else {
attr = maketlv(attrtype[1], 4, ttl);
if (attr) {
addvendorattr(msg, attrtype[0], attr);
freetlv(attr);
}
}
}
int decttl(uint8_t l, uint8_t *v) {
int i;
i = l - 1;
if (v[i]) {
if (--v[i--])
return 1;
while (i >= 0 && !v[i])
i--;
return i >= 0;
}
for (i--; i >= 0 && !v[i]; i--);
if (i < 0)
return 0;
v[i]--;
while (++i < l)
v[i] = 255;
return 1;
}
int dottl(struct radmsg *msg, uint32_t *attrtype, uint8_t addttl) {
uint8_t alen, *subattrs;
struct tlv *attr;
struct list_node *node;
uint32_t vendor;
int sublen;
if (attrtype[1] == -1) { /* not vendor */
attr = radmsg_gettype(msg, attrtype[0]);
if (attr)
return decttl(attr->l, attr->v);
} else
for (node = list_first(msg->attrs); node; node = list_next(node)) {
attr = (struct tlv *)node->data;
if (attr->t != RAD_Attr_Vendor_Specific || attr->l <= 4)
continue;
memcpy(&vendor, attr->v, 4);
if (ntohl(vendor) != attrtype[0])
continue;
sublen = attr->l - 4;
subattrs = attr->v + 4;
if (!attrvalidate(subattrs, sublen))
continue;
while (sublen > 1) {
if (ATTRTYPE(subattrs) == attrtype[1])
return decttl(ATTRVALLEN(subattrs), ATTRVAL(subattrs));
alen = ATTRLEN(subattrs);
sublen -= alen;
subattrs += alen;
}
}
if (addttl)
addttlattr(msg, attrtype, addttl);
return 1;
}
const char *radmsgtype2string(uint8_t code) {
static const char *rad_msg_names[] = {
"", "Access-Request", "Access-Accept", "Access-Reject",
......@@ -1846,6 +1936,11 @@ int radsrv(struct request *rq) {
if (from->conf->rewritein && !dorewrite(msg, from->conf->rewritein))
goto rmclrqexit;
if (!dottl(msg, options.ttlattrtype, options.addttl)) {
debug(DBG_WARN, "radsrv: ignoring request from client %s (%s), ttl exceeded", from->conf->name, addr2string(from->addr));
goto exit;
}
attr = radmsg_gettype(msg, RAD_Attr_User_Name);
if (!attr) {
if (msg->code == RAD_Accounting_Request) {
......@@ -1885,8 +1980,8 @@ int radsrv(struct request *rq) {
}
if (options.loopprevention && !strcmp(from->conf->name, to->conf->name)) {
debug(DBG_INFO, "radsrv: Loop prevented, not forwarding request from client %s to server %s, discarding",
from->conf->name, to->conf->name);
debug(DBG_INFO, "radsrv: Loop prevented, not forwarding request from client %s (%s) to server %s, discarding",
from->conf->name, addr2string(from->addr), to->conf->name);
goto exit;
}
......@@ -1989,6 +2084,11 @@ void replyh(struct server *server, unsigned char *buf) {
goto errunlock;
}
if (!dottl(msg, options.ttlattrtype, options.addttl)) {
debug(DBG_WARN, "replyh: ignoring reply from server %s, ttl exceeded", server->conf->host);
goto errunlock;
}
/* MS MPPE */
for (node = list_first(msg->attrs); node; node = list_next(node)) {
attr = (struct tlv *)node->data;
......@@ -3079,6 +3179,16 @@ void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs, c
debug(DBG_DBG, "addrewrite: added rewrite block %s", value);
}
int setttlattr(struct options *opts, char *defaultattr) {
char *ttlattr = opts->ttlattr ? opts->ttlattr : defaultattr;
if (vattrname2val(ttlattr, opts->ttlattrtype, opts->ttlattrtype + 1) &&
(opts->ttlattrtype[1] != -1 || opts->ttlattrtype[0] < 256))
return 1;
debug(DBG_ERR, "setttlattr: invalid TTLAttribute value %s", ttlattr);
return 0;
}
void freeclsrvconf(struct clsrvconf *conf) {
free(conf->name);
free(conf->host);
......@@ -3522,7 +3632,7 @@ int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, cha
}
void getmainconfig(const char *configfile) {
long int loglevel = LONG_MIN;
long int addttl = LONG_MIN, loglevel = LONG_MIN;
struct gconffile *cfs;
cfs = openconfigfile(configfile);
......@@ -3553,10 +3663,12 @@ void getmainconfig(const char *configfile) {
"ListenTCP", CONF_MSTR, &options.listenargs[RAD_TCP],
"ListenTLS", CONF_MSTR, &options.listenargs[RAD_TLS],
"ListenDTLS", CONF_MSTR, &options.listenargs[RAD_DTLS],
"SourceUDP", CONF_STR, &options.sourceudp,
"SourceTCP", CONF_STR, &options.sourcetcp,
"SourceTLS", CONF_STR, &options.sourcetls,
"SourceDTLS", CONF_STR, &options.sourcedtls,
"SourceUDP", CONF_STR, &options.sourcearg[RAD_UDP],
"SourceTCP", CONF_STR, &options.sourcearg[RAD_TCP],
"SourceTLS", CONF_STR, &options.sourcearg[RAD_TLS],
"SourceDTLS", CONF_STR, &options.sourcearg[RAD_DTLS],
"TTLAttribute", CONF_STR, &options.ttlattr,
"addTTL", CONF_LINT, &addttl,
"LogLevel", CONF_LINT, &loglevel,
"LogDestination", CONF_STR, &options.logdestination,
"LoopPrevention", CONF_BLN, &options.loopprevention,
......@@ -3574,6 +3686,13 @@ void getmainconfig(const char *configfile) {
debugx(1, DBG_ERR, "error in %s, value of option LogLevel is %d, must be 1, 2, 3 or 4", configfile, loglevel);
options.loglevel = (uint8_t)loglevel;
}
if (addttl != LONG_MIN) {
if (addttl < 1 || addttl > 255)
debugx(1, DBG_ERR, "error in %s, value of option addTTL is %d, must be 1-255", configfile, addttl);
options.addttl = (uint8_t)addttl;
}
if (!setttlattr(&options, DEFAULT_TTL_ATTR))
debugx(1, DBG_ERR, "Failed to set TTLAttribute, exiting");
}
void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *pretend, uint8_t *loglevel, char **configfile) {
......
......@@ -22,6 +22,9 @@
#define STATUS_SERVER_PERIOD 25
#define IDLE_TIMEOUT 300
/* 27262 is vendor DANTE Ltd. */
#define DEFAULT_TTL_ATTR "27262:1"
#define RAD_UDP 0
#define RAD_TLS 1
#define RAD_TCP 2
......@@ -30,11 +33,11 @@
struct options {
char **listenargs[RAD_PROTOCOUNT];
char *sourceudp;
char *sourcetcp;
char *sourcetls;
char *sourcedtls;
char *sourcearg[RAD_PROTOCOUNT];
char *logdestination;
char *ttlattr;
uint32_t ttlattrtype[2];
uint8_t addttl;
uint8_t loglevel;
uint8_t loopprevention;
};
......@@ -185,7 +188,6 @@ struct protodefs {
uint8_t retryintervalmax;
uint8_t duplicateintervaldefault;
void *(*listener)(void*);
char **srcaddrport;
int (*connecter)(struct server *, struct timeval *, int, char *);
void *(*clientconnreader)(void*);
int (*clientradput)(struct server *, unsigned char *);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment