sechecker.c File Reference


Detailed Description

Implementation of the public interface for all sechecker modules and the library.

Author:
Jeremy A. Mowery jmowery@tresys.com

Jason Tang jtang@tresys.com

Copyright (C) 2005-2008 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

Definition in file sechecker.c.

#include "sechecker.h"
#include "register_list.h"
#include "sechk_parse.h"
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <apol/policy.h>
#include <apol/util.h>
#include <apol/vector.h>
#include <sefs/util.h>
#include <sefs/fcfile.hh>
#include <sefs/query.hh>
#include <qpol/policy.h>
#include <qpol/util.h>

Go to the source code of this file.


Functions

int sechk_lib_compare_sev (const char *a, const char *b)
int sechk_lib_set_minsev (const char *minsev, sechk_lib_t *lib)
 Set the minimum severity level of the library.
sechk_module_tsechk_module_new (void)
 Create a new module structure.
sechk_lib_tsechk_lib_new (void)
 Create a new module library object.
void sechk_lib_destroy (sechk_lib_t **lib)
 Free all memory used by a module library and set it to NULL.
void sechk_module_free (void *module)
 Free all memory used by a module.
void sechk_fn_free (void *fn_struct)
 Free all memory used by a module function structure.
void sechk_name_value_free (void *nv)
 Free all memory used by a name value pair.
void sechk_result_destroy (sechk_result_t **res)
 Free all memory used by a result structure and set it to NULL.
void sechk_item_free (void *item)
 Free all memory used by a result item.
void sechk_proof_free (void *proof)
 Free all memory used by a result item proof element.
sechk_fn_tsechk_fn_new (void)
 Create a new module function structre.
sechk_name_value_tsechk_name_value_new (const char *name, const char *value)
 Create and initialize a new name value pair.
sechk_result_tsechk_result_new (void)
 Create a new results structure.
sechk_item_tsechk_item_new (free_fn_t fn)
 Create a new result item.
sechk_proof_tsechk_proof_new (free_fn_t fn)
 Create a new result item proof entry.
int sechk_lib_load_policy (apol_policy_path_t *policy_mods, sechk_lib_t *lib)
 Load the policy the library will analyze.
int sechk_lib_load_fc (const char *fcfilelocation, sechk_lib_t *lib)
 Load the file contexts file the library will use during analysis.
int sechk_lib_register_modules (const sechk_module_name_reg_t *register_fns, sechk_lib_t *lib)
 Register all known modules with the library.
sechk_mod_fn_t sechk_lib_get_module_function (const char *module_name, const char *function_name, const sechk_lib_t *lib)
 Get a pointer to a function registered for a module.
sechk_module_tsechk_lib_get_module (const char *module_name, const sechk_lib_t *lib)
 Find a module in the library.
sechk_result_tsechk_lib_get_module_result (const char *module_name, const sechk_lib_t *lib)
 Get the results of a module.
int sechk_lib_check_module_dependencies (sechk_lib_t *lib)
 Check that the dependencies of all selected modules can be met.
int sechk_lib_check_module_requirements (sechk_lib_t *lib)
 Check that the requirements of all selected modules are met.
int sechk_lib_init_modules (sechk_lib_t *lib)
 Initialize all selected modules.
int sechk_lib_run_modules (sechk_lib_t *lib)
 Run all selected modules.
int sechk_lib_print_modules_report (sechk_lib_t *lib)
 Print a report of all selected modules' results to stdout.
bool sechk_lib_check_requirement (sechk_name_value_t *req, sechk_lib_t *lib)
 Check that the library can meet a single requirement.
bool sechk_lib_check_dependency (sechk_name_value_t *dep, sechk_lib_t *lib)
 Check that the library can meet a single module dependency.
int sechk_lib_set_outputformat (unsigned char out, sechk_lib_t *lib)
 Set the default output format for the library.
sechk_proof_tsechk_proof_copy (sechk_proof_t *orig)
 Copy a proof element.
int sechk_lib_load_profile (const char *prof_name, sechk_lib_t *lib)
 Load a profile containing module options.
int sechk_option_name_compare (const void *a, const void *b, void *data __attribute__((unused)))
int sechk_lib_module_clear_option (sechk_module_t *module, char *option)
 Clear an option of all previous values.
int sechk_lib_get_module_idx (const char *name, sechk_lib_t *lib)
 Get the index of a module in the library by name.
int sechk_proof_with_element_compare (const void *in_proof, const void *elem, void *unused __attribute__((unused)))

Function Documentation

int sechk_lib_compare_sev const char *  a,
const char *  b
[static]
 

Definition at line 52 of file sechecker.c.

References SECHK_SEV_HIGH, SECHK_SEV_LOW, SECHK_SEV_MED, and SECHK_SEV_NONE.

Referenced by sechk_lib_print_modules_report(), and sechk_lib_run_modules().

00053 {
00054         int aval, bval;
00055 
00056         if (a == NULL || b == NULL) {
00057                 assert(false);
00058                 errno = EINVAL;
00059                 return -1;
00060         }
00061 
00062         if (strcmp(a, SECHK_SEV_NONE) == 0)
00063                 aval = 0;
00064         else if (strcmp(a, SECHK_SEV_LOW) == 0)
00065                 aval = 1;
00066         else if (strcmp(a, SECHK_SEV_MED) == 0)
00067                 aval = 2;
00068         else if (strcmp(a, SECHK_SEV_HIGH) == 0)
00069                 aval = 3;
00070         else {
00071                 assert(false);
00072                 errno = EINVAL;
00073                 return -1;
00074         }
00075 
00076         if (strcmp(b, SECHK_SEV_NONE) == 0)
00077                 bval = 0;
00078         else if (strcmp(b, SECHK_SEV_LOW) == 0)
00079                 bval = 1;
00080         else if (strcmp(b, SECHK_SEV_MED) == 0)
00081                 bval = 2;
00082         else if (strcmp(b, SECHK_SEV_HIGH) == 0)
00083                 bval = 3;
00084         else {
00085                 assert(false);
00086                 errno = EINVAL;
00087                 return -1;
00088         }
00089 
00090         if (aval == bval)
00091                 return 0;
00092 
00093         return aval < bval ? -1 : 1;
00094 }

int sechk_lib_set_minsev const char *  sev,
sechk_lib_t lib
 

Set the minimum severity level of the library.

Parameters:
sev Severity level to set as the minimum level for reporting. Must be one of SECHK_SEV_*.
lib The library for which to set the minimum severity level.
Returns:
0 on success and < 0 on failure; if the call fials, errno will be set.

Definition at line 96 of file sechecker.c.

References ERR, sechk_lib::minsev, sechk_lib::policy, sechk_lib_t, SECHK_SEV_HIGH, SECHK_SEV_LOW, and SECHK_SEV_MED.

Referenced by main().

00097 {
00098         if (lib == NULL || lib->policy == NULL || minsev == NULL) {
00099                 assert(false);
00100                 errno = EINVAL;
00101                 return -1;
00102         }
00103 
00104         if (strcmp(minsev, SECHK_SEV_LOW) == 0)
00105                 lib->minsev = SECHK_SEV_LOW;
00106         else if (strcmp(minsev, SECHK_SEV_MED) == 0)
00107                 lib->minsev = SECHK_SEV_MED;
00108         else if (strcmp(minsev, SECHK_SEV_HIGH) == 0)
00109                 lib->minsev = SECHK_SEV_HIGH;
00110         else {
00111                 ERR(lib->policy, "%s", "Invalid severity.");
00112                 errno = EINVAL;
00113                 return -1;
00114         }
00115         return 0;
00116 }

sechk_module_t* sechk_module_new void   ) 
 

Create a new module structure.

Returns:
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.

Definition at line 118 of file sechecker.c.

References apol_vector_create(), apol_vector_destroy(), sechk_module::dependencies, sechk_module::functions, sechk_module::options, sechk_module::requirements, sechk_fn_free(), sechk_module_t, and sechk_name_value_free().

Referenced by sechk_lib_new().

