Skip to content

Commit bc7d5f2

Browse files
committed
new: providers/base: add fscrypt test
1 parent a65231d commit bc7d5f2

File tree

9 files changed

+213
-25
lines changed

9 files changed

+213
-25
lines changed

.github/workflows/checkbox-promote-beta-to-candidate/job.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ test_data:
4545
else
4646
echo "Installing checkbox runtime on device (from deb package)"
4747
_run sudo add-apt-repository -y ppa:checkbox-dev/$CHANNEL
48-
_run install_packages checkbox-ng python3-checkbox-ng checkbox-provider-base checkbox-provider-resource checkbox-provider-sru fswebcam obexftp wmctrl iperf mesa-utils vim pastebinit fwts xorg-dev gir1.2-clutter-1.0
48+
_run install_packages checkbox-ng python3-checkbox-ng checkbox-provider-base checkbox-provider-resource checkbox-provider-sru fscrypt fswebcam obexftp wmctrl iperf mesa-utils vim pastebinit fwts xorg-dev gir1.2-clutter-1.0
4949
# list installed checkbox-related packages to facilitate debugging
5050
_run "apt list --installed | grep checkbox"
5151
CHECKBOX_CLI_CMD="checkbox-cli"

checkbox-core-snap/series24/snap/snapcraft.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ parts:
290290
- efibootmgr
291291
- ethtool
292292
- freeipmi-tools
293+
- fscrypt
293294
- fswebcam
294295
- gir1.2-cheese-3.0
295296
- gir1.2-clutter-1.0

providers/base/README.rst

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,28 @@ under the units folder.
1212
Base Provider Units
1313
###################
1414

15-
+------------+-------------+-------------+------------------+-------------+----------------+
16-
| 6lowpan | eeprom | i2c | miscellanea | serial | ubuntucore |
17-
+------------+-------------+-------------+------------------+-------------+----------------+
18-
| acpi | esata | image | mobilebroadband | smoke | usb |
19-
+------------+-------------+-------------+------------------+-------------+----------------+
20-
| audio | ethernet | info | monitor | snapd | virtualization |
21-
+------------+-------------+-------------+------------------+-------------+----------------+
22-
| benchmarks | expresscard | input | networking | socketcan | watchdog |
23-
+------------+-------------+-------------+------------------+-------------+----------------+
24-
| bluetooth | fingerprint | install | nvdimm | stress | wireless |
25-
+------------+-------------+-------------+------------------+-------------+----------------+
26-
| camera_ | firewire | kernel-snap | oob-management | submission | wwan |
27-
+------------+-------------+-------------+------------------+-------------+----------------+
28-
| canary | firmware | keys | optical | suspend | |
29-
+------------+-------------+-------------+------------------+-------------+----------------+
30-
| codecs | gadget | led | power-management | thunderbolt | |
31-
+------------+-------------+-------------+------------------+-------------+----------------+
32-
| cpu | gpio | location | rtc | touchpad | |
33-
+------------+-------------+-------------+------------------+-------------+----------------+
34-
| disk | graphics | mediacard | security | touchscreen | |
35-
+------------+-------------+-------------+------------------+-------------+----------------+
36-
| dock | hibernate | memory | self | tpm | |
37-
+------------+-------------+-------------+------------------+-------------+----------------+
15+
+-----------+-------------+-------------+-------------------+-------------+----------------+
16+
| 6lowpan | eeprom | hibernate | memory | self | tmp |
17+
+-----------+-------------+-------------+-------------------+-------------+----------------+
18+
| acpi | esata | i2c | miscellanea | serial | ubuntucore |
19+
+-----------+-------------+-------------+-------------------+-------------+----------------+
20+
| audio | ethernet | image | mobilebroadband | smoke | usb |
21+
+-----------+-------------+-------------+-------------------+-------------+----------------+
22+
| benchmarks| expresscard | info | monitor | snapd | virtualization |
23+
+-----------+-------------+-------------+-------------------+-------------+----------------+
24+
| bluetooth | fingerprint | input | networking | socketcan | watchdog |
25+
+-----------+-------------+-------------+-------------------+-------------+----------------+
26+
| camera_ | firewire | install | nvdimm | submission | wireless |
27+
+-----------+-------------+-------------+-------------------+-------------+----------------+
28+
| canary | firmware | kernel-snap | oob-management | suspend | wwan |
29+
+-----------+-------------+-------------+-------------------+-------------+----------------+
30+
| codecs | fscrypt | keys | optical | tpm | |
31+
+-----------+-------------+-------------+-------------------+-------------+----------------+
32+
| cpu | gadget | led | power-management | thunderbolt | |
33+
+-----------+-------------+-------------+-------------------+-------------+----------------+
34+
| disk | gpio | location | rtc | touchpad | |
35+
+-----------+-------------+-------------+-------------------+-------------+----------------+
36+
| dock | graphics | mediacard | security | touchscreen | |
37+
+-----------+-------------+-------------+-------------------+-------------+----------------+
3838

3939
.. _camera: units/camera/README.rst

