25RCSID(
"$Id: d958bb07a6f46a44c8a0e548a10198c3c32b4cdf $")
27#define LOG_PREFIX mctx->mi->name
32#include <freeradius-devel/util/skip.h>
74#ifndef CURLOPT_TLSAUTH_SRP
75# define CURLOPT_TLSAUTH_SRP 0
78# define CURLAUTH_BASIC 0
80#ifndef CURLAUTH_DIGEST
81# define CURLAUTH_DIGEST 0
83#ifndef CURLAUTH_DIGEST_IE
84# define CURLAUTH_DIGEST_IE 0
86#ifndef CURLAUTH_GSSNEGOTIATE
87# define CURLAUTH_GSSNEGOTIATE 0
90# define CURLAUTH_NTLM 0
92#ifndef CURLAUTH_NTLM_WB
93# define CURLAUTH_NTLM_WB 0
240 curl_easy_cleanup(randle->
candle);
270 if (!randle)
return NULL;
278 randle->
uctx = curl_ctx;
299 size_t freespace = (size * nmemb) - 1;
306 if (
data->len == 0)
return 0;
315 len = to_copy > freespace ? freespace : to_copy;
316 if (
len == 0)
return 0;
361 size_t freespace = (size * nmemb) - 1;
368 if ((ctx->
chunk) && (ctx->
chunk <= freespace)) freespace = (ctx->
chunk - 1);
375 while (freespace > 0) {
383 RDEBUG2(
"Encoding attribute \"%s\"",
vp->
da->name);
386 escaped = curl_escape(
vp->
da->name, 0);
388 REDEBUG(
"Failed escaping string \"%s\"",
vp->
da->name);
392 len = strlen(escaped);
393 if (freespace < (1 +
len)) {
401 len = encoded - (
char *)
out;
409 REDEBUG(
"Failed encoding attribute");
411 RDEBUG3(
"Returning %zu bytes of POST data "
412 "(buffer full or chunk exceeded)",
len);
434 if (slen < 0)
return 0;
437 RDEBUG3(
"Length : %zu", (
size_t)slen);
440 escaped = curl_escape(p, (
int)slen);
442 REDEBUG(
"Failed escaping string \"%s\"",
vp->
da->name);
445 len = strlen(escaped);
447 if (freespace <
len) {
468 if (freespace < 1)
goto no_space;
486 RDEBUG3(
"Returning %zu bytes of POST data",
len);
536 size_t freespace = (size * nmemb) - 1;
545 if (!encoded)
return -1;
548 data->len = strlen(encoded);
550 RDEBUG3(
"JSON Data: %s", encoded);
551 RDEBUG3(
"Returning %zu bytes of JSON data",
data->len);
557 len = to_copy > freespace ? freespace : to_copy;
559 if (
len == 0)
return 0;
601 buff = talloc_array(NULL,
char, needed);
611 if (needed > limit)
break;
613 MEM(
buff = talloc_realloc(NULL,
buff,
char, needed));
660 if (*raw ==
'\0')
return 0;
699 CURL *candle = randle->
candle;
701 char const *p = raw, *q;
710 if (*p ==
'\0')
return 0;
723 char const *to_parse = NULL;
724 char *expanded = NULL;
731 name = curl_easy_unescape(candle, p, (q - p), &curl_len);
742 .dict_def =
request->local_dict,
746 RPWDEBUG(
"Failed parsing attribute (skipping)");
752 RWDEBUG(
"Attribute name refers to outer request but not in a tunnel (skipping)");
759 RWDEBUG(
"List not valid in this context (skipping)");
772 len = (!q) ? (rawlen - (p - raw)) : (unsigned)(q - p);
774 value = curl_easy_unescape(candle, p, (
int)
len, &curl_len);
781 p += (!q) ?
len : (
len + 1);
783 RDEBUG3(
"Length : %i", curl_len);
790 RDEBUG2(
"Performing xlat expansion of response value");
802 REDEBUG(
"Failed creating valuepair");
812 TALLOC_FREE(expanded);
814 RWDEBUG(
"Incompatible value assignment, skipping");
856 char *expanded = NULL;
861 if (json_object_is_type(value_ctx->
value, json_type_null)) {
862 RDEBUG3(
"Got null value for attribute \"%s\" (skipping)", da->name);
869 switch (json_object_get_type(value_ctx->
value)) {
871 if (value_ctx->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'int', attribute \"%s\"", da->name);
875 case json_type_double:
876 if (value_ctx->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'double', attribute \"%s\"", da->name);
880 case json_type_string:
881 value = json_object_get_string(value_ctx->
value);
882 if (value_ctx->
do_xlat && memchr(
value,
'%', json_object_get_string_len(value_ctx->
value))) {
891 json_object_get_string_len(value_ctx->
value), NULL) < 0) ret = -1;
899 if (value_ctx->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'object', attribute \"%s\"", da->name);
906 str = json_object_get_string(value_ctx->
value);
908 RWDEBUG(
"Failed getting string value for attribute \"%s\" (skipping)", da->name);
920 RWDEBUG(
"Failed parsing value for attribute \"%s\" (skipping)", da->name);
992 if (!json_object_is_type(
object, json_type_object)) {
993#ifdef HAVE_JSON_TYPE_TO_NAME
994 REDEBUG(
"Can't process VP container, expected JSON object"
995 "got \"%s\" (skipping)",
996 json_type_to_name(json_object_get_type(
object)));
998 REDEBUG(
"Can't process VP container, expected JSON object"
1008 json_object_object_foreach(
object,
name,
value) {
1009 size_t i = 0, elements;
1010 struct json_object *element, *tmp;
1026 map = talloc_zero(NULL,
map_t);
1027 map_list_init(&map->
child);
1033 .dict_def = request->local_dict,
1034 .list_def = request_attr_reply
1037 RPWDEBUG(
"Failed parsing attribute (skipping)");
1042 RWDEBUG(
"Attribute name refers to outer request but not in a tunnel (skipping)");
1047 RWDEBUG(
"List not valid in this context (skipping)");
1067 if (json_object_is_type(
value, json_type_object)) {
1071 if (json_object_object_get_ex(
value,
"op", &tmp)) {
1074 RWDEBUG(
"Invalid operator value \"%s\" (skipping)",
1075 json_object_get_string(tmp));
1083 if (json_object_object_get_ex(
value,
"do_xlat", &tmp)) {
1084 value_ctx.do_xlat = json_object_get_boolean(tmp);
1090 if (json_object_object_get_ex(
value,
"is_json", &tmp)) {
1091 value_ctx.is_json = json_object_get_boolean(tmp);
1097 if (!json_object_object_get_ex(
value,
"value", &tmp)) {
1098 RWDEBUG(
"Value key missing (skipping)");
1111 if (!value_ctx.is_json && json_object_is_type(
value, json_type_array)) {
1112 elements = json_object_array_length(
value);
1114 RWDEBUG(
"Zero length value array (skipping)");
1117 element = json_object_array_get_idx(
value, 0);
1128 if (max_attrs-- <= 0) {
1129 RWDEBUG(
"At maximum attribute limit");
1141 if (json_object_is_type(element, json_type_object) && !value_ctx.is_json) {
1143 RWDEBUG(
"Found nested VP, these are not yet supported (skipping)");
1154 (
size_t) json_object_get_string_len(element)),
1156 REDEBUG(
"Failed parsing value into map");
1159 value_ctx.value = element;
1161 TALLOC_FREE(map->
rhs);
1167 }
while ((++i < elements) && (element = json_object_array_get_idx(
value, i)));
1173 return max - max_attrs;
1199 char const *p = raw;
1201 struct json_object *json;
1209 if (*p ==
'\0')
return 0;
1211 json = json_tokener_parse(p);
1213 REDEBUG(
"Malformed JSON data \"%s\"", raw);
1222 json_object_put(json);
1249 char const *start = (
char *)
in, *p = start, *end = p + (size * nmemb);
1257 REDEBUG(
"Forcing header decode failure");
1265 if (((end - p) == 2) && ((p[0] ==
'\r') && (p[1] ==
'\n'))) {
1271 if (ctx->
code == 100) {
1276 return (end - start);
1279 switch (ctx->
state) {
1281 RDEBUG2(
"Processing response header");
1289 if ((end - p) < 12) {
1290 REDEBUG(
"Malformed HTTP header: Status line too short");
1292 REDEBUG(
"Received %td bytes of invalid header data: %pV",
1302 return (end - start);
1308 REDEBUG(
"Malformed HTTP header: Missing HTTP version");
1316 q = memchr(p,
' ', (end - p));
1318 REDEBUG(
"Malformed HTTP header: Missing reason code");
1329 if ((end - p) < 6) {
1330 REDEBUG(
"Malformed HTTP header: Reason code too short");
1338 if (!isdigit(p[0]) || !isdigit(p[1]) || !isdigit(p[2]) || !((p[3] ==
' ') || (p[3] ==
'\r'))) {
1339 REDEBUG(
"Malformed HTTP header: Reason code malformed. "
1340 "Expected three digits then space or end of header, got \"%pV\"",
1352 ctx->
code = (int)strtoul(p, &qq, 10);
1363 q = memchr(p,
'\r', (end - p));
1364 if (!q)
goto malformed;
1376 if (((end - p) >= 14) &&
1383 q = memchr(p,
';', (end - p));
1388 if (!q) q = memchr(p,
'\r', (end - p));
1390 len = (
size_t)(!q ? (end - p) : (q - p));
1403 RDEBUG3(
"Forcing body type to \"%s\"",
1421 switch (ctx->
type) {
1423 RWDEBUG(
"Couldn't determine type, using the request's type \"%s\".",
1428 REDEBUG(
"Type \"%s\" is currently unsupported",
1433 REDEBUG(
"Type \"%s\" is unavailable, please rebuild this module with the required "
1438 REDEBUG(
"Type \"%s\" is not a valid web API data markup format",
1454 return (end - start);
1475 char const *start =
in, *p = start, *end = p + (size * nmemb);
1480 if (start == end)
return 0;
1484 REDEBUG(
"Forcing body read failure");
1494 switch (ctx->
type) {
1500 while ((q = memchr(p,
'\n', (end - p)))) {
1509 while ((q = memchr(p,
'\n', (end - p)))) {
1522 REDEBUG(
"Incoming data (%zu bytes) exceeds max_body_in (%zu bytes). "
1525 TALLOC_FREE(ctx->
buffer);
1530 if (needed > ctx->
alloc) {
1532 ctx->
alloc = needed;
1536 memcpy(out_p, p, (end - p));
1539 ctx->
used += (end - p);
1544 return (end - start);
1554 char const *p, *end;
1559 if (
len == 0)
return;
1563 RERROR(
"Server returned:");
1564 while ((q = memchr(p,
'\n', (end - p)))) {
1579 char const *p, *end;
1584 if (
len == 0)
return;
1589 while ((q = memchr(p,
'\n', (end - p)))) {
1623 TALLOC_FREE(ctx->
buffer);
1706 REDEBUG(
"Failed creating HTTP body content");
1709 RDEBUG2(
"Content-Length will be %zu bytes", (
size_t)
len);
1734 struct curl_slist *headers;
1736 if (validate && !strchr(header,
':')) {
1737 RWDEBUG(
"Invalid HTTP header \"%s\" must be in format '<attribute>: <value>'. Skipping...",
1746 headers = curl_slist_append(ctx->
headers, header);
1748 REDEBUG(
"Failed to add header \"%s\"", header);
1769 struct curl_slist *headers = ctx->
headers;
1773 sep = strchr(header,
':');
1774 cmp_len = sep ? (
size_t)(sep - header) : strlen(header);
1777 if (
strncasecmp(headers->data, header, cmp_len) == 0)
return true;
1778 headers = headers->next;
1814 char const *uri,
char const *body_data)
1819 CURL *candle = randle->
candle;
1824 CURLcode ret = CURLE_OK;
1842#if CURL_AT_LEAST_VERSION(7,85,0)
1857 timeout =
inst->conn_config.connect_timeout;
1858 RDEBUG3(
"Connect timeout is %pVs, request timeout is %pVs",
1866 RDEBUG3(
"Adding custom headers:");
1876 if (call_env->
request.header) {
1877 size_t len = talloc_array_length(call_env->
request.header), i;
1878 for (i = 0; i <
len; i++) {
1913 RDEBUG3(
"Request body content-type will be \"%s\"", content_type);
1964#define SET_AUTH_OPTION(_x, _y)\
1966 if ((ret = curl_easy_setopt(candle, _x, _y)) != CURLE_OK) {\
1967 option = STRINGIFY(_x);\
1968 REDEBUG("Failed setting curl option %s: %s (%u)", option, curl_easy_strerror(ret), ret); \
1972 RDEBUG3(
"Configuring HTTP auth type %s, user \"%pV\", password \"%pV\"",
2014 RDEBUG3(
"Using a HTTP method which does not require a body. Forcing request body type to \"none\"");
2119 RDEBUG2(
"Skipping attribute processing, no valid body data received");
2168 escaped = curl_escape(raw, 0);
2193 CURL *candle = randle->
candle;
2207 if (!p || (*++p !=
'/') || (*++p !=
'/')) {
2209 REDEBUG(
"URI \"%s\" is malformed, can't find start of path", uri);
2212 p = strchr(p + 1,
'/');
2222 scheme = curl_easy_unescape(candle, uri, (
int)
len, NULL);
2224 REDEBUG(
"Error unescaping host");
static int const char char buffer[256]
static uint8_t request[4]
#define L(_str)
Helper for initialising arrays of string literals.
#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_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_remove(fr_dcursor_t *cursor)
Remove the current item.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
#define RADIUSD_VERSION_STRING
char const * unlang_interpret_virtual_server(request_t *request)
Return the current virtual server for this request.
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.
int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t func, void *ctx)
Convert map_t to fr_pair_t (s) and add them to a request_t.
#define ROUND_UP(_num, _mul)
Round up - Works in all cases, but is slower.
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.
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, UNUSED bool tainted)
Convert string value to native attribute value.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
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_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
#define pair_update_request(_attr, _da)
fr_dict_attr_t const * request_attr_reply
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[]
static int json_map_getvalue(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map, void *uctx)
Converts JSON "value" key into fr_pair_t when processing a map_t.
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.
http_body_type_t rest_response_body_type_get(fr_curl_io_request_t *randle)
Return the body type of a HTTP response.
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.
static int json_pair_alloc(UNUSED 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.
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
int do_xlat
If true value will be expanded with xlat.
json_object * value
Object to extract value from.
fr_table_num_sorted_t const http_method_table[]
Conversion table for method config values.
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 rest_get_handle_data(char const **out, fr_curl_io_request_t *randle)
Extracts pointer to buffer containing response data.
static bool rest_request_contains_header(fr_curl_io_request_t *randle, char const *header)
See if the list of headers already contains a header.
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)
const unsigned long http_curl_auth[REST_HTTP_AUTH_NUM_ENTRIES]
static int rest_decode_post(UNUSED rlm_rest_t const *instance, 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.
const http_body_type_t http_body_type_supported[REST_HTTP_BODY_NUM_ENTRIES]
Table of encoder/decoder support.
#define CURLAUTH_GSSNEGOTIATE
int is_json
If true value will be inserted as raw JSON (multiple values not supported).
size_t rest_uri_escape(UNUSED request_t *request, char *out, size_t outlen, char const *raw, UNUSED void *arg)
URL encodes a string.
int rest_request_config_add_header(request_t *request, fr_curl_io_request_t *randle, char const *header, bool validate)
Adds an additional header to a handle to use in the next reques.
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
const bool http_body_type_binary[REST_HTTP_BODY_NUM_ENTRIES]
Table of which known body types are expected to give binary data.
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
bool is_json
Section default for the per-attribute "is_json" flag in JSON responses.
http_auth_type_t auth
HTTP auth type.
struct curl_slist * headers
Any HTTP headers which will be sent with the request.
rlm_rest_section_response_json_t json
Configuration for the JSON decoder.
tmpl_t * header
Where to create pairs representing HTTP response headers.
@ REST_HTTP_METHOD_DELETE
@ REST_HTTP_METHOD_UNKNOWN
@ REST_HTTP_METHOD_CUSTOM
Must always come last, should not be in method table.
request_t * request
Current request.
char * buffer
Raw incoming HTTP data.
int code
HTTP Status Code.
rlm_rest_section_response_post_t post
Configuration for the POST decoder.
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.
char * body
Pointer to the buffer which contains body data/ Only used when not performing chunked encoding.
#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.
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.
char const * method_str
The string version of the HTTP method.
@ REST_HTTP_AUTH_NUM_ENTRIES
@ REST_HTTP_AUTH_GSSNEGOTIATE
@ REST_HTTP_AUTH_DIGEST_IE
@ REST_HTTP_AUTH_ANY_SAFE
rlm_rest_section_t const * section
Section configuration.
struct rlm_rest_call_env_t::@212 response
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
struct rlm_rest_call_env_t::@211 request
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)
bool do_xlat
If true, values in POST responses are xlat expanded before being assigned to attributes.
#define REST_BODY_MAX_LEN
rlm_rest_section_t const * section
Section configuration.
void * encoder
Encoder specific data.
bool accept_all
Accept all content types.
rlm_rest_request_t request
Request context data.
rlm_rest_section_response_t response
Response configuration.
fr_time_delta_t timeout
Timeout timeval.
bool do_xlat
Section default for the per-attribute "do_xlat" flag in JSON responses.
char const * name
Section name.
size_t alloc
Space allocated for buffer.
request_t * request
Current request.
@ REST_HTTP_BODY_UNSUPPORTED
@ REST_HTTP_BODY_NUM_ENTRIES
@ REST_HTTP_BODY_UNAVAILABLE
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)
@ WRITE_STATE_PARSE_HEADERS
@ WRITE_STATE_PARSE_CONTENT
#define FR_SBUFF_IN(_start, _len_or_end)
#define FR_SBUFF_OUT(_start, _len_or_end)
void * data
Module's instance data.
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
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.
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.
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
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_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
fr_slen_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.
Optional arguments passed to vp_tmpl functions.
static char buff[sizeof("18446744073709551615")+3]
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
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)
fr_token_t op
The operator that controls insertion of the dst attribute.
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
map_list_t child
parent map, for nested ones
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
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.
#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.
fr_slen_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules)
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.
static fr_sbuff_err_t char size_t fr_sbuff_t * in
static fr_sbuff_err_t char size_t fr_sbuff_t size_t max
#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.
static fr_sbuff_err_t char ** out
static fr_sbuff_err_t char size_t * len
#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)