00119 {
00120         sechk_module_t *mod = NULL;
00121         int error = 0;
00122 
00123         mod = calloc(1, sizeof(sechk_module_t));
00124         if (!mod)
00125                 return NULL;
00126 
00127         /* create empty vectors */
00128         if (!(mod->options = apol_vector_create(sechk_name_value_free)) ||
00129             !(mod->requirements = apol_vector_create(sechk_name_value_free)) ||
00130             !(mod->dependencies = apol_vector_create(sechk_name_value_free))
00131             || !(mod->functions = apol_vector_create(sechk_fn_free))) {
00132                 error = errno;
00133                 apol_vector_destroy(&mod->options);
00134                 apol_vector_destroy(&mod->requirements);
00135                 apol_vector_destroy(&mod->dependencies);
00136                 apol_vector_destroy(&mod->functions);
00137                 free(mod);
00138                 errno = error;
00139                 return NULL;
00140         }
00141 
00142         return mod;
00143 }

sechk_lib_t* sechk_lib_new void   ) 
 

Create a new module library object.

Returns:
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.

Definition at line 145 of file sechecker.c.

References apol_vector_append(), apol_vector_create(), sechk_lib::minsev, sechk_lib::modules, sechk_module::name, sechk_lib::outputformat, sechk_lib_destroy(), sechk_lib_register_modules(), sechk_lib_t, sechk_module_free(), sechk_module_name_reg_t, sechk_module_new(), sechk_module_t, sechk_register_list_get_modules(), and sechk_register_list_get_num_modules().

Referenced by main().

00146 {
00147         sechk_lib_t *lib = NULL;
00148         int retv, error;
00149         const sechk_module_name_reg_t *reg_list;
00150         size_t num_known_modules = 0;
00151         size_t i = 0;
00152         sechk_module_t *tmp = NULL;
00153 
00154         /* allocate the new sechk_lib_t structure */
00155         lib = (sechk_lib_t *) calloc(1, sizeof(sechk_lib_t));
00156         if (!lib) {
00157                 error = errno;
00158                 perror("Error creating module library");
00159                 goto exit_err;
00160         }
00161 
00162         /* create the module array from the known modules in register list */
00163         num_known_modules = sechk_register_list_get_num_modules();
00164         reg_list = sechk_register_list_get_modules();
00165         lib->modules = apol_vector_create(sechk_module_free);
00166         if (!lib->modules) {
00167                 error = errno;
00168                 perror("Error adding modules");
00169                 goto exit_err;
00170 
00171         }
00172         for (i = 0; i < num_known_modules; i++) {
00173                 tmp = sechk_module_new();
00174                 if (!tmp) {
00175                         error = errno;
00176                         perror("Error adding modules");
00177                         goto exit_err;
00178                 }
00179                 tmp->name = strdup(reg_list[i].name);
00180                 if (!tmp->name) {
00181                         error = errno;
00182                         perror("Error adding modules");
00183                         goto exit_err;
00184                 }
00185                 if (apol_vector_append(lib->modules, tmp)) {
00186                         error = errno;
00187                         perror("Error adding modules");
00188                         goto exit_err;
00189                 }
00190                 tmp = NULL;
00191         }
00192 
00193         /* set the default output format */
00194         lib->outputformat = SECHK_OUT_SHORT;
00195         lib->minsev = SECHK_SEV_LOW;
00196 
00197         /* register modules */
00198         if ((retv = sechk_lib_register_modules(reg_list, lib)) != 0) {
00199                 error = errno;
00200                 perror("Error registering modules");
00201                 goto exit_err;
00202         }
00203       exit:
00204         return lib;
00205 
00206       exit_err:
00207         sechk_lib_destroy(&lib);
00208         sechk_module_free(tmp);
00209         errno = error;
00210         goto exit;
00211 }

void sechk_lib_destroy sechk_lib_t **  lib  ) 
 

Free all memory used by a module library and set it to NULL.

Parameters:
The library to destroy.

Definition at line 213 of file sechecker.c.

References apol_policy_destroy(), apol_policy_path_destroy(), apol_vector_destroy(), sechk_lib_t, and sefs_fclist_destroy().

Referenced by main(), and sechk_lib_new().

00214 {
00215         if (lib == NULL || *lib == NULL)
00216                 return;
00217 
00218         apol_vector_destroy(&((*lib)->modules));
00219         apol_policy_destroy(&((*lib)->policy));
00220         apol_vector_destroy(&((*lib)->fc_entries));
00221         free((*lib)->fc_path);
00222         sefs_fclist_destroy(&((*lib)->fc_file));
00223         free((*lib)->selinux_config_path);
00224         apol_policy_path_destroy(&((*lib)->policy_path));
00225         free(*lib);
00226         *lib = NULL;
00227 }

void sechk_module_free void *  module  ) 
 

Free all memory used by a module.

Parameters:
module The module to free.

Definition at line 229 of file sechecker.c.

References apol_vector_destroy(), sechk_module::data, sechk_module::data_free, sechk_module::dependencies, sechk_module::functions, sechk_module::name, sechk_module::options, sechk_module::requirements, sechk_module::result, sechk_module_t, and sechk_result_destroy().

Referenced by sechk_lib_new().

00230 {
00231         sechk_module_t *mod = (sechk_module_t *) module;
00232 
00233         if (!module)
00234                 return;
00235 
00236         /* do not free describtin fields */
00237         sechk_result_destroy(&mod->result);
00238         apol_vector_destroy(&mod->options);
00239         apol_vector_destroy(&mod->requirements);
00240         apol_vector_destroy(&mod->dependencies);
00241         /* do not free severity */
00242         if (mod->data) {
00243                 assert(mod->data_free);
00244                 mod->data_free(mod->data);
00245         }
00246         free(mod->name);
00247         mod->name = NULL;
00248         apol_vector_destroy(&mod->functions);
00249         free(mod);
00250 }

void sechk_fn_free void *  fn_struct  ) 
 

Free all memory used by a module function structure.

Parameters:
fn_struct The function structure to free.

Definition at line 252 of file sechecker.c.

References sechk_fn::name, and sechk_fn_t.

Referenced by sechk_module_new().

00253 {
00254         sechk_fn_t *fn = (sechk_fn_t *) fn_struct;
00255         if (!fn_struct)
00256                 return;
00257 
00258         free(fn->name);
00259         /* NEVER free fn->fn */
00260         free(fn);
00261 }

void sechk_name_value_free void *  nv  ) 
 

Free all memory used by a name value pair.

Parameters:
nv The name value pair to free.

Definition at line 263 of file sechecker.c.

References sechk_name_value::name, sechk_name_value_t, and sechk_name_value::value.

Referenced by sechk_lib_module_clear_option(), sechk_lib_process_xml_node(), and sechk_module_new().

00264 {
00265         sechk_name_value_t *in = (sechk_name_value_t *) nv;
00266         if (!nv)
00267                 return;
00268 
00269         free(in->name);
00270         free(in->value);
00271         free(nv);
00272 }

void sechk_result_destroy sechk_result_t **  res  ) 
 

Free all memory used by a result structure and set it to NULL.

Parameters:
res The result structure to destroy.

Definition at line 274 of file sechecker.c.

References apol_vector_destroy(), and sechk_result_t.

Referenced by attribs_wo_rules_run(), attribs_wo_types_run(), domain_and_file_run(), domains_wo_roles_run(), find_assoc_types_run(), find_domains_run(), find_file_types_run(), find_net_domains_run(), find_netif_types_run(), find_node_types_run(), find_port_types_run(), imp_range_trans_run(), inc_dom_trans_run(), inc_mount_run(), inc_net_access_run(), roles_wo_allow_run(), roles_wo_types_run(), roles_wo_users_run(), sechk_module_free(), spurious_audit_run(), types_wo_allow_run(), unreachable_doms_run(), users_wo_roles_run(), and xx_run().

00275 {
00276         if (!res || !(*res))
00277                 return;
00278 
00279         free((*res)->test_name);
00280         apol_vector_destroy(&((*res)->items));
00281         free(*res);
00282         *res = NULL;
00283 }

void sechk_item_free void *  item  ) 
 

Free all memory used by a result item.

Parameters:
item The result item to free.

Definition at line 285 of file sechecker.c.

References apol_vector_destroy(), sechk_item::item, sechk_item::item_free_fn, sechk_item::proof, and sechk_item_t.

Referenced by attribs_wo_rules_run(), attribs_wo_types_run(), domain_and_file_run(), domains_wo_roles_run(), find_assoc_types_run(), find_domains_run(), find_file_types_run(), find_net_domains_run(), find_netif_types_run(), find_node_types_run(), find_port_types_run(), imp_range_trans_run(), inc_dom_trans_run(), inc_mount_run(), inc_net_access_run(), roles_wo_allow_run(), roles_wo_types_run(), roles_wo_users_run(), spurious_audit_run(), types_wo_allow_run(), unreachable_doms_run(), users_wo_roles_run(), and xx_run().

