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;
 
 
  104static void _curl_easy_tls_keylog(
const SSL *ssl, 
const char *
line)
 
  106        fr_curl_tls_t const *
conf = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl), FR_TLS_EX_INDEX_CURL_CONF);
 
  108        FILE *fp = fopen(
conf->keylog_file, 
"a");
 
  120        fprintf(fp, 
"%s\n", 
line);
 
  124static CURLcode _curl_easy_ssl_ctx_conf(
UNUSED CURL *curl, 
void *ssl_ctx, 
void *clientp)
 
  126        SSL_CTX *ctx = ssl_ctx;
 
  129        SSL_CTX_set_ex_data(ctx, FR_TLS_EX_INDEX_CURL_CONF, 
UNCONST(
void *, 
conf));
 
  131        if (
conf->keylog_file) {
 
  132                SSL_CTX_set_keylog_callback(ctx, _curl_easy_tls_keylog);
 
  149#if !CURL_AT_LEAST_VERSION(7,84,0) 
  159        if (
conf->keylog_file) {
 
 
  172        CURL                    *candle = randle->
candle;
 
  179        struct curl_certinfo *to_certinfo = NULL;
 
  183        ret = curl_easy_getinfo(candle, CURLINFO_CERTINFO, &to_certinfo);
 
  184        if (ret != CURLE_OK) {
 
  185                REDEBUG(
"Getting certificate info failed: %i - %s", ret, curl_easy_strerror(ret));
 
  195        if (!to_certinfo || to_certinfo->num_of_certs == 0) 
return 0;
 
  197        RDEBUG2(
"Chain has %i certificate(s)", to_certinfo->num_of_certs);
 
  198        for (i = 0; i < to_certinfo->num_of_certs; i++) {
 
  199                struct curl_slist *cert_attrs;
 
  205                RDEBUG2(
"Processing certificate %i",i);
 
  207                for (cert_attrs = to_certinfo->certinfo[i];
 
  209                     cert_attrs = cert_attrs->next) {
 
  213                        q = strchr(cert_attrs->data, 
':');
 
  215                                RWDEBUG(
"Malformed certinfo from libcurl: %s", cert_attrs->data);
 
  219                        strlcpy(
buffer, cert_attrs->data, (q - cert_attrs->data) + 1);
 
  220                        for (p = 
buffer; *p != 
'\0'; p++) 
if (*p == 
' ') *p = 
'-';
 
  225                                RDEBUG3(
"If this value is required, define attribute \"%s\"", 
buffer);
 
 
  253        curl_easy_cleanup(arg);
 
 
  269        static _Thread_local CURL       *t_candle;
 
  274                MEM(candle = curl_easy_init());
 
 
  289        curl_version_info_data *curlversion;
 
  297        if (fr_openssl_init() < 0) 
return -1;
 
  301                PERROR(
"Failed loading dictionaries for curl");
 
  306                PERROR(
"Failed loading dictionaries for curl");
 
  310        ret = curl_global_init(CURL_GLOBAL_ALL);
 
  311        if (ret != CURLE_OK) {
 
  312                ERROR(
"CURL init returned error: %i - %s", ret, curl_easy_strerror(ret));
 
  318        curlversion = curl_version_info(CURLVERSION_NOW);
 
  319        if (strcmp(LIBCURL_VERSION, curlversion->version) != 0) {
 
  320                WARN(
"libcurl version changed since the server was built");
 
  321                WARN(
"linked: %s built: %s", curlversion->version, LIBCURL_VERSION);
 
  324        INFO(
"libcurl version: %s", curl_version());
 
  335                        ERROR(
"Failed registering \"uri.escape\" xlat");
 
  348                        ERROR(
"Failed registering \"uri.safe\" xlat");
 
  360                        ERROR(
"Failed registering \"uri.unescape\" xlat");
 
 
  377        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
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
#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_SECRET
Only print value if debug level >= 3.
@ CONF_FLAG_FILE_READABLE
File matching value must exist, and must be readable.
@ CONF_FLAG_FILE_WRITABLE
File matching value must exist, and must be writable.
#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)
#define DICT_AUTOLOAD_TERMINATOR
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)
CURL * fr_curl_tmp_handle(void)
Return a thread local curl easy handle.
conf_parser_t fr_curl_conn_config[]
fr_dict_attr_autoload_t curl_attr[]
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.
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.
#define FR_SLAB_CONFIG_CONF_PARSER
conf_parser_t entries to populate user configurable slab values
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.