diff options
| author | Linus Nordberg <linus@nordu.net> | 2011-03-21 13:33:22 +0100 | 
|---|---|---|
| committer | Linus Nordberg <linus@nordu.net> | 2011-03-21 13:33:22 +0100 | 
| commit | 217d24060890986d38848e0a9fd68ae6e7d1727f (patch) | |
| tree | c198d491ae8d4da1965dd295d56e9d84eeee12e1 /lib | |
| parent | ab01223c4583cb5da93046b05baddc75a3b27bc8 (diff) | |
API AND CONFIG CHANGE: rs_context_create() doesn't take DICT any more.
Use rs_context_create() to read FreeRADIUS dictionary, possibly by
taking dict file from configuration file.
CONFIG CHANGE: s/config/realm/g.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/conf.c | 69 | ||||
| -rw-r--r-- | lib/examples/client-blocking.c | 14 | ||||
| -rw-r--r-- | lib/examples/client-udp.conf | 10 | ||||
| -rw-r--r-- | lib/examples/client.conf (renamed from lib/examples/client-tls.conf) | 17 | ||||
| -rw-r--r-- | lib/include/radsec/radsec-impl.h | 16 | ||||
| -rw-r--r-- | lib/include/radsec/radsec.h | 24 | ||||
| -rw-r--r-- | lib/radsec.c | 111 | 
7 files changed, 161 insertions, 100 deletions
| @@ -13,8 +13,11 @@  #include "debug.h"  #if 0 -  # client config options -  config NAME { +  # common config options +  dictionary = STRING + +  # common realm config options +  realm NAME {        type = "UDP"|"TCP"|"TLS"|"DTLS"        timeout = INT        retries = INT @@ -22,6 +25,10 @@        #cacertpath = STRING        certfile = STRING        certkeyfile = STRING +  } + +  # client specific realm config options +  realm NAME {        server {            hostname = STRING  	  service = STRING @@ -33,11 +40,12 @@  int  rs_context_read_config(struct rs_context *ctx, const char *config_file)  { -  /* FIXME: Missing some error handling in rs_context_read_config().  */ +  /* FIXME: Missing some error handling!  */ -  cfg_t *cfg, *cfg_config, *cfg_server; +  cfg_t *cfg, *cfg_realm, *cfg_server;    int i, j;    const char *s; +  struct rs_config *config = NULL;    cfg_opt_t server_opts[] =      { @@ -46,7 +54,7 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)        CFG_STR ("secret", "radsec", CFGF_NONE),        CFG_END ()      }; -  cfg_opt_t config_opts[] = +  cfg_opt_t realm_opts[] =      {        CFG_STR ("type", "UDP", CFGF_NONE),        CFG_INT ("timeout", 2, CFGF_NONE), /* FIXME: Remove?  */ @@ -60,7 +68,8 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)      };    cfg_opt_t opts[] =      { -      CFG_SEC ("config", config_opts, CFGF_TITLE | CFGF_MULTI), +      CFG_STR ("dictionary", NULL, CFGF_NONE), +      CFG_SEC ("realm", realm_opts, CFGF_TITLE | CFGF_MULTI),        CFG_END ()      }; @@ -68,31 +77,37 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)    if (cfg_parse (cfg, config_file) == CFG_PARSE_ERROR)      return rs_err_ctx_push (ctx, RSE_CONFIG, "%s: invalid configuration file",  			    config_file); -  for (i = 0; i < cfg_size (cfg, "config"); i++) + +  config = rs_calloc (ctx, 1, sizeof (*config)); +  if (config == NULL) +    return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL); +  ctx->config = config; +  config->dictionary = cfg_getstr (cfg, "dictionary"); + +  for (i = 0; i < cfg_size (cfg, "realm"); i++)      { -      struct rs_realm *r = rs_malloc (ctx, sizeof(*r)); +      struct rs_realm *r = rs_calloc (ctx, 1, sizeof(*r));        const char *typestr;        if (!r)  	return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL); -      memset (r, 0, sizeof(*r)); -      if (ctx->realms) +      if (config->realms)  	{ -	  r->next = ctx->realms->next; -	  ctx->realms->next = r; +	  r->next = config->realms->next; +	  config->realms->next = r;  	}        else -	  ctx->realms = r; -      cfg_config = cfg_getnsec (cfg, "config", i); -      s = cfg_title (cfg_config); +	  config->realms = r; +      cfg_realm = cfg_getnsec (cfg, "realm", i); +      s = cfg_title (cfg_realm);        if (s == NULL)  	return rs_err_ctx_push_fl (ctx, RSE_CONFIG, __FILE__, __LINE__,  				   "missing config name"); -      r->name = strdup (s); +      r->name = strdup (s);	/* FIXME: Don't strdup.  */        if (!r->name)  	return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL); -      typestr = cfg_getstr (cfg_config, "type"); +      typestr = cfg_getstr (cfg_realm, "type");        if (!strcmp (typestr, "UDP"))  	r->type = RS_CONN_TYPE_UDP;        else if (!strcmp (typestr, "TCP")) @@ -104,16 +119,16 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)        else  	return rs_err_ctx_push_fl (ctx, RSE_CONFIG, __FILE__, __LINE__,  				   "invalid connection type: %s", typestr); -      r->timeout = cfg_getint (cfg_config, "timeout"); -      r->retries = cfg_getint (cfg_config, "retries"); +      r->timeout = cfg_getint (cfg_realm, "timeout"); +      r->retries = cfg_getint (cfg_realm, "retries"); -      r->cacertfile = cfg_getstr (cfg_config, "cacertfile"); -      /*r->cacertpath = cfg_getstr (cfg_config, "cacertpath");*/ -      r->certfile = cfg_getstr (cfg_config, "certfile"); -      r->certkeyfile = cfg_getstr (cfg_config, "certkeyfile"); +      r->cacertfile = cfg_getstr (cfg_realm, "cacertfile"); +      /*r->cacertpath = cfg_getstr (cfg_realm, "cacertpath");*/ +      r->certfile = cfg_getstr (cfg_realm, "certfile"); +      r->certkeyfile = cfg_getstr (cfg_realm, "certkeyfile");        /* Add peers, one per server stanza.  */ -      for (j = 0; j < cfg_size (cfg_config, "server"); j++) +      for (j = 0; j < cfg_size (cfg_realm, "server"); j++)  	{  	  struct rs_peer *p = peer_create (ctx, &r->peers);  	  if (!p) @@ -121,7 +136,7 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)  				       NULL);  	  p->realm = r; -	  cfg_server = cfg_getnsec (cfg_config, "server", j); +	  cfg_server = cfg_getnsec (cfg_realm, "server", j);  	  rs_resolv (&p->addr, r->type, cfg_getstr (cfg_server, "hostname"),  		     cfg_getstr (cfg_server, "service"));  	  p->secret = cfg_getstr (cfg_server, "secret"); @@ -130,7 +145,7 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)    /* Save config object in context, for freeing in       rs_context_destroy().  */ -  ctx->cfg =  cfg; +  ctx->config->cfg =  cfg;    return RSE_OK;  } @@ -139,7 +154,7 @@ rs_conf_find_realm(struct rs_context *ctx, const char *name)  {    struct rs_realm *r; -  for (r = ctx->realms; r; r = r->next) +  for (r = ctx->config->realms; r; r = r->next)      if (!strcmp (r->name, name))  	return r;    return NULL; diff --git a/lib/examples/client-blocking.c b/lib/examples/client-blocking.c index 718dc47..23cd674 100644 --- a/lib/examples/client-blocking.c +++ b/lib/examples/client-blocking.c @@ -23,13 +23,15 @@ blocking_client (const char *av1, const char *av2, int use_request_object_flag)    struct rs_packet *req = NULL, *resp = NULL;    struct rs_error *err = NULL; -  if (rs_context_create (&h, "/usr/share/freeradius/dictionary")) +  if (rs_context_create (&h))      return NULL;  #if !defined (USE_CONFIG_FILE)    {      struct rs_peer *server; +    if (rs_context_init_freeradius_dict (h, "/usr/share/freeradius/dictionary")) +      goto cleanup;      if (rs_conn_create (h, &conn, NULL))        goto cleanup;      rs_conn_set_type (conn, RS_CONN_TYPE_UDP); @@ -42,12 +44,14 @@ blocking_client (const char *av1, const char *av2, int use_request_object_flag)      if (rs_peer_set_secret (server, SECRET))        goto cleanup;    } -#else +#else  /* defined (USE_CONFIG_FILE) */    if (rs_context_read_config (h, av1))      goto cleanup; +  if (rs_context_init_freeradius_dict (h, NULL)) +    goto cleanup;    if (rs_conn_create (h, &conn, av2))      goto cleanup; -#endif	/* USE_CONFIG_FILE */ +#endif	/* defined (USE_CONFIG_FILE) */    if (use_request_object_flag)      { @@ -78,7 +82,9 @@ blocking_client (const char *av1, const char *av2, int use_request_object_flag)      fprintf (stderr, "%s: no response\n", __func__);   cleanup: -  err = rs_err_conn_pop (conn); +  err = rs_err_ctx_pop (h); +  if (err == RSE_OK) +    err = rs_err_conn_pop (conn);    if (resp)      rs_packet_destroy (resp);    if (request) diff --git a/lib/examples/client-udp.conf b/lib/examples/client-udp.conf deleted file mode 100644 index 8578e8b..0000000 --- a/lib/examples/client-udp.conf +++ /dev/null @@ -1,10 +0,0 @@ -config blocking-udp { -    type = "UDP" -    timeout = 2 -    retries = 2 -    server { -        hostname = "127.0.0.1" -	service = "1820" -	secret = "sikrit" -    } -} diff --git a/lib/examples/client-tls.conf b/lib/examples/client.conf index 4d0904d..c9500e8 100644 --- a/lib/examples/client-tls.conf +++ b/lib/examples/client.conf @@ -1,9 +1,22 @@ -config blocking-tls { +dictionary = "/usr/share/freeradius/dictionary" + +realm blocking-udp { +    type = "UDP" +    timeout = 2 +    retries = 2 +    server { +        hostname = "127.0.0.1" +	service = "1820" +	secret = "sikrit" +    } +} + +realm blocking-tls {      type = "TLS"      timeout = 1      retries = 3      cacertfile = "/home/linus/nordberg-ca.crt" -#    cacertfile = "/home/linus/p/moonshot/demoCA/cacert.pem" +    #cacertfile = "/home/linus/p/moonshot/demoCA/cacert.pem"      certfile = "/home/linus/p/moonshot/radsecproxy-test.crt"      certkeyfile = "/home/linus/p/moonshot/radsecproxy-test.key"      server { diff --git a/lib/include/radsec/radsec-impl.h b/lib/include/radsec/radsec-impl.h index 3c1c53c..f8891ee 100644 --- a/lib/include/radsec/radsec-impl.h +++ b/lib/include/radsec/radsec-impl.h @@ -35,7 +35,8 @@ struct rs_error {      char buf[1024];  }; -struct rs_peer {		/* Config object for a connection.  */ +/** Configuration object for a connection.  */ +struct rs_peer {      struct rs_connection *conn;      struct rs_realm *realm;      struct evutil_addrinfo *addr; @@ -43,7 +44,8 @@ struct rs_peer {		/* Config object for a connection.  */      struct rs_peer *next;  }; -struct rs_realm {	      /* Config object for a RADIUS realm.  */ +/** Configuration object for a RADIUS realm.  */ +struct rs_realm {      char *name;      enum rs_conn_type type;      int timeout; @@ -56,12 +58,18 @@ struct rs_realm {	      /* Config object for a RADIUS realm.  */      struct rs_realm *next;  }; -struct rs_context { +/** Top configuration object.  */ +struct rs_config { +    char *dictionary;      struct rs_realm *realms; +    cfg_t *cfg; +}; + +struct rs_context { +    struct rs_config *config;      struct rs_alloc_scheme alloc_scheme;      struct rs_error *err;      fr_randctx fr_randctx; -    cfg_t *cfg;  };  struct rs_connection { diff --git a/lib/include/radsec/radsec.h b/lib/include/radsec/radsec.h index 6b0a69c..a35077c 100644 --- a/lib/include/radsec/radsec.h +++ b/lib/include/radsec/radsec.h @@ -91,18 +91,30 @@ struct rs_conn_callbacks {      that the context must not be freed before all other libradsec      objects have been freed. -    \a ctx Address of pointer to a struct rs_context.  This is the output. +    \a ctx Address of pointer to a struct rs_context.  This is the +    output of this function. -    \a dict Name of a FreeRADIUS dictionary. - -    \return RSE_OK (0) on success, RSE_NOMEM on out of memory or -    RSE_FR on FreeRADIUS initialization error.  */ -int rs_context_create(struct rs_context **ctx, const char *dict); +    \return RSE_OK (0) on success or RSE_NOMEM on out of memory.  */ +int rs_context_create(struct rs_context **ctx);  /** Free a context.  Note that the context must not be freed before      all other libradsec objects have been freed.  */  void rs_context_destroy(struct rs_context *ctx); +/** Initialize FreeRADIUS dictionary needed for creating packets. + +    \a ctx Context. + +    \a dict Optional string with full path to FreeRADIUS dictionary. +    If \a dict is NULL the path to the dictionary file is taken from +    the "dictionary" configuration directive.  Note that the +    configuration file must be read prior to using this option (see \a +    rs_context_read_config). + +    \return RSE_OK (0) on success, RSE_NOMEM on memory allocation +    error and RSE_FR on FreeRADIUS error.  */ +int rs_context_init_freeradius_dict(struct rs_context *ctx, const char *dict); +  /** Set allocation scheme to use.  \a scheme is the allocation scheme      to use, see \a rs_alloc_scheme.  \return On success, RSE_OK (0) is      returned.  On error, !0 is returned and a struct \a rs_error is diff --git a/lib/radsec.c b/lib/radsec.c index a05a22b..6ff047d 100644 --- a/lib/radsec.c +++ b/lib/radsec.c @@ -28,14 +28,9 @@  /* Public functions.  */  int -rs_context_create (struct rs_context **ctx, const char *dict) +rs_context_create (struct rs_context **ctx)  { -  int err = RSE_OK;    struct rs_context *h; -  char *buf1 = NULL, *buf2 = NULL; -  char *dir, *fn; - -  assert (dict);    if (ctx)      *ctx = NULL; @@ -43,26 +38,6 @@ rs_context_create (struct rs_context **ctx, const char *dict)    if (!h)      return RSE_NOMEM; -  /* Initialize freeradius dictionary.  */ -  buf1 = malloc (strlen (dict) + 1); -  buf2 = malloc (strlen (dict) + 1); -  if (!buf1 || !buf2) -    { -      err = RSE_NOMEM; -      goto err_out; -    } -  strcpy (buf1, dict); -  dir = dirname (buf1); -  strcpy (buf2, dict); -  fn = basename (buf2); -  if (dict_init (dir, fn) < 0) -    { -      err = RSE_FR; -      goto err_out; -    } -  free (buf1); -  free (buf2); -  #if defined (RS_ENABLE_TLS)    ssl_init ();  #endif @@ -80,15 +55,48 @@ rs_context_create (struct rs_context **ctx, const char *dict)      *ctx = h;    return RSE_OK; +} - err_out: -  if (buf1) -    free (buf1); -  if (buf2) -    free (buf2); -  if (h) -    free (h); -  return err; +/** Initialize freeradius dictionary.  */ +int +rs_context_init_freeradius_dict (struct rs_context *ctx, const char *dict) +{ +  int r = RSE_OK; +  size_t dictlen; +  char *dir = NULL; +  char *fn = NULL; + +  if (dict == NULL) +    if (ctx->config != NULL) +      dict = ctx->config->dictionary; + +  if (dict == NULL) +    return rs_err_ctx_push_fl (ctx, RSE_INVAL, __FILE__, __LINE__, +			       "missing dictionary"); + +  dictlen = strlen (dict); +  dir = rs_calloc (ctx, 1, dictlen + 1); +  fn = rs_calloc (ctx, 1, dictlen + 1); +  if (dir == NULL || fn == NULL) +    { +      r = rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL); +      goto out; +    } +  strncpy (dir, dict, dictlen); +  strncpy (fn, dict, dictlen); + +  if (dict_init (dirname (dir), basename (fn)) < 0) +    { +      r = rs_err_ctx_push_fl (ctx, RSE_FR, __FILE__, __LINE__, "dict_init"); +      goto out; +    } + + out: +  if (dir) +    rs_free (ctx, dir); +  if (fn) +    rs_free (ctx, fn); +  return r;  }  struct rs_error *	   /* FIXME: Return int as all the others?  */ @@ -137,25 +145,34 @@ rs_context_destroy (struct rs_context *ctx)    struct rs_realm *r = NULL;    struct rs_peer *p = NULL; -  for (r = ctx->realms; r; ) +  if (ctx->config)      { -      struct rs_realm *tmp = r; -      for (p = r->peers; p; ) +      for (r = ctx->config->realms; r; )  	{ -	  struct rs_peer *tmp = p; -	  if (p->addr) -	    evutil_freeaddrinfo (p->addr); -	  p = p->next; +	  struct rs_realm *tmp = r; +	  for (p = r->peers; p; ) +	    { +	      struct rs_peer *tmp = p; +	      if (p->addr) +		evutil_freeaddrinfo (p->addr); +	      p = p->next; +	      rs_free (ctx, tmp); +	    } +	  rs_free (ctx, r->name); /* FIXME: Stop freeing once we stop strdup in rs_context_read_config().  */ +	  r = r->next;  	  rs_free (ctx, tmp);  	} -      rs_free (ctx, r->name); -      r = r->next; -      rs_free (ctx, tmp);      } -  if (ctx->cfg) -    cfg_free (ctx->cfg); -  ctx->cfg = NULL; +  if (ctx->config) +    { +      if (ctx->config->cfg) +	{ +	  cfg_free (ctx->config->cfg); +	  ctx->config->cfg = NULL; +	} +      rs_free (ctx, ctx->config); +    }    rs_free (ctx, ctx);  } | 
