Enable tls psk
[libradsec.git] / err.c
1 /* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
2    See LICENSE for licensing information. */
3
4 #if defined HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <assert.h>
12 #include <radsec/radsec.h>
13 #include <radsec/radsec-impl.h>
14
15 static const char *_errtxt[] = {
16   "SUCCESS",                                    /* 0 RSE_OK */
17   "out of memory",                              /* 1 RSE_NOMEM */
18   "not yet implemented",                        /* 2 RSE_NOSYS */
19   "invalid handle",                             /* 3 RSE_INVALID_CTX */
20   "invalid connection",                         /* 4 RSE_INVALID_CONN */
21   "connection type mismatch",                   /* 5 RSE_CONN_TYPE_MISMATCH */
22   "FreeRadius error",                           /* 6 RSE_FR */
23   "bad hostname or port",                       /* 7 RSE_BADADDR */
24   "no peer configured",                         /* 8 RSE_NOPEER */
25   "libevent error",                             /* 9 RSE_EVENT */
26   "socket error",                               /* 10 RSE_SOCKERR */
27   "invalid configuration file",                 /* 11 RSE_CONFIG */
28   "authentication failed",                      /* 12 RSE_BADAUTH */
29   "internal error",                             /* 13 RSE_INTERNAL */
30   "SSL error",                                  /* 14 RSE_SSLERR */
31   "invalid packet",                             /* 15 RSE_INVALID_PKT */
32   "connect timeout",                            /* 16 RSE_TIMEOUT_CONN */
33   "invalid argument",                           /* 17 RSE_INVAL */
34   "I/O timeout",                                /* 18 RSE_TIMEOUT_IO */
35   "timeout",                                    /* 19 RSE_TIMEOUT */
36   "peer disconnected",                          /* 20 RSE_DISCO */
37   "resource is in use",                         /* 21 RSE_INUSE */
38   "packet is too small",                        /* 22 RSE_PACKET_TOO_SMALL */
39   "packet is too large",                        /* 23 RSE_PACKET_TOO_LARGE */
40   "attribute overflows packet",                 /* 24 RSE_ATTR_OVERFLOW */
41   "attribute is too small",                     /* 25 RSE_ATTR_TOO_SMALL */
42   "attribute is too large",                     /* 26 RSE_ATTR_TOO_LARGE */
43   "unknown attribute",                          /* 27 RSE_ATTR_UNKNOWN */
44   "invalid name for attribute",                 /* 28 RSE_ATTR_BAD_NAME */
45   "invalid value for attribute",                /* 29 RSE_ATTR_VALUE_MALFORMED */
46   "invalid attribute",                          /* 30 RSE_ATTR_INVALID */
47   "too many attributes in the packet",          /* 31 RSE_TOO_MANY_ATTRS */
48   "attribute type unknown",                     /* 32 RSE_ATTR_TYPE_UNKNOWN */
49   "invalid message authenticator",              /* 33 RSE_MSG_AUTH_LEN */
50   "incorrect message authenticator",            /* 34 RSE_MSG_AUTH_WRONG */
51   "request is required",                        /* 35 RSE_REQUEST_REQUIRED */
52   "invalid request code",                       /* 36 RSE_REQUEST_CODE_INVALID */
53   "incorrect request authenticator",            /* 37 RSE_AUTH_VECTOR_WRONG */
54   "response code is unsupported",               /* 38 RSE_INVALID_RESPONSE_CODE */
55   "response ID is invalid",                     /* 39 RSE_INVALID_RESPONSE_ID */
56   "response from the wrong source address",     /* 40 RSE_INVALID_RESPONSE_SRC */
57   "no packet data",                             /* 41 RSE_NO_PACKET_DATA */
58   "vendor is unknown",                          /* 42 RSE_VENDOR_UNKNOWN */
59   "invalid credentials",                        /* 43 RSE_CRED */
60   "certificate validation error",               /* 44 RSE_CERT */
61 };
62 #define ERRTXT_SIZE (sizeof(_errtxt) / sizeof(*_errtxt))
63
64 static struct rs_error *
65 _err_vcreate (unsigned int code, const char *file, int line, const char *fmt,
66               va_list args)
67 {
68   struct rs_error *err = NULL;
69
70   err = malloc (sizeof(struct rs_error));
71   if (err)
72     {
73       int n;
74       memset (err, 0, sizeof(struct rs_error));
75       err->code = code;
76       if (fmt)
77         n = vsnprintf (err->buf, sizeof(err->buf), fmt, args);
78       else
79         {
80           strncpy (err->buf,
81                    err->code < ERRTXT_SIZE ? _errtxt[err->code] : "",
82                    sizeof(err->buf));
83           n = strlen (err->buf);
84         }
85       if (n >= 0 && file)
86         {
87           char *sep = strrchr (file, '/');
88           if (sep)
89             file = sep + 1;
90           snprintf (err->buf + n, sizeof(err->buf) - n, " (%s:%d)", file,
91                     line);
92         }
93     }
94   return err;
95 }
96
97 struct rs_error *
98 err_create (unsigned int code,
99             const char *file,
100             int line,
101             const char *fmt,
102             ...)
103 {
104   struct rs_error *err = NULL;
105
106   va_list args;
107   va_start (args, fmt);
108   err = _err_vcreate (code, file, line, fmt, args);
109   va_end (args);
110
111   return err;
112 }
113
114 static int
115 _ctx_err_vpush_fl (struct rs_context *ctx, int code, const char *file,
116                    int line, const char *fmt, va_list args)
117 {
118   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
119
120   if (!err)
121     return RSE_NOMEM;
122
123   /* TODO: Implement a stack.  */
124   if (ctx->err)
125     rs_err_free (ctx->err);
126   ctx->err = err;
127
128   return err->code;
129 }
130
131 int
132 rs_err_ctx_push (struct rs_context *ctx, int code, const char *fmt, ...)
133 {
134   int r = 0;
135   va_list args;
136
137   va_start (args, fmt);
138   r = _ctx_err_vpush_fl (ctx, code, NULL, 0, fmt, args);
139   va_end (args);
140
141   return r;
142 }
143
144 int
145 rs_err_ctx_push_fl (struct rs_context *ctx, int code, const char *file,
146                     int line, const char *fmt, ...)
147 {
148   int r = 0;
149   va_list args;
150
151   va_start (args, fmt);
152   r = _ctx_err_vpush_fl (ctx, code, file, line, fmt, args);
153   va_end (args);
154
155   return r;
156 }
157
158 int
159 err_conn_push_err (struct rs_connection *conn, struct rs_error *err)
160 {
161   assert (conn);
162   assert (err);
163
164   if (conn->err)
165     rs_err_free (conn->err);
166   conn->err = err;              /* FIXME: use a stack */
167
168   return err->code;
169 }
170
171 static int
172 _conn_err_vpush_fl (struct rs_connection *conn, int code, const char *file,
173                     int line, const char *fmt, va_list args)
174 {
175   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
176
177   if (!err)
178     return RSE_NOMEM;
179
180   return err_conn_push_err (conn, err);
181 }
182
183 int
184 rs_err_conn_push (struct rs_connection *conn, int code, const char *fmt, ...)
185 {
186   int r = 0;
187
188   va_list args;
189   va_start (args, fmt);
190   r = _conn_err_vpush_fl (conn, code, NULL, 0, fmt, args);
191   va_end (args);
192
193   return r;
194 }
195
196 int
197 rs_err_conn_push_fl (struct rs_connection *conn, int code, const char *file,
198                      int line, const char *fmt, ...)
199 {
200   int r = 0;
201
202   va_list args;
203   va_start (args, fmt);
204   r = _conn_err_vpush_fl (conn, code, file, line, fmt, args);
205   va_end (args);
206
207   return r;
208 }
209
210 struct rs_error *
211 rs_err_ctx_pop (struct rs_context *ctx)
212 {
213   struct rs_error *err;
214
215   if (!ctx)
216     return NULL;                /* FIXME: RSE_INVALID_CTX.  */
217   err = ctx->err;
218   ctx->err = NULL;
219
220   return err;
221 }
222
223 struct rs_error *
224 rs_err_conn_pop (struct rs_connection *conn)
225 {
226   struct rs_error *err;
227
228   if (!conn)
229     return NULL;                /* FIXME: RSE_INVALID_CONN */
230   err = conn->err;
231   conn->err = NULL;
232
233   return err;
234 }
235
236 int
237 rs_err_conn_peek_code (struct rs_connection *conn)
238 {
239   if (!conn)
240     return -1;                  /* FIXME: RSE_INVALID_CONN */
241   if (conn->err)
242     return conn->err->code;
243
244   return RSE_OK;
245 }
246
247 void
248 rs_err_free (struct rs_error *err)
249 {
250   assert (err);
251   free (err);
252 }
253
254 char *
255 rs_err_msg (struct rs_error *err)
256 {
257   if (!err)
258     return NULL;
259
260   return err->buf;
261 }
262
263 int
264 rs_err_code (struct rs_error *err, int dofree_flag)
265 {
266   int code;
267
268   if (!err)
269     return -1;
270   code = err->code;
271
272   if (dofree_flag)
273     rs_err_free (err);
274
275   return code;
276 }