Implement policy statistics functions.

Do counting in C where possible.
This commit is contained in:
Chris PeBenito 2014-11-30 13:30:36 -05:00
parent 16f2eab30c
commit 6258b648aa
4 changed files with 624 additions and 1 deletions

42
seinfo
View File

@ -155,6 +155,48 @@ try:
else:
q = setools.userquery.UserQuery(p)
else:
if p.mls:
mls = "enabled"
else:
mls = "disabled"
print("Statistics for policy file: {0}".format(args.policy))
print("Policy Version: {0} (MLS {1})".format(p.version, mls))
print(" Classes: {0:7} Permissions: {1:7}".format(
p.class_count, p.permission_count))
print(" Sensitivities: {0:7} Categories: {1:7}".format(
p.level_count, p.category_count))
print(" Types: {0:7} Attributes: {1:7}".format(
p.type_count, p.attribute_count))
print(" Users: {0:7} Roles: {1:7}".format(
p.user_count, p.role_count))
print(" Booleans: {0:7} Cond. Expr.: {1:7}".format(
p.boolean_count, p.conditional_count))
print(" Allow: {0:7} Neverallow: {1:7}".format(
p.allow_count, p.neverallow_count))
print(" Auditallow: {0:7} Dontaudit: {1:7}".format(
p.auditallow_count, p.dontaudit_count))
print(" Type_trans: {0:7} Type_change: {1:7}".format(
p.type_transition_count, p.type_change_count))
print(" Type_member: {0:7} Range_trans: {1:7}".format(
p.type_member_count, p.range_transition_count))
print(" Role allow: {0:7} Role_trans: {1:7}".format(
p.role_allow_count, p.role_transition_count))
print(" Constraints: {0:7} Validatetrans: {1:7}".format(
p.constraint_count, p.validatetrans_count))
print(" MLS Constrain: {0:7} MLS Val. Tran: {1:7}".format(
p.mlsconstraint_count, p.mlsvalidatetrans_count))
print(" Initial SIDs: {0:7} Fs_use: {1:7}".format(
p.initialsids_count, p.fs_use_count))
print(" Genfscon: {0:7} Portcon: {1:7}".format(
p.genfscon_count, p.portcon_count))
print(" Netifcon: {0:7} Nodecon: {1:7}".format(
p.netifcon_count, p.nodecon_count))
print(" Permissives: {0:7} Polcap: {1:7}".format(
p.permissives_count, p.polcap_count))
sys.exit(0)
for item in sorted(q.results()):
if args.expand:
print(item.statement())

View File

