tMerge pull request #267 from dyne/exec-hooks - tomb - the crypto undertaker
 (HTM) git clone git://parazyd.org/tomb.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit fb5eee002bdb497c647f01ebe0694db700bffb56
 (DIR) parent 5f71b486df105f7104d881ef1536511fa781390c
 (HTM) Author: Jaromil <jaromil@dyne.org>
       Date:   Tue, 13 Jun 2017 09:30:14 +0200
       
       Merge pull request #267 from dyne/exec-hooks
       
       Exec hooks
       Diffstat:
         M doc/tomb.1                          |      15 ++++++++-------
         M tomb                                |      50 +++++++++++++++++--------------
       
       2 files changed, 35 insertions(+), 30 deletions(-)
       ---
 (DIR) diff --git a/doc/tomb.1 b/doc/tomb.1
       t@@ -298,13 +298,14 @@ example:
        .EE
        
        .B
       -.IP "post-hooks"
       -This hook file gets executed as user by tomb right after opening it;
       -it should be a regular shell script, starting with a shebang. Tomb
       -executes this hook as user (dropping root privileges) and giving it
       -two arguments: "$1" is "open" or "close" depending from the tomb
       -command given, "$2" is the full path to the mountpoint where the tomb
       -is open.
       +.IP "exec-hooks"
       +This hook file gets executed as user by tomb with the first argument
       +determining the step of execution: "open" or "close". The exec-hooks
       +file should be an executable (ELF or shell script) present inside the
       +Tomb. Tomb executes this hook as user supplying two or more arguments,
       +the first being the step, followed by the mountpoint of the tomb and,
       +on close events, its name, loopback device and dev-mapper device
       +paths.
        
        .SH PRIVILEGE ESCALATION
        
 (DIR) diff --git a/tomb b/tomb
       t@@ -2065,10 +2065,11 @@ mount_tomb() {
        
        
            # process bind-hooks (mount -o bind of directories)
       -    # and post-hooks (execute on open)
       -    { option_is_set -n } || {
       +    # and exec-hooks (execute on open)
       +    option_is_set -n || {
                exec_safe_bind_hooks ${tombmount}
       -        exec_safe_post_hooks ${tombmount} open }
       +        exec_safe_func_hooks open ${tombmount} 
       +        }
        
            return 0
        }
       t@@ -2145,27 +2146,23 @@ exec_safe_bind_hooks() {
        
        # Execute automated actions configured in the tomb.
        #
       -# Synopsis: exec_safe_post_hooks /path/to/mounted/tomb [open|close]
       +# Synopsis: exec_safe_func_hooks /path/to/mounted/tomb 
        #
       -# If an executable file named 'post-hooks' is found inside the tomb,
       +# If an executable file named 'exec-hooks' is found inside the tomb,
        # run it as a user.  This might need a dialog for security on what is
        # being run, however we expect you know well what is inside your tomb.
        # If you're mounting an untrusted tomb, be safe and use the -n switch
        # to verify what it would run if you let it.  This feature opens the
        # possibility to make encrypted executables.
       -exec_safe_post_hooks() {
       -    local mnt=$1     # First argument is where the tomb is mounted
       -    local act=$2     # Either 'open' or 'close'
       -
       +exec_safe_func_hooks() {
            # Only run if post-hooks has the executable bit set
       -    [[ -x $mnt/post-hooks ]] || return
       -
       -    # If the file starts with a shebang, run it.
       -    head -n1 $mnt/post-hooks | grep '^#!\s*/'
       -    [[ $? == 0 ]] && {
       -        _success "Post hooks found, executing as user ::1 user name::." $USERNAME
       -        $mnt/post-hooks $act $mnt
       +    [[ -x $mnt/exec-hooks ]] && {
       +        _success "Exec hook: ::1 exec hook:: ::2 action:: ::3 argument::" \
       +                                 "${mnt}/exec-hooks" "$1" "$2"
       +        $mnt/exec-hooks "$1" "$2"
       +                return $?
            }
       +        return 0
        }
        
        # }}} - Tomb open
       t@@ -2629,6 +2626,16 @@ umount_tomb() {
                    _warning "Please specify an existing tomb."
                    return 0 }
        
       +                option_is_set -n || {
       +                        exec_safe_func_hooks \
       +                                close "$tombmount" "$tombname" "$tombloop" "$mapper"
       +                        exec_hook_res=$?
       +                        [[ $exec_hook_res = 0 ]] || {
       +                                _warning "close exec-hook returns a non-zero error code: ::1 error::" $exec_hook_res
       +                                _failure "Operation aborted"
       +                        }
       +                }
       +           
                [[ -n $SLAM ]] && {
                    _success "Slamming tomb ::1 tomb name:: mounted on ::2 mount point::" \
                        $tombname $tombmount
       t@@ -2656,10 +2663,6 @@ umount_tomb() {
                    }
                done
        
       -        # Execute post-hooks for eventual cleanup
       -        { option_is_set -n } || {
       -            exec_safe_post_hooks ${tombmount%%/} close }
       -
                _verbose "Performing umount of ::1 mount point::" $tombmount
                _sudo umount ${tombmount}
                [[ $? = 0 ]] || { _failure "Tomb is busy, cannot umount!" }
       t@@ -2676,9 +2679,10 @@ umount_tomb() {
                    _failure "Error occurred in cryptsetup luksClose ::1 mapper::" $mapper }
        
                # Normally the loopback device is detached when unused
       -        [[ -e "/dev/$tombloop" ]] && _sudo losetup -d "/dev/$tombloop"
       -        [[ $? = 0 ]] || {
       -            _verbose "/dev/$tombloop was already closed." }
       +        [[ -e "/dev/$tombloop" ]] && {
       +                        _sudo losetup -d "/dev/$tombloop"
       +                        [[ $? = 0 ]] || _verbose "/dev/$tombloop was already closed."
       +                }
        
                _success "Tomb ::1 tomb name:: closed: your bones will rest in peace." $tombname