24 RCSID(
"$Id: 4ef697e1a0dd9c762cd91474e35ec8cf07888f09 $")
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/token.h>
29 #include <freeradius-devel/rad_assert.h>
89 char const *username,
char const *password)
96 RDEBUG(
"Expanding URI components");
103 if (uri_len <= 0)
return -1;
112 uri, username, password);
114 if (ret < 0)
return -1;
121 if (ret < 0)
return -1;
132 RDEBUG2(
"&REST-HTTP-Code := %i", code);
135 value.
length =
sizeof(value.integer);
136 value.integer = code;
145 REDEBUG(
"Failed updating &REST-HTTP-Code");
159 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
164 size_t freespace = outlen;
167 for (p = fmt; *p !=
'\0'; p++) {
178 }
else if (*p ==
'\\') {
182 }
else if (*p ==
'/') {
186 }
else if (*p >=
' ') {
223 len =
snprintf(out_p, freespace,
"u%04X", *p);
224 if (
is_truncated(len, freespace))
return (outlen - freespace) + len;
233 return outlen - freespace;
239 void const *mod_inst,
UNUSED void const *xlat_inst,
240 REQUEST *request,
char const *fmt)
246 ssize_t len, slen = 0;
248 char const *p = fmt, *q;
259 .body_str =
"application/x-www-form-urlencoded",
260 .require_auth =
false,
266 RDEBUG(
"Expanding URI components");
269 if (!handle)
return -1;
283 while (isspace(*p) && p++);
299 if (q && (*++q !=
'\0')) {
315 if (ret < 0)
return -1;
322 if (ret < 0)
return -1;
343 if ((hcode >= 200) && (hcode < 300)) {
345 }
else if (hcode < 500) {
427 if ((hcode >= 200) && (hcode < 300)) {
433 }
else if (hcode < 500) {
477 username = request->username;
478 if (!request->username) {
479 REDEBUG(
"Can't perform authentication, 'User-Name' attribute not found in the request");
484 password = request->password;
486 (password->
da->
attr != PW_USER_PASSWORD)) {
487 REDEBUG(
"You set 'Auth-Type = REST' for a request that does not contain a User-Password attribute!");
494 ret =
rlm_rest_perform(instance, section, handle, request, username->vp_strvalue, password->vp_strvalue);
532 if ((hcode >= 200) && (hcode < 300)) {
538 }
else if (hcode < 500) {
591 }
else if (hcode == 204) {
593 }
else if ((hcode >= 200) && (hcode < 300)) {
647 }
else if (hcode == 204) {
649 }
else if ((hcode >= 200) && (hcode < 300)) {
702 cf_log_err_cs(cs,
"'username' and 'password' must both be set or both be absent");
716 cf_log_err_cs(cs,
"Unsupported HTTP auth type \"%s\", check libcurl version, OpenSSL build "
717 "configuration, then recompile this module", config->
auth_str);
745 cf_log_err_cs(cs,
"Unsupported HTTP body type \"%s\", please submit patches",
750 cf_log_err_cs(cs,
"Invalid HTTP body type. \"%s\" is not a valid web API data "
755 cf_log_err_cs(cs,
"Unavailable HTTP body type. \"%s\" is not available in this "
791 cf_log_err_cs(cs,
"Unsupported forced response body type \"%s\", please submit patches",
796 cf_log_err_cs(cs,
"Invalid HTTP forced response body type. \"%s\" is not a valid web API data "
861 if (!inst->
pool)
return -1;
897 .config = module_config,
char const * name
Section name.
#define PW_TYPE_FILE_INPUT
File matching value must exist, and must be readable.
rlm_rest_section_t post_auth
Configuration specific to Post-auth.
#define RINDENT()
Indent R* messages by one level.
static int rlm_rest_perform(rlm_rest_t *instance, rlm_rest_section_t *section, void *handle, REQUEST *request, char const *username, char const *password)
int xlat_register(void *mod_inst, char const *name, xlat_func_t func, xlat_escape_t escape, xlat_instantiate_t instantiate, size_t inst_size, size_t buf_len)
Register an xlat function.
Time value (struct timeval), only for config items.
#define rest_get_handle_code(_handle)
static ssize_t jsonquote_xlat(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, UNUSED REQUEST *request, char const *fmt)
static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
Write accounting data to Couchbase documents.
The module is OK, continue.
static rlm_rcode_t mod_post_auth(void *instance, REQUEST *request) CC_HINT(nonnull)
Metadata exported by the module.
const FR_NAME_NUMBER http_body_type_table[]
Conversion table for type config values.
http_body_type_t force_to
Override the Content-Type header in the response to force decoding as a particular type...
7 methods index for postauth section.
fr_connection_pool_t * pool
Pointer to the connection pool.
static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
Handle authorization requests using Couchbase document data.
#define RLM_TYPE_THREAD_SAFE
Module is threadsafe.
const FR_NAME_NUMBER http_content_type_table[]
Conversion table for "Content-Type" header values.
char const * password
Password used for HTTP-Auth.
int rest_init(rlm_rest_t *instance)
Initialises libcurl.
#define CONF_PARSER_TERMINATOR
static void rlm_rest_cleanup(rlm_rest_t const *instance, rlm_rest_section_t *section, void *handle)
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
static int parse_sub_section(CONF_SECTION *parent, rlm_rest_section_t *config, rlm_components_t comp)
const http_body_type_t http_body_type_supported[HTTP_BODY_NUM_ENTRIES]
Table of encoder/decoder support.
static rlm_rcode_t CC_HINT(nonnull)
#define PW_TYPE_SECRET
Only print value if debug level >= 3.
http_body_type_t body
What encoding type should be used.
The module considers the request invalid.
#define XLAT_DEFAULT_BUF_LEN
static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request) CC_HINT(nonnull)
#define PW_TYPE_SUBSECTION
Defines a CONF_PAIR to C data type mapping.
rlm_rest_section_t accounting
Configuration specific to accounting.
int fr_pair_update_by_num(TALLOC_CTX *ctx, VALUE_PAIR **list, unsigned int vendor, unsigned int attr, int8_t tag, PW_TYPE type, value_data_t *value)
Create a new VALUE_PAIR or replace the value of the head pair in the specified list.
size_t rest_uri_escape(UNUSED REQUEST *request, char *out, size_t outlen, char const *raw, UNUSED void *arg)
URL encodes a string.
int rest_request_config(rlm_rest_t const *instance, rlm_rest_section_t *section, REQUEST *request, void *handle, http_method_t method, http_body_type_t type, char const *uri, char const *username, char const *password)
Configures request curlopts.
#define is_truncated(_ret, _max)
int rest_response_decode(rlm_rest_t const *instance, rlm_rest_section_t *section, REQUEST *request, void *handle)
Sends the response to the correct decode function.
http_auth_type_t auth
HTTP auth type.
Reject the request (user is locked out).
int fr_str2int(FR_NAME_NUMBER const *table, char const *name, int def)
struct rlm_rest_t rlm_rest_t
rlm_rest_section_t authenticate
Configuration specific to authentication.
const FR_NAME_NUMBER http_auth_table[]
fr_connection_pool_t * module_connection_pool_init(CONF_SECTION *module, void *opaque, fr_connection_create_t c, fr_connection_alive_t a, char const *prefix)
Initialise a module specific connection pool.
char const * data
Custom body data (optional).
const FR_NAME_NUMBER http_method_table[]
Conversion table for method config values.
static int comp(void const *a, void const *b)
void rest_response_error(REQUEST *request, rlm_rest_handle_t *handle)
Print out the response text as error lines.
static void * mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
Create a new memcached handle.
ssize_t rest_uri_host_unescape(char **out, UNUSED rlm_rest_t const *mod_inst, REQUEST *request, void *handle, char const *uri)
Unescapes the host portion of a URI string.
static int mod_bootstrap(CONF_SECTION *conf, void *instance)
Must always come last, should not be in method table.
#define PW_TYPE_XLAT
string will be dynamically expanded.
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables)
Parse a configuration section into user-supplied variables.
unsigned int attr
Attribute number.
Immediately reject the request.
Attributes in incoming or internally proxied request.
3 methods index for accounting section.
char const * uri
URI to send HTTP request to.
const section_type_value_t section_type_value[]
Mappings between section names, typenames and control attributes.
Stores an attribute, a value and various bits of other data.
static int mod_instantiate(CONF_SECTION *conf, void *instance)
void void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt,...) CC_HINT(format(printf
0 methods index for authenticate section.
#define REXDENT()
Exdent (unindent) R* messages by one level.
char const * auth_str
The string version of the Auth-Type.
#define FR_CONF_DEPRECATED(_n, _t, _p, _f)
int rest_request_perform(UNUSED rlm_rest_t const *instance, UNUSED rlm_rest_section_t *section, REQUEST *request, void *handle)
Sends a REST (HTTP) request.
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
long timeout
Timeout in ms.
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
void fr_json_version_print(void)
Print JSON-C version.
char const * cf_section_name1(CONF_SECTION const *cs)
const unsigned long http_curl_auth[HTTP_AUTH_NUM_ENTRIES]
Module succeeded without doing anything.
static const CONF_PARSER section_config[]
static const CONF_PARSER module_config[]
Function prototypes and datatypes for the REST (HTTP) transport.
size_t length
Length of value data.
char * talloc_bstrndup(void const *t, char const *in, size_t inlen)
Binary safe strndup function.
uint64_t magic
Used to validate module struct.
Module failed, don't reply.
#define FR_CONF_OFFSET(_n, _t, _s, _f)
void rest_cleanup(void)
Cleans up after libcurl.
char const * method_str
The string version of the HTTP method.
enum rlm_components rlm_components_t
The different section components of the server.
rlm_rest_section_t authorize
Configuration specific to authorisation.
void * fr_connection_get(fr_connection_pool_t *pool)
Reserve a connection in the connection pool.
static int mod_detach(void *instance)
char const * username
Username used for HTTP-Auth.
char const * body_str
The string version of the encoding/content type.
size_t rest_get_handle_data(char const **out, rlm_rest_handle_t *handle)
Extracts pointer to buffer containing response data.
void rest_request_cleanup(UNUSED rlm_rest_t const *instance, UNUSED rlm_rest_section_t *section, void *handle)
Cleans up after a REST request.
int mod_conn_alive(UNUSED void *instance, void *handle)
Check the health of a connection handle.
char const * xlat_name
Instance name.
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
void fr_connection_release(fr_connection_pool_t *pool, void *conn)
Release a connection.
#define RADIUS_LIST_AND_CTX(_ctx, _head, _request, _ref, _list)
Determine the correct context and list head.
String of printable characters.
#define FR_CONF_POINTER(_n, _t, _p)
1 methods index for authorize section.
char const * section
Section name e.g. "Authorize".
int fr_substr2int(FR_NAME_NUMBER const *table, char const *name, int def, int len)
static CONF_PARSER tls_config[]
char const * force_to_str
Force decoding with this decoder.
http_method_t method
What HTTP method should be used, GET, POST etc...
ssize_t rest_uri_build(char **out, UNUSED rlm_rest_t *instance, REQUEST *request, char const *uri)
Builds URI; performs XLAT expansions and encoding.
static ssize_t rest_xlat(char **out, UNUSED size_t outlen, void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
struct timeval timeout_tv
Timeout timeval.
char const * cf_section_name2(CONF_SECTION const *cs)
void fr_connection_pool_free(fr_connection_pool_t *pool)
Delete a connection pool.