/** * @file * Defines the public interface for all sechecker modules and the library. * * @author Jeremy A. Mowery jmowery@tresys.com * @author Jason Tang jtang@tresys.com * * Copyright (C) 2005-2007 Tresys Technology, LLC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SECHECKER_H #define SECHECKER_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #include /* These should be defined from the make environment */ #ifndef PROF_SUBDIR #define PROF_SUBDIR "/sechecker-profiles" #endif #ifndef DEFAULT_PROFILE #define DEFAULT_PROFILE "" #endif /* defined flags for outformat */ /* report components */ #define SECHK_OUT_STATS 0x01 #define SECHK_OUT_LIST 0x02 #define SECHK_OUT_PROOF 0x04 /* mode flags from command line and test profiles */ /* NOTE: none is only valid in profiles */ #define SECHK_OUT_NONE 0x00 #define SECHK_OUT_QUIET 0x20 #define SECHK_OUT_SHORT (SECHK_OUT_STATS|SECHK_OUT_LIST) #define SECHK_OUT_VERBOSE (SECHK_OUT_STATS|SECHK_OUT_PROOF) typedef void (*free_fn_t) (void *x); /* severity categories */ #define SECHK_SEV_NONE "none" #define SECHK_SEV_LOW "low" #define SECHK_SEV_MED "med" #define SECHK_SEV_HIGH "high" /* module requirement name strings */ /** Require that the loaded policy has a given capability; * values should be set as one of SECHK_REQ_CAP_* from below. */ #define SECHK_REQ_POLICY_CAP "capability" /** Require that the running system supports a given feature; * values should be set as one of SECHK_REQ_SYS_* from below. */ #define SECHK_REQ_SYSTEM "system" /** Require a file_contexts file to be loaded. * This requirement has no associated value text. */ #define SECHK_REQ_FILE_CONTEXTS "file_contexts" /** Require a default_contexts file to be loaded. * This requirement has no associated value text. */ #define SECHK_REQ_DEFAULT_CONTEXTS "default_contexts" /* policy capability requirement strings: map to QPOL_CAP_* in policy_query.h */ /** Require that the loaded policy supports attribute names. */ #define SECHK_REQ_CAP_ATTRIB_NAMES "attribute names" /** Require that the loaded policy supports syntactic rules. */ #define SECHK_REQ_CAP_SYN_RULES "syntactic rules" /** Require that the loaded policy supports line numbers. */ #define SECHK_REQ_CAP_LINE_NOS "line numbers" /** Require that the loaded policy supports booleans and conditional statements. */ #define SECHK_REQ_CAP_CONDITIONALS "conditionals" /** Require that the loaded policy supports MLS. */ #define SECHK_REQ_CAP_MLS "mls" /** Require that the loaded policy supports module loading. */ #define SECHK_REQ_CAP_MODULES "module loading" /** Require that the loaded policy includes av/te rules. */ #define SECHK_REQ_CAP_RULES_LOADED "rules loaded" /* system requirement strings */ /** Require that the running system is a SELinux system. */ #define SECHK_REQ_SYS_SELINUX "selinux" /** Require that the running system supports MLS*/ #define SECHK_REQ_SYS_MLS "mls" /** item and proof element types to denote casting of the void pointer */ typedef enum sechk_item_type { SECHK_ITEM_CLASS, /*!< qpol_class_t */ SECHK_ITEM_COMMON, /*!< qpol_common_t */ SECHK_ITEM_PERM, /*!< char * representing the permission name */ SECHK_ITEM_CONSTR, /*!< qpol_constraint_t */ SECHK_ITEM_VTRANS, /*!< qpol_validatetrans_t */ SECHK_ITEM_QLEVEL, /*!< qpol_level_t */ SECHK_ITEM_CAT, /*!< qpol_cat_t */ SECHK_ITEM_QMLSLEVEL, /*!< qpol_mls_level_t */ SECHK_ITEM_QMLSRANGE, /*!< qpol_mls_range_t */ SECHK_ITEM_AMLSLEVEL, /*!< apol_mls_level_t */ SECHK_ITEM_AMLSRANGE, /*!< apol_mls_range_t */ SECHK_ITEM_TYPE, /*!< qpol_type_t */ SECHK_ITEM_ATTRIB, /*!< qpol_type_t but is an atribute not a type */ SECHK_ITEM_ROLE, /*!< qpol_role_t */ SECHK_ITEM_USER, /*!< qpol_user_t */ SECHK_ITEM_COND, /*!< qpol_cond_t */ SECHK_ITEM_AVRULE, /*!< qpol_avrule_t */ SECHK_ITEM_TERULE, /*!< qpol_terule_t */ SECHK_ITEM_RALLOW, /*!< qpol_role_allow_t */ SECHK_ITEM_RTRAMS, /*!< qpol_role_trans_t */ SECHK_ITEM_RANGETRANS, /*!< qpol_range_trans_t */ SECHK_ITEM_BOOL, /*!< qpol_bool_t */ SECHK_ITEM_FSUSE, /*!< qpol_fs_use_t */ SECHK_ITEM_GENFSCON, /*!< qpol_genfscon_t */ SECHK_ITEM_ISID, /*!< qpol_isid_t */ SECHK_ITEM_NETIFCON, /*!< qpol_netifcon_t */ SECHK_ITEM_NODECON, /*!< qpol_nodecon_t */ SECHK_ITEM_PORTCON, /*!< qpol_portcon_t */ SECHK_ITEM_CONTEXT, /*!< qpol_context_t */ /* add more here as needed */ SECHK_ITEM_FCENT, /*!< sefs_entry_t */ SECHK_ITEM_STR, /*!< char* generic string */ SECHK_ITEM_DTR, /*!< apol_domain_trans_result_t */ SECHK_ITEM_OTHER, /*!< void* data is something else (module specific) */ SECHK_ITEM_NONE /*!< there is no proof element only text */ } sechk_item_type_e; /** Module results proof element: This represents a single reason for the * inclusion of an item in the results. */ typedef struct sechk_proof { /** Component, rule, or other object relative to the policy */ void *elem; /** The type of element stored by this proof */ sechk_item_type_e type; /** Description of proof for prining the report */ char *text; xmlChar *xml_out; /* currently unused but retained for future use */ /** Function to call if elem should be free()'d or NULL */ free_fn_t elem_free_fn; } sechk_proof_t; /** Module results item: * This represents an item for which results were found. */ typedef struct sechk_item { /** The policy item */ void *item; /** Test result code for this item. This field is reserved for use * only within the module creating the item. */ unsigned char test_result; /** Vector of proof elements (of type sechk_proof_t) indicating * why an item appears in the results. */ apol_vector_t *proof; /** Function to call if item should be free()'d or NULL */ free_fn_t item_free_fn; } sechk_item_t; /** Module results: This represents the results generated by a module's * run function. This structure is used both to generate the report and * to comunicate with other modules that depend on the generating module. */ typedef struct sechk_result { /** Name of the module that created the results. */ char *test_name; /** The type of policy item processed by the module. */ sechk_item_type_e item_type; /** Vector of items for which results were found (of type sechk_item_t). */ apol_vector_t *items; } sechk_result_t; /** Generic name value pair: * Used for storing options, dependencies and requirements. */ typedef struct sechk_name_value { char *name; char *value; } sechk_name_value_t; /** Module library: * This structure tracks all modules that SEChecker can run, * the policy, and other policy related data. */ typedef struct sechk_lib { /** Vector of the modules (of type sechk_module_t) */ apol_vector_t *modules; /** The policy to analyze when running modules */ apol_policy_t *policy; /** Vector of file contexts data (of type sefs_entry_t). */ apol_vector_t *fc_entries; /** File name of the file_contexts file loaded. */ char *fc_path; /** The file_contexts file object. */ sefs_fclist_t *fc_file; /** The default output format for the report */ unsigned char outputformat; /** The path for the selinux configuration file */ char *selinux_config_path; /** File name of the policy loaded.*/ apol_policy_path_t *policy_path; /** Minimum severity level specified for the report. */ const char *minsev; } sechk_lib_t; typedef struct sechk_module { /** Unique module name */ char *name; /** Brief description of the module */ const char *brief_description; /** Detailed description of the module. This should include a listing of * of all steps performed by the module's checks. */ const char *detailed_description; /** Description of options, requirements, and dependencies */ const char *opt_description; /** Results generated by this module. */ sechk_result_t *result; /** Vector (of type sechk_name_value_t) containing all user specified * options for this module. */ apol_vector_t *options; /** Vector (of type sechk_name_value_t) containing all conditions required * by the module such as policy version or type. See profile documentation * for a complete listing of possible requirements. */ apol_vector_t *requirements; /** Vector (of type sechk_name_value_t) containing a list of modules * which need to run before this module may access their results. */ apol_vector_t *dependencies; /** Vector (of type sechk_fn_t) of all functions registered for this module. * All modules are required to have at least three: init, run, and print. */ apol_vector_t *functions; /** Default output format for the report. */ unsigned char outputformat; /** This field is used by the library to indicate that the user or another * module has selected this module to be run. */ bool selected; /** The severity level of this module's results. One of SECHK_SEV_* above. */ const char *severity; /** The module's private data. This includes data generated when processing * options and from reading its dependencies' results. */ void *data; /** Function to be used to free the private data. */ free_fn_t data_free; /** Pointer to the module's parent library. */ const sechk_lib_t *parent_lib; } sechk_module_t; /* Module function signatures */ /** * Function signature for the function to register a module with the library. * * @param lib The library with which to register. * * @return 0 on success and < 0 on failure; if the call fails, errno will be * set and the library should be destroyed. */ typedef int (*sechk_register_fn_t) (sechk_lib_t * lib); /** * Function signature for functions registed by a module. * * @param mod The module performing the operation. * @param policy The policy accessed by the module. * @param arg Arbitrary third parameter for use by the function. * * @return 0 on success, or < 0 on fatal error. If the call fails, * it is expected to set errno. Special: a run function is permitted * to return > 0 upon finding results; only the run function may return > 0. */ typedef int (*sechk_mod_fn_t) (sechk_module_t * mod, apol_policy_t * policy, void *arg); /* Module function names */ #define SECHK_MOD_FN_INIT "init" #define SECHK_MOD_FN_RUN "run" #define SECHK_MOD_FN_PRINT "print" /** Registered function container: used to allow the library and modules * to request functions of a specific name. */ typedef struct sechk_fn { /** Name of the function without any module prefix */ char *name; /** The function. */ sechk_mod_fn_t fn; } sechk_fn_t; /** Module name registration structure: used when the library tries to * discover all known modules. */ typedef struct sechk_module_name_reg { /** The name of the module. */ char *name; /** The register function for this module. */ sechk_register_fn_t fn; } sechk_module_name_reg_t; /** Profile name registration structure; used when the library tries to * discover all known installed profiles. */ typedef struct sechk_profile_name_reg { /** Name of the profile. */ char *name; /** Path of the profile file. */ char *file; /** Description of the modules run by the profile. */ char *desc; } sechk_profile_name_reg_t; /* alloc methods */ /** * Create a new module library object. * * @return A newly allocated module library or NULL on ENOMEM. * The caller is responsible for calling sechk_lib_destroy() * to free memory used by the library returned. */ sechk_lib_t *sechk_lib_new(void); /** * Create a new module structure. * * @return A newly allocated module or NULL on ENOMEM. * The caller is resbonsible for calling sechk_module_free() * to free memory used by the module returned. */ sechk_module_t *sechk_module_new(void); /** * Create a new module function structre. * * @return A newly allocated module function structure or NULL on ENOMEM. * The caller is responsible for calling sechk_fn_free() to free memory * used by the function structure returned. */ sechk_fn_t *sechk_fn_new(void); /** * Create and initialize a new name value pair. * The incoming strings are duplicated. * * @param name Name to assign. * @param value Value to assign to name. * * @return A newly allocated name value pair of NULL on error; if the * call fails errno will be set. */ sechk_name_value_t *sechk_name_value_new(const char *name, const char *value); /** * Create a new results structure. * * @return A newly allocated results structure or NULL on ENOMEM. * The caller is responsible for calling sechk_result_destroy() to free * the memory used by the returned result structure. */ sechk_result_t *sechk_result_new(void); /** * Create a new result item. * * @param fn Function to be used to free the item stored. * * @return A newly allocated result item or NULL on ENOMEM. * The caller is responsible for calling sechk_item_free() to free * the memory used by the returned item. */ sechk_item_t *sechk_item_new(free_fn_t fn); /** * Create a new result item proof entry. * * @param fn Function to be used to free the element stored. * * @return A newly allocated proof structure or NULL on ENOMEM. * The caller is responsible for calling sechk_proof_free() to free * the memory used by teh returned proof. */ sechk_proof_t *sechk_proof_new(free_fn_t fn); /* free methods */ /** * Free all memory used by a module library and set it to NULL. * * @param The library to destroy. */ void sechk_lib_destroy(sechk_lib_t ** lib); /** * Free all memory used by a module function structure. * * @param fn_struct The function structure to free. */ void sechk_fn_free(void *fn_struct); /** * Free all memory used by a result structure and set it to NULL. * * @param res The result structure to destroy. */ void sechk_result_destroy(sechk_result_t ** res); /** * Free all memory used by a result item. * * @param item The result item to free. */ void sechk_item_free(void *item); /** * Free all memory used by a result item proof element. * * @param proof The proof element to free. */ void sechk_proof_free(void *proof); /** * Free all memory used by a module. * * @param module The module to free. */ void sechk_module_free(void *module); /** * Free all memory used by a name value pair. * * @param nv The name value pair to free. */ void sechk_name_value_free(void *nv); /* register/check_dep/init/run/print - modules */ /** * Register all known modules with the library. * * @param regiser_fns NULL terminated array of module registration structures. * @param lib The library with which to register the modules in the array. * * @return 0 on success or < 0 on error; if the call fails, errno will be * set and the library should be destroyed. */ int sechk_lib_register_modules(const sechk_module_name_reg_t * register_fns, sechk_lib_t * lib); /** * Check that the dependencies of all selected modules can be met. * This function will select additional modules if needed by those * already selected to be run. * * @param lib The library containing the modules to check. * * @return 0 on success and < 0 on error; if the call fails, * errno will be set. */ int sechk_lib_check_module_dependencies(sechk_lib_t * lib); /** * Check that the requirements of all selected modules are met. If the * requirements are not met for a module and the library's default reporting * mode is not SECHK_OUT_QUIET, the module will be deselected so that others * might be checked. If the library is set to quiet, this function exits on * the first module found to not meet its requirements. This function * should only be called after sechk_lib_check_module_dependencies() * * @param lib The library containing the modules to check. * * @return 0 on success and < 0 on error; if the call fails, * errno will be set. */ int sechk_lib_check_module_requirements(sechk_lib_t * lib); /** * Initialize all selected modules. This function should only be called * after both sechk_lib_check_module_dependencies() and * sechk_lib_check_module_requirements() have been called. * * @param lib The library containing the modules to initialize. * * @return 0 on success and < 0 on failure; if the call fails, errno will be * set and the library should be destroyed. */ int sechk_lib_init_modules(sechk_lib_t * lib); /** * Run all selected modules. The modules must have been initialized. * * @param lib The library containing the modules to run. * * @return 0 on success or < 0 on error. Note that in quiet mode this * function is considered to fail if a module finds results. */ int sechk_lib_run_modules(sechk_lib_t * lib); /** * Print a report of all selected modules' results to stdout. * Modules must have been run. * * @param lib The library containing the modules with results to print. * * @return 0 on success and < 0 on error. */ int sechk_lib_print_modules_report(sechk_lib_t * lib); /* module accessors */ /** * Find a module in the library. * * @param module_name The name of the module to find. * @param lib The library to search. * * @return A pointer to the module or NULL if not found. */ sechk_module_t *sechk_lib_get_module(const char *module_name, const sechk_lib_t * lib); /** * Get a pointer to a function registered for a module. * * @param module_name Name of the module containing the function. * @param function_name Name of the function with out any module prefix. * @param lib The library containing the module. * * @return A pointer to the requested function, or NULL if either the module * or the function cannot be found. */ sechk_mod_fn_t sechk_lib_get_module_function(const char *module_name, const char *function_name, const sechk_lib_t * lib); /** * Get the results of a module. If the module has not been run, it will be run * and its results will be returned if it succeeds. * * @param module_name Name of the module containing the results. * @param lib The library containing the module. * * @return The requested module's results or NULL on error. If the module * was not previously run and it fails when run by this function, NULL * will be returned. If the call fails, errno will be set. */ sechk_result_t *sechk_lib_get_module_result(const char *module_name, const sechk_lib_t * lib); /* library utility functions */ /** * Load the policy the library will analyze. * * @param policy_mods Policy path object to use to load the policy. * @param lib The library into which to load the policy. * * @return 0 on success and < 0 on failure. */ int sechk_lib_load_policy(apol_policy_path_t * policy_mods, sechk_lib_t * lib); /** * Load the file contexts file the library will use during analysis. * * @param fcfilelocation Path of the file contexts file to load, or * NULL to search for system default file contexts. * @param lib The library into which to load the file contexts. * * @return 0 on success and < 0 on failure. */ int sechk_lib_load_fc(const char *fcfilelocation, sechk_lib_t * lib); /** * Load a profile containing module options. * * @param prof_name Name of a known installed profile or the absolute path * to a user created profile. * @param lib The library containing the modules specified in the profile. * * @return 0 on success and < 0 on failure; if the call fails errno will be * set and the library should be destroyed. */ int sechk_lib_load_profile(const char *prof_name, sechk_lib_t * lib); /** * Clear an option of all previous values. * * @param module Module containing the option to clear. * @param option Name of the option to clear. * * @return 0 on success or < 0 on failure; if the call fails, * errno will be set, and the module should be freed. */ int sechk_lib_module_clear_option(sechk_module_t * module, char *option); /** * Check that the library can meet a single requirement. * * @param req The requirement to check. * @param lib The library to query. * * @return 1 if the requirement is met, and 0 if it is either unmet or * if the library is unable to determine. */ bool sechk_lib_check_requirement(sechk_name_value_t * req, sechk_lib_t * lib); /** * Check that the library can meet a single module dependency. * * @param dep The dependency to check. * @param lib The library to query for the existence of the dependency. * * @return 1 if the dependency exists, and 0 if it either does not or * if the library is unable to determine. */ bool sechk_lib_check_dependency(sechk_name_value_t * dep, sechk_lib_t * lib); /** * Set the default output format for the library. * * @param out The format to use as a bit-wise or of SECHK_OUT_*. * @param lib The library for which to set the output format. * * @return 0 on success and < 0 on failure; if the call fails, * errno will be set. */ int sechk_lib_set_outputformat(unsigned char out, sechk_lib_t * lib); /** * Set the minimum severity level of the library. * * @param sev Severity level to set as the minimum level for reporting. * Must be one of SECHK_SEV_*. * @param lib The library for which to set the minimum severity level. * * @return 0 on success and < 0 on failure; if the call fials, * errno will be set. */ int sechk_lib_set_minsev(const char *sev, sechk_lib_t * lib); /** * Get the index of a module in the library by name. * * @param name Name of the module for which to get the index. * @param lib The library containing the desired module. * * @return index of the module or -1 if it was not found. * If not found, errno will be set. */ int sechk_lib_get_module_idx(const char *name, sechk_lib_t * lib); /* other utility functions */ /** * Copy a proof element. Note: the element in the proof is a shallow copy. * * @param orig The original proof to copy. * * @return a copy of the proof or NULL on error. If the call fails, * errno will be set. */ sechk_proof_t *sechk_proof_copy(sechk_proof_t * orig); /** * Callback for vector comparison of proof elements. * This callback takes two different type objects both cast to void * it is important that the order of the parameters is correct or the * vector code will fail when using this callback. * * @param in_proof One member of the vector of proofs. * @param elem A policy item to compare to the proof's element. * @param unused Unused. Needed to satisfy vector prototype. * * @return Pointer comparison value of < 0, 0 or > 0 if the element in the * proof is respectively less than, equal to, or greater than that of the * comparison element supplied. */ int sechk_proof_with_element_compare(const void *in_proof, const void *elem, void *unused); #ifdef __cplusplus } #endif #endif /* SECHECKER_H */