@ -20,6 +20,7 @@
# The idea is that this is module provides convenient
# abstractions and methods for accessing the policy
# structures.
from itertools import chain
from . import qpol
@ -70,6 +71,10 @@ class SELinuxPolicy(object):
raise OSError(
"Error opening policy file \"{0}\": {1}".format(policyfile, err))
#
# Policy properties
#
@property
def handle_unknown(self):
"""The handle unknown permissions setting (allow,deny,reject)"""
@ -85,6 +90,175 @@ class SELinuxPolicy(object):
"""The policy database version (e.g. v29)"""
return self.policy.version()
#
# Policy statistics
#
@property
def allow_count(self):
"""The number of (type) allow rules."""
return self.policy.avrule_allow_count()
@property
def attribute_count(self):
"""The number of (type) attributes."""
return sum(1 for _ in self.attributes())
@property
def auditallow_count(self):
"""The number of auditallow rules."""
return self.policy.avrule_auditallow_count()
@property
def boolean_count(self):
"""The number of Booleans."""
return self.policy.bool_count()
@property
def category_count(self):
"""The number of categories."""
return self.policy.cat_count()
@property
def class_count(self):
"""The number of object classes."""
return self.policy.class_count()
@property
def common_count(self):
"""The number of common permission sets."""
return self.policy.common_count()
@property
def conditional_count(self):
"""The number of conditionals."""
return self.policy.cond_count()
@property
def constraint_count(self):
"""The number of standard constraints."""
return sum(1 for _ in self.constraints())
@property
def dontaudit_count(self):
"""The number of dontaudit rules."""
return self.policy.avrule_dontaudit_count()
@property
def fs_use_count(self):
"""fs_use_* statements."""
return self.policy.fs_use_count()
@property
def genfscon_count(self):
"""The number of genfscon statements."""
return self.policy.genfscon_count()
@property
def initialsids_count(self):
"""The number of initial sid statements."""
return self.policy.isid_count()
@property
def level_count(self):
"""The number of levels."""
return self.policy.level_count()
@property
def mlsconstraint_count(self):
"""The number of MLS constraints."""
return sum(1 for _ in self.mlsconstraints())
@property
def mlsvalidatetrans_count(self):
"""The number of MLS validatetrans."""
return sum(1 for _ in self.mlsvalidatetrans())
@property
def netifcon_count(self):
"""The number of netifcon statements."""
return self.policy.netifcon_count()
@property
def neverallow_count(self):
"""The number of neverallow rules."""
return self.policy.avrule_neverallow_count()
@property
def nodecon_count(self):
"""The number of nodecon statements."""
return self.policy.nodecon_count()
@property
def permission_count(self):
"""The number of permissions."""
return sum(len(c.perms) for c in chain(self.commons(), self.classes()))
@property
def permissives_count(self):
"""The number of permissive types."""
return self.policy.permissive_count()
@property
def polcap_count(self):
"""The number of policy capabilities."""
return self.policy.polcap_count()
@property
def portcon_count(self):
"""The number of portcon statements."""
return self.policy.portcon_count()
@property
def range_transition_count(self):
"""The number of range_transition rules."""
return self.policy.range_trans_count()
@property
def role_count(self):
"""The number of roles."""
return self.policy.role_count()
@property
def role_allow_count(self):
"""The number of (role) allow rules."""
return self.policy.role_allow_count()
@property
def role_transition_count(self):
"""The number of role_transition rules."""
return self.policy.role_trans_count()
@property
def type_count(self):
"""The number of types."""
return sum(1 for _ in self.types())
@property
def type_change_count(self):
"""The number of type_change rules."""
return self.policy.terule_change_count()
@property
def type_member_count(self):
"""The number of type_member rules."""
return self.policy.terule_member_count()
@property
def type_transition_count(self):
"""The number of type_transition rules."""
return self.policy.terule_trans_count() + self.policy.filename_trans_count()
@property
def user_count(self):
"""The number of users."""
return self.policy.user_count()
@property
def validatetrans_count(self):
"""The number of validatetrans."""
return sum(1 for _ in self.validatetrans())
#
# Policy components lookup functions
#
@ -105,6 +279,15 @@ class SELinuxPolicy(object):
# Policy components generators
#
def attributes(self):
"""Generator which yields all (type) attributes."""
# libqpol unfortunately iterates over attributes and aliases
for type_ in self.policy.type_iter():
t = typeattr.TypeAttr(self.policy, type_)
if t.isattr:
yield t
def classes(self):
"""Generator which yields all object classes."""
@ -206,6 +389,22 @@ class SELinuxPolicy(object):
if c.ismls:
yield c
def mlsvalidatetrans(self):
"""Generator which yields all mlsvalidatetrans."""
for validatetrans in self.policy.validatetrans_iter():
v = constraint.ValidateTrans(self.policy, validatetrans)
if v.ismls:
yield v
def validatetrans(self):
"""Generator which yields all validatetrans."""
for validatetrans in self.policy.validatetrans_iter():
v = constraint.ValidateTrans(self.policy, validatetrans)
if not v.ismls:
yield v
#
# In-policy Labeling statement generators
#

View File

@ -190,7 +190,7 @@ class Constraint(symbol.PolicySymbol):
return objclass.ObjClass(self.policy, self.qpol_symbol.object_class(self.policy))
class ValidateTrans(symbol.PolicySymbol):
class ValidateTrans(Constraint):
"""A validate transition rule."""
pass

View File