00286 {
00287         sechk_item_t *it = (sechk_item_t *) item;
00288 
00289         if (!item)
00290                 return;
00291 
00292         apol_vector_destroy(&it->proof);
00293         if (it->item_free_fn)
00294                 it->item_free_fn(it->item);
00295 
00296         free(item);
00297 }

void sechk_proof_free void *  proof  ) 
 

Free all memory used by a result item proof element.

Parameters:
proof The proof element to free.

Definition at line 299 of file sechecker.c.

References sechk_proof::elem, sechk_proof::elem_free_fn, sechk_proof_t, sechk_proof::text, and sechk_proof::xml_out.

Referenced by attribs_wo_rules_run(), attribs_wo_types_run(), domain_and_file_run(), domains_wo_roles_run(), find_assoc_types_run(), find_domains_run(), find_file_types_run(), find_net_domains_run(), find_netif_types_run(), find_node_types_run(), find_port_types_run(), imp_range_trans_run(), inc_dom_trans_run(), inc_mount_run(), inc_net_access_run(), roles_wo_allow_run(), roles_wo_types_run(), roles_wo_users_run(), spurious_audit_run(), types_wo_allow_run(), unreachable_doms_run(), users_wo_roles_run(), and xx_run().

00300 {
00301         sechk_proof_t *p = (sechk_proof_t *) proof;
00302 
00303         if (!proof)
00304                 return;
00305 
00306         free(p->text);
00307         free(p->xml_out);
00308 
00309         if (p->elem_free_fn)
00310                 p->elem_free_fn(p->elem);
00311 
00312         free(proof);
00313 }

sechk_fn_t* sechk_fn_new void   ) 
 

Create a new module function structre.

Returns:
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.

Definition at line 315 of file sechecker.c.

References sechk_fn_t.

Referenced by attribs_wo_rules_register(), attribs_wo_types_register(), domain_and_file_register(), domains_wo_roles_register(), find_assoc_types_register(), find_domains_register(), find_file_types_register(), find_net_domains_register(), find_netif_types_register(), find_node_types_register(), find_port_types_register(), imp_range_trans_register(), inc_dom_trans_register(), inc_mount_register(), inc_net_access_register(), roles_wo_allow_register(), roles_wo_types_register(), roles_wo_users_register(), spurious_audit_register(), types_wo_allow_register(), unreachable_doms_register(), users_wo_roles_register(), and xx_register().

00316 {
00317         /* no initialization needed here */
00318         return (sechk_fn_t *) calloc(1, sizeof(sechk_fn_t));
00319 }

sechk_name_value_t* sechk_name_value_new const char *  name,
const char *  value
 

Create and initialize a new name value pair.

The incoming strings are duplicated.

Parameters:
name Name to assign.
value Value to assign to name.
Returns:
A newly allocated name value pair of NULL on error; if the call fails errno will be set.

Definition at line 321 of file sechecker.c.

References sechk_name_value::name, sechk_name_value_t, and sechk_name_value::value.

Referenced by attribs_wo_rules_register(), attribs_wo_types_register(), domain_and_file_register(), domains_wo_roles_register(), find_domains_register(), find_file_types_register(), find_net_domains_register(), imp_range_trans_register(), inc_dom_trans_register(), inc_net_access_register(), sechk_lib_module_clear_option(), sechk_lib_process_xml_node(), unreachable_doms_register(), and xx_register().

00322 {
00323         sechk_name_value_t *nv;
00324         int error;
00325 
00326         nv = (sechk_name_value_t *) calloc(1, sizeof(sechk_name_value_t));
00327         if (!nv)
00328                 return NULL;
00329         if (name) {
00330                 nv->name = strdup(name);
00331                 if (!nv->name) {
00332                         error = errno;
00333                         goto err;
00334                 }
00335         }
00336         if (value) {
00337                 nv->value = strdup(value);
00338                 if (!nv->value) {
00339                         error = errno;
00340                         goto err;
00341                 }
00342         }
00343 
00344         return nv;
00345 
00346       err:
00347         free(nv->name);
00348         free(nv);
00349         errno = error;
00350         return NULL;
00351 }

sechk_result_t* sechk_result_new void   ) 
 

Create a new results structure.

Returns:
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.

Definition at line 353 of file sechecker.c.

References sechk_result_t.

Referenced by attribs_wo_rules_run(), attribs_wo_types_run(), domain_and_file_run(), domains_wo_roles_run(), find_assoc_types_run(), find_domains_run(), find_file_types_run(), find_net_domains_run(), find_netif_types_run(), find_node_types_run(), find_port_types_run(), imp_range_trans_run(), inc_dom_trans_run(), inc_mount_run(), inc_net_access_run(), roles_wo_allow_run(), roles_wo_types_run(), roles_wo_users_run(), spurious_audit_run(), types_wo_allow_run(), unreachable_doms_run(), users_wo_roles_run(), and xx_run().

00354 {
00355         /* initilization to zero is sufficient here */
00356         return (sechk_result_t *) calloc(1, sizeof(sechk_result_t));
00357 }

sechk_item_t* sechk_item_new free_fn_t  fn  ) 
 

Create a new result item.

Parameters:
fn Function to be used to free the item stored.
Returns:
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.

Definition at line 359 of file sechecker.c.

References sechk_item::item_free_fn, and sechk_item_t.

Referenced by attribs_wo_rules_run(), attribs_wo_types_run(), domain_and_file_run(), domains_wo_roles_run(), find_assoc_types_run(), find_domains_run(), find_file_types_run(), find_net_domains_run(), find_netif_types_run(), find_node_types_run(), find_port_types_run(), imp_range_trans_run(), inc_dom_trans_run(), inc_mount_run(), inc_net_access_run(), roles_wo_allow_run(), roles_wo_types_run(), roles_wo_users_run(), spurious_audit_run(), types_wo_allow_run(), unreachable_doms_run(), and users_wo_roles_run().

00360 {
00361         sechk_item_t *it = NULL;
00362 
00363         it = (sechk_item_t *) calloc(1, sizeof(sechk_item_t));
00364         if (!it)
00365                 return NULL;
00366         it->item_free_fn = fn;
00367 
00368         return it;
00369 }

sechk_proof_t* sechk_proof_new free_fn_t  fn  ) 
 

Create a new result item proof entry.

Parameters:
fn Function to be used to free the element stored.
Returns:
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.

Definition at line 371 of file sechecker.c.

References sechk_proof::elem_free_fn, sechk_proof_t, and sechk_proof::type.

Referenced by attribs_wo_rules_run(), attribs_wo_types_run(), domain_and_file_run(), domains_wo_roles_run(), find_assoc_types_run(), find_domains_run(), find_file_types_run(), find_net_domains_run(), find_netif_types_run(), find_node_types_run(), find_port_types_run(), imp_range_trans_run(), inc_dom_trans_run(), inc_mount_run(), inc_net_access_run(), roles_wo_allow_run(), roles_wo_types_run(), roles_wo_users_run(), sechk_proof_copy(), spurious_audit_run(), types_wo_allow_run(), unreachable_doms_run(), and users_wo_roles_run().

00372 {
00373         sechk_proof_t *proof = NULL;
00374         proof = (sechk_proof_t *) calloc(1, sizeof(sechk_proof_t));
00375         if (!proof)
00376                 return NULL;
00377         proof->type = SECHK_ITEM_NONE;
00378         proof->elem_free_fn = fn;
00379         return proof;
00380 }

int sechk_lib_load_policy apol_policy_path_t policy_mods,
sechk_lib_t lib
 

Load the policy the library will analyze.

Parameters:
policy_mods Policy path object to use to load the policy.
lib The library into which to load the policy.
Returns:
0 on success and < 0 on failure.

Definition at line 382 of file sechecker.c.

References apol_policy_create_from_policy_path(), apol_policy_destroy(), apol_policy_path_create(), apol_policy_path_get_primary(), apol_policy_path_t, apol_policy_path_to_string(), APOL_POLICY_PATH_TYPE_MONOLITHIC, sechk_lib::outputformat, sechk_lib::policy, sechk_lib::policy_path, qpol_default_policy_find(), QPOL_POLICY_OPTION_MATCH_SYSTEM, and sechk_lib_t.

Referenced by main().

