WIP -- reading configuration.
[libradsec.git] / lib / conf.c
1 #include <confuse.h>
2 #include <string.h>
3 #include <radsec/radsec.h>
4 #include <radsec/radsec-impl.h>
5
6 #if 0
7   realm NAME {
8       type = STRING
9       server {
10           hostname = STRING
11           service = STRING
12           secret = STRING
13           timeout = INT         /* optional */
14           tries = INT           /* optional */
15       }
16   }
17 #endif
18
19 int
20 rs_context_read_config(struct rs_handle *ctx, const char *config_file)
21 {
22 #warning "Missing some error handling in rs_context_config_read()"
23   cfg_opt_t server_opts[] =
24     {
25       CFG_STR ("hostname", NULL, CFGF_NONE),
26       CFG_STR ("service", "radius", CFGF_NONE),
27       CFG_STR ("secret", NULL, CFGF_NONE),
28       CFG_INT ("timeout", 3, CFGF_NONE),
29       CFG_INT ("tries", 1, CFGF_NONE),
30       CFG_END ()
31     };
32   cfg_opt_t realm_opts[] =
33     {
34       CFG_STR ("type", "UDP", CFGF_NONE),
35       CFG_SEC ("server", server_opts, CFGF_MULTI),
36       CFG_END ()
37     };
38   cfg_opt_t opts[] =
39     {
40       CFG_SEC ("realm", realm_opts, CFGF_TITLE | CFGF_MULTI),
41       CFG_END ()
42     };
43   cfg_t *cfg, *cfg_realm, *cfg_server;
44   int i, j;
45
46   cfg = cfg_init (opts, CFGF_NONE);
47   if (cfg_parse (cfg, config_file) == CFG_PARSE_ERROR)
48     return rs_err_ctx_push (ctx, RSE_CONFIG, "%s: invalid configuration file",
49                             config_file);
50   for (i = 0; i < cfg_size (cfg, "realm"); i++)
51     {
52       struct rs_realm *r = rs_malloc (ctx, sizeof(*r));
53       const char *typestr;
54       enum rs_conn_type type;
55
56       if (!r)
57         return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL);
58       memset (r, 0, sizeof(*r));
59       if (ctx->realms)
60         ctx->realms->next = r;
61       else
62         ctx->realms = r;
63       cfg_realm = cfg_getnsec (cfg, "realm", i);
64       r->name = strdup (cfg_title (cfg_realm));
65       typestr = cfg_getstr (cfg_realm, "type");
66       if (!strcmp (typestr, "UDP"))
67         type = RS_CONN_TYPE_UDP;
68       else if (!strcmp (typestr, "TCP"))
69         type = RS_CONN_TYPE_TCP;
70       else if (!strcmp (typestr, "TLS"))
71         type = RS_CONN_TYPE_TLS;
72       else if (!strcmp (typestr, "DTLS"))
73         type = RS_CONN_TYPE_DTLS;
74       else
75         return rs_err_ctx_push_fl (ctx, RSE_CONFIG, __FILE__, __LINE__,
76                                    "%s: invalid connection type", typestr);
77       for (j = 0; j < cfg_size (cfg_realm, "server"); j++)
78         {
79           struct rs_peer *p = _rs_peer_create (ctx, &r->peers);
80           if (!p)
81             return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__,
82                                        NULL);
83
84           cfg_server = cfg_getnsec (cfg_realm, "server", j);
85           _rs_resolv (&p->addr, type, cfg_getstr (cfg_server, "hostname"),
86                       cfg_getstr (cfg_server, "service"));
87           p->secret = strdup (cfg_getstr (cfg_server, "secret"));
88           p->timeout = cfg_getint (cfg_server, "timeout");
89           p->tries = cfg_getint (cfg_server, "tries");
90         }
91     }
92   return RSE_OK;
93 }
94
95 struct rs_realm
96 *rs_conf_find_realm(struct rs_handle *ctx, const char *name)
97 {
98   struct rs_realm *r;
99
100   for (r = ctx->realms; r; r = r->next)
101     if (!strcmp (r->name, name))
102         return r;
103   return NULL;
104 }