Remove @version, doxygen seems to parse $id ok
[freeradius.git] / src / modules / rlm_rest / rest.h
1 /*
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; either version 2 of the License, or
5  *   (at your option) any later version.
6  *
7  *   This program is distributed in the hope that it will be useful,
8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *   GNU General Public License for more details.
11  *
12  *   You should have received a copy of the GNU General Public License
13  *   along with this program; if not, write to the Free Software
14  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16  
17 /*
18  * $Id$
19  *
20  * @brief Function prototypes and datatypes for the REST (HTTP) transport.
21  * @file rest.h
22  *
23  * @copyright 2012-2013  Arran Cudbard-Bell <a.cudbard-bell@freeradius.org>
24  */
25  
26 #include <freeradius-devel/ident.h>
27 RCSIDH(other_h, "$Id$")
28
29 #include <freeradius-devel/connection.h>
30 #include "config.h"
31
32 #ifdef HAVE_JSON_JSONH
33 #define HAVE_JSON
34 #endif
35
36 #include <curl/curl.h>
37
38 #ifdef HAVE_JSON
39 #include <json/json.h>
40 #endif
41
42 #define REST_URI_MAX_LEN                2048
43 #define REST_BODY_MAX_LEN               8192
44 #define REST_BODY_INCR                  512
45 #define REST_BODY_MAX_ATTRS             256
46
47 typedef enum {
48         HTTP_METHOD_CUSTOM,
49         HTTP_METHOD_GET,
50         HTTP_METHOD_POST,
51         HTTP_METHOD_PUT,
52         HTTP_METHOD_DELETE
53 } http_method_t;
54
55 typedef enum {
56         HTTP_BODY_UNKNOWN = 0,
57         HTTP_BODY_UNSUPPORTED,
58         HTTP_BODY_UNAVAILABLE,
59         HTTP_BODY_INVALID,
60         HTTP_BODY_POST,
61         HTTP_BODY_JSON,
62         HTTP_BODY_XML,
63         HTTP_BODY_YAML,
64         HTTP_BODY_HTML,
65         HTTP_BODY_PLAIN,
66         HTTP_BODY_NUM_ENTRIES
67 } http_body_type_t;
68
69 typedef enum {
70         HTTP_AUTH_UNKNOWN = 0,
71         HTTP_AUTH_NONE,
72         HTTP_AUTH_TLS_SRP,
73         HTTP_AUTH_BASIC,
74         HTTP_AUTH_DIGEST,
75         HTTP_AUTH_DIGEST_IE,
76         HTTP_AUTH_GSSNEGOTIATE,
77         HTTP_AUTH_NTLM,
78         HTTP_AUTH_NTLM_WB,
79         HTTP_AUTH_ANY,
80         HTTP_AUTH_ANY_SAFE,
81         HTTP_AUTH_NUM_ENTRIES
82 } http_auth_type_t;
83
84 /*
85  *      Must be updated (in rest.c) if additional values are added to
86  *      http_body_type_t
87  */
88 extern const http_body_type_t http_body_type_supported[HTTP_BODY_NUM_ENTRIES];
89
90 extern const http_body_type_t http_curl_auth[HTTP_AUTH_NUM_ENTRIES];
91
92 extern const FR_NAME_NUMBER http_auth_table[];
93
94 extern const FR_NAME_NUMBER http_method_table[];
95
96 extern const FR_NAME_NUMBER http_body_type_table[];
97
98 extern const FR_NAME_NUMBER http_content_header_table[];
99
100 /*
101  *      Structure for section configuration
102  */
103 typedef struct rlm_rest_section_t {
104         const char *name;
105         char *uri;
106         
107         char *method_str;
108         http_method_t method;
109
110         char *body_str;
111         http_body_type_t body;
112
113         char *username;
114         char *password;
115         char *auth_str;
116         http_auth_type_t auth;
117         int require_auth;
118         
119         char *tls_certfile;
120         char *tls_keyfile;
121         char *tls_keypassword;
122         char *tls_cacertfile;
123         char *tls_cacertdir;
124         char *tls_randfile;
125         int tls_verify_cert;
126         int tls_verify_cert_cn;
127         
128         int timeout;
129         unsigned int chunk;
130 } rlm_rest_section_t;
131
132 /*
133  *      Structure for module configuration
134  */
135 typedef struct rlm_rest_t {
136         const char *xlat_name;
137
138         char *connect_uri;
139
140         fr_connection_pool_t *conn_pool;
141
142         rlm_rest_section_t authorize;
143         rlm_rest_section_t authenticate;
144         rlm_rest_section_t accounting;
145         rlm_rest_section_t checksimul;
146         rlm_rest_section_t postauth;
147 } rlm_rest_t;
148
149 /*
150  *      States for stream based attribute encoders
151  */
152 typedef enum {
153         READ_STATE_INIT = 0,
154         READ_STATE_ATTR_BEGIN,
155         READ_STATE_ATTR_CONT,
156         READ_STATE_END,
157 } read_state_t;
158
159 /*
160  *      States for the response parser
161  */
162 typedef enum {
163         WRITE_STATE_INIT = 0,
164         WRITE_STATE_PARSE_HEADERS,
165         WRITE_STATE_PARSE_CONTENT,
166         WRITE_STATE_DISCARD,
167 } write_state_t;
168
169 /*
170  *      Outbound data context (passed to CURLOPT_READFUNCTION as CURLOPT_READDATA)
171  */
172 typedef struct rlm_rest_read_t {
173         rlm_rest_t      *instance;
174         REQUEST         *request;
175         read_state_t    state;
176
177         VALUE_PAIR      **first;
178         VALUE_PAIR      **next;
179
180         unsigned int    chunk;
181 } rlm_rest_read_t;
182
183 /*
184  *      Curl inbound data context (passed to CURLOPT_WRITEFUNCTION and
185  *      CURLOPT_HEADERFUNCTION as CURLOPT_WRITEDATA and CURLOPT_HEADERDATA)
186  */
187 typedef struct rlm_rest_write_t {
188         rlm_rest_t       *instance;
189         REQUEST          *request;
190         write_state_t    state;
191
192         char             *buffer;       /* HTTP incoming raw data */
193         size_t           alloc;         /* Space allocated for buffer */
194         size_t           used;          /* Space used in buffer */ 
195
196         int              code;          /* HTTP Status Code */
197         http_body_type_t type;          /* HTTP Content Type */
198 } rlm_rest_write_t;
199
200 /*
201  *      Curl context data
202  */
203 typedef struct rlm_rest_curl_context_t {
204         struct curl_slist       *headers;
205         char                    *body;
206         rlm_rest_read_t         read;
207         rlm_rest_write_t        write;
208 } rlm_rest_curl_context_t;
209
210 /*
211  *      Connection API handle
212  */
213 typedef struct rlm_rest_handle_t {
214         void    *handle;        /* Real Handle */
215         void    *ctx;           /* Context */
216 } rlm_rest_handle_t;
217
218 /*
219  *      Function prototype for rest_read_wrapper. Matches CURL's
220  *      CURLOPT_READFUNCTION prototype.
221  */
222 typedef size_t (*rest_read_t)(void *ptr, size_t size, size_t nmemb,
223                               void *userdata);
224
225 /*
226  *      Connection API callbacks
227  */
228 int rest_init(rlm_rest_t *instance);
229
230 void rest_cleanup(void);
231
232 void *rest_socket_create(void *instance);
233
234 int rest_socket_alive(void *instance, void *handle);
235
236 int rest_socket_delete(void *instance, void *handle);
237
238 /*
239  *      Request processing API
240  */
241 int rest_request_config(rlm_rest_t *instance,
242                         rlm_rest_section_t *section, REQUEST *request,
243                         void *handle, http_method_t method,
244                         http_body_type_t type, char *uri);
245
246 int rest_request_perform(rlm_rest_t *instance, rlm_rest_section_t *section,
247                          void *handle);
248
249 int rest_request_decode(rlm_rest_t *instance,
250                         UNUSED rlm_rest_section_t *section, REQUEST *request,
251                         void *handle);
252
253 void rest_request_cleanup(rlm_rest_t *instance, rlm_rest_section_t *section,
254                           void *handle);
255
256 #define rest_get_handle_code(handle)(((rlm_rest_curl_context_t*)((rlm_rest_handle_t*)handle)->ctx)->write.code)
257
258 #define rest_get_handle_type(handle)(((rlm_rest_curl_context_t*)((rlm_rest_handle_t*)handle)->ctx)->write.type)
259
260 /*
261  *      Helper functions
262  */
263 ssize_t rest_uri_build(rlm_rest_t *instance, rlm_rest_section_t *section,
264                        REQUEST *request, char *buffer, size_t bufsize);