The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
rest.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /**
19  * $Id: 2e6b27549bff96c1e759cf24245aff02f629bb54 $
20  *
21  * @brief Function prototypes and datatypes for the REST (HTTP) transport.
22  * @file rest.h
23  *
24  * @copyright 2012-2016 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25  */
26 RCSIDH(rest_h, "$Id: 2e6b27549bff96c1e759cf24245aff02f629bb54 $")
27 
28 #include <freeradius-devel/curl/base.h>
29 #include <freeradius-devel/curl/config.h>
30 #include <freeradius-devel/server/pairmove.h>
31 #include <freeradius-devel/util/slab.h>
32 
33 /*
34  * The common JSON library (also tells us if we have json-c)
35  */
36 #include <freeradius-devel/json/base.h>
37 
38 #define REST_URI_MAX_LEN 2048
39 #define REST_BODY_MAX_LEN 8192
40 #define REST_BODY_ALLOC_CHUNK 1024
41 #define REST_BODY_MAX_ATTRS 256
42 
43 typedef enum {
50  REST_HTTP_METHOD_CUSTOM //!< Must always come last, should not be in method table
52 
53 typedef enum {
68 
69 typedef enum {
83 
84 /** Magic pointer value for determining if we should disable proxying
85  */
86 extern char const *rest_no_proxy;
87 
88 /*
89  * Must be updated (in rest.c) if additional values are added to
90  * http_body_type_t
91  */
93 
94 extern const unsigned long http_curl_auth[REST_HTTP_AUTH_NUM_ENTRIES];
95 
97 extern size_t http_auth_table_len;
98 
100 extern size_t http_method_table_len;
101 
103 extern size_t http_body_type_table_len;
104 
106 extern size_t http_content_type_table_len;
107 
108 typedef struct {
109  char const *proxy; //!< Send request via this proxy.
110 
111  char const *method_str; //!< The string version of the HTTP method.
112  http_method_t method; //!< What HTTP method should be used, GET, POST etc...
113 
114  char const *body_str; //!< The string version of the encoding/content type.
115  http_body_type_t body; //!< What encoding type should be used.
116 
117  bool auth_is_set; //!< Whether a value was provided for auth_str.
118 
119  http_auth_type_t auth; //!< HTTP auth type.
120 
121  bool require_auth; //!< Whether HTTP-Auth is required or not.
122 
123  uint32_t chunk; //!< Max chunk-size (mainly for testing the encoders)
125 
126 typedef struct {
127  char const *force_to_str; //!< Force decoding with this decoder.
128  http_body_type_t force_to; //!< Override the Content-Type header in the response
129  //!< to force decoding as a particular type.
130 
131  size_t max_body_in; //!< Maximum size of incoming data.
133 
134 /*
135  * Structure for section configuration
136  */
137 typedef struct {
138  char const *name; //!< Section name.
139 
140  fr_time_delta_t timeout; //!< Timeout timeval.
141 
142  rlm_rest_section_request_t request; //!< Request configuration.
143  rlm_rest_section_response_t response; //!< Response configuration.
144 
147 
148 /*
149  * Structure for module configuration
150  */
151 typedef struct {
152  char const *connect_proxy; //!< Send request via this proxy.
153 
154  int http_negotiation; //!< What HTTP version to negotiate, and how to
155  ///< negotiate it. One or the CURL_HTTP_VERSION_ macros.
156 
157  bool multiplex; //!< Whether to perform multiple requests using a single
158  ///< connection.
159 
160  fr_curl_conn_config_t conn_config; //!< Configuration of slab allocated connection handles.
161 
162  rlm_rest_section_t xlat; //!< Configuration specific to xlat.
163  rlm_rest_section_t authorize; //!< Configuration specific to authorisation.
164  rlm_rest_section_t authenticate; //!< Configuration specific to authentication.
165  rlm_rest_section_t accounting; //!< Configuration specific to accounting.
166  rlm_rest_section_t post_auth; //!< Configuration specific to Post-auth
167 
168 #ifndef NDEBUG
169  bool fail_header_decode; //!< Force header decoding to fail for debugging purposes.
170  bool fail_body_decode; //!< Force body decoding to fail for debugging purposes.
171 #endif
172 } rlm_rest_t;
173 
176 
177 /** Thread specific rlm_rest instance data
178  *
179  */
180 typedef struct {
181  rlm_rest_t const *inst; //!< Instance of rlm_rest.
182  rest_slab_list_t *slab; //!< Slab list for connection handles.
183  fr_curl_handle_t *mhandle; //!< Thread specific multi handle. Serves as the dispatch
184  //!< and coralling structure for REST requests.
186 
187 /*
188  * States for stream based attribute encoders
189  */
190 typedef enum {
195 } read_state_t;
196 
197 /*
198  * States for the response parser
199  */
200 typedef enum {
205 } write_state_t;
206 
207 /*
208  * Outbound data context (passed to CURLOPT_READFUNCTION as CURLOPT_READDATA)
209  */
210 typedef struct {
211  rlm_rest_t const *instance; //!< This instance of rlm_rest.
212  rlm_rest_section_t const *section; //!< Section configuration.
213 
214  request_t *request; //!< Current request.
215  read_state_t state; //!< Encoder state
216 
217  fr_dcursor_t cursor; //!< Cursor pointing to the start of the list to encode.
218 
219  size_t chunk; //!< Chunk size
220 
221  void *encoder; //!< Encoder specific data.
223 
224 /*
225  * Curl inbound data context (passed to CURLOPT_WRITEFUNCTION and
226  * CURLOPT_HEADERFUNCTION as CURLOPT_WRITEDATA and CURLOPT_HEADERDATA)
227  */
228 typedef struct {
229  rlm_rest_t const *instance; //!< This instance of rlm_rest.
230  rlm_rest_section_t const *section; //!< Section configuration.
231 
232  request_t *request; //!< Current request.
233  write_state_t state; //!< Decoder state.
234 
235  char *buffer; //!< Raw incoming HTTP data.
236  size_t alloc; //!< Space allocated for buffer.
237  size_t used; //!< Space used in buffer.
238 
239  int code; //!< HTTP Status Code.
240  http_body_type_t type; //!< HTTP Content Type.
241  http_body_type_t force_to; //!< Force decoding the body type as a particular encoding.
242 
243  tmpl_t *header; //!< Where to create pairs representing HTTP response headers.
244  ///< If NULL no headers will be parsed other than content-type.
245 
246  void *decoder; //!< Decoder specific data.
248 
249 /*
250  * Curl context data
251  */
252 typedef struct {
253  struct curl_slist *headers; //!< Any HTTP headers which will be sent with the
254  //!< request.
255 
256  char *body; //!< Pointer to the buffer which contains body data/
257  //!< Only used when not performing chunked encoding.
258 
259  rlm_rest_request_t request; //!< Request context data.
260  rlm_rest_response_t response; //!< Response context data.
262 
263 /** Stores the state of a yielded xlat
264  *
265  */
266 typedef struct {
267  rlm_rest_section_t section; //!< Our mutated section config.
268  fr_curl_io_request_t *handle; //!< curl easy handle servicing our request.
270 
271 typedef struct {
272  struct {
273  fr_value_box_t *uri; //!< URI to send HTTP request to.
274  fr_value_box_list_t *header; //!< Headers to place in the request
275  fr_value_box_t *data; //!< Custom data to send in requests.
276  fr_value_box_t *username; //!< Username to use for authentication
277  fr_value_box_t *password; //!< Password to use for authentication
278  } request;
279 
280  struct {
281  tmpl_t *header; //!< Where to write response headers
282  } response;
284 
285 extern HIDDEN fr_dict_t const *dict_freeradius;
286 
290 
291 /*
292  * Function prototype for rest_read_wrapper. Matches CURL's
293  * CURLOPT_READFUNCTION prototype.
294  */
295 typedef size_t (*rest_read_t)(void *ptr, size_t size, size_t nmemb,
296  void *userdata);
297 
298 
299 void *rest_mod_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t timeout);
300 
301 /*
302  * Request processing API
303  */
304 int rest_request_config(module_ctx_t const *mctx, rlm_rest_section_t const *section,
305  request_t *request, fr_curl_io_request_t *randle, http_method_t method,
307  char const *uri, char const *body_data) CC_HINT(nonnull (1,2,4,7));
308 
309 int rest_response_decode(rlm_rest_t const *instance,
310  UNUSED rlm_rest_section_t const *section, request_t *request,
311  fr_curl_io_request_t *randle);
312 
313 void rest_response_error(request_t *request, fr_curl_io_request_t *handle);
314 void rest_response_debug(request_t *request, fr_curl_io_request_t *handle);
315 
316 #define rest_get_handle_code(_handle)(((rlm_rest_curl_context_t*)((fr_curl_io_request_t*)(_handle))->uctx)->response.code)
317 
318 #define rest_get_handle_type(_handle)(((rlm_rest_curl_context_t*)((fr_curl_io_request_t*)(_handle))->uctx)->response.type)
319 
320 size_t rest_get_handle_data(char const **out, fr_curl_io_request_t *handle);
321 
322 /*
323  * Helper functions
324  */
325 size_t rest_uri_escape(UNUSED request_t *request, char *out, size_t outlen, char const *raw, UNUSED void *arg);
326 ssize_t rest_uri_host_unescape(char **out, UNUSED rlm_rest_t const *mod_inst, request_t *request,
327  fr_curl_io_request_t *randle, char const *uri);
328 
329 /*
330  * Async IO helpers
331  */
332 void rest_io_module_signal(module_ctx_t const *mctx, request_t *request, fr_signal_t action);
333 void rest_io_xlat_signal(xlat_ctx_t const *xctx, request_t *request, fr_signal_t action);
#define RCSIDH(h, id)
Definition: build.h:482
#define HIDDEN
Definition: build.h:312
#define UNUSED
Definition: build.h:313
Uctx data for timer and I/O functions.
Definition: base.h:91
Structure representing an individual request being passed to curl for processing.
Definition: base.h:101
static fr_time_delta_t timeout
Definition: dhcpclient.c:54
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
unsigned long int size_t
Definition: merged_model.c:25
Temporary structure to hold arguments for module calls.
Definition: module_ctx.h:41
rlm_rest_t const * instance
This instance of rlm_rest.
Definition: rest.h:229
read_state_t state
Encoder state.
Definition: rest.h:215
HIDDEN fr_dict_attr_t const * attr_rest_http_header
Definition: rlm_rest.c:282
http_auth_type_t auth
HTTP auth type.
Definition: rest.h:119
size_t rest_get_handle_data(char const **out, fr_curl_io_request_t *handle)
Extracts pointer to buffer containing response data.
Definition: rest.c:1620
struct curl_slist * headers
Any HTTP headers which will be sent with the request.
Definition: rest.h:253
tmpl_t * header
Where to create pairs representing HTTP response headers.
Definition: rest.h:243
request_t * request
Current request.
Definition: rest.h:232
char * buffer
Raw incoming HTTP data.
Definition: rest.h:235
fr_table_num_sorted_t const http_auth_table[]
Definition: rest.c:160
int code
HTTP Status Code.
Definition: rest.h:239
fr_curl_handle_t * mhandle
Thread specific multi handle.
Definition: rest.h:183
write_state_t state
Decoder state.
Definition: rest.h:233
void rest_io_module_signal(module_ctx_t const *mctx, request_t *request, fr_signal_t action)
bool fail_header_decode
Force header decoding to fail for debugging purposes.
Definition: rest.h:169
char const * proxy
Send request via this proxy.
Definition: rest.h:109
size_t used
Space used in buffer.
Definition: rest.h:237
int rest_response_decode(rlm_rest_t const *instance, UNUSED rlm_rest_section_t const *section, request_t *request, fr_curl_io_request_t *randle)
http_body_type_t type
HTTP Content Type.
Definition: rest.h:240
void * rest_mod_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t timeout)
char * body
Pointer to the buffer which contains body data/ Only used when not performing chunked encoding.
Definition: rest.h:256
fr_curl_tls_t tls
Definition: rest.h:145
bool fail_body_decode
Force body decoding to fail for debugging purposes.
Definition: rest.h:170
http_body_type_t force_to
Override the Content-Type header in the response to force decoding as a particular type.
Definition: rest.h:128
http_method_t
Definition: rest.h:43
@ REST_HTTP_METHOD_PATCH
Definition: rest.h:48
@ REST_HTTP_METHOD_DELETE
Definition: rest.h:49
@ REST_HTTP_METHOD_PUT
Definition: rest.h:47
@ REST_HTTP_METHOD_POST
Definition: rest.h:46
@ REST_HTTP_METHOD_UNKNOWN
Definition: rest.h:44
@ REST_HTTP_METHOD_CUSTOM
Must always come last, should not be in method table.
Definition: rest.h:50
@ REST_HTTP_METHOD_GET
Definition: rest.h:45
size_t max_body_in
Maximum size of incoming data.
Definition: rest.h:131
fr_dcursor_t cursor
Cursor pointing to the start of the list to encode.
Definition: rest.h:217
http_body_type_t force_to
Force decoding the body type as a particular encoding.
Definition: rest.h:241
http_body_type_t
Definition: rest.h:53
@ REST_HTTP_BODY_HTML
Definition: rest.h:64
@ REST_HTTP_BODY_PLAIN
Definition: rest.h:65
@ REST_HTTP_BODY_JSON
Definition: rest.h:61
@ REST_HTTP_BODY_INVALID
Definition: rest.h:57
@ REST_HTTP_BODY_XML
Definition: rest.h:62
@ REST_HTTP_BODY_UNSUPPORTED
Definition: rest.h:55
@ REST_HTTP_BODY_YAML
Definition: rest.h:63
@ REST_HTTP_BODY_POST
Definition: rest.h:60
@ REST_HTTP_BODY_CUSTOM
Definition: rest.h:59
@ REST_HTTP_BODY_NUM_ENTRIES
Definition: rest.h:66
@ REST_HTTP_BODY_UNKNOWN
Definition: rest.h:54
@ REST_HTTP_BODY_NONE
Definition: rest.h:58
@ REST_HTTP_BODY_UNAVAILABLE
Definition: rest.h:56
char const * method_str
The string version of the HTTP method.
Definition: rest.h:111
read_state_t
Definition: rest.h:190
@ READ_STATE_ATTR_CONT
Definition: rest.h:193
@ READ_STATE_ATTR_BEGIN
Definition: rest.h:192
@ READ_STATE_END
Definition: rest.h:194
@ READ_STATE_INIT
Definition: rest.h:191
void rest_io_xlat_signal(xlat_ctx_t const *xctx, request_t *request, fr_signal_t action)
Handle asynchronous cancellation of a request.
Definition: io.c:56
rlm_rest_section_t const * section
Section configuration.
Definition: rest.h:230
fr_table_num_sorted_t const http_body_type_table[]
Conversion table for type config values.
Definition: rest.c:145
fr_curl_conn_config_t conn_config
Configuration of slab allocated connection handles.
Definition: rest.h:160
int http_negotiation
What HTTP version to negotiate, and how to.
Definition: rest.h:154
HIDDEN fr_dict_t const * dict_freeradius
Definition: base.c:77
char const * body_str
The string version of the encoding/content type.
Definition: rest.h:114
HIDDEN fr_dict_attr_t const * attr_rest_http_body
Definition: rlm_rest.c:281
fr_table_num_sorted_t const http_method_table[]
Conversion table for method config values.
Definition: rest.c:126
ssize_t rest_uri_host_unescape(char **out, UNUSED rlm_rest_t const *mod_inst, request_t *request, fr_curl_io_request_t *randle, char const *uri)
Unescapes the host portion of a URI string.
Definition: rest.c:2146
char const * force_to_str
Force decoding with this decoder.
Definition: rest.h:127
rlm_rest_section_request_t request
Request configuration.
Definition: rest.h:142
rlm_rest_response_t response
Response context data.
Definition: rest.h:260
size_t(* rest_read_t)(void *ptr, size_t size, size_t nmemb, void *userdata)
Definition: rest.h:295
void * decoder
Decoder specific data.
Definition: rest.h:246
bool auth_is_set
Whether a value was provided for auth_str.
Definition: rest.h:117
rlm_rest_section_t const * section
Section configuration.
Definition: rest.h:212
int rest_request_config(module_ctx_t const *mctx, rlm_rest_section_t const *section, request_t *request, fr_curl_io_request_t *randle, http_method_t method, http_body_type_t type, char const *uri, char const *body_data))
Configures request curlopts.
Definition: rest.c:1721
void * encoder
Encoder specific data.
Definition: rest.h:221
rlm_rest_section_t xlat
Configuration specific to xlat.
Definition: rest.h:162
HIDDEN fr_dict_attr_t const * attr_rest_http_status_code
Definition: rlm_rest.c:283
void rest_response_debug(request_t *request, fr_curl_io_request_t *handle)
Print out the response text.
Definition: rest.c:1563
rlm_rest_request_t request
Request context data.
Definition: rest.h:259
http_method_t method
What HTTP method should be used, GET, POST etc...
Definition: rest.h:112
fr_table_num_sorted_t const http_content_type_table[]
Conversion table for "Content-Type" header values.
Definition: rest.c:188
const unsigned long http_curl_auth[REST_HTTP_AUTH_NUM_ENTRIES]
Definition: rest.c:100
rlm_rest_section_response_t response
Response configuration.
Definition: rest.h:143
rlm_rest_section_t section
Our mutated section config.
Definition: rest.h:267
const http_body_type_t http_body_type_supported[REST_HTTP_BODY_NUM_ENTRIES]
Table of encoder/decoder support.
Definition: rest.c:51
fr_time_delta_t timeout
Timeout timeval.
Definition: rest.h:140
size_t rest_uri_escape(UNUSED request_t *request, char *out, size_t outlen, char const *raw, UNUSED void *arg)
URL encodes a string.
Definition: rest.c:2120
write_state_t
Definition: rest.h:200
@ WRITE_STATE_INIT
Definition: rest.h:201
@ WRITE_STATE_PARSE_HEADERS
Definition: rest.h:202
@ WRITE_STATE_PARSE_CONTENT
Definition: rest.h:203
@ WRITE_STATE_DISCARD
Definition: rest.h:204
bool multiplex
Whether to perform multiple requests using a single connection.
Definition: rest.h:157
rlm_rest_t const * inst
Instance of rlm_rest.
Definition: rest.h:181
rlm_rest_section_t accounting
Configuration specific to accounting.
Definition: rest.h:165
char const * name
Section name.
Definition: rest.h:138
http_auth_type_t
Definition: rest.h:69
@ REST_HTTP_AUTH_NTLM_WB
Definition: rest.h:78
@ REST_HTTP_AUTH_NUM_ENTRIES
Definition: rest.h:81
@ REST_HTTP_AUTH_BASIC
Definition: rest.h:73
@ REST_HTTP_AUTH_NTLM
Definition: rest.h:77
@ REST_HTTP_AUTH_DIGEST
Definition: rest.h:74
@ REST_HTTP_AUTH_TLS_SRP
Definition: rest.h:72
@ REST_HTTP_AUTH_UNKNOWN
Definition: rest.h:70
@ REST_HTTP_AUTH_GSSNEGOTIATE
Definition: rest.h:76
@ REST_HTTP_AUTH_ANY
Definition: rest.h:79
@ REST_HTTP_AUTH_NONE
Definition: rest.h:71
@ REST_HTTP_AUTH_DIGEST_IE
Definition: rest.h:75
@ REST_HTTP_AUTH_ANY_SAFE
Definition: rest.h:80
void rest_response_error(request_t *request, fr_curl_io_request_t *handle)
Print out the response text as error lines.
Definition: rest.c:1538
size_t alloc
Space allocated for buffer.
Definition: rest.h:236
rest_slab_list_t * slab
Slab list for connection handles.
Definition: rest.h:182
size_t http_body_type_table_len
Definition: rest.c:158
char const * connect_proxy
Send request via this proxy.
Definition: rest.h:152
rlm_rest_section_t post_auth
Configuration specific to Post-auth.
Definition: rest.h:166
size_t http_auth_table_len
Definition: rest.c:172
size_t http_content_type_table_len
Definition: rest.c:199
request_t * request
Current request.
Definition: rest.h:214
http_body_type_t body
What encoding type should be used.
Definition: rest.h:115
rlm_rest_section_t authorize
Configuration specific to authorisation.
Definition: rest.h:163
size_t http_method_table_len
Definition: rest.c:134
fr_curl_io_request_t * handle
curl easy handle servicing our request.
Definition: rest.h:268
rlm_rest_t const * instance
This instance of rlm_rest.
Definition: rest.h:211
char const * rest_no_proxy
Magic pointer value for determining if we should disable proxying.
Definition: rlm_rest.c:95
rlm_rest_section_t authenticate
Configuration specific to authentication.
Definition: rest.h:164
uint32_t chunk
Max chunk-size (mainly for testing the encoders)
Definition: rest.h:123
bool require_auth
Whether HTTP-Auth is required or not.
Definition: rest.h:121
size_t chunk
Chunk size.
Definition: rest.h:219
Thread specific rlm_rest instance data.
Definition: rest.h:180
Stores the state of a yielded xlat.
Definition: rest.h:266
username
Definition: rlm_securid.c:420
fr_signal_t
Definition: signal.h:48
#define FR_SLAB_FUNCS(_name, _type)
Define type specific wrapper functions for slabs and slab elements.
Definition: slab.h:120
#define FR_SLAB_TYPES(_name, _type)
Define type specific wrapper structs for slabs and slab elements.
Definition: slab.h:72
fr_aka_sim_id_type_t type
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:49
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
static fr_slen_t data
Definition: value.h:1265
int nonnull(2, 5))
static size_t char ** out
Definition: value.h:997
An xlat calling ctx.
Definition: xlat_ctx.h:49