diff options
| -rw-r--r-- | dtls.c | 47 | ||||
| -rw-r--r-- | dtls.h | 8 | ||||
| -rw-r--r-- | radsecproxy.c | 114 | ||||
| -rw-r--r-- | tcp.c | 37 | ||||
| -rw-r--r-- | tcp.h | 6 | ||||
| -rw-r--r-- | tls.c | 43 | ||||
| -rw-r--r-- | tls.h | 6 | ||||
| -rw-r--r-- | udp.c | 42 | ||||
| -rw-r--r-- | udp.h | 8 | 
9 files changed, 174 insertions, 137 deletions
@@ -31,11 +31,44 @@  #include "hash.h"  #include "util.h"  #include "radsecproxy.h" -#include "dtls.h" + +void *udpdtlsserverrd(void *arg); +int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *text); +void *dtlsclientrd(void *arg); +int clientradputdtls(struct server *server, unsigned char *rad); +void addserverextradtls(struct clsrvconf *conf); +void dtlssetsrcres(char *source); +void initextradtls(); + +static const struct protodefs protodefs = { +    "dtls", +    "mysecret", /* secretdefault */ +    SOCK_DGRAM, /* socktype */ +    "2083", /* portdefault */ +    REQUEST_RETRY_COUNT, /* retrycountdefault */ +    10, /* retrycountmax */ +    REQUEST_RETRY_INTERVAL, /* retryintervaldefault */ +    60, /* retryintervalmax */ +    DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    udpdtlsserverrd, /* listener */ +    dtlsconnect, /* connecter */ +    dtlsclientrd, /* clientconnreader */ +    clientradputdtls, /* clientradput */ +    NULL, /* addclient */ +    addserverextradtls, /* addserverextra */ +    dtlssetsrcres, /* setsrcres */ +    initextradtls /* initextra */ +};  static int client4_sock = -1;  static int client6_sock = -1;  static struct addrinfo *srcres = NULL; +static uint8_t handle; + +const struct protodefs *dtlsinit(uint8_t h) { +    handle = h; +    return &protodefs; +}  struct sessioncacheentry {      pthread_mutex_t mutex; @@ -51,7 +84,7 @@ struct dtlsservernewparams {  void dtlssetsrcres(char *source) {      if (!srcres) -	srcres = resolve_hostport_addrinfo(RAD_DTLS, source); +	srcres = resolve_hostport_addrinfo(handle, source);  }  int udp2bio(int s, struct queue *q, int cnt) { @@ -306,9 +339,9 @@ void *dtlsservernew(void *arg) {      uint8_t delay = 60;      debug(DBG_DBG, "dtlsservernew: starting"); -    conf = find_clconf(RAD_DTLS, (struct sockaddr *)¶ms->addr, NULL); +    conf = find_clconf(handle, (struct sockaddr *)¶ms->addr, NULL);      if (conf) { -	ctx = tlsgetctx(RAD_DTLS, conf->tlsconf); +	ctx = tlsgetctx(handle, conf->tlsconf);  	if (!ctx)  	    goto exit;  	ssl = dtlsacccon(1, ctx, params->sock, (struct sockaddr *)¶ms->addr, params->sesscache->rbios); @@ -336,7 +369,7 @@ void *dtlsservernew(void *arg) {  	    }  	    goto exit;  	} -	conf = find_clconf(RAD_DTLS, (struct sockaddr *)¶ms->addr, &cur); +	conf = find_clconf(handle, (struct sockaddr *)¶ms->addr, &cur);      }      debug(DBG_WARN, "dtlsservernew: ignoring request, no matching TLS client"); @@ -521,7 +554,7 @@ int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *  	SSL_free(server->ssl);  	server->ssl = NULL; -	ctx = tlsgetctx(RAD_DTLS, server->conf->tlsconf); +	ctx = tlsgetctx(handle, server->conf->tlsconf);  	if (!ctx)  	    continue;  	server->ssl = dtlsacccon(0, ctx, server->sock, server->conf->addrinfo->ai_addr, server->rbios); @@ -583,7 +616,7 @@ void *udpdtlsclientrd(void *arg) {  	    continue;  	} -	conf = find_srvconf(RAD_DTLS, (struct sockaddr *)&from, NULL); +	conf = find_srvconf(handle, (struct sockaddr *)&from, NULL);  	if (!conf) {  	    debug(DBG_WARN, "udpdtlsclientrd: got packet from wrong or unknown DTLS peer %s, ignoring", addr2string((struct sockaddr *)&from));  	    recv(s, buf, 4, 0); @@ -6,10 +6,4 @@   * copyright notice and this permission notice appear in all copies.   */ -void dtlssetsrcres(char *source); -void *udpdtlsserverrd(void *arg); -int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *text); -void *dtlsclientrd(void *arg); -int clientradputdtls(struct server *server, unsigned char *rad); -void addserverextradtls(struct clsrvconf *conf); -void initextradtls(); +const struct protodefs *dtlsinit(uint8_t h); diff --git a/radsecproxy.c b/radsecproxy.c index 8b1efa6..c041ae2 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -86,6 +86,7 @@ static pthread_mutex_t *ssl_locks = NULL;  static long *ssl_lock_count;  extern int optind;  extern char *optarg; +static const struct protodefs *protodefs[RAD_PROTOCOUNT + 1];  /* minimum required declarations to avoid reordering code */  struct realm *adddynamicrealmserver(struct realm *realm, struct clsrvconf *conf, char *id); @@ -97,87 +98,10 @@ void freerq(struct request *rq);  void freerqoutdata(struct rqout *rqout);  void rmclientrq(struct request *rq, uint8_t id); -static const struct protodefs protodefs[] = { -    {   "udp", /* UDP, assuming RAD_UDP defined as 0 */ -	NULL, /* secretdefault */ -	SOCK_DGRAM, /* socktype */ -	"1812", /* portdefault */ -	REQUEST_RETRY_COUNT, /* retrycountdefault */ -	10, /* retrycountmax */ -	REQUEST_RETRY_INTERVAL, /* retryintervaldefault */ -	60, /* retryintervalmax */ -	DUPLICATE_INTERVAL, /* duplicateintervaldefault */ -	udpserverrd, /* listener */ -	NULL, /* connecter */ -	NULL, /* clientconnreader */ -	clientradputudp, /* clientradput */ -	addclientudp, /* addclient */ -	addserverextraudp, /* addserverextra */ -	udpsetsrcres, /* setsrcres */ -	initextraudp /* initextra */ -    }, -    {   "tls", /* TLS, assuming RAD_TLS defined as 1 */ -	"mysecret", /* secretdefault */ -	SOCK_STREAM, /* socktype */ -	"2083", /* portdefault */ -	0, /* retrycountdefault */ -	0, /* retrycountmax */ -	REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */ -	60, /* retryintervalmax */ -	DUPLICATE_INTERVAL, /* duplicateintervaldefault */ -	tlslistener, /* listener */ -	tlsconnect, /* connecter */ -	tlsclientrd, /* clientconnreader */ -	clientradputtls, /* clientradput */ -	NULL, /* addclient */ -	NULL, /* addserverextra */ -	tlssetsrcres, /* setsrcres */ -	NULL /* initextra */ -    }, -    {   "tcp", /* TCP, assuming RAD_TCP defined as 2 */ -	NULL, /* secretdefault */ -	SOCK_STREAM, /* socktype */ -	"1812", /* portdefault */ -	0, /* retrycountdefault */ -	0, /* retrycountmax */ -	REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */ -	60, /* retryintervalmax */ -	DUPLICATE_INTERVAL, /* duplicateintervaldefault */ -	tcplistener, /* listener */ -	tcpconnect, /* connecter */ -	tcpclientrd, /* clientconnreader */ -	clientradputtcp, /* clientradput */ -	NULL, /* addclient */ -	NULL, /* addserverextra */ -	tcpsetsrcres, /* setsrcres */ -	NULL /* initextra */ -    }, -    {   "dtls", /* DTLS, assuming RAD_DTLS defined as 3 */ -	"mysecret", /* secretdefault */ -	SOCK_DGRAM, /* socktype */ -	"2083", /* portdefault */ -	REQUEST_RETRY_COUNT, /* retrycountdefault */ -	10, /* retrycountmax */ -	REQUEST_RETRY_INTERVAL, /* retryintervaldefault */ -	60, /* retryintervalmax */ -	DUPLICATE_INTERVAL, /* duplicateintervaldefault */ -	udpdtlsserverrd, /* listener */ -	dtlsconnect, /* connecter */ -	dtlsclientrd, /* clientconnreader */ -	clientradputdtls, /* clientradput */ -	NULL, /* addclient */ -	addserverextradtls, /* addserverextra */ -	dtlssetsrcres, /* setsrcres */ -	initextradtls /* initextra */ -    }, -    {   NULL, NULL, 0, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -    } -}; -  uint8_t protoname2int(const char *name) {      uint8_t i; -    for (i = 0; protodefs[i].name && strcasecmp(protodefs[i].name, name); i++); +    for (i = 0; protodefs[i]->name && strcasecmp(protodefs[i]->name, name); i++);      return i;  } @@ -372,7 +296,7 @@ struct clsrvconf *resolve_hostport(uint8_t type, char *lconf, char *default_port  	debugx(1, DBG_ERR, "malloc failed");      memset(conf, 0, sizeof(struct clsrvconf));      conf->type = type; -    conf->pdef = &protodefs[conf->type]; +    conf->pdef = protodefs[conf->type];      if (lconf) {  	parsehostport(lconf, conf, default_port);  	if (!strcmp(conf->host, "*")) { @@ -2373,7 +2297,7 @@ void createlistener(uint8_t type, char *arg) {      struct addrinfo *res;      int s = -1, on = 1, *sp = NULL; -    listenres = resolve_hostport(type, arg, protodefs[type].portdefault); +    listenres = resolve_hostport(type, arg, protodefs[type]->portdefault);      if (!listenres)  	debugx(1, DBG_ERR, "createlistener: failed to resolve %s", arg); @@ -2399,14 +2323,14 @@ void createlistener(uint8_t type, char *arg) {          if (!sp)              debugx(1, DBG_ERR, "malloc failed");  	*sp = s; -	if (pthread_create(&th, NULL, protodefs[type].listener, (void *)sp)) +	if (pthread_create(&th, NULL, protodefs[type]->listener, (void *)sp))              debugx(1, DBG_ERR, "pthread_create failed");  	pthread_detach(th);      }      if (!sp)  	debugx(1, DBG_ERR, "createlistener: socket/bind failed"); -    debug(DBG_WARN, "createlistener: listening for %s on %s:%s", protodefs[type].name, +    debug(DBG_WARN, "createlistener: listening for %s on %s:%s", protodefs[type]->name,  	  listenres->host ? listenres->host : "*", listenres->port);      freeclsrvres(listenres);  } @@ -2450,7 +2374,7 @@ void ssl_info_callback(const SSL *ssl, int where, int ret) {  }  #endif -void tlsinit() { +void sslinit() {      int i;      time_t t;      pid_t pid; @@ -2549,7 +2473,7 @@ SSL_CTX *tlscreatectx(uint8_t type, struct tls *conf) {      unsigned long error;      if (!ssl_locks) -	tlsinit(); +	sslinit();      switch (type) {      case RAD_TLS: @@ -3314,7 +3238,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char      if (!conftype)  	debugx(1, DBG_ERR, "error in block %s, option type missing", block);      conf->type = protoname2int(conftype); -    conf->pdef = &protodefs[conf->type]; +    conf->pdef = protodefs[conf->type];      if (!conf->pdef->name)  	debugx(1, DBG_ERR, "error in block %s, unknown transport %s", block, conftype);      free(conftype); @@ -3397,9 +3321,9 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) {      }      if (conf->retryinterval == 255) -	conf->retryinterval = protodefs[conf->type].retryintervaldefault; +	conf->retryinterval = conf->pdef->retryintervaldefault;      if (conf->retrycount == 255) -	conf->retrycount = protodefs[conf->type].retrycountdefault; +	conf->retrycount = conf->pdef->retrycountdefault;      conf->rewritein = conf->confrewritein ? getrewrite(conf->confrewritein, NULL) : getrewrite("defaultserver", "default");      if (conf->confrewriteout) @@ -3482,7 +3406,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char      if (!conftype)  	debugx(1, DBG_ERR, "error in block %s, option type missing", block);      conf->type = protoname2int(conftype); -    conf->pdef = &protodefs[conf->type]; +    conf->pdef = protodefs[conf->type];      if (!conf->pdef->name) {  	debug(DBG_ERR, "error in block %s, unknown transport %s", block, conftype);  	goto errexit; @@ -3805,7 +3729,13 @@ int main(int argc, char **argv) {      debug_init("radsecproxy");      debug_set_level(DEBUG_LEVEL); -  + +    protodefs[RAD_UDP] = udpinit(RAD_UDP); +    protodefs[RAD_TLS] = tlsinit(RAD_TLS); +    protodefs[RAD_TCP] = tcpinit(RAD_TCP); +    protodefs[RAD_DTLS] = dtlsinit(RAD_DTLS); +    protodefs[RAD_PROTOCOUNT + 1] = NULL; +          getargs(argc, argv, &foreground, &pretend, &loglevel, &configfile);      if (loglevel)  	debug_set_level(loglevel); @@ -3849,9 +3779,9 @@ int main(int argc, char **argv) {  	    debugx(1, DBG_ERR, "pthread_create failed");      } -    for (i = 0; protodefs[i].name; i++) { -	if (protodefs[i].initextra) -	    protodefs[i].initextra(); +    for (i = 0; protodefs[i]; i++) { +	if (protodefs[i]->initextra) +	    protodefs[i]->initextra();          if (find_clconf_type(i, NULL))  	    createlisteners(i, options.listenargs[i]);      } @@ -29,13 +29,44 @@  #include "list.h"  #include "util.h"  #include "radsecproxy.h" -#include "tcp.h" + +void *tcplistener(void *arg); +int tcpconnect(struct server *server, struct timeval *when, int timeout, char * text); +void *tcpclientrd(void *arg); +int clientradputtcp(struct server *server, unsigned char *rad); +void tcpsetsrcres(char *source); + +static const struct protodefs protodefs = { +    "tcp", +    NULL, /* secretdefault */ +    SOCK_STREAM, /* socktype */ +    "1812", /* portdefault */ +    0, /* retrycountdefault */ +    0, /* retrycountmax */ +    REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */ +    60, /* retryintervalmax */ +    DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    tcplistener, /* listener */ +    tcpconnect, /* connecter */ +    tcpclientrd, /* clientconnreader */ +    clientradputtcp, /* clientradput */ +    NULL, /* addclient */ +    NULL, /* addserverextra */ +    tcpsetsrcres, /* setsrcres */ +    NULL /* initextra */ +};  static struct addrinfo *srcres = NULL; +static uint8_t handle; + +const struct protodefs *tcpinit(uint8_t h) { +    handle = h; +    return &protodefs; +}  void tcpsetsrcres(char *source) {      if (!srcres) -	srcres = resolve_hostport_addrinfo(RAD_TCP, source); +	srcres = resolve_hostport_addrinfo(handle, source);  }  int tcpconnect(struct server *server, struct timeval *when, int timeout, char *text) { @@ -281,7 +312,7 @@ void *tcpservernew(void *arg) {      }      debug(DBG_WARN, "tcpservernew: incoming TCP connection from %s", addr2string((struct sockaddr *)&from)); -    conf = find_clconf(RAD_TCP, (struct sockaddr *)&from, NULL); +    conf = find_clconf(handle, (struct sockaddr *)&from, NULL);      if (conf) {  	client = addclient(conf, 1);  	if (client) { @@ -6,8 +6,4 @@   * copyright notice and this permission notice appear in all copies.   */ -void tcpsetsrcres(char *source); -int tcpconnect(struct server *server, struct timeval *when, int timeout, char *text); -int clientradputtcp(struct server *server, unsigned char *rad); -void *tcpclientrd(void *arg); -void *tcplistener(void *arg); +const struct protodefs *tcpinit(uint8_t h); @@ -30,13 +30,44 @@  #include "list.h"  #include "util.h"  #include "radsecproxy.h" -#include "tls.h" + +void *tlslistener(void *arg); +int tlsconnect(struct server *server, struct timeval *when, int timeout, char *text); +void *tlsclientrd(void *arg); +int clientradputtls(struct server *server, unsigned char *rad); +void tlssetsrcres(char *source); + +static const struct protodefs protodefs = { +    "tls", +    "mysecret", /* secretdefault */ +    SOCK_STREAM, /* socktype */ +    "2083", /* portdefault */ +    0, /* retrycountdefault */ +    0, /* retrycountmax */ +    REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */ +    60, /* retryintervalmax */ +    DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    tlslistener, /* listener */ +    tlsconnect, /* connecter */ +    tlsclientrd, /* clientconnreader */ +    clientradputtls, /* clientradput */ +    NULL, /* addclient */ +    NULL, /* addserverextra */ +    tlssetsrcres, /* setsrcres */ +    NULL /* initextra */ +};  static struct addrinfo *srcres = NULL; +static uint8_t handle; + +const struct protodefs *tlsinit(uint8_t h) { +    handle = h; +    return &protodefs; +}  void tlssetsrcres(char *source) {      if (!srcres) -	srcres = resolve_hostport_addrinfo(RAD_TLS, source); +	srcres = resolve_hostport_addrinfo(handle, source);  }  int tlsconnect(struct server *server, struct timeval *when, int timeout, char *text) { @@ -90,7 +121,7 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t  	SSL_free(server->ssl);  	server->ssl = NULL; -	ctx = tlsgetctx(RAD_TLS, server->conf->tlsconf); +	ctx = tlsgetctx(handle, server->conf->tlsconf);  	if (!ctx)  	    continue;  	server->ssl = SSL_new(ctx); @@ -347,9 +378,9 @@ void *tlsservernew(void *arg) {      }      debug(DBG_WARN, "tlsservernew: incoming TLS connection from %s", addr2string((struct sockaddr *)&from)); -    conf = find_clconf(RAD_TLS, (struct sockaddr *)&from, &cur); +    conf = find_clconf(handle, (struct sockaddr *)&from, &cur);      if (conf) { -	ctx = tlsgetctx(RAD_TLS, conf->tlsconf); +	ctx = tlsgetctx(handle, conf->tlsconf);  	if (!ctx)  	    goto exit;  	ssl = SSL_new(ctx); @@ -381,7 +412,7 @@ void *tlsservernew(void *arg) {  		debug(DBG_WARN, "tlsservernew: failed to create new client instance");  	    goto exit;  	} -	conf = find_clconf(RAD_TLS, (struct sockaddr *)&from, &cur); +	conf = find_clconf(handle, (struct sockaddr *)&from, &cur);      }      debug(DBG_WARN, "tlsservernew: ignoring request, no matching TLS client");      if (cert) @@ -6,8 +6,4 @@   * copyright notice and this permission notice appear in all copies.   */ -void tlssetsrcres(char *source); -int tlsconnect(struct server *server, struct timeval *when, int timeout, char *text); -int clientradputtls(struct server *server, unsigned char *rad); -void *tlsclientrd(void *arg); -void *tlslistener(void *arg); +const struct protodefs *tlsinit(uint8_t h); @@ -29,17 +29,49 @@  #include "list.h"  #include "util.h"  #include "radsecproxy.h" -#include "tls.h" + +void *udpserverrd(void *arg); +int clientradputudp(struct server *server, unsigned char *rad); +void addclientudp(struct client *client); +void addserverextraudp(struct clsrvconf *conf); +void udpsetsrcres(char *source); +void initextraudp(); + +static const struct protodefs protodefs = { +    "udp", +    NULL, /* secretdefault */ +    SOCK_DGRAM, /* socktype */ +    "1812", /* portdefault */ +    REQUEST_RETRY_COUNT, /* retrycountdefault */ +    10, /* retrycountmax */ +    REQUEST_RETRY_INTERVAL, /* retryintervaldefault */ +    60, /* retryintervalmax */ +    DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    udpserverrd, /* listener */ +    NULL, /* connecter */ +    NULL, /* clientconnreader */ +    clientradputudp, /* clientradput */ +    addclientudp, /* addclient */ +    addserverextraudp, /* addserverextra */ +    udpsetsrcres, /* setsrcres */ +    initextraudp /* initextra */ +};  static int client4_sock = -1;  static int client6_sock = -1;  static struct queue *server_replyq = NULL;  static struct addrinfo *srcres = NULL; +static uint8_t handle; + +const struct protodefs *udpinit(uint8_t h) { +    handle = h; +    return &protodefs; +}  void udpsetsrcres(char *source) {      if (!srcres) -	srcres = resolve_hostport_addrinfo(RAD_UDP, source); +	srcres = resolve_hostport_addrinfo(handle, source);  }  void removeudpclientfromreplyq(struct client *c) { @@ -92,8 +124,8 @@ unsigned char *radudpget(int s, struct client **client, struct server **server,  	}  	p = client -	    ? find_clconf(RAD_UDP, (struct sockaddr *)&from, NULL) -	    : find_srvconf(RAD_UDP, (struct sockaddr *)&from, NULL); +	    ? find_clconf(handle, (struct sockaddr *)&from, NULL) +	    : find_srvconf(handle, (struct sockaddr *)&from, NULL);  	if (!p) {  	    debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer %s, ignoring", addr2string((struct sockaddr *)&from));  	    recv(s, buf, 4, 0); @@ -285,7 +317,7 @@ void initextraudp() {  	if (pthread_create(&cl6th, NULL, udpclientrd, (void *)&client6_sock))  	    debugx(1, DBG_ERR, "pthread_create failed"); -    if (find_clconf_type(RAD_UDP, NULL)) { +    if (find_clconf_type(handle, NULL)) {  	server_replyq = newqueue();  	if (pthread_create(&srvth, NULL, udpserverwr, (void *)server_replyq))  	    debugx(1, DBG_ERR, "pthread_create failed"); @@ -6,10 +6,4 @@   * copyright notice and this permission notice appear in all copies.   */ -void udpsetsrcres(char *source); -int clientradputudp(struct server *server, unsigned char *rad); -void *udpclientrd(void *arg); -void *udpserverrd(void *arg); -void addclientudp(struct client *client); -void addserverextraudp(struct clsrvconf *conf); -void initextraudp(); +const struct protodefs *udpinit(uint8_t h);  | 
