25 RCSID(
"$Id: 5c9c465279d6eeb72570015af474c95d3f74a915 $")
27 #define LOG_PREFIX mctx->mi->name
33 #include <freeradius-devel/server/base.h>
34 #include <freeradius-devel/server/log.h>
35 #include <freeradius-devel/server/pool.h>
36 #include <freeradius-devel/server/tmpl.h>
37 #include <freeradius-devel/unlang/call.h>
38 #include <freeradius-devel/util/value.h>
73 #ifndef CURLOPT_TLSAUTH_SRP
74 # define CURLOPT_TLSAUTH_SRP 0
76 #ifndef CURLAUTH_BASIC
77 # define CURLAUTH_BASIC 0
79 #ifndef CURLAUTH_DIGEST
80 # define CURLAUTH_DIGEST 0
82 #ifndef CURLAUTH_DIGEST_IE
83 # define CURLAUTH_DIGEST_IE 0
85 #ifndef CURLAUTH_GSSNEGOTIATE
86 # define CURLAUTH_GSSNEGOTIATE 0
89 # define CURLAUTH_NTLM 0
91 #ifndef CURLAUTH_NTLM_WB
92 # define CURLAUTH_NTLM_WB 0
237 curl_easy_cleanup(randle->
candle);
267 if (!randle)
return NULL;
275 randle->
uctx = curl_ctx;
296 size_t freespace = (size * nmemb) - 1;
303 if (
data->len == 0)
return 0;
312 len = to_copy > freespace ? freespace : to_copy;
313 if (len == 0)
return 0;
358 size_t freespace = (size * nmemb) - 1;
365 if ((ctx->
chunk) && (ctx->
chunk <= freespace)) freespace = (ctx->
chunk - 1);
372 while (freespace > 0) {
380 RDEBUG2(
"Encoding attribute \"%s\"",
vp->
da->name);
383 escaped = curl_escape(
vp->
da->name, 0);
385 REDEBUG(
"Failed escaping string \"%s\"",
vp->
da->name);
389 len = strlen(escaped);
390 if (freespace < (1 + len)) {
398 len = encoded - (
char *)
out;
406 REDEBUG(
"Failed encoding attribute");
408 RDEBUG3(
"Returning %zd bytes of POST data "
409 "(buffer full or chunk exceeded)", len);
415 len =
snprintf(p, freespace,
"%s=", escaped);
431 if (slen < 0)
return 0;
434 RDEBUG3(
"Length : %zd", (
size_t)slen);
437 escaped = curl_escape(p, (
size_t)slen);
439 REDEBUG(
"Failed escaping string \"%s\"",
vp->
da->name);
442 len = strlen(escaped);
444 if (freespace < len) {
449 len =
strlcpy(p, escaped, len + 1);
465 if (freespace < 1)
goto no_space;
480 len = p - (
char *)
out;
483 RDEBUG3(
"Returning %zd bytes of POST data", len);
533 size_t freespace = (size * nmemb) - 1;
542 if (!encoded)
return -1;
545 data->len = strlen(encoded);
547 RDEBUG3(
"JSON Data: %s", encoded);
548 RDEBUG3(
"Returning %zd bytes of JSON data",
data->len);
554 len = to_copy > freespace ? freespace : to_copy;
556 if (len == 0)
return 0;
598 buff = talloc_array(NULL,
char, alloc);
608 if (alloc > limit)
break;
610 MEM(
buff = talloc_realloc(NULL,
buff,
char, alloc));
657 if (*raw ==
'\0')
return 0;
696 CURL *candle = randle->
candle;
698 char const *p = raw, *q;
707 if (*p ==
'\0')
return 0;
720 char *expanded = NULL;
727 name = curl_easy_unescape(candle, p, (q - p), &curl_len);
739 .dict_def = request->dict,
743 RPWDEBUG(
"Failed parsing attribute (skipping)");
749 RWDEBUG(
"Attribute name refers to outer request but not in a tunnel (skipping)");
756 RWDEBUG(
"List not valid in this context (skipping)");
769 len = (!q) ? (rawlen - (p - raw)) : (
unsigned)(q - p);
771 value = curl_easy_unescape(candle, p, len, &curl_len);
778 p += (!q) ? len : (len + 1);
780 RDEBUG3(
"Length : %i", curl_len);
786 RDEBUG2(
"Performing xlat expansion of response value");
788 if (
xlat_aeval(request, &expanded, request,
value, NULL, NULL) < 0)
goto skip;
794 REDEBUG(
"Failed creating valuepair");
804 TALLOC_FREE(expanded);
806 RWDEBUG(
"Incompatible value assignment, skipping");
851 char *expanded = NULL;
858 if (json_object_is_type(leaf, json_type_null)) {
859 RDEBUG3(
"Got null value for attribute \"%s\" (skipping)", da->name);
865 RWDEBUG(
"Failed creating valuepair for attribute \"%s\" (skipping)", da->name);
871 switch (json_object_get_type(leaf)) {
873 if (flags->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'int', attribute \"%s\"", da->name);
874 fr_value_box(&src, (int32_t)json_object_get_int(leaf),
true);
877 case json_type_double:
878 if (flags->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'double', attribute \"%s\"", da->name);
879 fr_value_box(&src, (
double)json_object_get_double(leaf),
true);
882 case json_type_string:
883 value = json_object_get_string(leaf);
884 if (flags->
do_xlat && memchr(
value,
'%', json_object_get_string_len(leaf))) {
890 talloc_array_length(expanded) - 1,
true);
893 json_object_get_string_len(leaf),
true);
900 if (flags->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'object', attribute \"%s\"", da->name);
907 str = json_object_get_string(leaf);
909 RWDEBUG(
"Failed getting string value for attribute \"%s\" (skipping)", da->name);
920 RWDEBUG(
"Failed parsing value for attribute \"%s\" (skipping)", da->name);
988 if (!json_object_is_type(
object, json_type_object)) {
989 #ifdef HAVE_JSON_TYPE_TO_NAME
990 REDEBUG(
"Can't process VP container, expected JSON object"
991 "got \"%s\" (skipping)",
992 json_type_to_name(json_object_get_type(
object)));
994 REDEBUG(
"Can't process VP container, expected JSON object"
1004 json_object_object_foreach(
object,
name,
value) {
1005 int i = 0, elements;
1006 struct json_object *element, *tmp;
1030 .dict_def = request->dict,
1034 RPWDEBUG(
"Failed parsing attribute (skipping)");
1039 RWDEBUG(
"Attribute name refers to outer request but not in a tunnel (skipping)");
1045 RWDEBUG(
"List not valid in this context (skipping)");
1066 if (json_object_is_type(
value, json_type_object)) {
1070 if (json_object_object_get_ex(
value,
"op", &tmp)) {
1073 RWDEBUG(
"Invalid operator value \"%s\" (skipping)",
1074 json_object_get_string(tmp));
1082 if (json_object_object_get_ex(
value,
"do_xlat", &tmp)) {
1083 flags.
do_xlat = json_object_get_boolean(tmp);
1089 if (json_object_object_get_ex(
value,
"is_json", &tmp)) {
1090 flags.
is_json = json_object_get_boolean(tmp);
1096 if (!json_object_object_get_ex(
value,
"value", &tmp)) {
1097 RWDEBUG(
"Value key missing (skipping)");
1110 if (!flags.
is_json && json_object_is_type(
value, json_type_array)) {
1111 elements = json_object_array_length(
value);
1113 RWDEBUG(
"Zero length value array (skipping)");
1116 element = json_object_array_get_idx(
value, 0);
1129 if (max_attrs-- <= 0) {
1130 RWDEBUG(
"At maximum attribute limit");
1142 if (json_object_is_type(element, json_type_object) && !flags.
is_json) {
1144 RWDEBUG(
"Found nested VP, these are not yet supported (skipping)");
1168 }
while ((++i < elements) && (element = json_object_array_get_idx(
value, i)));
1174 return max - max_attrs;
1200 char const *p = raw;
1202 struct json_object *json;
1210 if (*p ==
'\0')
return 0;
1212 json = json_tokener_parse(p);
1214 REDEBUG(
"Malformed JSON data \"%s\"", raw);
1223 json_object_put(json);
1250 char const *start = (
char *)
in, *p = start, *end = p + (size * nmemb);
1258 REDEBUG(
"Forcing header decode failure");
1266 if (((end - p) == 2) && ((p[0] ==
'\r') && (p[1] ==
'\n'))) {
1272 if (ctx->
code == 100) {
1277 return (end - start);
1280 switch (ctx->
state) {
1282 RDEBUG2(
"Processing response header");
1290 if ((end - p) < 12) {
1291 REDEBUG(
"Malformed HTTP header: Status line too short");
1293 REDEBUG(
"Received %zu bytes of invalid header data: %pV",
1303 return (end - start);
1309 REDEBUG(
"Malformed HTTP header: Missing HTTP version");
1317 q = memchr(p,
' ', (end - p));
1319 REDEBUG(
"Malformed HTTP header: Missing reason code");
1330 if ((end - p) < 6) {
1331 REDEBUG(
"Malformed HTTP header: Reason code too short");
1339 if (!isdigit(p[0]) || !isdigit(p[1]) || !isdigit(p[2]) || !((p[3] ==
' ') || (p[3] ==
'\r'))) {
1340 REDEBUG(
"Malformed HTTP header: Reason code malformed. "
1341 "Expected three digits then space or end of header, got \"%pV\"",
1350 ctx->
code = (int)strtoul(p, &q, 10);
1360 q = memchr(p,
'\r', (end - p));
1361 if (!q)
goto malformed;
1373 if (((end - p) >= 14) &&
1380 q = memchr(p,
';', (end - p));
1385 if (!q) q = memchr(p,
'\r', (end - p));
1387 len = (
size_t)(!q ? (end - p) : (q - p));
1400 RDEBUG3(
"Forcing body type to \"%s\"",
1409 switch (ctx->
type) {
1411 RWDEBUG(
"Couldn't determine type, using the request's type \"%s\".",
1416 REDEBUG(
"Type \"%s\" is currently unsupported",
1421 REDEBUG(
"Type \"%s\" is unavailable, please rebuild this module with the required "
1426 REDEBUG(
"Type \"%s\" is not a valid web API data markup format",
1442 return (end - start);
1463 char const *start =
in, *p = start, *end = p + (size * nmemb);
1468 if (start == end)
return 0;
1472 REDEBUG(
"Forcing body read failure");
1482 switch (ctx->
type) {
1486 while ((q = memchr(p,
'\n', (end - p)))) {
1495 while ((q = memchr(p,
'\n', (end - p)))) {
1508 REDEBUG(
"Incoming data (%zu bytes) exceeds max_body_in (%zu bytes). "
1511 TALLOC_FREE(ctx->
buffer);
1516 if (needed > ctx->
alloc) {
1518 ctx->
alloc = needed;
1522 memcpy(out_p, p, (end - p));
1525 ctx->
used += (end - p);
1530 return (end - start);
1540 char const *p, *end;
1545 if (len == 0)
return;
1549 RERROR(
"Server returned:");
1550 while ((q = memchr(p,
'\n', (end - p)))) {
1565 char const *p, *end;
1570 if (len == 0)
return;
1575 while ((q = memchr(p,
'\n', (end - p)))) {
1609 TALLOC_FREE(ctx->
buffer);
1679 REDEBUG(
"Failed creating HTTP body content");
1682 RDEBUG2(
"Content-Length will be %zu bytes", len);
1684 fr_assert((len == 0) || (talloc_array_length(
uctx->body) >= (
size_t)len));
1724 char const *uri,
char const *body_data)
1729 CURL *candle = randle->
candle;
1734 CURLcode ret = CURLE_OK;
1738 bool content_type_set =
false;
1753 #if CURL_AT_LEAST_VERSION(7,85,0)
1769 RDEBUG3(
"Connect timeout is %pVs, request timeout is %pVs",
1777 RDEBUG3(
"Adding custom headers:");
1784 if (!ctx->
headers)
goto error_header;
1791 if (!ctx->
headers)
goto error_header;
1796 if (call_env->
request.header) {
1797 size_t len = talloc_array_length(call_env->
request.header), i;
1798 for (i = 0; i < len; i++) {
1804 ctx->
headers = curl_slist_append(ctx->
headers, header->vb_strvalue);
1820 if (!strchr(header->vp_strvalue,
':')) {
1821 RWDEBUG(
"Invalid HTTP header \"%s\" must be in format '<attribute>: <value>'. Skipping...",
1822 header->vp_strvalue);
1827 RDEBUG3(
"%pV", &header->data);
1830 ctx->
headers = curl_slist_append(ctx->
headers, header->vp_strvalue);
1835 if (!content_type_set && (
strncasecmp(header->vp_strvalue,
"content-type:",
sizeof(
"content-type:") - 1) == 0)) {
1836 char const *content_type = header->vp_strvalue + (
sizeof(
"content-type:") - 1);
1838 while (isspace((
uint8_t)*content_type)) content_type++;
1840 RDEBUG3(
"Request body content-type provided as \"%s\"", content_type);
1842 content_type_set =
true;
1849 if (!content_type_set) {
1861 REDEBUG(
"Failed creating header");
1865 RDEBUG3(
"Request body content-type will be \"%s\"", content_type);
1916 #define SET_AUTH_OPTION(_x, _y)\
1918 if ((ret = curl_easy_setopt(candle, _x, _y)) != CURLE_OK) {\
1919 option = STRINGIFY(_x);\
1920 REDEBUG("Failed setting curl option %s: %s (%i)", option, curl_easy_strerror(ret), ret); \
1924 RDEBUG3(
"Configuring HTTP auth type %s, user \"%pV\", password \"%pV\"",
1966 RDEBUG3(
"Using a HTTP method which does not require a body. Forcing request body type to \"none\"");
1977 if (!ctx->
headers)
goto error_header;
1979 ctx->
headers = curl_slist_append(ctx->
headers,
"Transfer-Encoding: chunked");
1980 if (!ctx->
headers)
goto error_header;
2075 RDEBUG2(
"Skipping attribute processing, no valid body data received");
2124 escaped = curl_escape(raw, 0);
2149 CURL *candle = randle->
candle;
2163 if (!p || (*++p !=
'/') || (*++p !=
'/')) {
2165 REDEBUG(
"URI \"%s\" is malformed, can't find start of path", uri);
2168 p = strchr(p + 1,
'/');
2178 scheme = curl_easy_unescape(candle, uri, len, NULL);
2180 REDEBUG(
"Error unescaping host");
2195 return talloc_array_length(*
out) - 1;
static int const char char buffer[256]
#define L(_str)
Helper for initialising arrays of string literals.
CONF_SECTION * unlang_call_current(request_t *request)
Return the last virtual server that was called.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
#define FR_CURL_REQUEST_SET_OPTION(_x, _y)
fr_curl_io_request_t * fr_curl_io_request_alloc(TALLOC_CTX *ctx)
Allocate a new curl easy request and wrapper struct.
void * uctx
Private data for the module using the API.
CURL * candle
Request specific handle.
Structure representing an individual request being passed to curl for processing.
static void * fr_dcursor_remove(fr_dcursor_t *cursor)
Remove the current item.
fr_dcursor_eval_t void const * uctx
fr_dcursor_iter_t void * current
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
#define RADIUSD_VERSION_STRING
static fr_time_delta_t timeout
char * fr_json_afrom_pair_list(TALLOC_CTX *ctx, fr_pair_list_t *vps, fr_json_format_t const *format)
Returns a JSON string of a list of value pairs.
int fr_curl_easy_tls_init(fr_curl_io_request_t *randle, fr_curl_tls_t const *conf)
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RPWDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
#define ROUND_UP(_num, _mul)
Round up - Works in all cases, but is slower.
@ TMPL_ATTR_REF_PREFIX_NO
Attribute refs have no '&' prefix.
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
int strncasecmp(char *s1, char *s2, int n)
void * env_data
Per call environment data.
module_instance_t const * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, bool tainted)
Convert string value to native attribute value.
void radius_pairmove(request_t *request, fr_pair_list_t *to, fr_pair_list_t *from)
#define pair_update_request(_attr, _da)
fr_dict_attr_t const * request_attr_reply
static int rest_decode_post(UNUSED rlm_rest_t const *instance, UNUSED rlm_rest_section_t const *section, request_t *request, fr_curl_io_request_t *randle, char *raw, size_t rawlen)
Converts POST response into fr_pair_ts and adds them to the request.
static int rest_decode_plain(UNUSED rlm_rest_t const *inst, UNUSED rlm_rest_section_t const *section, request_t *request, UNUSED fr_curl_io_request_t *randle, char *raw, size_t rawlen)
Converts plain response into a single fr_pair_t.
fr_table_num_sorted_t const http_auth_table[]
size_t len
Length of data.
char const * start
Start of the buffer.
#define CURLAUTH_DIGEST_IE
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.
ssize_t rest_uri_host_unescape(char **out, UNUSED rlm_rest_t const *inst, request_t *request, fr_curl_io_request_t *randle, char const *uri)
Unescapes the host portion of a URI string.
int do_xlat
If true value will be expanded with xlat.
static size_t rest_encode_custom(void *out, size_t size, size_t nmemb, void *userdata)
Copies a pre-expanded xlat string to the output buffer.
fr_table_num_sorted_t const http_body_type_table[]
Conversion table for type config values.
static size_t rest_encode_json(void *out, size_t size, size_t nmemb, void *userdata)
Encodes fr_pair_t linked list in JSON format.
#define CURLOPT_TLSAUTH_SRP
fr_token_t op
The operator that determines how the new VP.
fr_table_num_sorted_t const http_method_table[]
Conversion table for method config values.
static fr_pair_t * json_pair_alloc_leaf(UNUSED rlm_rest_t const *instance, UNUSED rlm_rest_section_t const *section, TALLOC_CTX *ctx, request_t *request, fr_dict_attr_t const *da, json_flags_t *flags, json_object *leaf)
Converts JSON "value" key into fr_pair_t.
size_t rest_get_handle_data(char const **out, fr_curl_io_request_t *randle)
Extracts pointer to buffer containing response data.
static int json_pair_alloc(rlm_rest_t const *instance, rlm_rest_section_t const *section, request_t *request, json_object *object, UNUSED int level, int max)
Processes JSON response and converts it into multiple fr_pair_ts.
static void rest_request_init(rlm_rest_section_t const *section, request_t *request, rlm_rest_request_t *ctx)
(Re-)Initialises the data in a rlm_rest_request_t.
static ssize_t rest_request_encode_wrapper(char **out, UNUSED rlm_rest_t const *inst, rest_read_t func, size_t limit, void *userdata)
Emulates successive libcurl calls to an encoding function.
static int rest_decode_json(rlm_rest_t const *instance, rlm_rest_section_t const *section, request_t *request, UNUSED fr_curl_io_request_t *randle, char *raw, UNUSED size_t rawlen)
Converts JSON response into fr_pair_ts and adds them to the request.
void rest_response_debug(request_t *request, fr_curl_io_request_t *handle)
Print out the response text.
fr_table_num_sorted_t const http_content_type_table[]
Conversion table for "Content-Type" header values.
#define SET_AUTH_OPTION(_x, _y)
int is_json
If true value will be inserted as raw JSON.
const unsigned long http_curl_auth[REST_HTTP_AUTH_NUM_ENTRIES]
const http_body_type_t http_body_type_supported[REST_HTTP_BODY_NUM_ENTRIES]
Table of encoder/decoder support.
#define CURLAUTH_GSSNEGOTIATE
size_t rest_uri_escape(UNUSED request_t *request, char *out, size_t outlen, char const *raw, UNUSED void *arg)
URL encodes a string.
void rest_response_error(request_t *request, fr_curl_io_request_t *handle)
Print out the response text as error lines.
size_t http_body_type_table_len
static int rest_request_config_body(module_ctx_t const *mctx, rlm_rest_section_t const *section, request_t *request, fr_curl_io_request_t *randle, rest_read_t func)
Configures body specific curlopts.
static int _mod_conn_free(fr_curl_io_request_t *randle)
Frees a libcurl handle, and any additional memory used by context data.
static void rest_response_init(rlm_rest_section_t const *section, request_t *request, rlm_rest_response_t *ctx, http_body_type_t type, tmpl_t *header)
(Re-)Initialises the data in a rlm_rest_response_t.
static size_t rest_response_body(void *in, size_t size, size_t nmemb, void *userdata)
Processes incoming HTTP body data from libcurl.
static size_t rest_encode_post(void *out, size_t size, size_t nmemb, void *userdata)
Encodes fr_pair_t linked list in POST format.
char const * p
how much text we've sent so far.
size_t http_auth_table_len
static size_t rest_response_header(void *in, size_t size, size_t nmemb, void *userdata)
Processes incoming HTTP header data from libcurl.
size_t http_content_type_table_len
void * rest_mod_conn_create(TALLOC_CTX *ctx, void *instance, UNUSED fr_time_delta_t timeout)
Creates a new connection handle for use by the FR connection API.
size_t http_method_table_len
int rest_response_decode(rlm_rest_t const *instance, rlm_rest_section_t const *section, request_t *request, fr_curl_io_request_t *randle)
Sends the response to the correct decode function.
Flags to control the conversion of JSON values to fr_pair_ts.
Function prototypes and datatypes for the REST (HTTP) transport.
rlm_rest_t const * instance
This instance of rlm_rest.
read_state_t state
Encoder state.
HIDDEN fr_dict_attr_t const * attr_rest_http_header
http_auth_type_t auth
HTTP auth type.
struct curl_slist * headers
Any HTTP headers which will be sent with the request.
tmpl_t * header
Where to create pairs representing HTTP response headers.
request_t * request
Current request.
char * buffer
Raw incoming HTTP data.
int code
HTTP Status Code.
write_state_t state
Decoder state.
bool fail_header_decode
Force header decoding to fail for debugging purposes.
char const * proxy
Send request via this proxy.
size_t used
Space used in buffer.
http_body_type_t type
HTTP Content Type.
#define REST_BODY_MAX_ATTRS
bool fail_body_decode
Force body decoding to fail for debugging purposes.
http_body_type_t force_to
Override the Content-Type header in the response to force decoding as a particular type.
@ REST_HTTP_METHOD_DELETE
@ REST_HTTP_METHOD_UNKNOWN
@ REST_HTTP_METHOD_CUSTOM
Must always come last, should not be in method table.
size_t max_body_in
Maximum size of incoming data.
fr_dcursor_t cursor
Cursor pointing to the start of the list to encode.
http_body_type_t force_to
Force decoding the body type as a particular encoding.
@ REST_HTTP_BODY_UNSUPPORTED
@ REST_HTTP_BODY_NUM_ENTRIES
@ REST_HTTP_BODY_UNAVAILABLE
char const * method_str
The string version of the HTTP method.
rlm_rest_section_t const * section
Section configuration.
char const * body_str
The string version of the encoding/content type.
#define REST_BODY_ALLOC_CHUNK
HIDDEN fr_dict_attr_t const * attr_rest_http_body
rlm_rest_section_request_t request
Request configuration.
rlm_rest_response_t response
Response context data.
size_t(* rest_read_t)(void *ptr, size_t size, size_t nmemb, void *userdata)
#define REST_BODY_MAX_LEN
rlm_rest_section_t const * section
Section configuration.
void * encoder
Encoder specific data.
rlm_rest_request_t request
Request context data.
rlm_rest_section_response_t response
Response configuration.
fr_time_delta_t timeout
Timeout timeval.
@ WRITE_STATE_PARSE_HEADERS
@ WRITE_STATE_PARSE_CONTENT
char const * name
Section name.
@ REST_HTTP_AUTH_NUM_ENTRIES
@ REST_HTTP_AUTH_GSSNEGOTIATE
@ REST_HTTP_AUTH_DIGEST_IE
@ REST_HTTP_AUTH_ANY_SAFE
size_t alloc
Space allocated for buffer.
struct rlm_rest_call_env_t::@171 response
request_t * request
Current request.
rlm_rest_t const * instance
This instance of rlm_rest.
char const * rest_no_proxy
Magic pointer value for determining if we should disable proxying.
uint32_t chunk
Max chunk-size (mainly for testing the encoders)
struct rlm_rest_call_env_t::@170 request
#define FR_SBUFF_OUT(_start, _len_or_end)
void * data
Module's instance data.
TALLOC_CTX * tmpl_list_ctx(request_t *request, fr_dict_attr_t const *list)
Return the correct TALLOC_CTX to alloc fr_pair_t in, for a list.
static char const * tmpl_list_name(fr_dict_attr_t const *list, char const *def)
Return the name of a tmpl list or def if list not provided.
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, char const *name, tmpl_rules_t const *rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
fr_pair_list_t * tmpl_list_head(request_t *request, fr_dict_attr_t const *list)
Resolve attribute fr_pair_list_t value to an attribute list.
int tmpl_request_ptr(request_t **request, FR_DLIST_HEAD(tmpl_request_list) const *rql)
Resolve a tmpl_request_ref_t to a request_t.
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
Optional arguments passed to vp_tmpl functions.
static char buff[sizeof("18446744073709551615")+3]
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
size_t strlcpy(char *dst, char const *src, size_t siz)
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
#define fr_table_value_by_substr(_table, _name, _name_len, _def)
Convert a partial string to a value using an ordered or sorted table.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
Trim a bstr (char) buffer.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Functions which we wish were included in the standard talloc distribution.
#define talloc_get_type_abort_const
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
static int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
A time delta, a difference in time measured in nanoseconds.
fr_table_num_ordered_t const fr_tokens_table[]
ssize_t xlat_aeval(TALLOC_CTX *ctx, char **out, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx))
#define fr_pair_dcursor_by_da_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
ssize_t fr_pair_print_value_quoted(fr_sbuff_t *out, fr_pair_t const *vp, fr_token_t quote)
Print the value of an attribute to a string.
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
void fr_value_box_strdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a box, but don't copy it.
void fr_value_box_bstrndup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Assign a string to to a fr_value_box_t.
#define FR_VALUE_BOX_INITIALISER_NULL(_vb)
A static initialiser for stack/globally allocated boxes.
#define fr_box_strvalue_len(_val, _len)
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
#define fr_box_strvalue(_val)
#define fr_box_time_delta(_val)
#define fr_value_box(_box, _var, _tainted)
Automagically fill in a box, determining the value type from the type of the C variable.
#define fr_value_box_list_foreach(_list_head, _iter)
static size_t char ** out