00383 {
00384 
00385         char *default_policy_path = NULL;
00386         int retv = -1;
00387 
00388         if (!lib)
00389                 return -1;
00390 
00391         /* if no policy is given, attempt to find default */
00392         if (!policy_mods) {
00393                 retv = qpol_default_policy_find(&default_policy_path);
00394                 if (retv < 0) {
00395                         fprintf(stderr, "Default policy search failed: %s\n", strerror(errno));
00396                         return -1;
00397                 } else if (retv != 0) {
00398                         fprintf(stderr, "No default policy found.\n");
00399                         return -1;
00400                 }
00401                 policy_mods = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, default_policy_path, NULL);
00402                 lib->policy = apol_policy_create_from_policy_path(policy_mods, QPOL_POLICY_OPTION_MATCH_SYSTEM, NULL, NULL);
00403                 if (lib->policy == NULL) {
00404                         fprintf(stderr, "Error: failed opening default policy\n");
00405                         return -1;
00406                 }
00407                 lib->policy_path = policy_mods;
00408                 if (!(lib->outputformat & SECHK_OUT_QUIET)) {
00409                         fprintf(stderr, "Using policy: %s\n", apol_policy_path_get_primary(lib->policy_path));
00410                 }
00411         } else {
00412                 lib->policy_path = policy_mods;
00413                 lib->policy = apol_policy_create_from_policy_path(policy_mods, 0, NULL, NULL);
00414                 if (lib->policy == NULL) {
00415                         fprintf(stderr, "Error: failed opening policy %s\n", apol_policy_path_to_string(lib->policy_path));
00416                         goto err;
00417                 }
00418         }
00419         return 0;
00420 
00421       err:
00422         apol_policy_destroy(&lib->policy);
00423         return -1;
00424 }

int sechk_lib_load_fc const char *  fcfilelocation,
sechk_lib_t lib
 

Load the file contexts file the library will use during analysis.

Parameters:
fcfilelocation Path of the file contexts file to load, or NULL to search for system default file contexts.
lib The library into which to load the file contexts.
Returns:
0 on success and < 0 on failure.

Definition at line 426 of file sechecker.c.

References sechk_lib::fc_entries, sechk_lib::fc_file, sechk_lib::fc_path, sechk_lib::outputformat, sechk_lib::policy, sechk_lib_t, sefs_default_file_contexts_get_path(), sefs_fcfile_create_from_file(), sefs_fclist_run_query(), sefs_fclist_t, sefs_query_create(), sefs_query_destroy(), sefs_query_t, and WARN.

Referenced by main().

00427 {
00428         int error = 0;
00429         char *default_fc_path = NULL;
00430         sefs_fclist_t *fcfile = NULL;
00431         sefs_query_t *q = NULL;
00432 
00433         /* if no policy we can't parse the fc file */
00434         if (!lib || !lib->policy) {
00435                 errno = EINVAL;
00436                 return -1;
00437         }
00438 
00439         /* if no file_contexts file is given attempt to find the default */
00440         if (!fcfilelocation) {
00441                 default_fc_path = sefs_default_file_contexts_get_path();
00442                 if (default_fc_path == NULL) {
00443                         error = errno;
00444                         WARN(lib->policy, "Unable to find default file_contexts file: %s", strerror(error));
00445                         errno = error;
00446                         return 0;      /* not fatal error until a module requires this to exist */
00447                 }
00448                 if (strcmp(default_fc_path, "") == 0) {
00449                         WARN(lib->policy, "%s", "The system has no default file_contexts file.");
00450                         free(default_fc_path);
00451                         errno = ENOSYS;
00452                         return 0;      /* not fatal error until a module requires this to exist */
00453                 }
00454                 fcfile = sefs_fcfile_create_from_file(default_fc_path, NULL, NULL);
00455                 q = sefs_query_create();
00456                 lib->fc_entries = sefs_fclist_run_query(fcfile, q);
00457                 if (!(lib->fc_entries)) {
00458                         error = errno;
00459                         WARN(lib->policy, "Unable to process file_contexts file %s.", default_fc_path);
00460                         free(default_fc_path);
00461                         errno = error;
00462                         return -1;
00463                 } else {
00464                         lib->fc_path = default_fc_path;
00465                         lib->fc_file = fcfile;
00466                 }
00467                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00468                         fprintf(stderr, "Using file contexts: %s\n", lib->fc_path);
00469                 }
00470         } else {
00471                 fcfile = sefs_fcfile_create_from_file(fcfilelocation, NULL, NULL);
00472                 q = sefs_query_create();
00473                 lib->fc_entries = sefs_fclist_run_query(fcfile, q);
00474                 if (!(lib->fc_entries)) {
00475                         error = errno;
00476                         WARN(lib->policy, "Unable to process file_contexts file %s.", fcfilelocation);
00477                         errno = error;
00478                         return -1;
00479                 } else {
00480                         lib->fc_path = strdup(fcfilelocation);
00481                         lib->fc_file = fcfile;
00482                 }
00483         }
00484         sefs_query_destroy(&q);
00485 
00486         return 0;
00487 }

int sechk_lib_register_modules const sechk_module_name_reg_t register_fns,
sechk_lib_t lib
 

Register all known modules with the library.

Parameters:
regiser_fns NULL terminated array of module registration structures.
lib The library with which to register the modules in the array.
Returns:
0 on success or < 0 on error; if the call fails, errno will be set and the library should be destroyed.

Definition at line 489 of file sechecker.c.

References apol_vector_get_size(), sechk_module_name_reg::fn, sechk_lib::modules, sechk_lib_t, sechk_module_name_reg_t, sechk_register_fn_t, and sechk_register_list_get_num_modules().

Referenced by sechk_lib_new().

00490 {
00491         int retv, error = 0;
00492         size_t i;
00493         sechk_register_fn_t fn = NULL;
00494         if (!register_fns || !lib) {
00495                 fprintf(stderr, "Error: could not register modules\n");
00496                 errno = EINVAL;
00497                 return -1;
00498         }
00499         if (apol_vector_get_size(lib->modules) != sechk_register_list_get_num_modules()) {
00500                 fprintf(stderr,
00501                         "Error: the number of registered modules (%zd) does not match the number of modules in the configuration file (%zd).\n",
00502                         sechk_register_list_get_num_modules(), apol_vector_get_size(lib->modules));
00503                 errno = EINVAL;
00504                 return -1;
00505         }
00506         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00507                 fn = (sechk_register_fn_t) (register_fns[i].fn);
00508                 retv = fn(lib);
00509                 if (retv) {
00510                         error = errno;
00511                         fprintf(stderr, "Error: could not register module #%zd\n", i);
00512                         errno = error;
00513                         return retv;
00514                 }
00515         }
00516 
00517         return 0;
00518 }

sechk_mod_fn_t sechk_lib_get_module_function const char *  module_name,
const char *  function_name,
const sechk_lib_t lib
 

Get a pointer to a function registered for a module.

Parameters:
module_name Name of the module containing the function.
function_name Name of the function with out any module prefix.
lib The library containing the module.
Returns:
A pointer to the requested function, or NULL if either the module or the function cannot be found.

Definition at line 520 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_fn::fn, sechk_module::functions, sechk_fn::name, sechk_fn_t, sechk_lib_get_module(), sechk_lib_t, sechk_mod_fn_t, and sechk_module_t.

Referenced by domain_and_file_run(), domains_wo_roles_run(), inc_dom_trans_run(), inc_net_access_run(), sechk_lib_get_module_result(), sechk_lib_init_modules(), sechk_lib_print_modules_report(), sechk_lib_run_modules(), and unreachable_doms_run().

00521 {
00522         sechk_module_t *mod = NULL;
00523         sechk_fn_t *fn_struct = NULL;
00524         size_t i;
00525 
00526         if (!module_name || !function_name || !lib) {
00527                 fprintf(stderr, "Error: failed to get function from module\n");
00528                 errno = EINVAL;
00529                 return NULL;
00530         }
00531 
00532         /* find the correct module */
00533         mod = sechk_lib_get_module(module_name, lib);
00534         if (!mod) {
00535                 fprintf(stderr, "Error: %s: no such module\n", module_name);
00536                 errno = ENOENT;
00537                 return NULL;
00538         }
00539 
00540         /* find function in module */
00541         for (i = 0; i < apol_vector_get_size(mod->functions); i++) {
00542                 fn_struct = apol_vector_get_element(mod->functions, i);
00543                 if (!strcmp(fn_struct->name, function_name))
00544                         break;
00545                 else
00546                         fn_struct = NULL;
00547         }
00548         if (!fn_struct) {
00549                 fprintf(stderr, "Error: %s: no such function in module %s\n", function_name, module_name);
00550                 errno = ENOENT;
00551                 return NULL;
00552         }
00553 
00554         return fn_struct->fn;
00555 }

