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.
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.
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
20 * @brief Function prototypes and datatypes for the REST (HTTP) transport.
23 * @copyright 2012-2013 Arran Cudbard-Bell <a.cudbard-bell@freeradius.org>
26 RCSIDH(other_h, "$Id$")
28 #include <freeradius-devel/connection.h>
31 #ifdef HAVE_JSON_JSONH
35 #define CURL_NO_OLDIES 1
36 #include <curl/curl.h>
39 #include <json/json.h>
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
56 HTTP_BODY_UNKNOWN = 0,
57 HTTP_BODY_UNSUPPORTED,
58 HTTP_BODY_UNAVAILABLE,
70 HTTP_AUTH_UNKNOWN = 0,
76 HTTP_AUTH_GSSNEGOTIATE,
85 * Must be updated (in rest.c) if additional values are added to
88 extern const http_body_type_t http_body_type_supported[HTTP_BODY_NUM_ENTRIES];
90 extern const unsigned long http_curl_auth[HTTP_AUTH_NUM_ENTRIES];
92 extern const FR_NAME_NUMBER http_auth_table[];
94 extern const FR_NAME_NUMBER http_method_table[];
96 extern const FR_NAME_NUMBER http_body_type_table[];
98 extern const FR_NAME_NUMBER http_content_header_table[];
101 * Structure for section configuration
103 typedef struct rlm_rest_section_t {
108 http_method_t method;
111 http_body_type_t body;
116 http_auth_type_t auth;
121 char *tls_keypassword;
122 char *tls_cacertfile;
126 int tls_verify_cert_cn;
130 } rlm_rest_section_t;
133 * Structure for module configuration
135 typedef struct rlm_rest_t {
136 char const *xlat_name;
140 fr_connection_pool_t *conn_pool;
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;
150 * States for stream based attribute encoders
154 READ_STATE_ATTR_BEGIN,
155 READ_STATE_ATTR_CONT,
160 * States for the response parser
163 WRITE_STATE_INIT = 0,
164 WRITE_STATE_PARSE_HEADERS,
165 WRITE_STATE_PARSE_CONTENT,
170 * Outbound data context (passed to CURLOPT_READFUNCTION as CURLOPT_READDATA)
172 typedef struct rlm_rest_read_t {
173 rlm_rest_t *instance;
184 * Curl inbound data context (passed to CURLOPT_WRITEFUNCTION and
185 * CURLOPT_HEADERFUNCTION as CURLOPT_WRITEDATA and CURLOPT_HEADERDATA)
187 typedef struct rlm_rest_write_t {
188 rlm_rest_t *instance;
192 char *buffer; /* HTTP incoming raw data */
193 size_t alloc; /* Space allocated for buffer */
194 size_t used; /* Space used in buffer */
196 int code; /* HTTP Status Code */
197 http_body_type_t type; /* HTTP Content Type */
203 typedef struct rlm_rest_curl_context_t {
204 struct curl_slist *headers;
206 rlm_rest_read_t read;
207 rlm_rest_write_t write;
208 } rlm_rest_curl_context_t;
211 * Connection API handle
213 typedef struct rlm_rest_handle_t {
214 void *handle; /* Real Handle */
215 void *ctx; /* Context */
219 * Function prototype for rest_read_wrapper. Matches CURL's
220 * CURLOPT_READFUNCTION prototype.
222 typedef size_t (*rest_read_t)(void *ptr, size_t size, size_t nmemb,
226 * Connection API callbacks
228 int rest_init(rlm_rest_t *instance);
230 void rest_cleanup(void);
232 void *mod_conn_create(void *instance);
234 int mod_conn_alive(void *instance, void *handle);
236 int mod_conn_delete(void *instance, void *handle);
239 * Request processing API
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);
246 int rest_request_perform(rlm_rest_t *instance,
247 rlm_rest_section_t *section, REQUEST *request,
250 int rest_request_decode(rlm_rest_t *instance,
251 UNUSED rlm_rest_section_t *section, REQUEST *request,
254 void rest_request_cleanup(rlm_rest_t *instance, rlm_rest_section_t *section,
257 #define rest_get_handle_code(handle)(((rlm_rest_curl_context_t*)((rlm_rest_handle_t*)handle)->ctx)->write.code)
259 #define rest_get_handle_type(handle)(((rlm_rest_curl_context_t*)((rlm_rest_handle_t*)handle)->ctx)->write.type)
264 ssize_t rest_uri_build(char **out, rlm_rest_t *instance, rlm_rest_section_t *section, REQUEST *request);