diff options
| -rw-r--r-- | dtls.c | 20 | ||||
| -rw-r--r-- | radsecproxy.c | 76 | ||||
| -rw-r--r-- | radsecproxy.h | 11 | ||||
| -rw-r--r-- | tcp.c | 20 | ||||
| -rw-r--r-- | tls.c | 20 | ||||
| -rw-r--r-- | udp.c | 19 | 
6 files changed, 125 insertions, 41 deletions
| @@ -32,12 +32,14 @@  #include "util.h"  #include "radsecproxy.h" +static void setprotoopts(struct commonprotoopts *opts); +static char **getlistenerargs();  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 dtlssetsrcres();  void initextradtls();  static const struct protodefs protodefs = { @@ -50,6 +52,8 @@ static const struct protodefs protodefs = {      REQUEST_RETRY_INTERVAL, /* retryintervaldefault */      60, /* retryintervalmax */      DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    setprotoopts, /* setprotoopts */ +    getlistenerargs, /* getlistenerargs */      udpdtlsserverrd, /* listener */      dtlsconnect, /* connecter */      dtlsclientrd, /* clientconnreader */ @@ -64,12 +68,21 @@ static int client4_sock = -1;  static int client6_sock = -1;  static struct addrinfo *srcres = NULL;  static uint8_t handle; +static struct commonprotoopts *protoopts = NULL;  const struct protodefs *dtlsinit(uint8_t h) {      handle = h;      return &protodefs;  } +static void setprotoopts(struct commonprotoopts *opts) { +    protoopts = opts; +} + +static char **getlistenerargs() { +    return protoopts ? protoopts->listenargs : NULL; +} +  struct sessioncacheentry {      pthread_mutex_t mutex;      struct queue *rbios; @@ -82,9 +95,10 @@ struct dtlsservernewparams {      struct sockaddr_storage addr;      }; -void dtlssetsrcres(char *source) { +void dtlssetsrcres() {      if (!srcres) -	srcres = resolve_hostport_addrinfo(handle, source); +	srcres = resolve_hostport_addrinfo(handle, protoopts ? protoopts->sourcearg : NULL); +      }  int udp2bio(int s, struct queue *q, int cnt) { diff --git a/radsecproxy.c b/radsecproxy.c index c041ae2..75802e9 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -86,7 +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]; +static const struct protodefs *protodefs[RAD_PROTOCOUNT];  /* minimum required declarations to avoid reordering code */  struct realm *adddynamicrealmserver(struct realm *realm, struct clsrvconf *conf, char *id); @@ -98,11 +98,15 @@ void freerq(struct request *rq);  void freerqoutdata(struct rqout *rqout);  void rmclientrq(struct request *rq, uint8_t id); +static const struct protodefs *(*protoinits[])(uint8_t) = { udpinit, tlsinit, tcpinit, dtlsinit }; +  uint8_t protoname2int(const char *name) {      uint8_t i; -    for (i = 0; protodefs[i]->name && strcasecmp(protodefs[i]->name, name); i++); -    return i; +    for (i = 0; i < RAD_PROTOCOUNT; i++) +	if (protodefs[i] && protodefs[i]->name && !strcasecmp(protodefs[i]->name, name)) +	    return i; +    return 255;  }  /* callbacks for making OpenSSL thread safe */ @@ -591,7 +595,7 @@ int addserver(struct clsrvconf *conf) {      if (type == RAD_DTLS)  	conf->servers->rbios = newqueue(); -    conf->pdef->setsrcres(options.sourcearg[type]); +    conf->pdef->setsrcres();      conf->servers->sock = -1;      if (conf->pdef->addserverextra) @@ -2335,9 +2339,11 @@ void createlistener(uint8_t type, char *arg) {      freeclsrvres(listenres);  } -void createlisteners(uint8_t type, char **args) { +void createlisteners(uint8_t type) {      int i; +    char **args; +    args = protodefs[type]->getlistenerargs();      if (args)  	for (i = 0; args[i]; i++)  	    createlistener(type, args[i]); @@ -3238,10 +3244,10 @@ 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]; -    if (!conf->pdef->name) +    if (conf->type == 255)  	debugx(1, DBG_ERR, "error in block %s, unknown transport %s", block, conftype);      free(conftype); +    conf->pdef = protodefs[conf->type];      if (conf->type == RAD_TLS || conf->type == RAD_DTLS) {  	conf->tlsconf = conf->tls ? tlsgettls(conf->tls, NULL) : tlsgettls("defaultclient", "default"); @@ -3406,13 +3412,14 @@ 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]; -    if (!conf->pdef->name) { +    if (conf->type == 255) {  	debug(DBG_ERR, "error in block %s, unknown transport %s", block, conftype);  	goto errexit;      }      free(conftype);      conftype = NULL; +	 +    conf->pdef = protodefs[conf->type];      if (!conf->confrewritein)  	conf->confrewritein = rewriteinalias; @@ -3583,12 +3590,30 @@ int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, cha      return 1;  } +int setprotoopts(uint8_t type, char **listenargs, char *sourcearg) { +    struct commonprotoopts *protoopts; + +    protoopts = malloc(sizeof(struct commonprotoopts)); +    if (!protoopts) +	return 0; +    memset(protoopts, 0, sizeof(struct commonprotoopts)); +    protoopts->listenargs = listenargs; +    protoopts->sourcearg = sourcearg; +    protodefs[type]->setprotoopts(protoopts); +    return 1; +} +  void getmainconfig(const char *configfile) {      long int addttl = LONG_MIN, loglevel = LONG_MIN;      struct gconffile *cfs; - +    char **listenargs[RAD_PROTOCOUNT]; +    char *sourcearg[RAD_PROTOCOUNT]; +    int i; +          cfs = openconfigfile(configfile);      memset(&options, 0, sizeof(options)); +    memset(&listenargs, 0, sizeof(listenargs)); +    memset(&sourcearg, 0, sizeof(sourcearg));      clconfs = list_create();      if (!clconfs) @@ -3611,14 +3636,14 @@ void getmainconfig(const char *configfile) {  	debugx(1, DBG_ERR, "malloc failed");          if (!getgenericconfig(&cfs, NULL, -			  "ListenUDP", CONF_MSTR, &options.listenargs[RAD_UDP], -			  "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.sourcearg[RAD_UDP], -			  "SourceTCP", CONF_STR, &options.sourcearg[RAD_TCP], -			  "SourceTLS", CONF_STR, &options.sourcearg[RAD_TLS], -			  "SourceDTLS", CONF_STR, &options.sourcearg[RAD_DTLS], +			  "ListenUDP", CONF_MSTR, &listenargs[RAD_UDP], +			  "ListenTCP", CONF_MSTR, &listenargs[RAD_TCP], +			  "ListenTLS", CONF_MSTR, &listenargs[RAD_TLS], +			  "ListenDTLS", CONF_MSTR, &listenargs[RAD_DTLS], +			  "SourceUDP", CONF_STR, &sourcearg[RAD_UDP], +			  "SourceTCP", CONF_STR, &sourcearg[RAD_TCP], +			  "SourceTLS", CONF_STR, &sourcearg[RAD_TLS], +			  "SourceDTLS", CONF_STR, &sourcearg[RAD_DTLS],  			  "TTLAttribute", CONF_STR, &options.ttlattr,  			  "addTTL", CONF_LINT, &addttl,  			  "LogLevel", CONF_LINT, &loglevel, @@ -3645,6 +3670,10 @@ void getmainconfig(const char *configfile) {      }      if (!setttlattr(&options, DEFAULT_TTL_ATTR))      	debugx(1, DBG_ERR, "Failed to set TTLAttribute, exiting"); + +    for (i = 0; i < RAD_PROTOCOUNT; i++) +	if (listenargs[i] || sourcearg[i]) +	    setprotoopts(i, listenargs[i], sourcearg[i]);  }  void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *pretend, uint8_t *loglevel, char **configfile) { @@ -3730,11 +3759,8 @@ 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; +    for (i = 0; i < RAD_PROTOCOUNT; i++) +	protodefs[i] = protoinits[i](i);      getargs(argc, argv, &foreground, &pretend, &loglevel, &configfile);      if (loglevel) @@ -3779,11 +3805,11 @@ int main(int argc, char **argv) {  	    debugx(1, DBG_ERR, "pthread_create failed");      } -    for (i = 0; protodefs[i]; i++) { +    for (i = 0; i < RAD_PROTOCOUNT; i++) {  	if (protodefs[i]->initextra)  	    protodefs[i]->initextra();          if (find_clconf_type(i, NULL)) -	    createlisteners(i, options.listenargs[i]); +	    createlisteners(i);      }      /* just hang around doing nothing, anything to do here? */ diff --git a/radsecproxy.h b/radsecproxy.h index 7a83402..35a7b99 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -32,8 +32,6 @@  #define RAD_PROTOCOUNT 4  struct options { -    char **listenargs[RAD_PROTOCOUNT]; -    char *sourcearg[RAD_PROTOCOUNT];      char *logdestination;      char *ttlattr;      uint32_t ttlattrtype[2]; @@ -42,6 +40,11 @@ struct options {      uint8_t loopprevention;  }; +struct commonprotoopts { +    char **listenargs; +    char *sourcearg; +}; +  struct request {      struct timeval created;      uint32_t refcount; @@ -188,13 +191,15 @@ struct protodefs {      uint8_t retryintervaldefault;      uint8_t retryintervalmax;      uint8_t duplicateintervaldefault; +    void (*setprotoopts)(struct commonprotoopts *); +    char **(*getlistenerargs)();      void *(*listener)(void*);      int (*connecter)(struct server *, struct timeval *, int, char *);      void *(*clientconnreader)(void*);      int (*clientradput)(struct server *, unsigned char *);      void (*addclient)(struct client *);      void (*addserverextra)(struct clsrvconf *); -    void (*setsrcres)(char *source); +    void (*setsrcres)();      void (*initextra)();  }; @@ -30,11 +30,13 @@  #include "util.h"  #include "radsecproxy.h" +static void setprotoopts(struct commonprotoopts *opts); +static char **getlistenerargs();  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); +void tcpsetsrcres();  static const struct protodefs protodefs = {      "tcp", @@ -46,6 +48,8 @@ static const struct protodefs protodefs = {      REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */      60, /* retryintervalmax */      DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    setprotoopts, /* setprotoopts */ +    getlistenerargs, /* getlistenerargs */      tcplistener, /* listener */      tcpconnect, /* connecter */      tcpclientrd, /* clientconnreader */ @@ -58,15 +62,23 @@ static const struct protodefs protodefs = {  static struct addrinfo *srcres = NULL;  static uint8_t handle; - +static struct commonprotoopts *protoopts = NULL;  const struct protodefs *tcpinit(uint8_t h) {      handle = h;      return &protodefs;  } -void tcpsetsrcres(char *source) { +static void setprotoopts(struct commonprotoopts *opts) { +    protoopts = opts; +} + +static char **getlistenerargs() { +    return protoopts ? protoopts->listenargs : NULL; +} + +void tcpsetsrcres() {      if (!srcres) -	srcres = resolve_hostport_addrinfo(handle, source); +	srcres = resolve_hostport_addrinfo(handle, protoopts ? protoopts->sourcearg : NULL);  }  int tcpconnect(struct server *server, struct timeval *when, int timeout, char *text) { @@ -31,11 +31,13 @@  #include "util.h"  #include "radsecproxy.h" +static void setprotoopts(struct commonprotoopts *opts); +static char **getlistenerargs();  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); +void tlssetsrcres();  static const struct protodefs protodefs = {      "tls", @@ -47,6 +49,8 @@ static const struct protodefs protodefs = {      REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT, /* retryintervaldefault */      60, /* retryintervalmax */      DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    setprotoopts, /* setprotoopts */ +    getlistenerargs, /* getlistenerargs */      tlslistener, /* listener */      tlsconnect, /* connecter */      tlsclientrd, /* clientconnreader */ @@ -59,15 +63,25 @@ static const struct protodefs protodefs = {  static struct addrinfo *srcres = NULL;  static uint8_t handle; +static struct commonprotoopts *protoopts = NULL;  const struct protodefs *tlsinit(uint8_t h) {      handle = h;      return &protodefs;  } -void tlssetsrcres(char *source) { +static void setprotoopts(struct commonprotoopts *opts) { +    protoopts = opts; +} + +static char **getlistenerargs() { +    return protoopts ? protoopts->listenargs : NULL; +} + +void tlssetsrcres() {      if (!srcres) -	srcres = resolve_hostport_addrinfo(handle, source); +	srcres = resolve_hostport_addrinfo(handle, protoopts ? protoopts->sourcearg : NULL); +      }  int tlsconnect(struct server *server, struct timeval *when, int timeout, char *text) { @@ -30,11 +30,13 @@  #include "util.h"  #include "radsecproxy.h" +static void setprotoopts(struct commonprotoopts *opts); +static char **getlistenerargs();  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 udpsetsrcres();  void initextraudp();  static const struct protodefs protodefs = { @@ -47,6 +49,8 @@ static const struct protodefs protodefs = {      REQUEST_RETRY_INTERVAL, /* retryintervaldefault */      60, /* retryintervalmax */      DUPLICATE_INTERVAL, /* duplicateintervaldefault */ +    setprotoopts, /* setprotoopts */ +    getlistenerargs, /* getlistenerargs */      udpserverrd, /* listener */      NULL, /* connecter */      NULL, /* clientconnreader */ @@ -63,15 +67,24 @@ static struct queue *server_replyq = NULL;  static struct addrinfo *srcres = NULL;  static uint8_t handle; +static struct commonprotoopts *protoopts = NULL;  const struct protodefs *udpinit(uint8_t h) {      handle = h;      return &protodefs;  } -void udpsetsrcres(char *source) { +static void setprotoopts(struct commonprotoopts *opts) { +    protoopts = opts; +} + +static char **getlistenerargs() { +    return protoopts ? protoopts->listenargs : NULL; +} + +void udpsetsrcres() {      if (!srcres) -	srcres = resolve_hostport_addrinfo(handle, source); +	srcres = resolve_hostport_addrinfo(handle, protoopts ? protoopts->sourcearg : NULL);  }  void removeudpclientfromreplyq(struct client *c) { | 