sechk_module_t* sechk_lib_get_module const char *  module_name,
const sechk_lib_t lib
 

Find a module in the library.

Parameters:
module_name The name of the module to find.
lib The library to search.
Returns:
A pointer to the module or NULL if not found.

Definition at line 557 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_lib::modules, sechk_module::name, sechk_lib_t, and sechk_module_t.

Referenced by attribs_wo_rules_register(), attribs_wo_types_register(), domain_and_file_register(), domain_and_file_run(), domains_wo_roles_register(), domains_wo_roles_run(), find_assoc_types_register(), find_domains_register(), find_file_types_register(), find_net_domains_register(), find_netif_types_register(), find_node_types_register(), find_port_types_register(), imp_range_trans_register(), inc_dom_trans_register(), inc_dom_trans_run(), inc_mount_register(), inc_net_access_register(), inc_net_access_run(), roles_wo_allow_register(), roles_wo_types_register(), roles_wo_users_register(), sechk_lib_check_dependency(), sechk_lib_get_module_function(), spurious_audit_register(), types_wo_allow_register(), unreachable_doms_register(), unreachable_doms_run(), users_wo_roles_register(), and xx_register().

00558 {
00559         size_t i;
00560         sechk_module_t *mod = NULL;
00561 
00562         if (!module_name || !lib) {
00563                 fprintf(stderr, "Error: failed to get module\n");
00564                 errno = EINVAL;
00565                 return NULL;
00566         }
00567 
00568         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00569                 mod = apol_vector_get_element(lib->modules, i);
00570                 if (!(mod->name))
00571                         continue;
00572                 if (!strcmp(mod->name, module_name))
00573                         return mod;
00574         }
00575         fprintf(stderr, "Error: %s: no such module\n", module_name);
00576         errno = ENOENT;
00577         return NULL;
00578 }

sechk_result_t* sechk_lib_get_module_result const char *  module_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.

Parameters:
module_name Name of the module containing the results.
lib The library containing the module.
Returns:
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.

Definition at line 580 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_lib::modules, sechk_module::name, sechk_lib::policy, sechk_module::result, sechk_lib_get_module_function(), sechk_lib_t, SECHK_MOD_FN_RUN, sechk_mod_fn_t, sechk_module_t, and sechk_result_t.

Referenced by domain_and_file_run(), domains_wo_roles_run(), inc_dom_trans_run(), inc_net_access_run(), and unreachable_doms_run().

00581 {
00582         size_t i;
00583         sechk_module_t *mod = NULL;
00584         sechk_mod_fn_t run = NULL;
00585 
00586         if (!module_name || !lib) {
00587                 fprintf(stderr, "Error: failed to get module result\n");
00588                 errno = EINVAL;
00589                 return NULL;
00590         }
00591 
00592         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00593                 mod = apol_vector_get_element(lib->modules, i);
00594                 if (!(mod->name))
00595                         continue;
00596                 if (strcmp(mod->name, module_name))
00597                         continue;
00598                 if (!(mod->result)) {
00599                         if (!(run = sechk_lib_get_module_function(module_name, SECHK_MOD_FN_RUN, lib)) ||
00600                             run(mod, lib->policy, NULL) < 0) {
00601                                 return NULL;    /* run or get function will set errno */
00602                         }
00603                 }
00604                 return mod->result;
00605         }
00606         fprintf(stderr, "Error: %s: no such module\n", module_name);
00607         errno = ENOENT;
00608         return NULL;
00609 }

int sechk_lib_check_module_dependencies 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.

Parameters:
lib The library containing the modules to check.
Returns:
0 on success and < 0 on error; if the call fails, errno will be set.

Definition at line 611 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_module::dependencies, ERR, sechk_lib::modules, sechk_name_value::name, sechk_module::name, sechk_lib::policy, sechk_lib_check_dependency(), sechk_lib_get_module_idx(), sechk_lib_t, sechk_module_t, sechk_name_value_t, sechk_module::selected, and sechk_name_value::value.

Referenced by main().

00612 {
00613         int idx = 0;
00614         size_t i, j;
00615         bool test = true, done = false, *processed = NULL;
00616         sechk_name_value_t *nv = NULL;
00617         sechk_module_t *mod = NULL, *dep = NULL;
00618 
00619         if (!lib) {
00620                 fprintf(stderr, "Error: invalid module library\n");
00621                 errno = EINVAL;
00622                 return -1;
00623         }
00624 
00625         processed = (bool *) calloc(apol_vector_get_size(lib->modules), sizeof(bool));
00626         if (!processed) {
00627                 perror(NULL);
00628                 return -1;
00629         }
00630 
00631         /* check dependencies and select dependencies to be run */
00632         while (!done) {
00633                 for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00634                         if (processed[i])
00635                                 continue;
00636                         mod = apol_vector_get_element(lib->modules, i);
00637                         if (!mod->selected) {
00638                                 processed[i] = true;
00639                                 continue;
00640                         }
00641                         for (j = 0; j < apol_vector_get_size(mod->dependencies); j++) {
00642                                 nv = apol_vector_get_element(mod->dependencies, j);
00643                                 test = false;
00644                                 test = sechk_lib_check_dependency(nv, lib);
00645                                 if (!test) {
00646                                         ERR(lib->policy, "Dependency %s not found for %s.", nv->name, mod->name);
00647                                         free(processed);
00648                                         errno = ENOENT;
00649                                         return -1;
00650                                 }
00651                                 idx = sechk_lib_get_module_idx(nv->value, lib);
00652                                 dep = apol_vector_get_element(lib->modules, idx);
00653                                 if (!dep->selected) {
00654                                         processed[idx] = false;
00655                                         dep->selected = true;
00656                                 }
00657                         }
00658                         processed[i] = true;
00659                 }
00660                 for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00661                         if (!processed[i])
00662                                 break;
00663                 }
00664                 if (i == apol_vector_get_size(lib->modules))
00665                         done = true;
00666         }
00667         free(processed);
00668 
00669         return 0;
00670 }

int sechk_lib_check_module_requirements 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()

Parameters:
lib The library containing the modules to check.
Returns:
0 on success and < 0 on error; if the call fails, errno will be set.

Definition at line 672 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), ERR, sechk_lib::modules, sechk_module::name, sechk_lib::outputformat, sechk_lib::policy, sechk_module::requirements, sechk_lib_check_requirement(), sechk_lib_t, sechk_module_t, sechk_name_value_t, and sechk_module::selected.

Referenced by main().

00673 {
00674         int retv = 0;
00675         size_t i, j;
00676         bool test = true;
00677         sechk_name_value_t *nv = NULL;
00678         sechk_module_t *mod = NULL;
00679 
00680         /* check requirements for all selected modules */
00681         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00682                 mod = apol_vector_get_element(lib->modules, i);
00683                 if (!mod->selected)
00684                         continue;
00685                 for (j = 0; j < apol_vector_get_size(mod->requirements); j++) {
00686                         nv = apol_vector_get_element(mod->requirements, j);
00687                         test = false;
00688                         test = sechk_lib_check_requirement(nv, lib);
00689                         if (!test) {
00690                                 /* if we're in quiet mode then we quit on a failed requirement */
00691                                 if (lib->outputformat & (SECHK_OUT_QUIET)) {
00692                                         errno = ENOTSUP;
00693                                         return -1;
00694                                 } else {
00695                                         /* otherwise we just disable this module and keep testing */
00696                                         ERR(lib->policy, "Requirements not met for %s.", mod->name);
00697                                         mod->selected = false;
00698                                         retv = -1;
00699                                         break;
00700                                 }
00701                         }
00702                 }
00703         }
00704         return retv;
00705 }

int sechk_lib_init_modules 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.

Parameters:
lib The library containing the modules to initialize.
Returns:
0 on success and < 0 on failure; if the call fails, errno will be set and the library should be destroyed.

Definition at line 707 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_lib::modules, sechk_module::name, sechk_lib::policy, sechk_lib_get_module_function(), sechk_lib_t, SECHK_MOD_FN_INIT, sechk_mod_fn_t, sechk_module_t, and sechk_module::selected.

Referenced by main().