@ -359,6 +359,18 @@ typedef enum qpol_capability
return NULL;
};
size_t type_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_type_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject role_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_role_from_void) %}
qpol_iterator_t *role_iter() {
@ -373,6 +385,18 @@ typedef enum qpol_capability
return NULL;
};
size_t role_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_role_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject level_iter();
qpol_iterator_t *level_iter() {
BEGIN_EXCEPTION
@ -385,6 +409,19 @@ typedef enum qpol_capability
fail:
return NULL;
};
size_t level_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_level_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject cat_iter();
qpol_iterator_t *cat_iter() {
BEGIN_EXCEPTION
@ -397,6 +434,19 @@ typedef enum qpol_capability
fail:
return NULL;
};
size_t cat_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_cat_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject user_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_user_from_void) %}
qpol_iterator_t *user_iter() {
@ -411,6 +461,19 @@ typedef enum qpol_capability
return NULL;
};
size_t user_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_user_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject bool_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_bool_from_void) %}
qpol_iterator_t *bool_iter() {
@ -425,6 +488,18 @@ typedef enum qpol_capability
return NULL;
};
size_t bool_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_bool_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject class_iter(char*);
%pythoncode %{ @QpolGenerator(_qpol.qpol_class_from_void) %}
qpol_iterator_t *class_iter(char *perm=NULL) {
@ -445,6 +520,18 @@ typedef enum qpol_capability
return NULL;
};
size_t class_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_class_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject common_iter(char*);
%pythoncode %{ @QpolGenerator(_qpol.qpol_common_from_void) %}
qpol_iterator_t *common_iter(char *perm=NULL) {
@ -465,6 +552,18 @@ typedef enum qpol_capability
return NULL;
};
size_t common_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_common_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject fs_use_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_fs_use_from_void) %}
qpol_iterator_t *fs_use_iter() {
@ -479,6 +578,18 @@ typedef enum qpol_capability
return NULL;
};
size_t fs_use_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_fs_use_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject genfscon_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_genfscon_from_void) %}
qpol_iterator_t *genfscon_iter() {
@ -493,6 +604,18 @@ typedef enum qpol_capability
return NULL;
};
size_t genfscon_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_genfscon_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject isid_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_isid_from_void) %}
qpol_iterator_t *isid_iter() {
@ -507,6 +630,18 @@ typedef enum qpol_capability
return NULL;
};
size_t isid_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_isid_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject netifcon_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_netifcon_from_void) %}
qpol_iterator_t *netifcon_iter() {
@ -521,6 +656,18 @@ typedef enum qpol_capability
return NULL;
};
size_t netifcon_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_netifcon_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject nodecon_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_nodecon_from_void) %}
qpol_iterator_t *nodecon_iter() {
@ -535,6 +682,18 @@ typedef enum qpol_capability
return NULL;
};
size_t nodecon_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_nodecon_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject portcon_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_portcon_from_void) %}
qpol_iterator_t *portcon_iter() {
@ -549,6 +708,18 @@ typedef enum qpol_capability
return NULL;
};
size_t portcon_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_portcon_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject constraint_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_constraint_from_void) %}
qpol_iterator_t *constraint_iter() {
@ -563,6 +734,18 @@ typedef enum qpol_capability
return NULL;
};
size_t constraint_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_constraint_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject validatetrans_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_validatetrans_from_void) %}
qpol_iterator_t *validatetrans_iter() {
@ -577,6 +760,18 @@ typedef enum qpol_capability
return NULL;
};
size_t validatetrans_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_validatetrans_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject role_allow_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_role_allow_from_void) %}
qpol_iterator_t *role_allow_iter() {
@ -591,6 +786,18 @@ typedef enum qpol_capability
return NULL;
};
size_t role_allow_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_role_allow_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject role_trans_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_role_trans_from_void) %}
qpol_iterator_t *role_trans_iter() {
@ -605,6 +812,18 @@ typedef enum qpol_capability
return NULL;
};
size_t role_trans_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_role_trans_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject range_trans_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_range_trans_from_void) %}
qpol_iterator_t *range_trans_iter() {
@ -619,6 +838,18 @@ typedef enum qpol_capability
return NULL;
};
size_t range_trans_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_range_trans_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject avrule_iter(int);
%pythoncode %{ @QpolGenerator(_qpol.qpol_avrule_from_void) %}
qpol_iterator_t *avrule_iter() {
@ -638,6 +869,58 @@ typedef enum qpol_capability
return NULL;
};
size_t avrule_allow_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_avrule_iter(self, QPOL_RULE_ALLOW, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
size_t avrule_auditallow_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_avrule_iter(self, QPOL_RULE_AUDITALLOW, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
size_t avrule_neverallow_count() {
if (qpol_policy_has_capability(self, QPOL_CAP_NEVERALLOW)) {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_avrule_iter(self, QPOL_RULE_NEVERALLOW, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
} else {
return 0;
}
fail:
return 0;
};
size_t avrule_dontaudit_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_avrule_iter(self, QPOL_RULE_DONTAUDIT, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject terule_iter(int);
%pythoncode %{ @QpolGenerator(_qpol.qpol_terule_from_void) %}
qpol_iterator_t *terule_iter() {
@ -654,6 +937,42 @@ typedef enum qpol_capability
return NULL;
};
size_t terule_trans_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_terule_iter(self, QPOL_RULE_TYPE_TRANS, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
size_t terule_change_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_terule_iter(self, QPOL_RULE_TYPE_CHANGE, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
size_t terule_member_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_terule_iter(self, QPOL_RULE_TYPE_MEMBER, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject cond_iter();
qpol_iterator_t *cond_iter() {
BEGIN_EXCEPTION
@ -666,6 +985,19 @@ typedef enum qpol_capability
fail:
return NULL;
};
size_t cond_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_cond_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject filename_trans_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_filename_trans_from_void) %}
qpol_iterator_t *filename_trans_iter() {
@ -680,6 +1012,18 @@ typedef enum qpol_capability
return NULL;
};
size_t filename_trans_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_filename_trans_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject permissive_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_type_from_void) %}
qpol_iterator_t *permissive_iter() {
@ -694,6 +1038,18 @@ typedef enum qpol_capability
return NULL;
};
size_t permissive_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_permissive_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject typebounds_iter();
qpol_iterator_t *typebounds_iter() {
BEGIN_EXCEPTION
@ -706,6 +1062,19 @@ typedef enum qpol_capability
fail:
return NULL;
};
size_t typebounds_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_typebounds_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
%newobject polcap_iter();
%pythoncode %{ @QpolGenerator(_qpol.qpol_polcap_from_void) %}
qpol_iterator_t *polcap_iter() {
@ -719,6 +1088,19 @@ typedef enum qpol_capability
fail:
return NULL;
};
size_t polcap_count() {
qpol_iterator_t *iter;
size_t count = 0;
if (qpol_policy_get_polcap_iter(self, &iter)) {
SWIG_exception(SWIG_MemoryError, "Out of Memory");
}
qpol_iterator_get_size(iter, &count);
return count;
fail:
return 0;
};
};
/* qpol iterator */