24 #include <freeradius-devel/curl/base.h>
25 #include <freeradius-devel/curl/xlat.h>
27 #include <freeradius-devel/tls/base.h>
30 #include <freeradius-devel/util/talloc.h>
31 #include <freeradius-devel/util/syserror.h>
32 #include <freeradius-devel/unlang/xlat_func.h>
51 {
L(
"allow"), CURLUSESSL_TRY },
52 {
L(
"demand"), CURLUSESSL_ALL },
53 {
L(
"never"), CURLUSESSL_NONE },
59 char const *ca_path = NULL;
60 #if CURL_AT_LEAST_VERSION(7,70,0)
61 ca_path = curl_version_info(CURLVERSION_NOW)->capath;
63 if (!ca_path)
return 0;
106 static void _curl_easy_tls_keylog(
const SSL *ssl,
const char *
line)
108 fr_curl_tls_t const *
conf = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl), FR_TLS_EX_INDEX_CURL_CONF);
110 FILE *fp = fopen(
conf->keylog_file,
"a");
122 fprintf(fp,
"%s\n",
line);
126 static CURLcode _curl_easy_ssl_ctx_conf(
UNUSED CURL *curl,
void *ssl_ctx,
void *clientp)
128 SSL_CTX *ctx = ssl_ctx;
131 SSL_CTX_set_ex_data(ctx, FR_TLS_EX_INDEX_CURL_CONF,
UNCONST(
void *,
conf));
133 if (
conf->keylog_file) {
134 SSL_CTX_set_keylog_callback(ctx, _curl_easy_tls_keylog);
151 #if !CURL_AT_LEAST_VERSION(7,84,0)
161 if (
conf->keylog_file) {
174 CURL *candle = randle->
candle;
189 struct curl_slist *to_info;
190 struct curl_certinfo *to_certinfo;
196 ret = curl_easy_getinfo(candle, CURLINFO_CERTINFO, &ptr.to_info);
197 if (ret != CURLE_OK) {
198 REDEBUG(
"Getting certificate info failed: %i - %s", ret, curl_easy_strerror(ret));
208 if (ptr.to_certinfo->num_of_certs == 0)
return 0;
210 RDEBUG2(
"Chain has %i certificate(s)", ptr.to_certinfo->num_of_certs);
211 for (i = 0; i < ptr.to_certinfo->num_of_certs; i++) {
212 struct curl_slist *cert_attrs;
218 RDEBUG2(
"Processing certificate %i",i);
220 for (cert_attrs = ptr.to_certinfo->certinfo[i];
222 cert_attrs = cert_attrs->next) {
226 q = strchr(cert_attrs->data,
':');
228 RWDEBUG(
"Malformed certinfo from libcurl: %s", cert_attrs->data);
232 strlcpy(
buffer, cert_attrs->data, (q - cert_attrs->data) + 1);
233 for (p =
buffer; *p !=
'\0'; p++)
if (*p ==
' ') *p =
'-';
238 RDEBUG3(
"If this value is required, define attribute \"%s\"",
buffer);
266 curl_easy_cleanup(arg);
282 static _Thread_local CURL *t_candle;
287 MEM(candle = curl_easy_init());
302 curl_version_info_data *curlversion;
310 if (fr_openssl_init() < 0)
return -1;
314 PERROR(
"Failed loading dictionaries for curl");
319 PERROR(
"Failed loading dictionaries for curl");
323 ret = curl_global_init(CURL_GLOBAL_ALL);
324 if (ret != CURLE_OK) {
325 ERROR(
"CURL init returned error: %i - %s", ret, curl_easy_strerror(ret));
331 curlversion = curl_version_info(CURLVERSION_NOW);
332 if (strcmp(LIBCURL_VERSION, curlversion->version) != 0) {
333 WARN(
"libcurl version changed since the server was built");
334 WARN(
"linked: %s built: %s", curlversion->version, LIBCURL_VERSION);
337 INFO(
"libcurl version: %s", curl_version());
348 ERROR(
"Failed registering \"uri.escape\" xlat");
361 ERROR(
"Failed registering \"uri.safe\" xlat");
373 ERROR(
"Failed registering \"uri.unescape\" xlat");
390 curl_global_cleanup();
static int const char char buffer[256]
#define fr_atexit_thread_local(_name, _free, _uctx)
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
char const * name1
Name of the CONF_ITEM to parse.
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
@ CONF_FLAG_FILE_OUTPUT
File matching value must exist, and must be writable.
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Defines a CONF_PAIR to C data type mapping.
Configuration AVP similar to a fr_pair_t.
A section grouping multiple CONF_PAIR.
CONF_PAIR * cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *value, fr_token_t op, fr_token_t lhs_quote, fr_token_t rhs_quote)
Allocate a CONF_PAIR.
#define FR_CURL_ROPTIONAL_SET_OPTION(_x, _y)
request_t * request
Current request.
CURL * candle
Request specific handle.
Structure representing an individual request being passed to curl for processing.
xlat_action_t fr_curl_xlat_uri_escape(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
xlat function to escape URI encoded strings
xlat_arg_parser_t const fr_curl_xlat_uri_args[]
xlat_action_t fr_curl_xlat_uri_unescape(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, fr_value_box_list_t *in)
xlat function to unescape URI encoded strings
xlat_arg_parser_t const fr_curl_xlat_safe_args[]
#define CURL_URI_SAFE_FOR
safe for value suitable for all users of the curl library
#define fr_dict_autofree(_to_free)
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
#define fr_dict_autoload(_to_load)
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
char const * name
Name of library and section within global config.
Structure to define how to initialise libraries with global configuration.
static fr_table_num_sorted_t const fr_curl_sslcode_table[]
static fr_dict_t const * dict_freeradius
int fr_curl_response_certinfo(request_t *request, fr_curl_io_request_t *randle)
static size_t fr_curl_sslcode_table_len
static int fr_curl_init(void)
Initialise global curl options.
static conf_parser_t reuse_curl_conn_config[]
int fr_curl_easy_tls_init(fr_curl_io_request_t *randle, fr_curl_tls_t const *conf)
static int tls_config_dflt_capath(CONF_PAIR **out, UNUSED void *parent, CONF_SECTION *cs, fr_token_t quote, conf_parser_t const *rule)
fr_dict_attr_t const * attr_tls_certificate
Attribute definitions for lib curl.
global_lib_autoinst_t fr_curl_autoinst
static void fr_curl_free(void)
conf_parser_t fr_curl_conn_config[]
fr_dict_attr_autoload_t curl_attr[]
CURL * fr_curl_tmp_handle(void)
Return a thread local curl easy handle.
conf_parser_t fr_curl_tls_config[]
static fr_dict_autoload_t curl_dict[]
static int _curl_tmpl_handle(void *arg)
Free the curl easy handle.
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
#define RATE_LIMIT_GLOBAL(_log, _fmt,...)
Rate limit messages using a global limiting entry.
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
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_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.
Tuneable parameters for slabs.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
size_t strlcpy(char *dst, char const *src, size_t siz)
Stores an attribute, a value and various bits of other data.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
An element in a lexicographically sorted array of name to num mappings.
xlat_action_t xlat_transparent(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
static size_t char ** out
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
void xlat_func_unregister(char const *name)
Unregister an xlat function.
#define xlat_func_safe_for_set(_xlat, _escaped)
Set the escaped values for output boxes.