00708 {
00709         int retv, error = 0;
00710         size_t i;
00711         sechk_module_t *mod = NULL;
00712         sechk_mod_fn_t init_fn = NULL;
00713 
00714         if (lib == NULL || lib->modules == NULL) {
00715                 errno = EINVAL;
00716                 return -1;
00717         }
00718         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00719                 mod = apol_vector_get_element(lib->modules, i);
00720                 if (!mod->selected)
00721                         continue;
00722                 init_fn = sechk_lib_get_module_function(mod->name, SECHK_MOD_FN_INIT, lib);
00723                 if (!init_fn) {
00724                         error = errno;
00725                         fprintf(stderr, "Error: could not initialize module %s\n", mod->name);
00726                         errno = error;
00727                         return -1;
00728                 }
00729                 retv = init_fn(mod, lib->policy, NULL);
00730                 if (retv)
00731                         return retv;
00732         }
00733 
00734         return 0;
00735 }

int sechk_lib_run_modules sechk_lib_t lib  ) 
 

Run all selected modules.

The modules must have been initialized.

Parameters:
lib The library containing the modules to run.
Returns:
0 on success or < 0 on error. Note that in quiet mode this function is considered to fail if a module finds results.

Definition at line 737 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), ERR, sechk_lib::minsev, sechk_lib::modules, sechk_module::name, sechk_lib::outputformat, sechk_lib::policy, sechk_lib_compare_sev(), sechk_lib_get_module_function(), sechk_lib_t, SECHK_MOD_FN_RUN, sechk_mod_fn_t, sechk_module_t, sechk_module::selected, and sechk_module::severity.

Referenced by main().

00738 {
00739         int retv, num_selected = 0, rc = 0;
00740         size_t i;
00741         sechk_module_t *mod = NULL;
00742         sechk_mod_fn_t run_fn = NULL;
00743 
00744         if (!lib) {
00745                 fprintf(stderr, "Error: invalid library\n");
00746                 errno = EINVAL;
00747                 return -1;
00748         }
00749         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00750                 mod = apol_vector_get_element(lib->modules, i);
00751                 if (mod->selected)
00752                         num_selected++;
00753         }
00754         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00755                 mod = apol_vector_get_element(lib->modules, i);
00756                 /* if module is "off" do not run */
00757                 if (!mod->selected)
00758                         continue;
00759                 /* if module is below the minsev do not run unless its exactly one module */
00760                 if (lib->minsev && sechk_lib_compare_sev(mod->severity, lib->minsev) < 0 && num_selected != 1)
00761                         continue;
00762                 assert(mod->name);
00763                 run_fn = sechk_lib_get_module_function(mod->name, SECHK_MOD_FN_RUN, lib);
00764                 if (!run_fn) {
00765                         ERR(lib->policy, "Could not run module %s.", mod->name);
00766                         errno = ENOTSUP;
00767                         return -1;
00768                 }
00769                 retv = run_fn(mod, lib->policy, NULL);
00770 
00771                 if (retv < 0) {
00772                         /* module failure */
00773                         /* only put output failures if we are not in quiet mode */
00774                         if (lib->outputformat & ~(SECHK_OUT_QUIET))
00775                                 ERR(lib->policy, "Module %s failed.", mod->name);
00776                         rc = -1;
00777                 } else if (retv > 0) {
00778                         /* a module looking for policy errors has found one
00779                          * if in quiet mode stop since running additional
00780                          * modules will not change the return code */
00781                         if (lib->outputformat & (SECHK_OUT_QUIET))
00782                                 return -1;
00783                 }
00784         }
00785         return rc;
00786 }

int sechk_lib_print_modules_report sechk_lib_t lib  ) 
 

Print a report of all selected modules' results to stdout.

Modules must have been run.

Parameters:
lib The library containing the modules with results to print.
Returns:
0 on success and < 0 on error.

Definition at line 788 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_module::detailed_description, ERR, sechk_lib::minsev, sechk_lib::modules, sechk_module::name, sechk_module::outputformat, sechk_lib::policy, sechk_lib_compare_sev(), sechk_lib_get_module_function(), sechk_lib_t, SECHK_MOD_FN_PRINT, sechk_mod_fn_t, sechk_module_t, SECHK_OUT_NONE, sechk_module::selected, and sechk_module::severity.

Referenced by main().

00789 {
00790         int retv, num_selected = 0, rc = 0;
00791         size_t i;
00792         sechk_module_t *mod = NULL;
00793         sechk_mod_fn_t print_fn = NULL;
00794 
00795         if (!lib) {
00796                 fprintf(stderr, "Error: invalid library\n");
00797                 errno = EINVAL;
00798                 return -1;
00799         }
00800         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00801                 mod = apol_vector_get_element(lib->modules, i);
00802                 if (mod->selected)
00803                         num_selected++;
00804         }
00805         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
00806                 mod = apol_vector_get_element(lib->modules, i);
00807                 /* if module is "off" or its output format is quiet continue */
00808                 if (!mod->selected || mod->outputformat & SECHK_OUT_QUIET)
00809                         continue;
00810                 /* if module is below the minsev do not print unless exactly one module is selected */
00811                 if (lib->minsev && sechk_lib_compare_sev(mod->severity, lib->minsev) < 0 && num_selected != 1)
00812                         continue;
00813                 /* if module is the only selected one make sure output is generated */
00814                 if (mod->outputformat == SECHK_OUT_NONE && num_selected == 1)
00815                         mod->outputformat = SECHK_OUT_SHORT;
00816                 assert(mod->name);
00817                 printf("\nModule name: %s\tSeverity: %s\n%s\n", mod->name, mod->severity, mod->detailed_description);
00818                 print_fn = sechk_lib_get_module_function(mod->name, SECHK_MOD_FN_PRINT, lib);
00819                 if (!print_fn) {
00820                         ERR(lib->policy, "Could not get print function for module %s.", mod->name);
00821                         errno = ENOTSUP;
00822                         return -1;
00823                 }
00824                 retv = print_fn(mod, lib->policy, NULL);
00825                 if (retv) {
00826                         fprintf(stderr, "Error: unable to print results for module %s \n", mod->name);
00827                         rc = -1;
00828                 }
00829         }
00830 
00831         return rc;
00832 }

bool sechk_lib_check_requirement sechk_name_value_t req,
sechk_lib_t lib
 

Check that the library can meet a single requirement.

Parameters:
req The requirement to check.
lib The library to query.
Returns:
1 if the requirement is met, and 0 if it is either unmet or if the library is unable to determine.

Definition at line 834 of file sechecker.c.

References apol_policy_get_qpol(), apol_vector_get_size(), ERR, sechk_lib::fc_entries, sechk_name_value::name, sechk_lib::outputformat, sechk_lib::policy, QPOL_CAP_ATTRIB_NAMES, QPOL_CAP_CONDITIONALS, QPOL_CAP_LINE_NUMBERS, QPOL_CAP_MLS, QPOL_CAP_MODULES, QPOL_CAP_RULES_LOADED, QPOL_CAP_SYN_RULES, qpol_policy_has_capability(), sechk_lib_t, sechk_name_value_t, SECHK_REQ_CAP_ATTRIB_NAMES, SECHK_REQ_CAP_CONDITIONALS, SECHK_REQ_CAP_LINE_NOS, SECHK_REQ_CAP_MLS, SECHK_REQ_CAP_MODULES, SECHK_REQ_CAP_RULES_LOADED, SECHK_REQ_CAP_SYN_RULES, SECHK_REQ_DEFAULT_CONTEXTS, SECHK_REQ_FILE_CONTEXTS, SECHK_REQ_POLICY_CAP, SECHK_REQ_SYS_MLS, SECHK_REQ_SYS_SELINUX, SECHK_REQ_SYSTEM, and sechk_name_value::value.

Referenced by sechk_lib_check_module_requirements().

