summaryrefslogtreecommitdiff
diff options
authorJonathan Cave <jonathan.cave@canonical.com>2018-06-18 12:53:05 +0100
committerJonathan Cave <jonathan.cave@canonical.com>2018-06-19 10:32:20 +0100
commita06844f2badc6d020b4e1bdcd1669307e5d8d0a6 (patch)
tree66e51fe9a2a37740f6ea8b101415151185857d38
parent216f3095a5efe4741f1975a0ef860fbc6f766b8b (diff)
Add disk encryption test
-rwxr-xr-xbin/fde_tests.py103
-rw-r--r--units/disk/encryption.pxu21
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