diff options
author | Jonathan Cave <jonathan.cave@canonical.com> | 2018-06-18 12:53:05 +0100 |
---|---|---|
committer | Jonathan Cave <jonathan.cave@canonical.com> | 2018-06-19 10:32:20 +0100 |
commit | a06844f2badc6d020b4e1bdcd1669307e5d8d0a6 (patch) | |
tree | 66e51fe9a2a37740f6ea8b101415151185857d38 | |
parent | 216f3095a5efe4741f1975a0ef860fbc6f766b8b (diff) |
Add disk encryption test
-rwxr-xr-x | bin/fde_tests.py | 103 | ||||
-rw-r--r-- | units/disk/encryption.pxu | 21 |
2 files changed, 124 insertions, 0 deletions
diff --git a/bin/fde_tests.py b/bin/fde_tests.py new file mode 100755 index 0000000..92a6cc2 --- /dev/null +++ b/bin/fde_tests.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# Copyright 2018 Canonical Ltd. +# Written by: +# Jonathan Cave <jonathan.cave@canonical.com> + +"""Test that Full Disk Encryption is in use. + +$ fde_tests.py +Canonical has a reference implementation of full disk encryption for IoT +devices. With no arguments passed this test checks this implementation is in +operation on the device under test. + +$ fde_tests.py desktop +Checks if the system appears to be using full disk encryption as configured by +the desktop installer. +""" + +import os +import re +import subprocess as sp +import sys + + +def main(argv): + on_desktop = False + if len(sys.argv) > 1 and sys.argv[1] == 'desktop': + on_desktop = True + + # the mountpoint corresponding to the on disk encrypted partition + base_mount = '/' if on_desktop else '/writable' + + # discover the underlying mount point for the encrypted part + cmd = 'findmnt {} -n -o SOURCE'.format(base_mount) + print('+ {}'.format(cmd)) + try: + source = sp.check_output(cmd, shell=True).decode( + sys.stdout.encoding).strip() + except sp.CalledProcessError: + raise SystemExit( + 'ERROR: could not find mountpoint for {}'.format(base_mount)) + print(source, '\n') + + # resolve the source to an actual device node + print('+ realpath {}'.format(source)) + device = os.path.realpath(source) + print(device, '\n') + + # work upwards through the tree of devices until we find the one that has + # the type 'crypt' + kname = os.path.basename(device) + while True: + cmd = 'lsblk -r -n -i -o KNAME,TYPE,PKNAME | grep "^{}"'.format(kname) + print('+ {}'.format(cmd)) + try: + lsblk = sp.check_output(cmd, shell=True).decode( + sys.stdout.encoding).strip() + except sp.CalledProcessError: + raise SystemExit('ERROR: lsblk call failed') + _, devtype, parent = lsblk.split(maxsplit=2) + print(devtype, '\n') + if devtype == 'crypt': + # found the device + break + if devtype == 'disk': + # reached the physical device, end the search + raise SystemExit( + 'ERROR: could not find a block device of type "crypt"') + kname = parent + + # the presence of device with type 'crypt' is probably confirmation enough + # but to be really sure lets check to see it is found by cryptsetup + + # first we need to know its mapper name + cmd = 'dmsetup info /dev/{} | grep "^Name:"'.format(kname) + print('+ {}'.format(cmd)) + try: + mapper_name = sp.check_output(cmd, shell=True).decode( + sys.stdout.encoding).strip().split()[-1] + except sp.CalledProcessError: + raise SystemExit( + 'ERROR: dmsetup info on device {} failed'.format(kname)) + print(mapper_name, '\n') + + # then query the info in cryptsetup + cmd = 'cryptsetup status {}'.format(mapper_name) + print('+ {}'.format(cmd)) + try: + cryptinfo = sp.check_output(cmd, shell=True).decode( + sys.stdout.encoding).strip() + except sp.CalledProcessError: + raise SystemExit('ERROR: dmsetup failed') + print(cryptinfo, '\n') + + # use the type as the final arbiter of success + regexp = re.compile(r'type:\ *LUKS1') + if regexp.search(cryptinfo): + print('Full Disk Encryption is operational on this device') + else: + raise SystemExit('ERROR: cryptsetup did not report LUKS1 in use') + + +if __name__ == "__main__": + main(sys.argv) diff --git a/units/disk/encryption.pxu b/units/disk/encryption.pxu new file mode 100644 index 0000000..b7d41c8 --- /dev/null +++ b/units/disk/encryption.pxu @@ -0,0 +1,21 @@ + +id: disk/encryption/detect +category_id: com.canonical.plainbox::disk +plugin: shell +template-engine: jinja2 +user: root +requires: + executable.name == 'lsblk' + executable.name == 'dmsetup' + executable.name == 'cryptsetup' +_summary: Test that Full Disk Encryption is in use +_description: + Examine the system to detect if one of the standard full disk encryption + implementations is in use +command: + {%- if __on_ubuntucore__ %} + fde_tests.py + {%- else %} + fde_tests.py desktop + {% endif -%} +estimated_duration: 2.0 \ No newline at end of file |