00835 {
00836         struct stat stat_buf;
00837 
00838         if (!req) {
00839                 fprintf(stderr, "Error: invalid requirement\n");
00840                 errno = EINVAL;
00841                 return false;
00842         }
00843 
00844         if (!lib || !lib->policy) {
00845                 fprintf(stderr, "Error: invalid library\n");
00846                 errno = EINVAL;
00847                 return false;
00848         }
00849 
00850         if (!strcmp(req->name, SECHK_REQ_POLICY_CAP)) {
00851                 if (!strcmp(req->value, SECHK_REQ_CAP_ATTRIB_NAMES)) {
00852                         if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_ATTRIB_NAMES)) {
00853                                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00854                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00855                                 }
00856                                 return false;
00857                         }
00858                 } else if (!strcmp(req->value, SECHK_REQ_CAP_MLS)) {
00859                         if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_MLS)) {
00860                                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00861                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00862                                 }
00863                                 return false;
00864                         }
00865                 } else if (!strcmp(req->value, SECHK_REQ_CAP_SYN_RULES)) {
00866                         if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_SYN_RULES)) {
00867                                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00868                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00869                                 }
00870                                 return false;
00871                         }
00872                 } else if (!strcmp(req->value, SECHK_REQ_CAP_RULES_LOADED)) {
00873                         if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_RULES_LOADED)) {
00874                                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00875                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00876                                 }
00877                                 return false;
00878                         }
00879                 } else if (!strcmp(req->value, SECHK_REQ_CAP_LINE_NOS)) {
00880                         if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_LINE_NUMBERS)) {
00881                                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00882                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00883                                 }
00884                                 return false;
00885                         }
00886                 } else if (!strcmp(req->value, SECHK_REQ_CAP_CONDITIONALS)) {
00887                         if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_CONDITIONALS)) {
00888                                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00889                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00890                                 }
00891                                 return false;
00892                         }
00893                 } else if (!strcmp(req->value, SECHK_REQ_CAP_MODULES)) {
00894                         if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_MODULES)) {
00895                                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00896                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00897                                 }
00898                                 return false;
00899                         }
00900                 } else {
00901                         ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value);
00902                         return false;
00903                 }
00904         } else if (!strcmp(req->name, SECHK_REQ_DEFAULT_CONTEXTS)) {
00905 #ifdef LIBSELINUX
00906                 if (stat(selinux_default_context_path(), &stat_buf) < 0) {
00907                         if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00908                                 ERR(lib->policy, "Requirement %s not met.", req->name);
00909                         }
00910                         return false;
00911                 }
00912 #else
00913                 if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00914                         ERR(lib->policy, "Checking requirement %s: %s", req->name, strerror(ENOTSUP));
00915                 }
00916                 return false;
00917 #endif
00918         } else if (!strcmp(req->name, SECHK_REQ_FILE_CONTEXTS)) {
00919                 if (!lib->fc_entries || !apol_vector_get_size(lib->fc_entries)) {
00920                         if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
00921                                 ERR(lib->policy, "Requirement %s not met.", req->name);
00922                         }
00923                 }
00924         } else if (!strcmp(req->name, SECHK_REQ_SYSTEM)) {
00925                 if (!strcmp(req->value, SECHK_REQ_SYS_SELINUX)) {
00926 #ifdef LIBSELINUX
00927                         if (!is_selinux_mls_enabled() || !is_selinux_enabled()) {
00928                                 if (lib->outputformat & ~(SECHK_OUT_QUIET))
00929                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00930                                 return false;
00931                         }
00932 #else
00933                         if (lib->outputformat & ~(SECHK_OUT_QUIET))
00934                                 ERR(lib->policy, "Checking requirement %s, %s: %s", req->name, req->value, strerror(ENOTSUP));
00935                         return false;
00936 #endif
00937                 } else if (!strcmp(req->value, SECHK_REQ_SYS_MLS)) {
00938 #ifdef LIBSELINUX
00939                         if (!is_selinux_mls_enabled() || !is_selinux_enabled()) {
00940                                 if (lib->outputformat & ~(SECHK_OUT_QUIET))
00941                                         ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
00942                                 return false;
00943                         }
00944 #else
00945                         if (lib->outputformat & ~(SECHK_OUT_QUIET))
00946                                 ERR(lib->policy, "Checking requirement %s, %s: %s", req->name, req->value, strerror(ENOTSUP));
00947                         return false;
00948 #endif
00949                 } else {
00950                         ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value);
00951                         return false;
00952                 }
00953         } else {
00954                 ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value);
00955                 return false;
00956         }
00957 
00958         return true;
00959 }

bool sechk_lib_check_dependency sechk_name_value_t dep,
sechk_lib_t lib
 

Check that the library can meet a single module dependency.

Parameters:
dep The dependency to check.
lib The library to query for the existence of the dependency.
Returns:
1 if the dependency exists, and 0 if it either does not or if the library is unable to determine.

Definition at line 961 of file sechecker.c.

References sechk_lib_get_module(), sechk_lib_t, sechk_module_t, sechk_name_value_t, and sechk_name_value::value.

Referenced by sechk_lib_check_module_dependencies().

00962 {
00963         sechk_module_t *mod = NULL;
00964 
00965         if (!dep || !dep->value) {
00966                 fprintf(stderr, "Error: invalid dependency\n");
00967                 errno = EINVAL;
00968                 return false;
00969         }
00970 
00971         if (!lib) {
00972                 fprintf(stderr, "Error: invalid library\n");
00973                 errno = EINVAL;
00974                 return false;
00975         }
00976 
00977         mod = sechk_lib_get_module(dep->value, lib);
00978         if (!mod) {
00979                 fprintf(stderr, "Error: could not find dependency %s\n", dep->value);
00980                 errno = ENOENT;
00981                 return false;
00982         }
00983 
00984         return true;
00985 }

int sechk_lib_set_outputformat unsigned char  out,
sechk_lib_t lib
 

Set the default output format for the library.

Parameters:
out The format to use as a bit-wise or of SECHK_OUT_*.
lib The library for which to set the output format.
Returns:
0 on success and < 0 on failure; if the call fails, errno will be set.

Definition at line 987 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_lib::modules, sechk_lib::outputformat, sechk_module::outputformat, sechk_lib_t, and sechk_module_t.

Referenced by main().

00988 {
00989         size_t i;
00990         sechk_module_t *mod = NULL;
00991 
00992         if (!lib || !out) {
00993                 errno = EINVAL;
00994                 return -1;
00995         }
00996 
00997         lib->outputformat = out;
00998 
00999         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
01000                 mod = apol_vector_get_element(lib->modules, i);
01001                 mod->outputformat = out;
01002         }
01003 
01004         return 0;
01005 }

sechk_proof_t* sechk_proof_copy sechk_proof_t orig  ) 
 

Copy a proof element.

Note: the element in the proof is a shallow copy.

Parameters:
orig The original proof to copy.
Returns:
a copy of the proof or NULL on error. If the call fails, errno will be set.

Definition at line 1007 of file sechecker.c.

References sechk_proof::elem, sechk_proof::elem_free_fn, sechk_proof_new(), sechk_proof_t, sechk_proof::text, sechk_proof::type, and sechk_proof::xml_out.

01008 {
01009         sechk_proof_t *copy = NULL;
01010 
01011         if (!orig)
01012                 return NULL;
01013 
01014         copy = sechk_proof_new(orig->elem_free_fn);
01015         if (!copy) {
01016                 fprintf(stderr, "Error: out of memory\n");
01017                 errno = ENOMEM;
01018                 return NULL;
01019         }
01020 
01021         copy->elem = orig->elem;
01022         copy->type = orig->type;
01023         copy->text = strdup(orig->text);
01024         if (!copy->text) {
01025                 fprintf(stderr, "Error: out of memory\n");
01026                 errno = ENOMEM;
01027                 return NULL;
01028         }
01029         copy->xml_out = NULL;          /* TODO: do xml string copy here */
01030 
01031         return copy;
01032 }

int sechk_lib_load_profile const char *  prof_name,
sechk_lib_t lib
 

Load a profile containing module options.

Parameters:
prof_name Name of a known installed profile or the absolute path to a user created profile.
lib The library containing the modules specified in the profile.
Returns:
0 on success and < 0 on failure; if the call fails errno will be set and the library should be destroyed.

Definition at line 1034 of file sechecker.c.

References apol_file_find(), apol_vector_get_element(), apol_vector_get_size(), sechk_lib::modules, sechk_module::outputformat, PROF_SUBDIR, sechk_lib_parse_profile, sechk_lib_t, sechk_module_t, sechk_profile_name_reg_t, sechk_register_list_get_num_profiles(), sechk_register_list_get_profiles(), and sechk_module::selected.

Referenced by main().

