The FreeRADIUS server
$Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
Functions and datatypes for the REST (HTTP) transport. More...
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/log.h>
#include <freeradius-devel/server/pool.h>
#include <freeradius-devel/server/tmpl.h>
#include <freeradius-devel/unlang/call.h>
#include <freeradius-devel/util/value.h>
#include <talloc.h>
#include "rest.h"
Go to the source code of this file.
Data Structures | |
struct | json_flags_t |
Flags to control the conversion of JSON values to fr_pair_ts. More... | |
struct | rest_custom_data_t |
Macros | |
#define | CURLAUTH_BASIC 0 |
#define | CURLAUTH_DIGEST 0 |
#define | CURLAUTH_DIGEST_IE 0 |
#define | CURLAUTH_GSSNEGOTIATE 0 |
#define | CURLAUTH_NTLM 0 |
#define | CURLAUTH_NTLM_WB 0 |
#define | CURLOPT_TLSAUTH_SRP 0 |
#define | LOG_PREFIX mctx->mi->name |
#define | SET_AUTH_OPTION(_x, _y) |
Functions | |
static int | _mod_conn_free (fr_curl_io_request_t *randle) |
Frees a libcurl handle, and any additional memory used by context data. More... | |
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. More... | |
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. More... | |
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. More... | |
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. More... | |
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. More... | |
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. More... | |
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. More... | |
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. More... | |
size_t | rest_get_handle_data (char const **out, fr_curl_io_request_t *randle) |
Extracts pointer to buffer containing response data. More... | |
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. More... | |
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. More... | |
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. More... | |
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. More... | |
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. More... | |
static size_t | rest_response_body (void *in, size_t size, size_t nmemb, void *userdata) |
Processes incoming HTTP body data from libcurl. More... | |
void | rest_response_debug (request_t *request, fr_curl_io_request_t *handle) |
Print out the response text. More... | |
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. More... | |
void | rest_response_error (request_t *request, fr_curl_io_request_t *handle) |
Print out the response text as error lines. More... | |
static size_t | rest_response_header (void *in, size_t size, size_t nmemb, void *userdata) |
Processes incoming HTTP header data from libcurl. More... | |
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. More... | |
size_t | rest_uri_escape (UNUSED request_t *request, char *out, size_t outlen, char const *raw, UNUSED void *arg) |
URL encodes a string. More... | |
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. More... | |
Variables | |
fr_table_num_sorted_t const | http_auth_table [] |
size_t | http_auth_table_len = NUM_ELEMENTS(http_auth_table) |
const http_body_type_t | http_body_type_supported [REST_HTTP_BODY_NUM_ENTRIES] |
Table of encoder/decoder support. More... | |
fr_table_num_sorted_t const | http_body_type_table [] |
Conversion table for type config values. More... | |
size_t | http_body_type_table_len = NUM_ELEMENTS(http_body_type_table) |
fr_table_num_sorted_t const | http_content_type_table [] |
Conversion table for "Content-Type" header values. More... | |
size_t | http_content_type_table_len = NUM_ELEMENTS(http_content_type_table) |
const unsigned long | http_curl_auth [REST_HTTP_AUTH_NUM_ENTRIES] |
fr_table_num_sorted_t const | http_method_table [] |
Conversion table for method config values. More... | |
size_t | http_method_table_len = NUM_ELEMENTS(http_method_table) |
Functions and datatypes for the REST (HTTP) transport.
Definition in file rest.c.
struct json_flags_t |
Flags to control the conversion of JSON values to fr_pair_ts.
These fields are set when parsing the expanded format for value pairs in JSON, and control how json_pair_alloc_leaf and json_pair_alloc convert the JSON value, and move the new fr_pair_t into an attribute list.
Data Fields | ||
---|---|---|
int | do_xlat | If true value will be expanded with xlat. |
int | is_json | If true value will be inserted as raw JSON. |
fr_token_t | op | The operator that determines how the new VP. |
struct rest_custom_data_t |
#define SET_AUTH_OPTION | ( | _x, | |
_y | |||
) |
|
static |
Frees a libcurl handle, and any additional memory used by context data.
[in] | randle | fr_curl_io_request_t to close and free. |
Definition at line 235 of file rest.c.
|
static |
Processes JSON response and converts it into multiple fr_pair_ts.
Processes JSON attribute declarations in the format below. Will recurse when processing nested attributes. When processing nested attributes flags and operators from previous attributes are not inherited.
JSON response format is:
{ "<attribute0>":{ "do_xlat":<bool>, "is_json":<bool>, "op":"<operator>", "value":[<value0>,<value1>,<valueN>] }, "<attribute1>":{ "value":{ "<nested-attribute0>":{ "op":"<operator>", "value":<value0> } } }, "<attribute2>":"<value0>", "<attributeN>":[<value0>,<value1>,<valueN>] }
JSON valuepair flags:
If "op" is ':=' or '=', it will be automagically changed to '+=' for the second and subsequent values in multivalued attributes. This does not work between multiple attribute declarations.
[in] | instance | configuration data. |
[in] | section | configuration data. |
[in] | request | Current request. |
[in] | object | containing root node, or parent node. |
[in] | level | Current nesting level. |
[in] | max | counter, decremented after each fr_pair_t is created, when 0 no more attributes will be processed. |
Definition at line 982 of file rest.c.
|
static |
Converts JSON "value" key into fr_pair_t.
If leaf is not in fact a leaf node, but contains JSON data, the data will written to the attribute in JSON string format.
[in] | instance | configuration data. |
[in] | section | configuration data. |
[in] | ctx | to allocate new fr_pair_ts in. |
[in] | request | Current request. |
[in] | da | Attribute to create. |
[in] | flags | containing the operator other flags controlling value expansion. |
[in] | leaf | object containing the fr_pair_t value. |
Definition at line 846 of file rest.c.
|
static |
Converts JSON response into fr_pair_ts and adds them to the request.
Converts the raw JSON string into a json-c object tree and passes it to json_pair_alloc. After the tree has been parsed json_object_put is called which decrements the reference count of the root node by one, and frees the entire tree.
[in] | instance | configuration data. |
[in] | section | configuration data. |
[in,out] | request | Current request. |
[in] | randle | REST handle. |
[in] | raw | buffer containing JSON data. |
[in] | rawlen | Length of data in raw buffer. |
Definition at line 1197 of file rest.c.
|
static |
Converts plain response into a single fr_pair_t.
[in] | inst | configuration data. |
[in] | section | configuration data. |
[in] | randle | fr_curl_io_request_t to use. |
[in] | request | Current request. |
[in] | raw | buffer containing POST data. |
[in] | rawlen | Length of data in raw buffer. |
Definition at line 649 of file rest.c.
|
static |
Converts POST response into fr_pair_ts and adds them to the request.
Accepts fr_pair_tS in the same format as rest_encode_post, but with the addition of optional attribute list qualifiers as part of the attribute name string.
If no qualifiers are specified, will default to the request list.
POST response format is:
[outer.][<list>.]<attribute0>=<value0>&[outer.][<list>.]<attribute1>=<value1>&[outer.][<list>.]<attributeN>=<valueN>
[in] | instance | configuration data. |
[in] | section | configuration data. |
[in] | randle | fr_curl_io_request_t to use. |
[in] | request | Current request. |
[in] | raw | buffer containing POST data. |
[in] | rawlen | Length of data in raw buffer. |
Definition at line 693 of file rest.c.
Copies a pre-expanded xlat string to the output buffer.
[out] | out | Char buffer to write encoded data to. |
[in] | size | Multiply by nmemb to get the length of ptr. |
[in] | nmemb | Multiply by size to get the length of ptr. |
[in] | userdata | rlm_rest_request_t to keep encoding state between calls. |
Definition at line 291 of file rest.c.
Encodes fr_pair_t linked list in JSON format.
This is a stream function matching the rest_read_t prototype. Multiple successive calls will return additional encoded fr_pair_ts.
Only complete attribute headers
"<name>":{"type":"<type>","value":['
and complete attribute values will be written to ptr.
If an attribute occurs multiple times in the request the attribute values will be concatenated into a single value array.
JSON request format is:
{ "<attribute0>":{ "type":"<type0>", "value":[<value0>,<value1>,<valueN>] }, "<attribute1>":{ "type":"<type1>", "value":[...] }, "<attributeN>":{ "type":"<typeN>", "value":[...] }, }
[out] | out | Char buffer to write encoded data to. |
[in] | size | Multiply by nmemb to get the length of ptr. |
[in] | nmemb | Multiply by size to get the length of ptr. |
[in] | userdata | rlm_rest_request_t to keep encoding state between calls. |
Definition at line 527 of file rest.c.
Encodes fr_pair_t linked list in POST format.
This is a stream function matching the rest_read_t prototype. Multiple successive calls will return additional encoded fr_pair_ts. Only complete attribute headers
'<name>='
and values will be written to the ptr buffer.
POST request format is:
<attribute0>=<value0>&<attribute1>=<value1>&<attributeN>=<valueN>
All attributes and values are url encoded. There is currently no support for nested attributes, or attribute qualifiers.
Nested attributes may be added in the future using
<attribute-outer>:<attribute-inner>
to denotate nesting.
Requires libcurl for url encoding.
[out] | out | Char buffer to write encoded data to. |
[in] | size | Multiply by nmemb to get the length of ptr. |
[in] | nmemb | Multiply by size to get the length of ptr. |
[in] | userdata | rlm_rest_request_t to keep encoding state between calls. |
Definition at line 350 of file rest.c.
size_t rest_get_handle_data | ( | char const ** | out, |
fr_curl_io_request_t * | randle | ||
) |
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.
Matches the fr_pool_connection_create_t function prototype, is passed to fr_pool_init, and called when a new connection is required by the connection pool API.
Creates an instances of fr_curl_io_request_t, and rlm_rest_curl_context_t which hold the context data required for generating requests and parsing responses.
Definition at line 256 of file rest.c.
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.
Configures libcurl handle setting various curlopts for things like local client time, Content-Type, and other FreeRADIUS custom headers.
Current FreeRADIUS custom headers are:
Sets up callbacks for all response processing (buffers and body data).
[in] | mctx | call data. |
[in] | section | configuration data. |
[in] | randle | to configure. |
[in] | request | Current request. |
[in] | method | to use (HTTP verbs PUT, POST, DELETE etc...). |
[in] | type | Content-Type for request encoding, also sets the default for decoding. |
[in] | uri | buffer containing the expanded URI to send the request to. |
[in] | body_data | (optional) custom body data. Must persist whilst we're writing data out to the socket. Must be a talloced buffer which is \0 terminated. |
Definition at line 1721 of file rest.c.
|
static |
Configures body specific curlopts.
Configures libcurl handle to use either chunked mode, where the request data will be sent using multiple HTTP requests, or contiguous mode where the request data will be sent in a single HTTP request.
[in] | mctx | Call data. |
[in] | section | configuration data. |
[in] | request | Current request. |
[in] | randle | fr_curl_io_request_t to configure. |
[in] | func | to pass to libcurl for chunked. transfers (NULL if not using chunked mode). |
Definition at line 1646 of file rest.c.
|
static |
Emulates successive libcurl calls to an encoding function.
This function is used when the request will be sent to the HTTP server as one contiguous entity. A buffer of REST_BODY_ALLOC_CHUNK bytes is allocated and passed to the stream encoding function.
If the stream function does not return 0, a new buffer is allocated which is the size of the previous buffer + REST_BODY_ALLOC_CHUNK bytes, the data from the previous buffer is copied, and freed, and another call is made to the stream function, passing a pointer into the new buffer at the end of the previously written data.
This process continues until the stream function signals (by returning 0) that it has no more data to write.
[out] | out | where the pointer to the alloced buffer should be written. |
[in] | inst | of rlm_rest. |
[in] | func | Stream function. |
[in] | limit | Maximum buffer size to alloc. |
[in] | userdata | rlm_rest_request_t to keep encoding state between calls to stream function. |
Definition at line 590 of file rest.c.
|
static |
(Re-)Initialises the data in a rlm_rest_request_t.
Resets the values of a rlm_rest_request_t to their defaults.
[in] | section | configuration data. |
[in] | request | Current request. |
[in] | ctx | to initialise. |
Definition at line 626 of file rest.c.
Processes incoming HTTP body data from libcurl.
Writes incoming body data to an intermediary buffer for later parsing by one of the decode functions.
[in] | in | Char buffer where inbound header data is written |
[in] | size | Multiply by nmemb to get the length of ptr. |
[in] | nmemb | Multiply by size to get the length of ptr. |
[in] | userdata | rlm_rest_response_t to keep parsing state between calls. |
Definition at line 1458 of file rest.c.
void rest_response_debug | ( | request_t * | request, |
fr_curl_io_request_t * | handle | ||
) |
Print out the response text.
request | The Current request. |
handle | fr_curl_io_request_t used to execute the previous request. |
Definition at line 1563 of file rest.c.
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.
Uses the Content-Type information written in rest_response_header to determine the correct decode function to use. The decode function will then convert the raw received data into fr_pair_ts.
[in] | instance | configuration data. |
[in] | section | configuration data. |
[in] | request | Current request. |
[in] | randle | to use. |
Definition at line 2067 of file rest.c.
void rest_response_error | ( | request_t * | request, |
fr_curl_io_request_t * | handle | ||
) |
Print out the response text as error lines.
request | The Current request. |
handle | fr_curl_io_request_t used to execute the previous request. |
Definition at line 1538 of file rest.c.
Processes incoming HTTP header data from libcurl.
Processes the status line, and Content-Type headers from the incoming HTTP response.
Matches prototype for CURLOPT_HEADERFUNCTION, and will be called directly by libcurl.
[in] | in | Char buffer where inbound header data is written. |
[in] | size | Multiply by nmemb to get the length of ptr. |
[in] | nmemb | Multiply by size to get the length of ptr. |
[in] | userdata | rlm_rest_response_t to keep parsing state between calls. |
Definition at line 1245 of file rest.c.
|
static |
(Re-)Initialises the data in a rlm_rest_response_t.
This resets the values of the a rlm_rest_response_t to their defaults. Must be called between encoding sessions.
[in] | section | that created the request. |
[in] | request | Current request. |
[in] | ctx | data to initialise. |
[in] | type | Default http_body_type to use when decoding raw data, may be overwritten by rest_response_header. |
[in] | header | Where to write out headers, may be NULL. |
Definition at line 1598 of file rest.c.
size_t rest_uri_escape | ( | UNUSED request_t * | request, |
char * | out, | ||
size_t | outlen, | ||
char const * | raw, | ||
UNUSED void * | arg | ||
) |
URL encodes a string.
Encode special chars as per RFC 3986 section 4.
[in] | request | Current request. |
[out] | out | Where to write escaped string. |
[in] | outlen | Size of out buffer. |
[in] | raw | string to be urlencoded. |
[in] | arg | pointer, gives context for escaping. |
Definition at line 2120 of file rest.c.
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.
This is required because the xlat functions which operate on the input string cannot distinguish between host and path components.
[out] | out | Where to write the pointer to the new buffer containing the escaped URI. |
[in] | inst | of rlm_rest. |
[in] | request | Current request |
[in] | randle | to use. |
[in] | uri | configuration data. |
Definition at line 2146 of file rest.c.
fr_table_num_sorted_t const http_auth_table[] |
size_t http_auth_table_len = NUM_ELEMENTS(http_auth_table) |
const http_body_type_t http_body_type_supported[REST_HTTP_BODY_NUM_ENTRIES] |
Table of encoder/decoder support.
Indexes in this table match the http_body_type_t enum, and should be updated if additional enum values are added.
fr_table_num_sorted_t const http_body_type_table[] |
Conversion table for type config values.
Textual names for http_body_type_t enum values, used by the configuration parser.
size_t http_body_type_table_len = NUM_ELEMENTS(http_body_type_table) |
fr_table_num_sorted_t const http_content_type_table[] |
Conversion table for "Content-Type" header values.
Used by rest_response_header for parsing incoming headers.
Values we expect to see in the 'Content-Type:' header of the incoming response.
Some data types (like YAML) do no have standard MIME types defined, so multiple types, are listed here.
size_t http_content_type_table_len = NUM_ELEMENTS(http_content_type_table) |
const unsigned long http_curl_auth[REST_HTTP_AUTH_NUM_ENTRIES] |
fr_table_num_sorted_t const http_method_table[] |
Conversion table for method config values.
HTTP verb strings for http_method_t enum values. Used by libcurl in the status line of the outgoing HTTP header, by rest_response_header for decoding incoming HTTP responses, and by the configuration parser.
size_t http_method_table_len = NUM_ELEMENTS(http_method_table) |