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