01035 {
01036         const sechk_profile_name_reg_t *profiles;
01037         char *profpath = NULL, *prof_filename = NULL, *path = NULL;
01038         int retv = -1, error = 0;
01039         size_t num_profiles, i;
01040         sechk_module_t *mod = NULL;
01041 
01042         if (!prof_name || !lib) {
01043                 fprintf(stderr, "Error: invalid parameters to load profile\n");
01044                 return -1;
01045         }
01046 
01047         /* try to find the profile in our known profiles */
01048         profiles = sechk_register_list_get_profiles();
01049         num_profiles = sechk_register_list_get_num_profiles();
01050         for (i = 0; i < num_profiles; i++) {
01051                 if (strcmp(profiles[i].name, prof_name) == 0) {
01052                         break;
01053                 }
01054         }
01055         /* this is a known installed profile, look for it in that directory */
01056         if (i < num_profiles) {
01057                 /* first look in the local subdir using just PROF_SUBDIR/profile */
01058                 prof_filename = (char *)calloc(strlen(profiles[i].file) + 4 + strlen(PROF_SUBDIR), sizeof(char));
01059                 if (!prof_filename) {
01060                         fprintf(stderr, "Error: out of memory\n");
01061                         errno = ENOMEM;
01062                         return -1;
01063                 }
01064                 sprintf(prof_filename, "%s/%s", PROF_SUBDIR, profiles[i].file);
01065                 path = apol_file_find(prof_filename);
01066                 if (!path) {
01067                         free(prof_filename);
01068                         prof_filename = NULL;
01069                         prof_filename = (char *)calloc(strlen(PROFILE_INSTALL_DIR) + strlen(profiles[i].file) + 4, sizeof(char));
01070                         if (!prof_filename) {
01071                                 fprintf(stderr, "Error: out of memory\n");
01072                                 errno = ENOMEM;
01073                                 return -1;
01074                         }
01075                         sprintf(prof_filename, "%s/%s", PROFILE_INSTALL_DIR, profiles[i].file);
01076                         path = apol_file_find(prof_filename);
01077                         if (!path) {
01078                                 fprintf(stderr, "Error: Unable to find path\n");
01079                                 error = ENOENT;
01080                                 goto sechk_load_profile_error;
01081                         }
01082                 }
01083 
01084                 /* concatenate path and filename */
01085                 profpath = (char *)calloc(3 + strlen(path) + strlen(prof_filename), sizeof(char));
01086                 if (!profpath) {
01087                         fprintf(stderr, "Error: out of memory\n");
01088                         error = ENOMEM;
01089                         goto sechk_load_profile_error;
01090                 }
01091                 sprintf(profpath, "%s/%s", path, prof_filename);
01092                 free(path);
01093                 free(prof_filename);
01094                 path = NULL;
01095                 prof_filename = NULL;
01096         } else {
01097                 profpath = strdup(prof_name);
01098         }
01099 
01100         /* parse the profile */
01101         retv = sechk_lib_parse_profile(profpath, lib);
01102         if (retv) {
01103                 error = errno;
01104                 fprintf(stderr, "Error: could not parse profile\n");
01105                 goto sechk_load_profile_error;
01106         }
01107 
01108         /* turn off output for any unselected modules */
01109         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
01110                 mod = apol_vector_get_element(lib->modules, i);
01111                 if (!mod->selected)
01112                         mod->outputformat = SECHK_OUT_NONE;
01113         }
01114 
01115         free(profpath);
01116         free(prof_filename);
01117         free(path);
01118         return 0;
01119 
01120       sechk_load_profile_error:
01121         free(profpath);
01122         free(prof_filename);
01123         free(path);
01124         errno = error;
01125         return -1;
01126 }

int sechk_option_name_compare const void *  a,
const void *  b,
void *data   __attribute__((unused))
[static]
 

Definition at line 1128 of file sechecker.c.

References sechk_name_value::name, and sechk_name_value_t.

Referenced by sechk_lib_module_clear_option().

01129 {
01130         sechk_name_value_t *in_a, *in_b;
01131 
01132         in_a = (sechk_name_value_t *) a;
01133         in_b = (sechk_name_value_t *) b;
01134 
01135         return strcmp(in_a->name, in_b->name);
01136 }

int sechk_lib_module_clear_option sechk_module_t module,
char *  option
 

Clear an option of all previous values.

Parameters:
module Module containing the option to clear.
option Name of the option to clear.
Returns:
0 on success or < 0 on failure; if the call fails, errno will be set, and the module should be freed.

Definition at line 1138 of file sechecker.c.

References apol_vector_append(), apol_vector_create(), apol_vector_destroy(), apol_vector_get_element(), apol_vector_get_index(), apol_vector_get_size(), apol_vector_t, ERR, sechk_name_value::name, sechk_module::options, sechk_module::parent_lib, sechk_lib::policy, sechk_module_t, sechk_name_value_free(), sechk_name_value_new(), sechk_name_value_t, sechk_option_name_compare(), and WARN.

Referenced by sechk_lib_process_xml_node().

01139 {
01140         apol_vector_t *new_opts = NULL;
01141         sechk_name_value_t *needle = NULL, *nv = NULL, *tmp = NULL;
01142         int error = 0;
01143         size_t i = 0;
01144 
01145         if (!module || !option) {
01146                 errno = EINVAL;
01147                 return -1;
01148         }
01149 
01150         if (!(needle = sechk_name_value_new(option, NULL))) {
01151                 error = errno;
01152                 ERR(module->parent_lib->policy, "Clearing option %s: %s.", option, strerror(error));
01153                 errno = error;
01154                 return -1;
01155         }
01156 
01157         /* if not here nothing to do */
01158         if (apol_vector_get_index(module->options, needle, sechk_option_name_compare, NULL, &i) < 0) {
01159                 sechk_name_value_free(needle);
01160                 return 0;
01161         }
01162 
01163         if (!(new_opts = apol_vector_create(sechk_name_value_free))) {
01164                 error = errno;
01165                 ERR(module->parent_lib->policy, "%s", strerror(error));
01166                 errno = error;
01167                 return -1;
01168         }
01169 
01170         /* add all options of a different name to a new vector to replace the old */
01171         for (i = 0; i < apol_vector_get_size(module->options); i++) {
01172                 nv = apol_vector_get_element(module->options, i);
01173                 if (strcmp(nv->name, needle->name)) {
01174                         if (!(tmp = sechk_name_value_new(nv->name, nv->value))) {
01175                                 error = errno;
01176                                 WARN(module->parent_lib->policy, "Clearing option %s: %s.", option, strerror(error));
01177                                 goto err;
01178                         }
01179                         if (apol_vector_append(new_opts, (void *)tmp)) {
01180                                 error = errno;
01181                                 WARN(module->parent_lib->policy, "Clearing option %s: %s.", option, strerror(error));
01182                                 goto err;
01183                         }
01184                         tmp = NULL;    /* avoid double free */
01185                 }
01186         }
01187 
01188         sechk_name_value_free(needle);
01189         apol_vector_destroy(&module->options);
01190         module->options = new_opts;
01191 
01192         return 0;
01193 
01194       err:
01195         sechk_name_value_free(tmp);
01196         sechk_name_value_free(needle);
01197         apol_vector_destroy(&new_opts);
01198         errno = error;
01199         return -1;
01200 }

int sechk_lib_get_module_idx const char *  name,
sechk_lib_t lib
 

Get the index of a module in the library by name.

Parameters:
name Name of the module for which to get the index.
lib The library containing the desired module.
Returns:
index of the module or -1 if it was not found. If not found, errno will be set.

Definition at line 1203 of file sechecker.c.

References apol_vector_get_element(), apol_vector_get_size(), sechk_lib::modules, sechk_module::name, sechk_lib_t, and sechk_module_t.

Referenced by main(), sechk_lib_check_module_dependencies(), and sechk_lib_process_xml_node().

01204 {
01205         size_t i;
01206         sechk_module_t *mod = NULL;
01207 
01208         if (!name || !lib || !lib->modules) {
01209                 errno = EINVAL;
01210                 return -1;
01211         }
01212         for (i = 0; i < apol_vector_get_size(lib->modules); i++) {
01213                 mod = apol_vector_get_element(lib->modules, i);
01214                 if (mod->name && !strcmp(name, mod->name))
01215                         return i;
01216         }
01217         errno = ENOENT;
01218         return -1;
01219 }

int sechk_proof_with_element_compare const void *  in_proof,
const void *  elem,
void *unused   __attribute__((unused))
 

Definition at line 1221 of file sechecker.c.

References sechk_proof::elem, and sechk_proof_t.

Referenced by find_domains_run().

01222 {
01223         const sechk_proof_t *proof = (const sechk_proof_t *)in_proof;
01224 
01225         if (!proof)
01226                 return 1;
01227 
01228         /* explicit pointer to integer cast */
01229         return (int)((char *)proof->elem - (char *)elem);
01230 }