#!/bin/sh # ecryptfs-filename-plain2encrypted: utility script to map plaintext to # encrypted filenames (and vice versa) in an eCryptfs directory. # Copyright (C) 2011 Sergio Mena de la Cruz # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # v0.1.0 Sergio Mena 2011-06-18 version='v0.1.0 (2011-06-18)' #Default values (assuming an encrypted home directory) if [ -z "$HOME" ]; then encryptedrootdefault="" plaintextrootdefault="" else encryptedrootdefault="`dirname ${HOME}`/.ecryptfs/`basename ${HOME}`/.Private" plaintextrootdefault="$HOME" fi currentversion() { cat << EOF $0, $version Copyright (C) 2011 Free Software Foundation, Inc. License GPLv2+: GNU GPL version 2 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Sergio Mena. EOF } usage() { cat << EOF usage: $0 [OPTIONS] filename This script prints to stdout the ecryptfs filename (including its path) that corresponds to its plaintext counterpart passed as argument. Note that this script does not use the current directory (e.g., PWD) to locate the filename. Argument is a path to a file/directory, relative to the plaintext root. Likewise, the filename returned includes the path relative to the encrypted root. The script needs the plaintext root to be mounted, and assumes that "ls -i filename_plaintext" and "ls -i filename_ecrypted" will yield the same i-node if filename_ecrypted is the encrypted counterpart of filename_plaintext. N.B.: Only the first argument (after all the options) is taken as a filename; the remaining arguments are discarded. OPTIONS: -h show this message and exit -e path path to encrypted root path (default: $encryptedrootdefault) -p path path to plaintext root path (default: $plaintextrootdefault) -s swap root paths. The command effectively takes the opposite effect (i.e., from encrypted filename to plaintext) -v print version and exit Report bugs at https://bugs.launchpad.net/ecryptfs/+filebug EOF } encryptedroot= plaintextroot= reverse=0 while getopts "he:p:sv" OPTION; do case $OPTION in h) usage exit 0 ;; e) encryptedroot="$OPTARG" ;; p) plaintextroot="$OPTARG" ;; s) reverse=1 ;; v) currentversion exit 0 ;; ?) usage >&2 exit 1 ;; esac done [ \( -z "$encryptedroot" -o -z "$plaintextroot" \) -a -z "$HOME" ] &&\ echo "$0: HOME variable not defined. Please define it or provide options -e and -p" >&2 &&\ exit 1 [ -z "$encryptedroot" ] &&\ encryptedroot="$encryptedrootdefault" [ -z "$plaintextroot" ] &&\ plaintextroot="$plaintextrootdefault" shift $((OPTIND - 1)) [ -z "$1" ] &&\ echo "$0: No filename provided" >&2 &&\ usage >&2 &&\ exit 1 # If "swap" option is selected, swap the roots [ $reverse -eq 1 ] &&\ aux="${encryptedroot}" &&\ encryptedroot="${plaintextroot}" &&\ plaintextroot="${aux}" currentencryptedpath= currentplaintextpath= rest="$1" while true; do nextplaintextdir=`printf '%s\n' "$rest" | sed -e 's/\/.*$//'` rest=`printf '%s\n' "$rest" | sed 's/^[^/]*\/*//'` currentplaintextpath=${currentplaintextpath}/${nextplaintextdir} absptpath="${plaintextroot}/${currentplaintextpath}" [ ! \( -e "$absptpath" -o -h "$absptpath" \) ] &&\ echo "$0: cannot access $1: No such file or directory" >&2 &&\ exit 1 inode=`ls -aid "$absptpath" | awk '{print $1}' ` nextencrypteddir=`ls -ai "${encryptedroot}/${currentencryptedpath}" | \ grep '^\s*'${inode}'\s' | head -1 | sed 's/^\s*[0-9][0-9]*\s\s*//'` [ -z "$nextencrypteddir" ] &&\ echo -n "$0: Hmmm strange, no encrypted file/dir corresponds to plaintext file/dir (" &&\ ( printf '%s)\n' "${currentplaintextpath}" | sed 's/^\///' ) >&2 &&\ exit 2 currentencryptedpath="${currentencryptedpath}/${nextencrypteddir}" [ -z "$rest" ] &&\ ( printf '%s\n' "${currentencryptedpath}" | sed 's/^\///' ) &&\ exit 0 done