providers/base/bin/fscrypt_test.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env python3
2+
"""
3+
script to test fscrypt support
4+
5+
Copyright (C) 2025 Canonical Ltd.
6+
7+
Authors
8+
Alexis Cellier <[email protected]>
9+
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU General Public License version 3,
12+
as published by the Free Software Foundation.
13+
14+
This program is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
GNU General Public License for more details.
18+
19+
You should have received a copy of the GNU General Public License
20+
along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
22+
The purpose of this scrupt is to make a small fscrupt test on a generated
23+
ext4 disk image to validate the filesystem encryption support.
24+
"""
25+
26+
import os
27+
import subprocess
28+
import tempfile
29+
import re
30+
from pathlib import Path
31+
32+
33+
def recursive_rmdir(path):
34+
"""Equivalent of rm -rf <path>"""
35+
if path.is_dir():
36+
for child in path.iterdir():
37+
recursive_rmdir(child)
38+
path.rmdir()
39+
else:
40+
path.unlink()
41+
42+
43+
def main():
44+
"""
45+
Create an ext4 disk image, mount it, setup fscrypt and use it with a simple
46+
file
47+
"""
48+
tmp = Path(tempfile.mkdtemp())
49+
mnt = tmp / "mnt"
50+
img = tmp / "fs.img"
51+
key_file = tmp / "key"
52+
test_dir = mnt / "test"
53+
test_file = test_dir / "test.txt"
54+
fscrypt_setup = Path("/etc/fscrypt.conf").exists()
55+
56+
try:
57+
# Create a 50MB file
58+
subprocess.check_call(["truncate", "-s", "50M", str(img)])
59+
60+
mnt.mkdir(parents=True, exist_ok=True)
61+
62+
# Make ext4 image with encryption support
63+
subprocess.check_call(
64+
["mkfs.ext4", "-F", "-O", "encrypt,stable_inodes", str(img)]
65+
)
66+
67+
# Mount it
68+
subprocess.check_call(["mount", str(img), str(mnt)])
69+
70+
try:
71+
# Setup fscrypt
72+
print("Setup fscrupt")
73+
if not fscrypt_setup:
74+
subprocess.run(
75+
["fscrypt", "setup", "--force"],
76+
input="n\n",
77+
text=True,
78+
check=True,
79+
)
80+
subprocess.run(
81+
["fscrypt", "setup", "--force", str(mnt)],
82+
input="n\n",
83+
text=True,
84+
check=True,
85+
)
86+
87+
# Confirm fscrypt is enabled
88+
output = subprocess.check_output(
89+
["fscrypt", "status"],
90+
text=True,
91+
)
92+
found = False
93+
pattern = re.compile(rf"^{re.escape(str(mnt))}.*supported *Yes$")
94+
for line in output.splitlines():
95+
if pattern.match(line):
96+
found = True
97+
break
98+
if not found:
99+
raise SystemExit("fscrypt not enabled")
100+
101+
# Write random key
102+
with key_file.open("wb") as f:
103+
f.write(os.urandom(32))
104+
105+
# Make test directory
106+
test_dir.mkdir(parents=True, exist_ok=True)
107+
108+
# Encrypt directory
109+
subprocess.check_call([
110+
"fscrypt", "encrypt", "--quiet",
111+
"--source=raw_key", "--name=test_key",
112+
f"--key={str(key_file)}", str(test_dir)
113+
])
114+
115+
# Write a file inside
116+
with test_file.open("w") as f:
117+
f.write("test\n")
118+
119+
# Lock the directory
120+
subprocess.check_call(["fscrypt", "lock", str(test_dir)])
121+
122+
# Should not be able to list the file
123+
if test_file.exists():
124+
raise SystemExit("File should not be accessible when locked")
125+
print("File correctly inaccessible when locked")
126+
127+
# Unlock the directory
128+
subprocess.check_call(
129+
["fscrypt", "unlock", f"--key={str(key_file)}", str(test_dir)]
130+
)
131+
132+
with test_file.open("r") as f:
133+
content = f.read().strip()
134+
if content != "test":
135+
raise SystemExit("File contents not correct after unlock")
136+
print("File is accessible and content is correct after unlock")
137+
finally:
138+
subprocess.check_call(["umount", str(mnt)])
139+
finally:
140+
print("Cleaning temporary files")
141+
recursive_rmdir(tmp)
142+
if not fscrypt_setup:
143+
Path("/etc/fscrypt.conf").unlink()
144+
145+
146+
if __name__ == "__main__":
147+
main()

providers/base/debian/control

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ Recommends: bonnie++,
4242
smartmontools,
4343
sysstat,
4444
${plainbox:Recommends}
45-
Suggests: fswebcam,
45+
Suggests: fscrypt,
46+
fswebcam,
4647
fwts,
4748
glmark2,
4849
glmark2-es2,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
unit: category
2+
id: fscrypt
3+
_name: Ubuntu filesystem encryption feature tests
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
id: fscrypt/check-kernel-config
2+
plugin: shell
3+
category_id: fscrypt
4+
command: kernel_config.py --config-flag CONFIG_FS_ENCRYPTION
5+
estimated_duration: 0.005
6+
_purpose: Checks the value of the CONFIG_FS_ENCRYPTION flag in the kernel configuration
7+
_summary: Check if the kernel is compiled with filesystem encryption support
8+
9+
id: fscrypt/check-support
10+
plugin: shell
11+
category_id: fscrypt
12+
estimated_duration: 5s
13+
user: root
14+
depends: fscrypt/check-kernel-config
15+
requires: executable.name == "fscrypt"
16+
_summary: Check fscrypt support
17+
_purpose: Create an ext4 image and test the filesystem encryption feature
18+
command: fscrypt_test.py
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
unit: packaging meta-data
2+
os-id: ubuntu
3+
Depends: fscrypt
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
id: fscrypt-full
2+
unit: test plan
3+
_name: fscrypt tests
4+
_description: fscrypt tests
5+
include:
6+
nested_part:
7+
fscrypt-automated
8+
9+
id: fscrypt-automated
10+
unit: test plan
11+
_name: automated fscrypt tests
12+
_description: Automated fscrypt tests
13+
include:
14+
fscrypt/check-kernel-config
15+
fscrypt/check-support

0 commit comments

Comments
 (0)