From: Matthew Monaco <matthew.monaco@0x01b.net> ct_check_filter - Compare $FILTER (-O) to an optlist. If a token from filter starts with !opt, then "opt" must not be in optlist. Other than somewhat emulating mount here, later we'll allow options to have a % prefix, for example %usb will allow -O %usb to map all volumes with the %usb tag. We'll add an implicit tag called %random for devices which use /dev/urandom or /dev/random as a key. This will allow -O !%random to be done before the random seed is restored an -O %random afterwards. Of course, %random may also be specified expliticly in crypttab. ct_read_crypttab - Feed each line of /etc/crypttab to a function. each line is divided into a name, device, key, and options. ct_check_filter is applied to the options and if ok, the 4 fields are passed to the function. All operations that require reading crypttab will use this There is also a -1 option for ct_read_crypttab to exit after the first successful call to the function, this will be useful for identifying a specific volume. Co-authored-by: Dave Reisner <dreisner@archlinux.org> --- cryptmount.sh | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/cryptmount.sh b/cryptmount.sh index fa25fdf..03b8575 100755 --- a/cryptmount.sh +++ b/cryptmount.sh @@ -160,6 +160,111 @@ ct_main() { fi } + +# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +# # +# Functions for iterating over crypttab # +# # + +ct_read_crypttab() { + + if [ ! -f "$CRYPTTAB" -o ! -r "$CRYPTTAB" ]; then + error "cannot read $CRYPTTAB" + return 1 + fi + + local func="$@" line lineno=0 name dev key options ret=0 adhoc=0 + + if [ "$1" = "-1" ]; then + adhoc=1 + shift + func="$@" + fi + + while read -r name dev key options <&3; do + + lineno=$(( lineno + 1 )) + [ -z "$name" ] || [ ${name:0:1} = "#" ] && continue + + # unescape devname and keyname + name=$(printf '%b' "$name") + dev=$(printf '%b' "$dev") + key=$(printf '%b' "$key") + + if [ -z "$name" ]; then + warn "$CRYPTTAB:$lineno: the name (first column) cannot be blank" + continue + elif [ -z "$dev" ]; then + warn "$CRYPTTAB:$lineno: the device (second column) cannot be blank" + continue + fi + + case $key in + -|none|"") + key=- + ;; + /*|UUID=*|PARTUUID=*|LABEL=*) + : + ;; + *) + warn "$CRYPTTAB:$lineno: plain text keys are not supported" + key=- + ;; + esac + + if ct_check_filter $options; then + if ! $func "$name" "$dev" "$key" $options; then + ret=$(( ret + 1 )) + elif [ $adhoc -eq 1 ]; then + ret=0 + break + fi + fi + + done 3< "$CRYPTTAB" + + return $ret +} + +ct_check_filter() { + + local IFS=$',' fltr opt + + for fltr in $FILTER; do + fltr="$(trim $fltr)" + [ -z "$fltr" ] && continue + + if [ "x${fltr:0:1}" != "x!" ]; then + + for opt in $*; do + opt="$(trim $opt)" + [ -z "$opt" ] && continue + + if [ "$fltr" = "$opt" -o "$fltr" = "${opt%%=*}" ]; then + continue 2 + fi + done + + return 1 + + else + + for opt in $*; do + opt="$(trim $opt)" + [ -z "$opt" ] && continue + + if [ "$fltr" = "!$opt" -o "$fltr" = "!${opt%%=*}" ]; then + return 1 + fi + done + + fi + + done + + return 0 +} + # # # ---------------------------------------------------------------------------- # -- 1.7.10.2