Improve protocol robustness and invoke user callbacks.
[libradsec.git] / lib / radsec.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 <stdio.h>
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include <libgen.h>
12 #include <assert.h>
13
14 #include <freeradius/libradius.h>
15 #include <event2/event.h>
16 #include <event2/util.h>
17 #include <radsec/radsec.h>
18 #include <radsec/radsec-impl.h>
19 #if defined (RS_ENABLE_TLS)
20 #include <regex.h>
21 #include "rsp_list.h"
22 #include "../radsecproxy.h"
23 #endif
24 #include "rsp_debug.h"
25
26 int
27 rs_context_create(struct rs_context **ctx, const char *dict)
28 {
29   int err = RSE_OK;
30   struct rs_context *h;
31   char *buf1 = NULL, *buf2 = NULL;
32   char *dir, *fn;
33
34   assert (dict);
35
36   if (ctx)
37     *ctx = NULL;
38   h = (struct rs_context *) malloc (sizeof(struct rs_context));
39   if (!h)
40     return RSE_NOMEM;
41
42   /* Initialize freeradius dictionary.  */
43   buf1 = malloc (strlen (dict) + 1);
44   buf2 = malloc (strlen (dict) + 1);
45   if (!buf1 || !buf2)
46     {
47       err = RSE_NOMEM;
48       goto err_out;
49     }
50   strcpy (buf1, dict);
51   dir = dirname (buf1);
52   strcpy (buf2, dict);
53   fn = basename (buf2);
54   if (dict_init (dir, fn) < 0)
55     {
56       err = RSE_SOME_ERROR;
57       goto err_out;
58     }
59   free (buf1);
60   free (buf2);
61
62 #if defined (RS_ENABLE_TLS)
63   ssl_init ();
64 #endif
65 #if defined (DEBUG)
66   fr_log_fp = stderr;
67   fr_debug_flag = 1;
68 #endif
69   debug_init ("libradsec");     /* radsecproxy compat, FIXME: remove */
70
71   memset (h, 0, sizeof(struct rs_context));
72   h->realms = malloc (sizeof (struct rs_realm));
73   if (!h->realms)
74     {
75       err = RSE_NOMEM;
76       goto err_out;
77     }
78   memset (h->realms, 0, sizeof (struct rs_realm));
79   h->realms->next = h->realms;
80   fr_randinit (&h->fr_randctx, 0);
81   fr_rand_seed (NULL, 0);
82
83   if (ctx)
84     *ctx = h;
85
86   return RSE_OK;
87
88  err_out:
89   if (buf1)
90     free (buf1);
91   if (buf2)
92     free (buf2);
93   if (h)
94     free (h);
95   return err;
96 }
97
98 void rs_context_destroy(struct rs_context *ctx)
99 {
100   free (ctx);
101 }
102
103 int rs_context_set_alloc_scheme(struct rs_context *ctx,
104                                 struct rs_alloc_scheme *scheme)
105 {
106   return rs_err_ctx_push_fl (ctx, RSE_NOSYS, __FILE__, __LINE__,
107                              "%s: NYI", __func__);
108 }
109
110
111 struct rs_peer *
112 _rs_peer_create (struct rs_context *ctx, struct rs_peer **rootp)
113 {
114   struct rs_peer *p;
115
116   p = (struct rs_peer *) rs_malloc (ctx, sizeof(*p));
117   if (p)
118     {
119       memset (p, 0, sizeof(struct rs_peer));
120       p->fd = -1;
121       if (*rootp)
122         (*rootp)->next = p;
123       else
124         *rootp = p;
125     }
126   return p;
127 }
128
129 int
130 rs_server_create (struct rs_connection *conn, struct rs_peer **server)
131 {
132   struct rs_peer *srv;
133
134   srv = _rs_peer_create (conn->ctx, &conn->peers);
135   if (srv)
136     {
137       srv->conn = conn;
138       srv->timeout = 1;
139       srv->tries = 3;
140     }
141   else
142     return rs_err_conn_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL);
143   if (*server)
144     *server = srv;
145   return RSE_OK;
146 }
147
148 int
149 rs_server_set_address (struct rs_peer *server, const char *hostname,
150                        const char *service)
151 {
152   struct rs_error *err;
153
154   err = _rs_resolv (&server->addr, server->conn->type, hostname, service);
155   if (err)
156     return _rs_err_conn_push_err (server->conn, err);
157   return RSE_OK;
158 }
159
160 void
161 rs_server_set_timeout (struct rs_peer *server, int timeout)
162 {
163   server->timeout = timeout;
164 }
165 void
166 rs_server_set_tries (struct rs_peer *server, int tries)
167 {
168   server->tries = tries;
169 }
170
171 int
172 rs_server_set_secret (struct rs_peer *server, const char *secret)
173 {
174   if (server->secret)
175     free (server->secret);
176   server->secret = (char *) malloc (strlen(secret) + 1);
177   if (!server->secret)
178     return rs_err_conn_push (server->conn, RSE_NOMEM, NULL);
179   strcpy (server->secret, secret);
180   return RSE_OK;
181 }
182