Commit ceac2d9d authored by venaas's avatar venaas Committed by venaas
Browse files

added configuration of tcp transport

git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@318 e88ac4ed-0b26-0410-9574-a7f39faa03bf
parent 707854bd
......@@ -63,11 +63,6 @@
static struct options options;
struct list *clconfs, *srvconfs, *realms, *tlsconfs, *rewriteconfs;
static int client_udp_count = 0;
static int client_tls_count = 0;
static int server_udp_count = 0;
static int server_tls_count = 0;
static struct addrinfo *srcudpres = NULL;
static struct addrinfo *srctcpres = NULL;
......@@ -88,20 +83,38 @@ void freeclsrvconf(struct clsrvconf *conf);
void freerqdata(struct request *rq);
static const struct protodefs protodefs[] = {
{ /* UDP, assuming RAD_UDP defined as 0 */
{ "udp", /* UDP, assuming RAD_UDP defined as 0 */
NULL, /* secretdefault */
REQUEST_RETRY_COUNT, /* retrycountdefault */
10, /* retrycountmax */
REQUEST_RETRY_INTERVAL, /* retryintervaldefault */
60 /* retryintervalmax */
},
{ /* TLS, assuming RAD_TLS defined as 1 */
{ "tls", /* TLS, assuming RAD_TLS defined as 1 */
"mysecret", /* secretdefault */
0, /* retrycountdefault */
0, /* retrycountmax */
REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */
60 /* retryintervalmax */
},
{ "tcp", /* TCP, assuming RAD_TCP defined as 2 */
NULL, /* secretdefault */
0, /* retrycountdefault */
0, /* retrycountmax */
REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */
60 /* retryintervalmax */
},
{ NULL
}
};
uint8_t protoname2int(const char *name) {
int i;
for (i = 0; protodefs[i].name && strcasecmp(protodefs[i].name, name); i++);
return i;
}
/* callbacks for making OpenSSL thread safe */
unsigned long ssl_thread_id() {
return (unsigned long)pthread_self();
......@@ -452,6 +465,22 @@ struct clsrvconf *find_conf(uint8_t type, struct sockaddr *addr, struct list *co
return NULL;
}
/* returns next config of given type, or NULL */
struct clsrvconf *find_conf_type(uint8_t type, struct list *confs, struct list_node **cur) {
struct list_node *entry;
struct clsrvconf *conf;
for (entry = (cur && *cur ? list_next(*cur) : list_first(confs)); entry; entry = list_next(entry)) {
conf = (struct clsrvconf *)entry->data;
if (conf->type == type) {
if (cur)
*cur = entry;
return conf;
}
}
return NULL;
}
struct replyq *newreplyq() {
struct replyq *replyq;
......@@ -3373,7 +3402,6 @@ void addrewrite(char *value, char **attrs, char **vattrs) {
void freeclsrvconf(struct clsrvconf *conf) {
free(conf->name);
free(conf->conftype);
free(conf->host);
free(conf->port);
free(conf->secret);
......@@ -3418,7 +3446,6 @@ int mergeconfstring(char **dst, char **src) {
/* assumes dst is a shallow copy */
int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
if (!mergeconfstring(&dst->name, &src->name) ||
!mergeconfstring(&dst->conftype, &src->conftype) ||
!mergeconfstring(&dst->host, &src->host) ||
!mergeconfstring(&dst->port, &src->port) ||
!mergeconfstring(&dst->secret, &src->secret) ||
......@@ -3427,6 +3454,8 @@ int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
!mergeconfstring(&dst->confrewrite, &src->confrewrite) ||
!mergeconfstring(&dst->dynamiclookupcommand, &src->dynamiclookupcommand))
return 0;
if (src->pdef)
dst->pdef = src->pdef;
dst->statusserver = src->statusserver;
dst->certnamecheck = src->certnamecheck;
if (src->retryinterval != 255)
......@@ -3435,9 +3464,10 @@ int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
dst->retrycount = src->retrycount;
return 1;
}
int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
struct clsrvconf *conf;
char *conftype = NULL;
debug(DBG_DBG, "confclient_cb called for %s", block);
......@@ -3448,7 +3478,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
conf->certnamecheck = 1;
if (!getgenericconfig(cf, block,
"type", CONF_STR, &conf->conftype,
"type", CONF_STR, &conftype,
"host", CONF_STR, &conf->host,
"secret", CONF_STR, &conf->secret,
"tls", CONF_STR, &conf->tls,
......@@ -3463,20 +3493,22 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
conf->name = stringcopy(val, 0);
if (!conf->host)
conf->host = stringcopy(val, 0);
if (!conftype)
debugx(1, DBG_ERR, "error in block %s, option type missing", block);
conf->type = protoname2int(conftype);
conf->pdef = &protodefs[conf->type];
if (!conf->pdef->name)
debugx(1, DBG_ERR, "error in block %s, unknown transport %s", block, conftype);
free(conftype);
if (conf->conftype && !strcasecmp(conf->conftype, "udp")) {
conf->type = RAD_UDP;
client_udp_count++;
} else if (conf->conftype && !strcasecmp(conf->conftype, "tls")) {
if (conf->type == RAD_TLS) {
conf->ssl_ctx = conf->tls ? tlsgetctx(conf->tls, NULL) : tlsgetctx("defaultclient", "default");
if (!conf->ssl_ctx)
debugx(1, DBG_ERR, "error in block %s, no tls context defined", block);
if (conf->matchcertattr && !addmatchcertattr(conf))
debugx(1, DBG_ERR, "error in block %s, invalid MatchCertificateAttributeValue", block);
conf->type = RAD_TLS;
client_tls_count++;
} else
debugx(1, DBG_ERR, "error in block %s, type must be set to UDP or TLS", block);
}
conf->rewrite = conf->confrewrite ? getrewrite(conf->confrewrite, NULL) : getrewrite("defaultclient", "default");
......@@ -3489,9 +3521,11 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
debugx(1, DBG_ERR, "failed to resolve host %s port %s, exiting", conf->host ? conf->host : "(null)", conf->port ? conf->port : "(null)");
if (!conf->secret) {
if (conf->type != RAD_TLS)
debugx(1, DBG_ERR, "error in block %s, secret must be specified when not TLS", block);
conf->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
if (!conf->pdef->secretdefault)
debugx(1, DBG_ERR, "error in block %s, secret must be specified for transport type %s", block, conf->pdef->name);
conf->secret = stringcopy(conf->pdef->secretdefault, 0);
if (!conf->secret)
debugx(1, DBG_ERR, "malloc failed");
}
return 1;
}
......@@ -3523,10 +3557,13 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) {
conf->retrycount = protodefs[conf->type].retrycountdefault;
conf->rewrite = conf->confrewrite ? getrewrite(conf->confrewrite, NULL) : getrewrite("defaultserver", "default");
if (!conf->secret) {
if (conf->type != RAD_TLS)
debug(DBG_ERR, "error in block %s, secret must be specified when not TLS", block);
conf->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
if (!conf->pdef->secretdefault) {
debug(DBG_ERR, "error in block %s, secret must be specified for transport type %s", block, conf->pdef->name);
return 0;
}
conf->secret = stringcopy(conf->pdef->secretdefault, 0);
if (!conf->secret) {
debug(DBG_ERR, "malloc failed");
return 0;
......@@ -3542,7 +3579,7 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) {
int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
struct clsrvconf *conf, *resconf;
const struct protodefs *pdef;
char *conftype = NULL;
long int retryinterval = LONG_MIN, retrycount = LONG_MIN;
debug(DBG_DBG, "confserver_cb called for %s", block);
......@@ -3561,7 +3598,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
conf->certnamecheck = 1;
if (!getgenericconfig(cf, block,
"type", CONF_STR, &conf->conftype,
"type", CONF_STR, &conftype,
"host", CONF_STR, &conf->host,
"port", CONF_STR, &conf->port,
"secret", CONF_STR, &conf->secret,
......@@ -3591,20 +3628,21 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
goto errexit;
}
}
if (conf->conftype && !strcasecmp(conf->conftype, "udp"))
conf->type = RAD_UDP;
else if (conf->conftype && !strcasecmp(conf->conftype, "tls"))
conf->type = RAD_TLS;
else {
debug(DBG_ERR, "error in block %s, type must be set to UDP or TLS", block);
if (!conftype)
debugx(1, DBG_ERR, "error in block %s, option type missing", block);
conf->type = protoname2int(conftype);
conf->pdef = &protodefs[conf->type];
if (!conf->pdef->name) {
debug(DBG_ERR, "error in block %s, unknown transport %s", block, conftype);
free(conftype);
goto errexit;
}
pdef = &protodefs[conf->type];
free(conftype);
if (retryinterval != LONG_MIN) {
if (retryinterval < 1 || retryinterval > pdef->retryintervalmax) {
debug(DBG_ERR, "error in block %s, value of option RetryInterval is %d, must be 1-%d", block, retryinterval, pdef->retryintervalmax);
if (retryinterval < 1 || retryinterval > conf->pdef->retryintervalmax) {
debug(DBG_ERR, "error in block %s, value of option RetryInterval is %d, must be 1-%d", block, retryinterval, conf->pdef->retryintervalmax);
goto errexit;
}
conf->retryinterval = (uint8_t)retryinterval;
......@@ -3612,8 +3650,8 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
conf->retryinterval = 255;
if (retrycount != LONG_MIN) {
if (retrycount < 0 || retrycount > pdef->retrycountmax) {
debug(DBG_ERR, "error in block %s, value of option RetryCount is %d, must be 0-%d", block, pdef->retrycountmax);
if (retrycount < 0 || retrycount > conf->pdef->retrycountmax) {
debug(DBG_ERR, "error in block %s, value of option RetryCount is %d, must be 0-%d", block, retrycount, conf->pdef->retrycountmax);
goto errexit;
}
conf->retrycount = (uint8_t)retrycount;
......@@ -3639,17 +3677,6 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
if (resconf)
return 1;
switch (conf->type) {
case RAD_UDP:
server_udp_count++;
break;
case RAD_TLS:
server_tls_count++;
break;
default:
goto errexit;
}
if (!list_push(srvconfs, conf)) {
debug(DBG_ERR, "malloc failed");
goto errexit;
......@@ -3751,6 +3778,7 @@ void getmainconfig(const char *configfile) {
if (!getgenericconfig(&cfs, NULL,
"ListenUDP", CONF_MSTR, &options.listenudp,
"ListenTCP", CONF_MSTR, &options.listentcp,
"ListenTLS", CONF_MSTR, &options.listentls,
"ListenAccountingUDP", CONF_MSTR, &options.listenaccudp,
"SourceUDP", CONF_STR, &options.sourceudp,
"SourceTCP", CONF_STR, &options.sourcetcp,
......@@ -3886,8 +3914,8 @@ int main(int argc, char **argv) {
sigaddset(&sigset, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
pthread_create(&sigth, NULL, sighandler, NULL);
if (client_udp_count) {
if (find_conf_type(RAD_UDP, clconfs, NULL)) {
udp_server_replyq = newreplyq();
if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
debugx(1, DBG_ERR, "pthread_create failed");
......@@ -3918,8 +3946,8 @@ int main(int argc, char **argv) {
if (pthread_create(&udpclient6rdth, NULL, udpclientrd, (void *)&udp_client6_sock))
debugx(1, DBG_ERR, "pthread_create failed");
if (client_tls_count)
createlisteners(RAD_TLS, options.listentcp, 0);
if (find_conf_type(RAD_TLS, clconfs, NULL))
createlisteners(RAD_TLS, options.listentls, 0);
/* just hang around doing nothing, anything to do here? */
for (;;)
......
......@@ -12,7 +12,6 @@
/* MAX_REQUESTS must be 256 due to Radius' 8 bit ID field */
#define MAX_REQUESTS 256
#define DEFAULT_TLS_SECRET "mysecret"
#define DEFAULT_UDP_PORT "1812"
#define DEFAULT_TLS_PORT "2083"
#define REQUEST_RETRY_INTERVAL 5
......@@ -31,6 +30,7 @@
#define RAD_UDP 0
#define RAD_TLS 1
#define RAD_TCP 2
#define RAD_Attr_User_Name 1
#define RAD_Attr_User_Password 2
......@@ -46,6 +46,7 @@
struct options {
char **listenudp;
char **listentcp;
char **listentls;
char **listenaccudp;
char *sourceudp;
char *sourcetcp;
......@@ -88,8 +89,8 @@ struct listenerarg {
struct clsrvconf {
char *name;
char *conftype;
uint8_t type; /* RAD_UDP/RAD_TLS */
uint8_t type; /* RAD_UDP/RAD_TLS/RAD_TCP */
const struct protodefs *pdef;
char *host;
char *port;
char *secret;
......@@ -166,6 +167,8 @@ struct rewriteconf {
};
struct protodefs {
char *name;
char *secretdefault;
uint8_t retrycountdefault;
uint8_t retrycountmax;
uint8_t retryintervaldefault;
......
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