]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Simplify and document conf parser macros
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 3 Apr 2023 00:07:50 +0000 (18:07 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 3 Apr 2023 20:14:38 +0000 (14:14 -0600)
src/lib/server/cf_parse.h
src/process/ttls/base.c

index d085bb75bbde916dfdb008eadb7dbf8432312ed3..12ef1df6fe8ec73a90795484eb0b889189fe0bac 100644 (file)
@@ -180,109 +180,126 @@ _Generic((_ct), \
        double **       : __builtin_choose_expr((FR_BASE_TYPE(_t) == FR_TYPE_FLOAT64) && ((_t) & FR_TYPE_MULTI), \
                        _p, (_mismatch_double_m) 0), \
        default: (conf_type_mismatch)0)))))))))))))
+#else
+#  define FR_CONF_TYPE_CHECK(_type, _c_type, _ptr_or_offset) _ptr_or_offset
+#endif
 
-#  define FR_CONF_OFFSET(_n, _t, _s, _f) \
-       .name = _n, \
-       .type = _t, \
-       .offset = FR_CONF_TYPE_CHECK((_t), &(((_s *)NULL)->_f), offsetof(_s, _f))
-#  define FR_CONF_OFFSET_IS_SET(_n, _t, _s, _f) \
-       .name = _n, \
-       .type = (_t) | FR_TYPE_IS_SET, \
-       .offset = FR_CONF_TYPE_CHECK((_t), &(((_s *)NULL)->_f), offsetof(_s, _f)), \
-       .is_set_offset = offsetof(_s, _f ## _is_set)
-#  define FR_CONF_POINTER(_n, _t, _p) \
-       .name = _n, \
-       .type = _t, \
-       .data = FR_CONF_TYPE_CHECK((_t), (_p), _p)
-#  define FR_CONF_POINTER_IS_SET(_n, _t, _p) \
-       .name = _n, \
-       .type = (_t) | FR_TYPE_IS_SET, \
-       .data = FR_CONF_TYPE_CHECK((_t), (_p), _p), \
-       .is_set_ptr = _p ## _is_set
-#  define FR_ITEM_POINTER(_t, _p) _t, FR_CONF_TYPE_CHECK((_t), (_p), _p)
+/** CONF_PARSER which parses a single CONF_PAIR, writing the result to a field in a struct
+ *
+ * @param[in] _name            of the CONF_PAIR to search for.
+ * @param[in] _type            to parse the CONF_PAIR as.
+ * @param[in] _struct          contaning the field to write the result to.
+ * @param[in] _field           to write the result to.
+ */
+#  define FR_CONF_OFFSET(_name, _type, _struct, _field) \
+       .name = _name, \
+       .type = _type, \
+       .offset = FR_CONF_TYPE_CHECK((_type), &(((_struct *)NULL)->_field), offsetof(_struct, _field))
 
-/** A CONF_PARSER multi-subsection
+/** CONF_PARSER which parses a single CONF_PAIR, writing the result to a field in a struct, recording if a default was used in <_field>_is_set
  *
- * Parse multiple instance of a subsection.
+ * @param[in] _name            of the CONF_PAIR to search for.
+ * @param[in] _type            to parse the CONF_PAIR as.
+ * @param[in] _struct          contaning the field to write the result to.
+ * @param[in] _field           to write the result to.
+ */
+#  define FR_CONF_OFFSET_IS_SET(_name, _type, _struct, _field) \
+       .name = _name, \
+       .type = (_type) | FR_TYPE_IS_SET, \
+       .offset = FR_CONF_TYPE_CHECK((_type), &(((_struct *)NULL)->_field), offsetof(_struct, _field)), \
+       .is_set_offset = offsetof(_struct, _field ## _is_set)
+
+/** CONF_PARSER which populates a sub-struct using a CONF_SECTION
  *
- * @param _n   name of subsection to search for.
- * @param _t   Must be FR_TYPE_SUBSECTION | FR_TYPE_MULTI and any optional flags.
- * @param _s   instance data struct.
- * @param _f   field in instance data struct.
- * @param _sub CONF_PARSER array to use to parse subsection data.
+ * @param[in] _name            of the CONF_SECTION to search for.
+ * @param[in] _flags           any additional flags to set.
+ * @param[in] _struct          containing the sub-struct to populate.
+ * @param[in] _field           containing the sub-struct to populate.
  */
-#  define FR_CONF_SUBSECTION_ALLOC(_n, _t, _s, _f, _sub) \
-       .name = _n, \
-       .type = (_t), \
-       .offset = FR_CONF_TYPE_CHECK((_t), &(((_s *)NULL)->_f), offsetof(_s, _f)), \
-       .subcs = _sub, \
-       .subcs_size = sizeof(**(((_s *)0)->_f))
-#else
-#  define FR_CONF_OFFSET(_n, _t, _s, _f) \
-       .name = _n, \
-       .type = _t, \
-       .offset = offsetof(_s, _f)
-#  define FR_CONF_OFFSET_IS_SET(_n, _t, _s, _f) \
-       .name = _n, \
-       .type = (_t) | FR_TYPE_IS_SET, \
-       .offset = offsetof(_s, _f), \
-       .is_set_offset = offsetof(_s, _f ## _is_set)
-#  define FR_CONF_POINTER(_n, _t, _p) \
-       .name = _n, \
-       .type = _t, \
-       .data = _p
-#  define FR_CONF_POINTER_IS_SET(_n, _t, _p) \
-       .name = _n, \
-       .type = (_t) | FR_TYPE_IS_SET, \
-       .data = _p, \
-       .is_set_ptr = _p ## _is_set
-#  define FR_ITEM_POINTER(_t, _p) _t, _p
+#  define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs) \
+       .name = _name, \
+       .type = (FR_TYPE_SUBSECTION | _flags), \
+       .offset = offsetof(_struct, _field), \
+       .subcs = _subcs
+
+/** CONF_PARSER which parses a single CONF_PAIR producing a single global result
+ *
+ * @param[in] _name            of the CONF_PAIR to search for.
+ * @param[in] _type            to parse the CONF_PAIR as.
+ * @param[out] _res_p          pointer to a global var, where the result will be written.
+ */
+#  define FR_CONF_POINTER(_name, _type, _res_p) \
+       .name = _name, \
+       .type = _type, \
+       .data = FR_CONF_TYPE_CHECK((_type), (_res_p), _res_p)
+
+/** CONF_PARSER which parses a single CONF_PAIR producing a single global result, recording if a default was used in <_res_p>_is_set
+ *
+ * @note is set state is recorded in variable <_res_p>_is_set.
+ *
+ * @param[in] _name            of the CONF_PAIR to search for.
+ * @param[in] _type            to parse the CONF_PAIR as.
+ * @param[out] _res_p          pointer to a global var, where the result will be written.
+ */
+#  define FR_CONF_POINTER_IS_SET(_name, _type, _res_p) \
+       .name = _name, \
+       .type = (_type) | FR_TYPE_IS_SET, \
+       .data = FR_CONF_TYPE_CHECK((_type), (_res_p), _res_p), \
+       .is_set_ptr = _res_p ## _is_set
+#  define FR_ITEM_POINTER(_type, _res_p) _type, FR_CONF_TYPE_CHECK((_type), (_res_p), _res_p)
 
 /** A CONF_PARSER multi-subsection
  *
- * Parse multiple instance of a subsection.
+ * Parse multiple instance of a subsection, allocating an array of structs
+ * to hold the result.
  *
- * @param _n   name of subsection to search for.
- * @param _t   Must be FR_TYPE_SUBSECTION | FR_TYPE_MULTI and any optional flags.
- * @param _s   instance data struct.
- * @param _f   field in instance data struct.
- * @param _sub CONF_PARSER array to use to parse subsection data.
+ * @param _name                name of subsection to search for.
+ * @param _type                Must be FR_TYPE_SUBSECTION | FR_TYPE_MULTI and any optional flags.
+ * @param _struct      instance data struct.
+ * @param _field       field in instance data struct.
+ * @param _subcs       CONF_PARSER array to use to parse subsection data.
  */
-#  define FR_CONF_SUBSECTION_ALLOC(_n, _t, _s, _f, _sub) \
-       .name = _n, \
-       .type = _t, \
-       .offset = offsetof(_s, _f), \
-       .subcs = _sub, \
-       .subcs_size = sizeof(**(((_s *)0)->_f))
-#endif
+#  define FR_CONF_SUBSECTION_ALLOC(_name, _type, _struct, _field, _subcs) \
+       .name = _name, \
+       .type = (_type), \
+       .offset = FR_CONF_TYPE_CHECK((_type), &(((_struct *)NULL)->_field), offsetof(_struct, _field)), \
+       .subcs = _subcs, \
+       .subcs_size = sizeof(**(((_struct *)0)->_field))
 
 /** CONF_PARSER entry which doesn't fill in a pointer or offset, but relies on functions to record values
  *
- * @param[in] _n               name of pair to search for.
- * @param[in] _t               base type to parse pair as.
+ * @param[in] _nand            name of pair to search for.
+ * @param[in] _type            base type to parse pair as.
  * @param[in] _func            to use to record value.
  * @param[in] _dflt_func       to use to get defaults from a 3rd party library.
  */
-#  define FR_CONF_FUNC(_n, _t, _func, _dflt_func) \
-       .name = _n, \
-       .type = _t, \
+#  define FR_CONF_FUNC(_name, _type, _func, _dflt_func) \
+       .name = _name, \
+       .type = _type, \
        .func = _func, \
        .dflt_func = _dflt_func
 
 /** CONF_PARSER entry which runs CONF_PARSER entries for a subsection without any output
  *
- * @param[in] _n               name of pair to search for.
+ * @param[in] _name            of pair to search for.
  * @param[in] _flags           any extra flags to add.
  * @param[in] _subcs           to use to get defaults from a 3rd party library.
  */
-#  define FR_CONF_SUBSECTION_GLOBAL(_n, _flags, _subcs) \
-       .name = _n, \
-       .type = FR_TYPE_SUBSECTION | 0, \
+#  define FR_CONF_SUBSECTION_GLOBAL(_name, _flags, _subcs) \
+       .name = _name, \
+       .type = FR_TYPE_SUBSECTION, \
        .subcs = _subcs
 
-#define FR_CONF_DEPRECATED(_n, _t, _p, _f) \
-       .name = _n, \
-       .type = (_t) | FR_TYPE_DEPRECATED
+/** CONF_PARSER entry which raises an error if a matching CONF_PAIR is found
+ *
+ * @param[in] _name            of pair to search for.
+ * @param[in] _type            type, mostly unused.
+ * @param[in] _struct          where the result was previously written.
+ * @param[in] _field           in the struct where the result was previously written.
+ */
+#define FR_CONF_DEPRECATED(_name, _type, _struct, _field) \
+       .name = _name, \
+       .type = (_type) | FR_TYPE_DEPRECATED
 
 /*
  *  Instead of putting the information into a configuration structure,
index df6f8c2783224f442a2d3d7eafd962162517af0f..b491d86866d033163d9fcdcb47790a618ffe2500 100644 (file)
@@ -123,29 +123,37 @@ typedef struct {
 } process_ttls_sections_t;
 
 typedef struct {
-       bool            log_stripped_names;
-       bool            log_auth;               //!< Log authentication attempts.
-       bool            log_auth_badpass;       //!< Log successful authentications.
-       bool            log_auth_goodpass;      //!< Log failed authentications.
+       bool            stripped_names;
+       bool            auth;           //!< Log authentication attempts.
+       bool            auth_badpass;   //!< Log successful authentications.
+       bool            auth_goodpass;  //!< Log failed authentications.
        char const      *auth_badpass_msg;      //!< Additional text to append to successful auth messages.
        char const      *auth_goodpass_msg;     //!< Additional text to append to failed auth messages.
 
        char const      *denied_msg;            //!< Additional text to append if the user is already logged
                                                //!< in (simultaneous use check failed).
+} process_ttls_auth_log_t;
 
-       fr_time_delta_t session_timeout;        //!< Maximum time between the last response and next request.
-       uint32_t        max_session;            //!< Maximum ongoing session allowed.
+typedef struct {
+       fr_time_delta_t timeout;        //!< Maximum time between the last response and next request.
+       uint32_t        max;            //!< Maximum ongoing session allowed.
 
        uint8_t         state_server_id;        //!< Sets a specific byte in the state to allow the
                                                //!< authenticating server to be identified in packet
                                                //!<captures.
+} process_ttls_session_t;
+
+typedef struct {
+       process_ttls_auth_log_t         log;            //!< Log setting for TTLS.
+
+       process_ttls_session_t          session;        //!< Session settings.
 
-       fr_state_tree_t *state_tree;            //!< State tree to link multiple requests/responses.
+       fr_state_tree_t                 *state_tree;    //!< State tree to link multiple requests/responses.
 } process_ttls_auth_t;
 
 typedef struct {
        CONF_SECTION                    *server_cs;     //!< Our virtual server.
-       process_ttls_sections_t sections;       //!< Pointers to various config sections
+       process_ttls_sections_t         sections;       //!< Pointers to various config sections
                                                        ///< we need to execute.
        process_ttls_auth_t             auth;           //!< Authentication configuration.
 } process_ttls_t;
@@ -158,36 +166,35 @@ typedef struct {
 #include <freeradius-devel/server/process.h>
 
 static const CONF_PARSER session_config[] = {
-       { FR_CONF_OFFSET("timeout", FR_TYPE_TIME_DELTA, process_ttls_auth_t, session_timeout), .dflt = "15" },
-       { FR_CONF_OFFSET("max", FR_TYPE_UINT32, process_ttls_auth_t, max_session), .dflt = "4096" },
-       { FR_CONF_OFFSET("state_server_id", FR_TYPE_UINT8, process_ttls_auth_t, state_server_id) },
+       { FR_CONF_OFFSET("timeout", FR_TYPE_TIME_DELTA, process_ttls_session_t, timeout), .dflt = "15" },
+       { FR_CONF_OFFSET("max", FR_TYPE_UINT32, process_ttls_session_t, max), .dflt = "4096" },
+       { FR_CONF_OFFSET("state_server_id", FR_TYPE_UINT8, process_ttls_session_t, state_server_id) },
 
        CONF_PARSER_TERMINATOR
 };
 
 static const CONF_PARSER log_config[] = {
-       { FR_CONF_OFFSET("stripped_names", FR_TYPE_BOOL, process_ttls_auth_t, log_stripped_names), .dflt = "no" },
-       { FR_CONF_OFFSET("auth", FR_TYPE_BOOL, process_ttls_auth_t, log_auth), .dflt = "no" },
-       { FR_CONF_OFFSET("auth_badpass", FR_TYPE_BOOL, process_ttls_auth_t, log_auth_badpass), .dflt = "no" },
-       { FR_CONF_OFFSET("auth_goodpass", FR_TYPE_BOOL,process_ttls_auth_t,  log_auth_goodpass), .dflt = "no" },
-       { FR_CONF_OFFSET("msg_badpass", FR_TYPE_STRING, process_ttls_auth_t, auth_badpass_msg) },
-       { FR_CONF_OFFSET("msg_goodpass", FR_TYPE_STRING, process_ttls_auth_t, auth_goodpass_msg) },
-       { FR_CONF_OFFSET("msg_denied", FR_TYPE_STRING, process_ttls_auth_t, denied_msg), .dflt = "You are already logged in - access denied" },
+       { FR_CONF_OFFSET("stripped_names", FR_TYPE_BOOL, process_ttls_auth_log_t, stripped_names), .dflt = "no" },
+       { FR_CONF_OFFSET("auth", FR_TYPE_BOOL, process_ttls_auth_log_t, auth), .dflt = "no" },
+       { FR_CONF_OFFSET("auth_badpass", FR_TYPE_BOOL, process_ttls_auth_log_t, auth_badpass), .dflt = "no" },
+       { FR_CONF_OFFSET("auth_goodpass", FR_TYPE_BOOL,process_ttls_auth_log_t,  auth_goodpass), .dflt = "no" },
+       { FR_CONF_OFFSET("msg_badpass", FR_TYPE_STRING, process_ttls_auth_log_t, auth_badpass_msg) },
+       { FR_CONF_OFFSET("msg_goodpass", FR_TYPE_STRING, process_ttls_auth_log_t, auth_goodpass_msg) },
+       { FR_CONF_OFFSET("msg_denied", FR_TYPE_STRING, process_ttls_auth_log_t, denied_msg), .dflt = "You are already logged in - access denied" },
 
        CONF_PARSER_TERMINATOR
 };
 
 static const CONF_PARSER auth_config[] = {
-       { FR_CONF_POINTER("log", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) log_config },
+       { FR_CONF_OFFSET_SUBSECTION("log,", 0, process_ttls_auth_t, log, log_config) },
 
-       { FR_CONF_POINTER("session", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) session_config },
+       { FR_CONF_OFFSET_SUBSECTION("session", 0, process_ttls_auth_t, session, session_config )},
 
        CONF_PARSER_TERMINATOR
 };
 
 static const CONF_PARSER config[] = {
-       { FR_CONF_POINTER("Access-Request", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) auth_config,
-         .offset = offsetof(process_ttls_t, auth), },
+       { FR_CONF_OFFSET_SUBSECTION("Access-Request", 0, process_ttls_t, auth, auth_config) },
 
        CONF_PARSER_TERMINATOR
 };
@@ -288,12 +295,12 @@ static void CC_HINT(format (printf, 4, 5)) auth_message(process_ttls_auth_t cons
        /*
         *      No logs?  Then no logs.
         */
-       if (!inst->log_auth) return;
+       if (!inst->log.auth) return;
 
        /*
         * Get the correct username based on the configured value
         */
-       if (!inst->log_stripped_names) {
+       if (!inst->log.stripped_names) {
                username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_name);
        } else {
                username = fr_pair_find_by_da(&request->request_pairs, NULL, attr_stripped_user_name);
@@ -303,7 +310,7 @@ static void CC_HINT(format (printf, 4, 5)) auth_message(process_ttls_auth_t cons
        /*
         *      Clean up the password
         */
-       if (inst->log_auth_badpass || inst->log_auth_goodpass) {
+       if (inst->log.auth_badpass || inst->log.auth_goodpass) {
                password = fr_pair_find_by_da(&request->request_pairs, NULL, attr_user_password);
                if (!password) {
                        fr_pair_t *auth_type;
@@ -322,11 +329,11 @@ static void CC_HINT(format (printf, 4, 5)) auth_message(process_ttls_auth_t cons
        }
 
        if (goodpass) {
-               logit = inst->log_auth_goodpass;
-               extra_msg = inst->auth_goodpass_msg;
+               logit = inst->log.auth_goodpass;
+               extra_msg = inst->log.auth_goodpass_msg;
        } else {
-               logit = inst->log_auth_badpass;
-               extra_msg = inst->auth_badpass_msg;
+               logit = inst->log.auth_badpass;
+               extra_msg = inst->log.auth_badpass_msg;
        }
 
        if (extra_msg) {
@@ -664,8 +671,8 @@ static int mod_instantiate(module_inst_ctx_t const *mctx)
 {
        process_ttls_t  *inst = talloc_get_type_abort(mctx->inst->data, process_ttls_t);
 
-       inst->auth.state_tree = fr_state_tree_init(inst, attr_state, main_config->spawn_workers, inst->auth.max_session,
-                                                  inst->auth.session_timeout, inst->auth.state_server_id,
+       inst->auth.state_tree = fr_state_tree_init(inst, attr_state, main_config->spawn_workers, inst->auth.session.max,
+                                                  inst->auth.session.timeout, inst->auth.session.state_server_id,
                                                   fr_hash_string(cf_section_name2(inst->server_cs)));
 
        return 0;