25RCSID(
"$Id: ec936891dfb0f216f0b5a8bd8110c11f94f12d65 $")
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
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);
738 .dict_def = request->dict,
742 RPWDEBUG(
"Failed parsing attribute (skipping)");
748 RWDEBUG(
"Attribute name refers to outer request but not in a tunnel (skipping)");
755 RWDEBUG(
"List not valid in this context (skipping)");
768 len = (!q) ? (rawlen - (p - raw)) : (unsigned)(q - p);
770 value = curl_easy_unescape(candle, p, len, &curl_len);
777 p += (!q) ? len : (len + 1);
779 RDEBUG3(
"Length : %i", curl_len);
785 RDEBUG2(
"Performing xlat expansion of response value");
787 if (
xlat_aeval(request, &expanded, request,
value, NULL, NULL) < 0)
goto skip;
793 REDEBUG(
"Failed creating valuepair");
803 TALLOC_FREE(expanded);
805 RWDEBUG(
"Incompatible value assignment, skipping");
850 char *expanded = NULL;
857 if (json_object_is_type(leaf, json_type_null)) {
858 RDEBUG3(
"Got null value for attribute \"%s\" (skipping)", da->name);
864 RWDEBUG(
"Failed creating valuepair for attribute \"%s\" (skipping)", da->name);
870 switch (json_object_get_type(leaf)) {
872 if (flags->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'int', attribute \"%s\"", da->name);
873 fr_value_box(&src, (int32_t)json_object_get_int(leaf),
true);
876 case json_type_double:
877 if (flags->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'double', attribute \"%s\"", da->name);
878 fr_value_box(&src, (
double)json_object_get_double(leaf),
true);
881 case json_type_string:
882 value = json_object_get_string(leaf);
883 if (flags->
do_xlat && memchr(
value,
'%', json_object_get_string_len(leaf))) {
889 talloc_array_length(expanded) - 1,
true);
892 json_object_get_string_len(leaf),
true);
899 if (flags->
do_xlat)
RWDEBUG(
"Ignoring do_xlat on 'object', attribute \"%s\"", da->name);
906 str = json_object_get_string(leaf);
908 RWDEBUG(
"Failed getting string value for attribute \"%s\" (skipping)", da->name);
919 RWDEBUG(
"Failed parsing value for attribute \"%s\" (skipping)", da->name);
987 if (!json_object_is_type(
object, json_type_object)) {
988#ifdef HAVE_JSON_TYPE_TO_NAME
989 REDEBUG(
"Can't process VP container, expected JSON object"
990 "got \"%s\" (skipping)",
991 json_type_to_name(json_object_get_type(
object)));
993 REDEBUG(
"Can't process VP container, expected JSON object"
1003 json_object_object_foreach(
object,
name,
value) {
1004 int i = 0, elements;
1005 struct json_object *element, *tmp;
1028 .dict_def = request->dict,
1032 RPWDEBUG(
"Failed parsing attribute (skipping)");
1037 RWDEBUG(
"Attribute name refers to outer request but not in a tunnel (skipping)");
1043 RWDEBUG(
"List not valid in this context (skipping)");
1064 if (json_object_is_type(
value, json_type_object)) {
1068 if (json_object_object_get_ex(
value,
"op", &tmp)) {
1071 RWDEBUG(
"Invalid operator value \"%s\" (skipping)",
1072 json_object_get_string(tmp));
1080 if (json_object_object_get_ex(
value,
"do_xlat", &tmp)) {
1081 flags.
do_xlat = json_object_get_boolean(tmp);
1087 if (json_object_object_get_ex(
value,
"is_json", &tmp)) {
1088 flags.
is_json = json_object_get_boolean(tmp);
1094 if (!json_object_object_get_ex(
value,
"value", &tmp)) {
1095 RWDEBUG(
"Value key missing (skipping)");
1108 if (!flags.
is_json && json_object_is_type(
value, json_type_array)) {
1109 elements = json_object_array_length(
value);
1111 RWDEBUG(
"Zero length value array (skipping)");
1114 element = json_object_array_get_idx(
value, 0);
1127 if (max_attrs-- <= 0) {
1128 RWDEBUG(
"At maximum attribute limit");
1140 if (json_object_is_type(element, json_type_object) && !flags.
is_json) {
1142 RWDEBUG(
"Found nested VP, these are not yet supported (skipping)");
1166 }
while ((++i < elements) && (element = json_object_array_get_idx(
value, i)));
1172 return max - max_attrs;
1198 char const *p = raw;
1200 struct json_object *json;
1208 if (*p ==
'\0')
return 0;
1210 json = json_tokener_parse(p);
1212 REDEBUG(
"Malformed JSON data \"%s\"", raw);
1221 json_object_put(json);
1248 char const *start = (
char *)
in, *p = start, *end = p + (size * nmemb);
1256 REDEBUG(
"Forcing header decode failure");
1264 if (((end - p) == 2) && ((p[0] ==
'\r') && (p[1] ==
'\n'))) {
1270 if (ctx->
code == 100) {
1275 return (end - start);
1278 switch (ctx->
state) {
1280 RDEBUG2(
"Processing response header");
1288 if ((end - p) < 12) {
1289 REDEBUG(
"Malformed HTTP header: Status line too short");
1291 REDEBUG(
"Received %zu bytes of invalid header data: %pV",
1301 return (end - start);
1307 REDEBUG(
"Malformed HTTP header: Missing HTTP version");
1315 q = memchr(p,
' ', (end - p));
1317 REDEBUG(
"Malformed HTTP header: Missing reason code");
1328 if ((end - p) < 6) {
1329 REDEBUG(
"Malformed HTTP header: Reason code too short");
1337 if (!isdigit(p[0]) || !isdigit(p[1]) || !isdigit(p[2]) || !((p[3] ==
' ') || (p[3] ==
'\r'))) {
1338 REDEBUG(
"Malformed HTTP header: Reason code malformed. "
1339 "Expected three digits then space or end of header, got \"%pV\"",
1348 ctx->
code = (int)strtoul(p, &q, 10);
1358 q = memchr(p,
'\r', (end - p));
1359 if (!q)
goto malformed;
1371 if (((end - p) >= 14) &&
1378 q = memchr(p,
';', (end - p));
1383 if (!q) q = memchr(p,
'\r', (end - p));
1385 len = (
size_t)(!q ? (end - p) : (q - p));
1398 RDEBUG3(
"Forcing body type to \"%s\"",
1407 switch (ctx->
type) {
1409 RWDEBUG(
"Couldn't determine type, using the request's type \"%s\".",
1414 REDEBUG(
"Type \"%s\" is currently unsupported",
1419 REDEBUG(
"Type \"%s\" is unavailable, please rebuild this module with the required "
1424 REDEBUG(
"Type \"%s\" is not a valid web API data markup format",
1440 return (end - start);
1461 char const *start =
in, *p = start, *end = p + (size * nmemb);
1466 if (start == end)
return 0;
1470 REDEBUG(
"Forcing body read failure");
1480 switch (ctx->
type) {
1484 while ((q = memchr(p,
'\n', (end - p)))) {
1493 while ((q = memchr(p,
'\n', (end - p)))) {
1506 REDEBUG(
"Incoming data (%zu bytes) exceeds max_body_in (%zu bytes). "
1509 TALLOC_FREE(ctx->
buffer);
1514 if (needed > ctx->
alloc) {
1516 ctx->
alloc = needed;
1520 memcpy(out_p, p, (end - p));
1523 ctx->
used += (end - p);
1528 return (end - start);
1538 char const *p, *end;
1543 if (len == 0)
return;
1547 RERROR(
"Server returned:");
1548 while ((q = memchr(p,
'\n', (end - p)))) {
1563 char const *p, *end;
1568 if (len == 0)
return;
1573 while ((q = memchr(p,
'\n', (end - p)))) {
1607 TALLOC_FREE(ctx->
buffer);
1677 REDEBUG(
"Failed creating HTTP body content");
1680 RDEBUG2(
"Content-Length will be %zu bytes", len);
1682 fr_assert((len == 0) || (talloc_array_length(uctx->
body) >= (
size_t)len));
1705 struct curl_slist *headers;
1707 if (validate && !strchr(header,
':')) {
1708 RWDEBUG(
"Invalid HTTP header \"%s\" must be in format '<attribute>: <value>'. Skipping...",
1717 headers = curl_slist_append(ctx->
headers, header);
1719 REDEBUG(
"Failed to add header \"%s\"", header);
1740 struct curl_slist *headers = ctx->
headers;
1744 sep = strchr(header,
':');
1745 cmp_len = sep ? (
size_t)(sep - header) : strlen(header);
1748 if (
strncasecmp(headers->data, header, cmp_len) == 0)
return true;
1749 headers = headers->next;
1785 char const *uri,
char const *body_data)
1790 CURL *candle = randle->
candle;
1795 CURLcode ret = CURLE_OK;
1813#if CURL_AT_LEAST_VERSION(7,85,0)
1828 timeout =
inst->conn_config.connect_timeout;
1829 RDEBUG3(
"Connect timeout is %pVs, request timeout is %pVs",
1837 RDEBUG3(
"Adding custom headers:");
1847 if (call_env->
request.header) {
1848 size_t len = talloc_array_length(call_env->
request.header), i;
1849 for (i = 0; i < len; i++) {
1884 RDEBUG3(
"Request body content-type will be \"%s\"", content_type);
1935#define SET_AUTH_OPTION(_x, _y)\
1937 if ((ret = curl_easy_setopt(candle, _x, _y)) != CURLE_OK) {\
1938 option = STRINGIFY(_x);\
1939 REDEBUG("Failed setting curl option %s: %s (%i)", option, curl_easy_strerror(ret), ret); \
1943 RDEBUG3(
"Configuring HTTP auth type %s, user \"%pV\", password \"%pV\"",
1985 RDEBUG3(
"Using a HTTP method which does not require a body. Forcing request body type to \"none\"");
2090 RDEBUG2(
"Skipping attribute processing, no valid body data received");
2139 escaped = curl_escape(raw, 0);
2164 CURL *candle = randle->
candle;
2178 if (!p || (*++p !=
'/') || (*++p !=
'/')) {
2180 REDEBUG(
"URI \"%s\" is malformed, can't find start of path", uri);
2183 p = strchr(p + 1,
'/');
2193 scheme = curl_easy_unescape(candle, uri, len, NULL);
2195 REDEBUG(
"Error unescaping host");
2210 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_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 * 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.
#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.
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.
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.
void radius_pairmove(request_t *request, fr_pair_list_t *to, fr_pair_list_t *from)
static rc_request_t * current
#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.
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 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.
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.
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.
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
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.
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.
@ 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.
struct rlm_rest_call_env_t::@179 response
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::@178 request
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)
#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)
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.
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.
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.
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.
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)
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