#============================================================================
import os
+import sha
import stat
import array
import struct
# Constants needed for generating a binary policy from its XML
# representation
-ACM_POLICY_VERSION = 3 # Latest one
+ACM_POLICY_VERSION = 4 # Latest one
ACM_CHWALL_VERSION = 1
ACM_STE_VERSION = 1
return dom.toxml()
return None
+ def hash(self):
+ """ Calculate a SAH1 hash of the XML policy """
+ return sha.sha(self.toxml())
+
def save(self):
### Save the XML policy into a file ###
rc = -xsconstants.XSERR_FILE_ERROR
ste_bin += "\x00"
#Write binary header:
- headerformat="!iiiiiiiiii"
+ headerformat="!iiiiiiiiii20s"
totallen_bin = struct.calcsize(headerformat) + \
len(pr_bin) + len(chw_bin) + len(ste_bin)
polref_offset = struct.calcsize(headerformat)
primpoloffset,
secpolcode,
secpoloffset,
- major, minor)
+ major, minor,
+ self.hash().digest())
all_bin = array.array('B')
for s in [ hdr_bin, pr_bin, chw_bin, ste_bin ]:
rc = -xsconstants.XSERR_BAD_LABEL
return rc, mapfile, all_bin.tostring()
+ def validate_enforced_policy_hash(self):
+ """ verify that the policy hash embedded in the binary policy
+ that is currently enforce matches the one of the XML policy.
+ """
+ if self.hash().digest() != self.get_enforced_policy_hash():
+ raise Exception('Policy hashes do not match')
+
+ def get_enforced_policy_hash(self):
+ binpol = self.get_enforced_binary()
+ headerformat="!iiiiiiiiii20s"
+ res = struct.unpack(headerformat, binpol[:60])
+ if len(res) >= 11:
+ return res[10]
+ return None
+
def get_enforced_binary(self):
rc, binpol = security.hv_get_policy()
if rc != 0:
try:
self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref)
self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID)
+ self.xsobjs[ref].validate_enforced_policy_hash()
except Exception, e:
log.error("Could not find XML representation of policy '%s': "
"%s" % (act_pol_name,e))
* whenever the interpretation of the related
* policy's data structure changes
*/
-#define ACM_POLICY_VERSION 3
+#define ACM_POLICY_VERSION 4
#define ACM_CHWALL_VERSION 1
#define ACM_STE_VERSION 1
/* high-16 = version, low-16 = check magic */
#define ACM_MAGIC 0x0001debc
+/* size of the SHA1 hash identifying the XML policy from which the
+ binary policy was created */
+#define ACM_SHA1_HASH_SIZE 20
+
/* each offset in bytes from start of the struct they
* are part of */
uint32_t secondary_policy_code;
uint32_t secondary_buffer_offset;
struct acm_policy_version xml_pol_version; /* add in V3 */
+ uint8_t xml_policy_hash[ACM_SHA1_HASH_SIZE]; /* added in V4 */
};
u16 primary_policy_code;
u16 secondary_policy_code;
struct acm_policy_version xml_pol_version;
+ u8 xml_policy_hash[ACM_SHA1_HASH_SIZE];
};
struct chwall_binary_policy {
&pol->xml_pol_version,
sizeof(acm_bin_pol.xml_pol_version));
+ memcpy(&acm_bin_pol.xml_policy_hash,
+ pol->xml_policy_hash,
+ sizeof(acm_bin_pol.xml_policy_hash));
+
if ( acm_primary_ops->is_default_policy() &&
acm_secondary_ops->is_default_policy() )
require_update = 0;
&acm_bin_pol.xml_pol_version,
sizeof(struct acm_policy_version));
+ memcpy(&bin_pol->xml_policy_hash,
+ &acm_bin_pol.xml_policy_hash,
+ sizeof(acm_bin_pol.xml_policy_hash));
+
ret = acm_dump_policy_reference(
policy_buffer + be32_to_cpu(bin_pol->policy_reference_offset),
buf_size - be32_to_cpu(bin_pol->policy_reference_offset));