3
# etl_funcs.sh: eCryptfs test library (etl) helper functions
4
# Author: Tyler Hicks <tyhicks@canonical.com>
6
# Copyright (C) 2012 Canonical Ltd.
8
# This program is free software; you can redistribute it and/or
9
# modify it under the terms of the GNU General Public License
10
# as published by the Free Software Foundation version 2
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program; if not, write to the Free Software
20
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22
etl=$(dirname $BASH_SOURCE[0])
24
default_fekek_pass="foo"
25
default_fekek_salt_hex="0011223344556677"
27
default_fnek_pass="$default_fekek_pass"
28
default_fnek_salt_hex="9988776655443322"
31
default_lmount_opts="rw,relatime"
32
default_ext_opts="user_xattr,acl,commit=600,barrier=1,data=ordered"
33
default_mount_opts="rw,relatime,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_sig=\${ETL_FEKEK_SIG}"
34
default_fne_mount_opts="${default_mount_opts},ecryptfs_fnek_sig=\${ETL_FNEK_SIG}"
38
# etl_add_fekek_passphrase [PASS] [SALT_HEX]
40
# Adds a passphrase-based file encryption key to the kernel keyring. A default
41
# PASS and SALT_HEX will be used if they are not specified. The key signature
42
# is exported into ETL_FEKEK_SIG upon success.
44
# Only call this directly if your test needs to add a specific fekek.
46
etl_add_fekek_passphrase()
49
pass=$default_fekek_pass
54
salt_hex=$default_fekek_salt_hex
59
sig=$(${etl}/etl-add-passphrase-key-to-keyring $pass $salt_hex)
64
export ETL_FEKEK_SIG=$sig
69
# etl_add_fnek_passphrase [PASS] [SALT_HEX]
71
# Adds a passphrase-based filename encryption key to the kernel keyring. A
72
# default PASS and SALT_HEX will be used if they are not specified. The key
73
# signature is exported into ETL_FNEK_SIG upon success.
75
# Only call this directly if your test needs to add a specific fnek.
77
etl_add_fnek_passphrase()
80
pass=$default_fnek_pass
85
salt_hex=$default_fnek_salt_hex
90
sig=$(${etl}/etl-add-passphrase-key-to-keyring $pass $salt_hex)
95
export ETL_FNEK_SIG=$sig
102
# Adds a fekek and, if appropriate, a fnek to the kernel keyring using the
103
# default values defined above. Most test cases requiring a generic mount will
104
# use this rather than the lower level functions that this calls.
106
# Set ETL_TEST_FNE to true if you want filename encryption enabled (it is best
107
# to lest the test harness handle that). ETL_FEKEK_SIG and, if appropriate,
108
# ETL_FNEK_SIG will contain the key signatures upon success.
112
# TODO: This should support non-passphrase based keys, too
114
etl_add_fekek_passphrase
115
if [ $? -ne 0 ]; then
119
if $ETL_TEST_FNE ; then
120
etl_add_fnek_passphrase
128
# etl_unlink_key_sig SIGNATURE
130
# Unlinks the key corresponding to the specified signature.
138
show_line=$(keyctl list @u | grep -s $1)
139
if [ $? -ne 0 ]; then
143
key=$(printf $show_line | awk -F ':' '{ print $1 }')
144
keyctl unlink $key &>/dev/null
150
# Unlinks the key corresponding to the value of ETL_FEKEK_SIG. Unsets
151
# that variable upon success.
155
if [ -z "$ETL_FEKEK_SIG" ]; then
159
etl_unlink_key_sig $ETL_FEKEK_SIG
160
if [ $? -ne 0 ]; then
170
# Unlinks the key corresponding to the value of ETL_FNEK_SIG. Unsets
171
# that variable upon success.
175
if [ -z "$ETL_FNEK_SIG" ]; then
179
etl_unlink_key_sig $ETL_FNEK_SIG
180
if [ $? -ne 0 ]; then
190
# Unlinks the fekek and, if appropriate, the fnek from the kernel keyring. See
191
# the functions called by etl_unlink_keys() for more information.
193
# Most test cases requiring a generic mount will use this rather than the lower
194
# level functions that this calls.
199
if [ $? -ne 0 ]; then
203
if $ETL_TEST_FNE ; then
212
# etl_create_disk DISK_SIZE [DIR_PATH]
214
# Creates a disk image for testing. This disk image will be formatted and ready
215
# for mounting as the lower filesystem.
217
# DISK_SIZE must be specified in 1K block sizes. DIR_PATH can be specified so
218
# that the image file is stored somewhere other than the /tmp/ directory.
230
if [ -z "$ETL_LFS" ]; then
236
img=$(mktemp -q /${dir_path}/etl-img-XXXXXXXXXX)
237
if [ $? -ne 0 ]; then
241
dd if=/dev/zero of=$img bs=1024 count=$1 &>/dev/null
242
if [ $? -ne 0 ]; then
247
mkfs -F -t $lfs $img &>/dev/null
248
if [ $? -ne 0 ]; then
254
export ETL_LMOUNT_SRC=$img
261
# Removes any lower test disk created by etl_create_disk().
265
if [ -z "$ETL_DISK" ] || [ ! -f "$ETL_DISK" ]; then
268
if grep -q $ETL_DISK /proc/mounts; then
272
rm -f $ETL_DISK &>/dev/null
278
# Ensures that the eCryptfs kernel code is either loaded, if a module, or
281
# If your test only needs an eCryptfs mount, don't call this function. The mount
282
# process will autoload the module for you. If you need access to something like
283
# /dev/ecryptfs, but don't need an eCryptfs mount, this function is for you.
287
if ! grep -q ecryptfs /proc/filesystems; then
296
# etl_construct_lmount_opts
298
# Construct the lower filesystem mount options. If mount options are already
299
# set, nothing is done. Otherwise, the default mount options for the lower
300
# filesystem are set.
302
# If you need specific options, you should probably construct them yourself and
303
# simply export them as ETL_LMOUNT_OPTS. This function is mostly a helper for
304
# other etl functions.
306
etl_construct_lmount_opts()
308
if [ -n "$ETL_LMOUNT_OPTS" ]; then
311
if [ -z "$ETL_LFS" ]; then
312
export ETL_LFS=$default_lfs
315
# TODO: Add support for more filesystems
318
lmount_opts=${default_lmount_opts},${default_ext_opts}
321
lmount_opts=$default_lmount_opts
325
if [ -f "$ETL_LMOUNT_SRC" ]; then
326
lmount_opts="${lmount_opts},loop"
329
export ETL_LMOUNT_OPTS=$lmount_opts
336
# Mounts the lower filesystem based upon the various env variables.
340
if [ -z "$ETL_LMOUNT_SRC" ] || [ -z "$ETL_LMOUNT_DST" ]; then
343
if ! etl_construct_lmount_opts; then
347
mount -t "$ETL_LFS" -o "$ETL_LMOUNT_OPTS" \
348
"$ETL_LMOUNT_SRC" "$ETL_LMOUNT_DST" &>/dev/null
354
# Unmounts the lower filesystem.
358
if [ -z "$ETL_LMOUNT_SRC" ]; then
363
umount "$ETL_LMOUNT_SRC" &>/dev/null
369
# Performs an eCryptfs mount, bypassing the eCryptfs mount helper.
371
# If you're fine with the default eCryptfs mount options, or have constructed
372
# your own mount options, and have already added the appropriate keys to the
373
# kernel keyring, this is the easiest way to do an eCryptfs mount.
377
if [ -z "$ETL_MOUNT_SRC" ] || [ -z "$ETL_MOUNT_DST" ]; then
380
if [ -z "$ETL_MOUNT_OPTS" ]; then
381
if [ -n "ETL_FNEK_SIG" ]; then
382
export ETL_MOUNT_OPTS=$(eval \
383
"echo $default_fne_mount_opts")
385
export ETL_MOUNT_OPTS=$(eval "echo $default_mount_opts")
389
mount -it ecryptfs -o "$ETL_MOUNT_OPTS" \
390
"$ETL_MOUNT_SRC" "$ETL_MOUNT_DST"
396
# Unmounts the eCryptfs mount point specified by ETL_MOUNT_DST. Note that the
397
# eCryptfs umount helper will not be called.
401
if [ -z "$ETL_MOUNT_DST" ]; then
405
if ! grep -q $ETL_MOUNT_DST /proc/mounts; then
410
umount -i "$ETL_MOUNT_DST" &>/dev/null
416
# Unmounts the eCryptfs mount point specified by ETL_MOUNT_DST. Note that the
417
# eCryptfs umount helper will be called.
421
if [ -z "$ETL_MOUNT_DST" ]; then
425
if ! grep -q $ETL_MOUNT_DST /proc/mounts; then
430
umount "$ETL_MOUNT_DST" &>/dev/null
434
# etl_create_test_dir
436
# Creates a directory for carrying out tests inside of the eCryptfs mount point
439
# Upon success, the newly created directory's name is echoed to stdout.
441
etl_create_test_dir()
443
if [ -z "$ETL_MOUNT_DST" ] || [ -z "$1" ]; then
447
test_basename=$(basename $0)
448
test_dir=$(mktemp -qd /${ETL_MOUNT_DST}/etl-${test_basename}-XXXXXXXXXX)
449
if [ $? -ne 0 ]; then
458
# etl_remove_test_dir TEST_DIR
460
# Removes the specified test directory.
462
# For now, it is nothing much more than a wrapper around rm -rf, but it may
463
# gain more functionality and/or safety checks in the future, so please use it.
465
etl_remove_test_dir()
469
elif [ ! -d "$1" ]; then
471
elif [ "$1" = "/" ]; then
475
rm -rf $1 &>/dev/null