diff options
author | Jussi Laako <jussi.laako@linux.intel.com> | 2014-03-25 15:25:44 +0200 |
---|---|---|
committer | Jussi Laako <jussi.laako@linux.intel.com> | 2014-03-25 15:26:50 +0200 |
commit | bb0ada3bddfeeb4e98d3415c37266061c865005f (patch) | |
tree | f644444272c1a5f01b333977a94677bdc80f2184 /src/utils | |
download | ecryptfs-utils-bb0ada3bddfeeb4e98d3415c37266061c865005f.tar.gz ecryptfs-utils-bb0ada3bddfeeb4e98d3415c37266061c865005f.tar.bz2 ecryptfs-utils-bb0ada3bddfeeb4e98d3415c37266061c865005f.zip |
Initial release for Tizenupstream/104submit/tizen/20140325.142353
Change-Id: I5f609bdfdf73bda344b01c41519f6cd65ea76f55
Diffstat (limited to 'src/utils')
28 files changed, 6647 insertions, 0 deletions
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am new file mode 100644 index 0000000..83cf851 --- /dev/null +++ b/src/utils/Makefile.am @@ -0,0 +1,72 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +EXTRA_DIST=ecryptfsrc ecryptfs-rewrite-file ecryptfs-setup-private ecryptfs-setup-swap ecryptfs-mount-private ecryptfs-umount-private ecryptfs-migrate-home ecryptfs-recover-private ecryptfs-find ecryptfs-verify + +rootsbin_PROGRAMS=mount.ecryptfs \ + umount.ecryptfs \ + mount.ecryptfs_private +bin_PROGRAMS=ecryptfs-manager ecryptfs-wrap-passphrase \ + ecryptfs-unwrap-passphrase \ + ecryptfs-insert-wrapped-passphrase-into-keyring \ + ecryptfs-rewrap-passphrase \ + ecryptfs-add-passphrase \ + ecryptfs-stat +bin_SCRIPTS = ecryptfs-setup-private \ + ecryptfs-setup-swap \ + ecryptfs-mount-private \ + ecryptfs-umount-private \ + ecryptfs-rewrite-file \ + ecryptfs-recover-private \ + ecryptfs-migrate-home \ + ecryptfs-find \ + ecryptfs-verify +bin2dir = $(bindir) + +noinst_PROGRAMS=test + +if ENABLE_TESTS +TESTS=test +endif + +if BUILD_TSPI +bin_PROGRAMS+=ecryptfs-generate-tpm-key +endif + +AM_CPPFLAGS += -I$(top_srcdir)/src/include + +mount_ecryptfs_SOURCES = mount.ecryptfs.c io.c io.h gen_key.c plaintext_decision_graph.c +mount_ecryptfs_CFLAGS = $(AM_CFLAGS) $(KEYUTILS_CFLAGS) $(LIBGCRYPT_CFLAGS) +mount_ecryptfs_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) $(LIBGCRYPT_LIBS) +umount_ecryptfs_SOURCES = umount.ecryptfs.c +umount_ecryptfs_CFLAGS = $(AM_CFLAGS) $(KEYUTILS_CFLAGS) +umount_ecryptfs_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_manager_SOURCES = manager.c io.c io.h gen_key.c +ecryptfs_manager_CFLAGS = $(AM_CFLAGS) $(KEYUTILS_CFLAGS) $(LIBGCRYPT_CFLAGS) +ecryptfs_manager_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) $(LIBGCRYPT_LIBS) +ecryptfs_wrap_passphrase_SOURCES = ecryptfs_wrap_passphrase.c +ecryptfs_wrap_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_unwrap_passphrase_SOURCES = ecryptfs_unwrap_passphrase.c +ecryptfs_unwrap_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_insert_wrapped_passphrase_into_keyring_SOURCES = ecryptfs_insert_wrapped_passphrase_into_keyring.c +ecryptfs_insert_wrapped_passphrase_into_keyring_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_rewrap_passphrase_SOURCES = ecryptfs_rewrap_passphrase.c +ecryptfs_rewrap_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_add_passphrase_SOURCES = ecryptfs_add_passphrase.c +ecryptfs_add_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la + +ecryptfs_generate_tpm_key_SOURCES = ecryptfs_generate_tpm_key.c +ecryptfs_generate_tpm_key_CFLAGS = $(AM_CFLAGS) $(TSPI_CFLAGS) +ecryptfs_generate_tpm_key_LDADD = $(TSPI_LIBS) + +mount_ecryptfs_private_SOURCES = mount.ecryptfs_private.c +mount_ecryptfs_private_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) + +ecryptfs_stat_SOURCES = ecryptfs-stat.c +ecryptfs_stat_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la + +test_SOURCES = test.c io.c +test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la + +install-exec-hook: install-rootsbinPROGRAMS + -rm -f "$(DESTDIR)/$(rootsbindir)/umount.ecryptfs_private" + $(LN_S) "mount.ecryptfs_private" "$(DESTDIR)/$(rootsbindir)/umount.ecryptfs_private" diff --git a/src/utils/Makefile.in b/src/utils/Makefile.in new file mode 100644 index 0000000..b243e08 --- /dev/null +++ b/src/utils/Makefile.in @@ -0,0 +1,1517 @@ +# Makefile.in generated by automake 1.13.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +rootsbin_PROGRAMS = mount.ecryptfs$(EXEEXT) umount.ecryptfs$(EXEEXT) \ + mount.ecryptfs_private$(EXEEXT) +bin_PROGRAMS = ecryptfs-manager$(EXEEXT) \ + ecryptfs-wrap-passphrase$(EXEEXT) \ + ecryptfs-unwrap-passphrase$(EXEEXT) \ + ecryptfs-insert-wrapped-passphrase-into-keyring$(EXEEXT) \ + ecryptfs-rewrap-passphrase$(EXEEXT) \ + ecryptfs-add-passphrase$(EXEEXT) ecryptfs-stat$(EXEEXT) \ + $(am__EXEEXT_1) +noinst_PROGRAMS = test$(EXEEXT) +@ENABLE_TESTS_TRUE@TESTS = test$(EXEEXT) +@BUILD_TSPI_TRUE@am__append_1 = ecryptfs-generate-tpm-key +subdir = src/utils +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp $(top_srcdir)/test-driver +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_pkg_swig.m4 \ + $(top_srcdir)/m4/ac_python_devel.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/swig_python.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@BUILD_TSPI_TRUE@am__EXEEXT_1 = ecryptfs-generate-tpm-key$(EXEEXT) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(rootsbindir)" \ + "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(rootsbin_PROGRAMS) +am_ecryptfs_add_passphrase_OBJECTS = \ + ecryptfs_add_passphrase.$(OBJEXT) +ecryptfs_add_passphrase_OBJECTS = \ + $(am_ecryptfs_add_passphrase_OBJECTS) +ecryptfs_add_passphrase_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +am_ecryptfs_generate_tpm_key_OBJECTS = \ + ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.$(OBJEXT) +ecryptfs_generate_tpm_key_OBJECTS = \ + $(am_ecryptfs_generate_tpm_key_OBJECTS) +am__DEPENDENCIES_1 = +ecryptfs_generate_tpm_key_DEPENDENCIES = $(am__DEPENDENCIES_1) +ecryptfs_generate_tpm_key_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(ecryptfs_generate_tpm_key_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_ecryptfs_insert_wrapped_passphrase_into_keyring_OBJECTS = \ + ecryptfs_insert_wrapped_passphrase_into_keyring.$(OBJEXT) +ecryptfs_insert_wrapped_passphrase_into_keyring_OBJECTS = \ + $(am_ecryptfs_insert_wrapped_passphrase_into_keyring_OBJECTS) +ecryptfs_insert_wrapped_passphrase_into_keyring_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la +am_ecryptfs_manager_OBJECTS = ecryptfs_manager-manager.$(OBJEXT) \ + ecryptfs_manager-io.$(OBJEXT) \ + ecryptfs_manager-gen_key.$(OBJEXT) +ecryptfs_manager_OBJECTS = $(am_ecryptfs_manager_OBJECTS) +ecryptfs_manager_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la \ + $(am__DEPENDENCIES_1) +ecryptfs_manager_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(ecryptfs_manager_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_ecryptfs_rewrap_passphrase_OBJECTS = \ + ecryptfs_rewrap_passphrase.$(OBJEXT) +ecryptfs_rewrap_passphrase_OBJECTS = \ + $(am_ecryptfs_rewrap_passphrase_OBJECTS) +ecryptfs_rewrap_passphrase_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la +am_ecryptfs_stat_OBJECTS = ecryptfs-stat.$(OBJEXT) +ecryptfs_stat_OBJECTS = $(am_ecryptfs_stat_OBJECTS) +ecryptfs_stat_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la +am_ecryptfs_unwrap_passphrase_OBJECTS = \ + ecryptfs_unwrap_passphrase.$(OBJEXT) +ecryptfs_unwrap_passphrase_OBJECTS = \ + $(am_ecryptfs_unwrap_passphrase_OBJECTS) +ecryptfs_unwrap_passphrase_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la +am_ecryptfs_wrap_passphrase_OBJECTS = \ + ecryptfs_wrap_passphrase.$(OBJEXT) +ecryptfs_wrap_passphrase_OBJECTS = \ + $(am_ecryptfs_wrap_passphrase_OBJECTS) +ecryptfs_wrap_passphrase_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la +am_mount_ecryptfs_OBJECTS = mount_ecryptfs-mount.ecryptfs.$(OBJEXT) \ + mount_ecryptfs-io.$(OBJEXT) mount_ecryptfs-gen_key.$(OBJEXT) \ + mount_ecryptfs-plaintext_decision_graph.$(OBJEXT) +mount_ecryptfs_OBJECTS = $(am_mount_ecryptfs_OBJECTS) +mount_ecryptfs_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la \ + $(am__DEPENDENCIES_1) +mount_ecryptfs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(mount_ecryptfs_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ + $@ +am_mount_ecryptfs_private_OBJECTS = mount.ecryptfs_private.$(OBJEXT) +mount_ecryptfs_private_OBJECTS = $(am_mount_ecryptfs_private_OBJECTS) +mount_ecryptfs_private_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la \ + $(am__DEPENDENCIES_1) +am_test_OBJECTS = test.$(OBJEXT) io.$(OBJEXT) +test_OBJECTS = $(am_test_OBJECTS) +test_DEPENDENCIES = $(top_builddir)/src/libecryptfs/libecryptfs.la +am_umount_ecryptfs_OBJECTS = \ + umount_ecryptfs-umount.ecryptfs.$(OBJEXT) +umount_ecryptfs_OBJECTS = $(am_umount_ecryptfs_OBJECTS) +umount_ecryptfs_DEPENDENCIES = \ + $(top_builddir)/src/libecryptfs/libecryptfs.la +umount_ecryptfs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(umount_ecryptfs_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(ecryptfs_add_passphrase_SOURCES) \ + $(ecryptfs_generate_tpm_key_SOURCES) \ + $(ecryptfs_insert_wrapped_passphrase_into_keyring_SOURCES) \ + $(ecryptfs_manager_SOURCES) \ + $(ecryptfs_rewrap_passphrase_SOURCES) $(ecryptfs_stat_SOURCES) \ + $(ecryptfs_unwrap_passphrase_SOURCES) \ + $(ecryptfs_wrap_passphrase_SOURCES) $(mount_ecryptfs_SOURCES) \ + $(mount_ecryptfs_private_SOURCES) $(test_SOURCES) \ + $(umount_ecryptfs_SOURCES) +DIST_SOURCES = $(ecryptfs_add_passphrase_SOURCES) \ + $(ecryptfs_generate_tpm_key_SOURCES) \ + $(ecryptfs_insert_wrapped_passphrase_into_keyring_SOURCES) \ + $(ecryptfs_manager_SOURCES) \ + $(ecryptfs_rewrap_passphrase_SOURCES) $(ecryptfs_stat_SOURCES) \ + $(ecryptfs_unwrap_passphrase_SOURCES) \ + $(ecryptfs_wrap_passphrase_SOURCES) $(mount_ecryptfs_SOURCES) \ + $(mount_ecryptfs_private_SOURCES) $(test_SOURCES) \ + $(umount_ecryptfs_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DVIPS = @DVIPS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GPGME_CFLAGS = @GPGME_CFLAGS@ +GPGME_LIBS = @GPGME_LIBS@ +GREP = @GREP@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +KEYUTILS_CFLAGS = @KEYUTILS_CFLAGS@ +KEYUTILS_LIBS = @KEYUTILS_LIBS@ +LATEX = @LATEX@ +LATEX2HTML = @LATEX2HTML@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBECRYPTFS_LT_AGE = @LIBECRYPTFS_LT_AGE@ +LIBECRYPTFS_LT_CURRENT = @LIBECRYPTFS_LT_CURRENT@ +LIBECRYPTFS_LT_REVISION = @LIBECRYPTFS_LT_REVISION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOCALEDIR = @LOCALEDIR@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PAM_CFLAGS = @PAM_CFLAGS@ +PAM_LIBS = @PAM_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKCS11_HELPER_CFLAGS = @PKCS11_HELPER_CFLAGS@ +PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PS2PDF = @PS2PDF@ +PYTHON = @PYTHON@ +PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ +PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ +PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SWIG = @SWIG@ +SWIG_LIB = @SWIG_LIB@ +SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ +SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ +TAR = @TAR@ +TSPI_CFLAGS = @TSPI_CFLAGS@ +TSPI_LIBS = @TSPI_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +ecryptfskeymoddir = @ecryptfskeymoddir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pamdir = @pamdir@ +pamlibdir = @pamlibdir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +rootsbindir = @rootsbindir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in +EXTRA_DIST = ecryptfsrc ecryptfs-rewrite-file ecryptfs-setup-private ecryptfs-setup-swap ecryptfs-mount-private ecryptfs-umount-private ecryptfs-migrate-home ecryptfs-recover-private ecryptfs-find ecryptfs-verify +bin_SCRIPTS = ecryptfs-setup-private \ + ecryptfs-setup-swap \ + ecryptfs-mount-private \ + ecryptfs-umount-private \ + ecryptfs-rewrite-file \ + ecryptfs-recover-private \ + ecryptfs-migrate-home \ + ecryptfs-find \ + ecryptfs-verify + +bin2dir = $(bindir) +mount_ecryptfs_SOURCES = mount.ecryptfs.c io.c io.h gen_key.c plaintext_decision_graph.c +mount_ecryptfs_CFLAGS = $(AM_CFLAGS) $(KEYUTILS_CFLAGS) $(LIBGCRYPT_CFLAGS) +mount_ecryptfs_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) $(LIBGCRYPT_LIBS) +umount_ecryptfs_SOURCES = umount.ecryptfs.c +umount_ecryptfs_CFLAGS = $(AM_CFLAGS) $(KEYUTILS_CFLAGS) +umount_ecryptfs_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_manager_SOURCES = manager.c io.c io.h gen_key.c +ecryptfs_manager_CFLAGS = $(AM_CFLAGS) $(KEYUTILS_CFLAGS) $(LIBGCRYPT_CFLAGS) +ecryptfs_manager_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) $(LIBGCRYPT_LIBS) +ecryptfs_wrap_passphrase_SOURCES = ecryptfs_wrap_passphrase.c +ecryptfs_wrap_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_unwrap_passphrase_SOURCES = ecryptfs_unwrap_passphrase.c +ecryptfs_unwrap_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_insert_wrapped_passphrase_into_keyring_SOURCES = ecryptfs_insert_wrapped_passphrase_into_keyring.c +ecryptfs_insert_wrapped_passphrase_into_keyring_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_rewrap_passphrase_SOURCES = ecryptfs_rewrap_passphrase.c +ecryptfs_rewrap_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_add_passphrase_SOURCES = ecryptfs_add_passphrase.c +ecryptfs_add_passphrase_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +ecryptfs_generate_tpm_key_SOURCES = ecryptfs_generate_tpm_key.c +ecryptfs_generate_tpm_key_CFLAGS = $(AM_CFLAGS) $(TSPI_CFLAGS) +ecryptfs_generate_tpm_key_LDADD = $(TSPI_LIBS) +mount_ecryptfs_private_SOURCES = mount.ecryptfs_private.c +mount_ecryptfs_private_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) +ecryptfs_stat_SOURCES = ecryptfs-stat.c +ecryptfs_stat_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +test_SOURCES = test.c io.c +test_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/utils/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/utils/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +install-rootsbinPROGRAMS: $(rootsbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(rootsbin_PROGRAMS)'; test -n "$(rootsbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(rootsbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(rootsbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(rootsbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(rootsbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-rootsbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(rootsbin_PROGRAMS)'; test -n "$(rootsbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(rootsbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(rootsbindir)" && rm -f $$files + +clean-rootsbinPROGRAMS: + @list='$(rootsbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +ecryptfs-add-passphrase$(EXEEXT): $(ecryptfs_add_passphrase_OBJECTS) $(ecryptfs_add_passphrase_DEPENDENCIES) $(EXTRA_ecryptfs_add_passphrase_DEPENDENCIES) + @rm -f ecryptfs-add-passphrase$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecryptfs_add_passphrase_OBJECTS) $(ecryptfs_add_passphrase_LDADD) $(LIBS) + +ecryptfs-generate-tpm-key$(EXEEXT): $(ecryptfs_generate_tpm_key_OBJECTS) $(ecryptfs_generate_tpm_key_DEPENDENCIES) $(EXTRA_ecryptfs_generate_tpm_key_DEPENDENCIES) + @rm -f ecryptfs-generate-tpm-key$(EXEEXT) + $(AM_V_CCLD)$(ecryptfs_generate_tpm_key_LINK) $(ecryptfs_generate_tpm_key_OBJECTS) $(ecryptfs_generate_tpm_key_LDADD) $(LIBS) + +ecryptfs-insert-wrapped-passphrase-into-keyring$(EXEEXT): $(ecryptfs_insert_wrapped_passphrase_into_keyring_OBJECTS) $(ecryptfs_insert_wrapped_passphrase_into_keyring_DEPENDENCIES) $(EXTRA_ecryptfs_insert_wrapped_passphrase_into_keyring_DEPENDENCIES) + @rm -f ecryptfs-insert-wrapped-passphrase-into-keyring$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecryptfs_insert_wrapped_passphrase_into_keyring_OBJECTS) $(ecryptfs_insert_wrapped_passphrase_into_keyring_LDADD) $(LIBS) + +ecryptfs-manager$(EXEEXT): $(ecryptfs_manager_OBJECTS) $(ecryptfs_manager_DEPENDENCIES) $(EXTRA_ecryptfs_manager_DEPENDENCIES) + @rm -f ecryptfs-manager$(EXEEXT) + $(AM_V_CCLD)$(ecryptfs_manager_LINK) $(ecryptfs_manager_OBJECTS) $(ecryptfs_manager_LDADD) $(LIBS) + +ecryptfs-rewrap-passphrase$(EXEEXT): $(ecryptfs_rewrap_passphrase_OBJECTS) $(ecryptfs_rewrap_passphrase_DEPENDENCIES) $(EXTRA_ecryptfs_rewrap_passphrase_DEPENDENCIES) + @rm -f ecryptfs-rewrap-passphrase$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecryptfs_rewrap_passphrase_OBJECTS) $(ecryptfs_rewrap_passphrase_LDADD) $(LIBS) + +ecryptfs-stat$(EXEEXT): $(ecryptfs_stat_OBJECTS) $(ecryptfs_stat_DEPENDENCIES) $(EXTRA_ecryptfs_stat_DEPENDENCIES) + @rm -f ecryptfs-stat$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecryptfs_stat_OBJECTS) $(ecryptfs_stat_LDADD) $(LIBS) + +ecryptfs-unwrap-passphrase$(EXEEXT): $(ecryptfs_unwrap_passphrase_OBJECTS) $(ecryptfs_unwrap_passphrase_DEPENDENCIES) $(EXTRA_ecryptfs_unwrap_passphrase_DEPENDENCIES) + @rm -f ecryptfs-unwrap-passphrase$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecryptfs_unwrap_passphrase_OBJECTS) $(ecryptfs_unwrap_passphrase_LDADD) $(LIBS) + +ecryptfs-wrap-passphrase$(EXEEXT): $(ecryptfs_wrap_passphrase_OBJECTS) $(ecryptfs_wrap_passphrase_DEPENDENCIES) $(EXTRA_ecryptfs_wrap_passphrase_DEPENDENCIES) + @rm -f ecryptfs-wrap-passphrase$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ecryptfs_wrap_passphrase_OBJECTS) $(ecryptfs_wrap_passphrase_LDADD) $(LIBS) + +mount.ecryptfs$(EXEEXT): $(mount_ecryptfs_OBJECTS) $(mount_ecryptfs_DEPENDENCIES) $(EXTRA_mount_ecryptfs_DEPENDENCIES) + @rm -f mount.ecryptfs$(EXEEXT) + $(AM_V_CCLD)$(mount_ecryptfs_LINK) $(mount_ecryptfs_OBJECTS) $(mount_ecryptfs_LDADD) $(LIBS) + +mount.ecryptfs_private$(EXEEXT): $(mount_ecryptfs_private_OBJECTS) $(mount_ecryptfs_private_DEPENDENCIES) $(EXTRA_mount_ecryptfs_private_DEPENDENCIES) + @rm -f mount.ecryptfs_private$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(mount_ecryptfs_private_OBJECTS) $(mount_ecryptfs_private_LDADD) $(LIBS) + +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +umount.ecryptfs$(EXEEXT): $(umount_ecryptfs_OBJECTS) $(umount_ecryptfs_DEPENDENCIES) $(EXTRA_umount_ecryptfs_DEPENDENCIES) + @rm -f umount.ecryptfs$(EXEEXT) + $(AM_V_CCLD)$(umount_ecryptfs_LINK) $(umount_ecryptfs_OBJECTS) $(umount_ecryptfs_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs-stat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_add_passphrase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_insert_wrapped_passphrase_into_keyring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_manager-gen_key.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_manager-io.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_manager-manager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_rewrap_passphrase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_unwrap_passphrase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfs_wrap_passphrase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount.ecryptfs_private.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_ecryptfs-gen_key.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_ecryptfs-io.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_ecryptfs-mount.ecryptfs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_ecryptfs-plaintext_decision_graph.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/umount_ecryptfs-umount.ecryptfs.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.o: ecryptfs_generate_tpm_key.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_generate_tpm_key_CFLAGS) $(CFLAGS) -MT ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.o -MD -MP -MF $(DEPDIR)/ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.Tpo -c -o ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.o `test -f 'ecryptfs_generate_tpm_key.c' || echo '$(srcdir)/'`ecryptfs_generate_tpm_key.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.Tpo $(DEPDIR)/ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs_generate_tpm_key.c' object='ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_generate_tpm_key_CFLAGS) $(CFLAGS) -c -o ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.o `test -f 'ecryptfs_generate_tpm_key.c' || echo '$(srcdir)/'`ecryptfs_generate_tpm_key.c + +ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.obj: ecryptfs_generate_tpm_key.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_generate_tpm_key_CFLAGS) $(CFLAGS) -MT ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.obj -MD -MP -MF $(DEPDIR)/ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.Tpo -c -o ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.obj `if test -f 'ecryptfs_generate_tpm_key.c'; then $(CYGPATH_W) 'ecryptfs_generate_tpm_key.c'; else $(CYGPATH_W) '$(srcdir)/ecryptfs_generate_tpm_key.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.Tpo $(DEPDIR)/ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs_generate_tpm_key.c' object='ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_generate_tpm_key_CFLAGS) $(CFLAGS) -c -o ecryptfs_generate_tpm_key-ecryptfs_generate_tpm_key.obj `if test -f 'ecryptfs_generate_tpm_key.c'; then $(CYGPATH_W) 'ecryptfs_generate_tpm_key.c'; else $(CYGPATH_W) '$(srcdir)/ecryptfs_generate_tpm_key.c'; fi` + +ecryptfs_manager-manager.o: manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -MT ecryptfs_manager-manager.o -MD -MP -MF $(DEPDIR)/ecryptfs_manager-manager.Tpo -c -o ecryptfs_manager-manager.o `test -f 'manager.c' || echo '$(srcdir)/'`manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_manager-manager.Tpo $(DEPDIR)/ecryptfs_manager-manager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='manager.c' object='ecryptfs_manager-manager.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -c -o ecryptfs_manager-manager.o `test -f 'manager.c' || echo '$(srcdir)/'`manager.c + +ecryptfs_manager-manager.obj: manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -MT ecryptfs_manager-manager.obj -MD -MP -MF $(DEPDIR)/ecryptfs_manager-manager.Tpo -c -o ecryptfs_manager-manager.obj `if test -f 'manager.c'; then $(CYGPATH_W) 'manager.c'; else $(CYGPATH_W) '$(srcdir)/manager.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_manager-manager.Tpo $(DEPDIR)/ecryptfs_manager-manager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='manager.c' object='ecryptfs_manager-manager.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -c -o ecryptfs_manager-manager.obj `if test -f 'manager.c'; then $(CYGPATH_W) 'manager.c'; else $(CYGPATH_W) '$(srcdir)/manager.c'; fi` + +ecryptfs_manager-io.o: io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -MT ecryptfs_manager-io.o -MD -MP -MF $(DEPDIR)/ecryptfs_manager-io.Tpo -c -o ecryptfs_manager-io.o `test -f 'io.c' || echo '$(srcdir)/'`io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_manager-io.Tpo $(DEPDIR)/ecryptfs_manager-io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='ecryptfs_manager-io.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -c -o ecryptfs_manager-io.o `test -f 'io.c' || echo '$(srcdir)/'`io.c + +ecryptfs_manager-io.obj: io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -MT ecryptfs_manager-io.obj -MD -MP -MF $(DEPDIR)/ecryptfs_manager-io.Tpo -c -o ecryptfs_manager-io.obj `if test -f 'io.c'; then $(CYGPATH_W) 'io.c'; else $(CYGPATH_W) '$(srcdir)/io.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_manager-io.Tpo $(DEPDIR)/ecryptfs_manager-io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='ecryptfs_manager-io.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -c -o ecryptfs_manager-io.obj `if test -f 'io.c'; then $(CYGPATH_W) 'io.c'; else $(CYGPATH_W) '$(srcdir)/io.c'; fi` + +ecryptfs_manager-gen_key.o: gen_key.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -MT ecryptfs_manager-gen_key.o -MD -MP -MF $(DEPDIR)/ecryptfs_manager-gen_key.Tpo -c -o ecryptfs_manager-gen_key.o `test -f 'gen_key.c' || echo '$(srcdir)/'`gen_key.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_manager-gen_key.Tpo $(DEPDIR)/ecryptfs_manager-gen_key.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen_key.c' object='ecryptfs_manager-gen_key.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -c -o ecryptfs_manager-gen_key.o `test -f 'gen_key.c' || echo '$(srcdir)/'`gen_key.c + +ecryptfs_manager-gen_key.obj: gen_key.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -MT ecryptfs_manager-gen_key.obj -MD -MP -MF $(DEPDIR)/ecryptfs_manager-gen_key.Tpo -c -o ecryptfs_manager-gen_key.obj `if test -f 'gen_key.c'; then $(CYGPATH_W) 'gen_key.c'; else $(CYGPATH_W) '$(srcdir)/gen_key.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfs_manager-gen_key.Tpo $(DEPDIR)/ecryptfs_manager-gen_key.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen_key.c' object='ecryptfs_manager-gen_key.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfs_manager_CFLAGS) $(CFLAGS) -c -o ecryptfs_manager-gen_key.obj `if test -f 'gen_key.c'; then $(CYGPATH_W) 'gen_key.c'; else $(CYGPATH_W) '$(srcdir)/gen_key.c'; fi` + +mount_ecryptfs-mount.ecryptfs.o: mount.ecryptfs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-mount.ecryptfs.o -MD -MP -MF $(DEPDIR)/mount_ecryptfs-mount.ecryptfs.Tpo -c -o mount_ecryptfs-mount.ecryptfs.o `test -f 'mount.ecryptfs.c' || echo '$(srcdir)/'`mount.ecryptfs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-mount.ecryptfs.Tpo $(DEPDIR)/mount_ecryptfs-mount.ecryptfs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mount.ecryptfs.c' object='mount_ecryptfs-mount.ecryptfs.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-mount.ecryptfs.o `test -f 'mount.ecryptfs.c' || echo '$(srcdir)/'`mount.ecryptfs.c + +mount_ecryptfs-mount.ecryptfs.obj: mount.ecryptfs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-mount.ecryptfs.obj -MD -MP -MF $(DEPDIR)/mount_ecryptfs-mount.ecryptfs.Tpo -c -o mount_ecryptfs-mount.ecryptfs.obj `if test -f 'mount.ecryptfs.c'; then $(CYGPATH_W) 'mount.ecryptfs.c'; else $(CYGPATH_W) '$(srcdir)/mount.ecryptfs.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-mount.ecryptfs.Tpo $(DEPDIR)/mount_ecryptfs-mount.ecryptfs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mount.ecryptfs.c' object='mount_ecryptfs-mount.ecryptfs.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-mount.ecryptfs.obj `if test -f 'mount.ecryptfs.c'; then $(CYGPATH_W) 'mount.ecryptfs.c'; else $(CYGPATH_W) '$(srcdir)/mount.ecryptfs.c'; fi` + +mount_ecryptfs-io.o: io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-io.o -MD -MP -MF $(DEPDIR)/mount_ecryptfs-io.Tpo -c -o mount_ecryptfs-io.o `test -f 'io.c' || echo '$(srcdir)/'`io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-io.Tpo $(DEPDIR)/mount_ecryptfs-io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='mount_ecryptfs-io.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-io.o `test -f 'io.c' || echo '$(srcdir)/'`io.c + +mount_ecryptfs-io.obj: io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-io.obj -MD -MP -MF $(DEPDIR)/mount_ecryptfs-io.Tpo -c -o mount_ecryptfs-io.obj `if test -f 'io.c'; then $(CYGPATH_W) 'io.c'; else $(CYGPATH_W) '$(srcdir)/io.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-io.Tpo $(DEPDIR)/mount_ecryptfs-io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='mount_ecryptfs-io.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-io.obj `if test -f 'io.c'; then $(CYGPATH_W) 'io.c'; else $(CYGPATH_W) '$(srcdir)/io.c'; fi` + +mount_ecryptfs-gen_key.o: gen_key.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-gen_key.o -MD -MP -MF $(DEPDIR)/mount_ecryptfs-gen_key.Tpo -c -o mount_ecryptfs-gen_key.o `test -f 'gen_key.c' || echo '$(srcdir)/'`gen_key.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-gen_key.Tpo $(DEPDIR)/mount_ecryptfs-gen_key.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen_key.c' object='mount_ecryptfs-gen_key.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-gen_key.o `test -f 'gen_key.c' || echo '$(srcdir)/'`gen_key.c + +mount_ecryptfs-gen_key.obj: gen_key.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-gen_key.obj -MD -MP -MF $(DEPDIR)/mount_ecryptfs-gen_key.Tpo -c -o mount_ecryptfs-gen_key.obj `if test -f 'gen_key.c'; then $(CYGPATH_W) 'gen_key.c'; else $(CYGPATH_W) '$(srcdir)/gen_key.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-gen_key.Tpo $(DEPDIR)/mount_ecryptfs-gen_key.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen_key.c' object='mount_ecryptfs-gen_key.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-gen_key.obj `if test -f 'gen_key.c'; then $(CYGPATH_W) 'gen_key.c'; else $(CYGPATH_W) '$(srcdir)/gen_key.c'; fi` + +mount_ecryptfs-plaintext_decision_graph.o: plaintext_decision_graph.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-plaintext_decision_graph.o -MD -MP -MF $(DEPDIR)/mount_ecryptfs-plaintext_decision_graph.Tpo -c -o mount_ecryptfs-plaintext_decision_graph.o `test -f 'plaintext_decision_graph.c' || echo '$(srcdir)/'`plaintext_decision_graph.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-plaintext_decision_graph.Tpo $(DEPDIR)/mount_ecryptfs-plaintext_decision_graph.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plaintext_decision_graph.c' object='mount_ecryptfs-plaintext_decision_graph.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-plaintext_decision_graph.o `test -f 'plaintext_decision_graph.c' || echo '$(srcdir)/'`plaintext_decision_graph.c + +mount_ecryptfs-plaintext_decision_graph.obj: plaintext_decision_graph.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -MT mount_ecryptfs-plaintext_decision_graph.obj -MD -MP -MF $(DEPDIR)/mount_ecryptfs-plaintext_decision_graph.Tpo -c -o mount_ecryptfs-plaintext_decision_graph.obj `if test -f 'plaintext_decision_graph.c'; then $(CYGPATH_W) 'plaintext_decision_graph.c'; else $(CYGPATH_W) '$(srcdir)/plaintext_decision_graph.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mount_ecryptfs-plaintext_decision_graph.Tpo $(DEPDIR)/mount_ecryptfs-plaintext_decision_graph.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plaintext_decision_graph.c' object='mount_ecryptfs-plaintext_decision_graph.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mount_ecryptfs_CFLAGS) $(CFLAGS) -c -o mount_ecryptfs-plaintext_decision_graph.obj `if test -f 'plaintext_decision_graph.c'; then $(CYGPATH_W) 'plaintext_decision_graph.c'; else $(CYGPATH_W) '$(srcdir)/plaintext_decision_graph.c'; fi` + +umount_ecryptfs-umount.ecryptfs.o: umount.ecryptfs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(umount_ecryptfs_CFLAGS) $(CFLAGS) -MT umount_ecryptfs-umount.ecryptfs.o -MD -MP -MF $(DEPDIR)/umount_ecryptfs-umount.ecryptfs.Tpo -c -o umount_ecryptfs-umount.ecryptfs.o `test -f 'umount.ecryptfs.c' || echo '$(srcdir)/'`umount.ecryptfs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/umount_ecryptfs-umount.ecryptfs.Tpo $(DEPDIR)/umount_ecryptfs-umount.ecryptfs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='umount.ecryptfs.c' object='umount_ecryptfs-umount.ecryptfs.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(umount_ecryptfs_CFLAGS) $(CFLAGS) -c -o umount_ecryptfs-umount.ecryptfs.o `test -f 'umount.ecryptfs.c' || echo '$(srcdir)/'`umount.ecryptfs.c + +umount_ecryptfs-umount.ecryptfs.obj: umount.ecryptfs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(umount_ecryptfs_CFLAGS) $(CFLAGS) -MT umount_ecryptfs-umount.ecryptfs.obj -MD -MP -MF $(DEPDIR)/umount_ecryptfs-umount.ecryptfs.Tpo -c -o umount_ecryptfs-umount.ecryptfs.obj `if test -f 'umount.ecryptfs.c'; then $(CYGPATH_W) 'umount.ecryptfs.c'; else $(CYGPATH_W) '$(srcdir)/umount.ecryptfs.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/umount_ecryptfs-umount.ecryptfs.Tpo $(DEPDIR)/umount_ecryptfs-umount.ecryptfs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='umount.ecryptfs.c' object='umount_ecryptfs-umount.ecryptfs.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(umount_ecryptfs_CFLAGS) $(CFLAGS) -c -o umount_ecryptfs-umount.ecryptfs.obj `if test -f 'umount.ecryptfs.c'; then $(CYGPATH_W) 'umount.ecryptfs.c'; else $(CYGPATH_W) '$(srcdir)/umount.ecryptfs.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +test.log: test$(EXEEXT) + @p='test$(EXEEXT)'; \ + b='test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(rootsbindir)" "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS clean-rootsbinPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-rootsbinPROGRAMS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-binSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-rootsbinPROGRAMS + +.MAKE: check-am install-am install-exec-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS clean-rootsbinPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-binSCRIPTS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-hook \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-rootsbinPROGRAMS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-rootsbinPROGRAMS + + +install-exec-hook: install-rootsbinPROGRAMS + -rm -f "$(DESTDIR)/$(rootsbindir)/umount.ecryptfs_private" + $(LN_S) "mount.ecryptfs_private" "$(DESTDIR)/$(rootsbindir)/umount.ecryptfs_private" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/utils/ecryptfs-find b/src/utils/ecryptfs-find new file mode 100755 index 0000000..fc7ada2 --- /dev/null +++ b/src/utils/ecryptfs-find @@ -0,0 +1,59 @@ +#!/bin/sh -e +# +# ecryptfs-find - use inode numbers to match encrypted/decrypted filenames +# Copyright (C) 2011 Dustin Kirkland +# Copyright (C) 2011 Sergio Mena de la Cruz +# +# Authors: Dustin Kirkland <kirkland@ubuntu.com> +# 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, version 2 of the License. +# +# 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, see <http://www.gnu.org/licenses/>. + +if [ ! -e "$1" ]; then + echo "ERROR: [$1] not found" 1>&2 + exit 1 +fi + +# Use one utility for both directions; same method is used +case "$1" in + *ECRYPTFS_FNEK_ENCRYPTED.*) + direction="decrypt" + ;; + *) + direction="encrypt" + ;; +esac + +# Grab the target inode number +inum=$(ls -aid "$1" | awk '{print $1}') +mounts= + +# Process /proc/mounts +while read lower upper fstype opts dump pass; do + [ "$fstype" = "ecryptfs" ] || continue + if [ "$direction" = "encrypt" ]; then + find="$lower" + else + find="$upper" + fi + # Match against filesystem or mountpoint, build list of + # mounts to search + if [ -r "$find" ] && [ -x "$find" ]; then + mounts="$mounts $find" + fi +done < /proc/mounts + +# Do the search +for m in $mounts; do + find "$m/" -inum "$inum" +done diff --git a/src/utils/ecryptfs-migrate-home b/src/utils/ecryptfs-migrate-home new file mode 100755 index 0000000..b810146 --- /dev/null +++ b/src/utils/ecryptfs-migrate-home @@ -0,0 +1,206 @@ +#!/bin/sh +# -*- sh-basic-offset: 4; sh-indentation: 4; tab-width: 4; indent-tabs-mode: t; sh-indent-comment: t; -*- +# This script encrypts an user's home +# +# Written by Yan Li <yan.i.li@intel.com>, <yanli@gnome.org> +# Copyright (C) 2010 Intel Corporation +# +# Modified by Dustin Kirkland <kirkland@ubuntu.com> +# +# 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., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +set -e + +PRIVATE_DIR="Private" + +usage() { + echo " +Usage: + +$0 -u USER + + -u,--user Migrate USER's home directory to an encrypted home directory + +WARNING: Make a complete backup copy of the non-encrypted data to +another system or external media. This script is dangerous and, in +case of an error, could result in data lost, or lock you out of your +system! + +This program must be executed by root. + +" + exit 1 +} + +error() { + echo "$(gettext 'ERROR: ')" "$@" 1>&2 + exit 1 +} + +warning() { + echo "$(gettext 'WARNING: ')" "$@" 1>&2 +} + +info() { + echo "$(gettext 'INFO: ')" "$@" 1>&2 +} + +assert_dir_empty() { + local DIR="$1" + if [ -e "$DIR" ]; then + # if $DIR is a directory, make sure it's empty + if [ -d "$DIR" ]; then + ls=$(ls -A "$DIR" | wc -l) + if [ "$ls" != "0" ]; then + echo 1>&2 "If you already have some data in directory $DIR," + echo 1>&2 "please move all of these files and directories out of the way, and" + echo 1>&2 "follow the instructions in:" + echo 1>&2 " ecryptfs-setup-private --undo" + echo 1>&2 + error "$DIR is not empty, cannot continue." + fi + else + error "$DIR exists but is not an empty directory, cannot continue." + fi + fi +} + +# get user home by username +get_user_home () { + local USER_NAME="$1" + local USER_HOME=$(getent passwd "$USER_NAME" | cut -d":" -f 6) + if [ -z "$USER_HOME" ]; then + error "Cannot find the home directory of $USER_NAME." + fi + echo "$USER_HOME" +} + +sanity_check () { + local USER_NAME="$1" + local USER_HOME="$2" + if [ -e "$USER_HOME/.ecryptfs" ]; then + error "$USER_HOME appears to be encrypted already." + fi + # Check for rsync + if ! which rsync >/dev/null 2>&1; then + error "Please install the rsync package." + fi + # Check free space: make sure we have sufficient disk space + # available. To make a full copy, we will need at least 2.5x the + # disk usage of the target home directory. + info "Checking disk space, this may take a few moments. Please be patient." + needed=$(du -s "$USER_HOME" | awk '{printf "%.0f", $1*2.5}') + free=$(df -P "$USER_HOME" | tail -n 1 | awk '{print $4}') + if [ $needed -gt $free ]; then + info "2.5x the size your current home directory is required to perform a migration." + info "Once the migration succeeds, you may recover most of this space by deleting the cleartext directory." + error "Not enough free disk space." + fi + assert_dir_empty "$USER_HOME/.$PRIVATE_DIR" + assert_dir_empty "$USER_HOME/.ecryptfs" + assert_dir_empty "/home/.ecryptfs/$USER_NAME" +} + +encrypt_dir () { + local USER_NAME="$1" + local USER_HOME="$2" + if ! which lsof >/dev/null 2>&1; then + info "Please install lsof." + error "Can not tell whether $USER_HOME is in use or not." + fi + info "Checking for open files in $USER_HOME" + lsof=$(lsof +D "$USER_HOME" | wc -l) + if [ "$lsof" != "0" ]; then + info "The following files are in use:" + echo + lsof +D "$USER_HOME" | sed "s/^/ /" + echo + error "Cannot proceed." + fi + # start encryption + orig=$(mktemp /home/$USER_NAME.XXXXXXXX) + rm "$orig" && mv "$USER_HOME" "$orig" + chmod 700 "$orig" + mkdir -p -m 700 "$USER_HOME" + USER_GROUP=$(id -g "$USER_NAME") + chown "$USER_NAME:$USER_GROUP" "$USER_HOME" "$orig" + ECRYPTFS_SETUP_PRIVATE_ARGS="" + if [ -n "$LOGINPASS" ]; then + ECRYPTFS_SETUP_PRIVATE_ARGS="-l $LOGINPASS" + fi + if [ -n "$MOUNTPASS" ]; then + ECRYPTFS_SETUP_PRIVATE_ARGS="$ECRYPTFS_SETUP_PRIVATE_ARGS -m $MOUNTPASS" + fi + export ECRYPTFS_MIGRATE="1" + if ! ecryptfs-setup-private -u "$USER_NAME" -b $ECRYPTFS_SETUP_PRIVATE_ARGS; then + # too bad, something went wrong, we'll try to recover + rm -rf "$USER_HOME" + mv "$orig" "$USER_HOME" + exit 1 + fi + info "Encrypted home has been set up, encrypting files now...this may take a while." + # Show progress, but on stderr, in case the user wants to filter that out + rsync -aP "$orig/" "$USER_HOME/" 1>&2 + umount "$USER_HOME/" + echo + echo "========================================================================" + echo "Some Important Notes!" + echo + echo " 1. The file encryption appears to have completed successfully, however," + echo " $USER_NAME MUST LOGIN IMMEDIATELY, _BEFORE_THE_NEXT_REBOOT_," + echo " TO COMPLETE THE MIGRATION!!!" + echo + echo " 2. If $USER_NAME can log in and read and write their files, then the migration is complete," + echo " and you should remove $orig." + echo " Otherwise, restore $orig back to $USER_HOME." + echo + echo " 3. $USER_NAME should also run 'ecryptfs-unwrap-passphrase' and record" + echo " their randomly generated mount passphrase as soon as possible." + echo + echo " 4. To ensure the integrity of all encrypted data on this system, you" + echo " should also encrypt swap space with 'ecryptfs-setup-swap'." + echo "========================================================================" + echo +} + +DO_ENCRYPT= +while true; do + [ -z "$1" ] && break + case "$1" in + -u|--user) + DO_ENCRYPT=1 + USER_NAME="$2" + shift 2 + ;; + *) + usage + ;; + esac +done + +if [ "$DO_ENCRYPT" != "1" ]; then + usage +fi + +if [ "$(id -u)" != "0" ]; then + error "This program must be executed with root privileges" +fi + +if [ "$DO_ENCRYPT" = "1" ]; then + USER_HOME=$(get_user_home "$USER_NAME") + sanity_check "$USER_NAME" "$USER_HOME" + encrypt_dir "$USER_NAME" "$USER_HOME" "$LOGINPASS" "$MOUNTPASS" +fi diff --git a/src/utils/ecryptfs-mount-private b/src/utils/ecryptfs-mount-private new file mode 100755 index 0000000..c32708f --- /dev/null +++ b/src/utils/ecryptfs-mount-private @@ -0,0 +1,81 @@ +#!/bin/sh -e +# This script mounts a user's confidential private folder +# +# Original by Michael Halcrow, IBM +# Extracted to a stand-alone script by Dustin Kirkland <kirkland@ubuntu.com> +# +# This script: +# * interactively prompts for a user's wrapping passphrase (defaults to their +# login passphrase) +# * checks it for validity +# * unwraps a users mount passphrase with their supplied wrapping passphrase +# * inserts the mount passphrase into the keyring +# * and mounts a user's encrypted private folder + +PRIVATE_DIR="Private" +WRAPPING_PASS="LOGIN" +PW_ATTEMPTS=3 +TEXTDOMAIN="ecryptfs-utils" +MESSAGE=`gettext "Enter your login passphrase:"` + +if [ -f $HOME/.ecryptfs/wrapping-independent ]; then + # use a wrapping passphrase different from the login passphrase + WRAPPING_PASS="INDEPENDENT" + MESSAGE=`gettext "Enter your wrapping passphrase:"` +fi + +WRAPPED_PASSPHRASE_FILE="$HOME/.ecryptfs/wrapped-passphrase" +MOUNT_PASSPHRASE_SIG_FILE="$HOME/.ecryptfs/$PRIVATE_DIR.sig" + +# First, silently try to perform the mount, which would succeed if the appropriate +# key is available in the keyring +if /sbin/mount.ecryptfs_private >/dev/null 2>&1; then + exit 0 +fi + +# Otherwise, interactively prompt for the user's password +if [ -f "$WRAPPED_PASSPHRASE_FILE" -a -f "$MOUNT_PASSPHRASE_SIG_FILE" ]; then + tries=0 + stty_orig=`stty -g` + while [ $tries -lt $PW_ATTEMPTS ]; do + echo -n "$MESSAGE" + stty -echo + LOGINPASS=`head -n1` + stty $stty_orig + echo + if [ $(wc -l < "$MOUNT_PASSPHRASE_SIG_FILE") = "1" ]; then + # No filename encryption; only insert fek + if printf "%s\0" "$LOGINPASS" | ecryptfs-unwrap-passphrase "$WRAPPED_PASSPHRASE_FILE" - | ecryptfs-add-passphrase -; then + break + else + echo `gettext "ERROR:"` `gettext "Your passphrase is incorrect"` + tries=$(($tries + 1)) + continue + fi + else + if printf "%s\0" "$LOGINPASS" | ecryptfs-insert-wrapped-passphrase-into-keyring "$WRAPPED_PASSPHRASE_FILE" - ; then + break + else + echo `gettext "ERROR:"` `gettext "Your passphrase is incorrect"` + tries=$(($tries + 1)) + continue + fi + fi + done + if [ $tries -ge $PW_ATTEMPTS ]; then + echo `gettext "ERROR:"` `gettext "Too many incorrect password attempts, exiting"` + exit 1 + fi + /sbin/mount.ecryptfs_private +else + echo `gettext "ERROR:"` `gettext "Encrypted private directory is not setup properly"` + exit 1 +fi +if grep -qs "$HOME/.Private $PWD ecryptfs " /proc/mounts 2>/dev/null; then + echo + echo `gettext "INFO:"` `gettext "Your private directory has been mounted."` + echo `gettext "INFO:"` `gettext "To see this change in your current shell:"` + echo " cd $PWD" + echo +fi +exit 0 diff --git a/src/utils/ecryptfs-recover-private b/src/utils/ecryptfs-recover-private new file mode 100755 index 0000000..8a609f1 --- /dev/null +++ b/src/utils/ecryptfs-recover-private @@ -0,0 +1,123 @@ +#!/bin/sh -e +# +# ecryptfs-recover-private +# Copyright (C) 2010 Canonical Ltd. +# +# Authors: Dustin Kirkland <kirkland@ubuntu.com> +# +# 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, version 2 of the License. +# +# 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, see <http://www.gnu.org/licenses/>. + +error() { + echo "ERROR: $@" 1>&2 + exit 1 +} + +info() { + echo "INFO: $@" +} + +# We need root access to do the deep find and the mount +[ "$(id -u)" = "0" ] || error "This program must be run as root." + +# Handle parameters +opts="ro" +if [ "$1" = "--rw" ]; then + opts="rw" + shift +fi + +if [ -d "$1" ]; then + # Allow for target directories on the command line + dirs="$@" +else + # Otherwise, search the system for directories named ".Private" + info "Searching for encrypted private directories (this might take a while)..." + dirs=$(find / -type d -name ".Private") + if [ -z "$dirs" ]; then + info "Hint: click 'Places' and select your hard disk, then run this again." + error "No private directories found; make sure that your root filesystem is mounted." + fi +fi + +# Examine directories +for d in $dirs; do + if [ -d "$d" ]; then + info "Found [$d]." + echo -n "Try to recover this directory? [Y/n]: " + answer=$(head -n1) + case "$answer" in n*|N*) continue ;; esac + else + continue + fi + # Determine if filename encryption is on + ls "$d/ECRYPTFS_FNEK_ENCRYPTED"* >/dev/null 2>&1 && fnek="--fnek" || fnek= + if [ -f "$d/../.ecryptfs/wrapped-passphrase" ]; then + info "Found your wrapped-passphrase" + echo -n "Do you know your LOGIN passphrase? [Y/n] " + lpw=$(head -n1) + case "$lpw" in + y|Y|"") + # Use the wrapped-passphrase, if available + info "Enter your LOGIN passphrase..." + ecryptfs-insert-wrapped-passphrase-into-keyring "$d/../.ecryptfs/wrapped-passphrase" + sigs=$(sed -e "s/[^0-9a-f]//g" "$d/../.ecryptfs/Private.sig") + use_mount_passphrase=0 + ;; + *) + use_mount_passphrase=1 + ;; + esac + else + # Fall back to mount passphrase + info "Could not find your wrapped passphrase file." + use_mount_passphrase=1 + fi + if [ "$use_mount_passphrase" = "1" ]; then + + info "To recover this directory, you MUST have your original MOUNT passphrase." + info "When you first setup your encrypted private directory, you were told to record" + info "your MOUNT passphrase." + info "It should be 32 characters long, consisting of [0-9] and [a-f]." + echo + echo -n "Enter your MOUNT passphrase: " + stty_orig=$(stty -g) + stty -echo + passphrase=$(head -n1) + stty $stty_orig + echo + sigs=$(printf "%s\0" "$passphrase" | ecryptfs-add-passphrase $fnek | grep "^Inserted" | sed -e "s/^.*\[//" -e "s/\].*$//" -e "s/[^0-9a-f]//g") + fi + case $(echo "$sigs" | wc -l) in + 1) + mount_sig=$(echo "$sigs" | head -n1) + fnek_sig= + mount_opts="$opts,ecryptfs_sig=$mount_sig,ecryptfs_cipher=aes,ecryptfs_key_bytes=16" + ;; + 2) + mount_sig=$(echo "$sigs" | head -n1) + fnek_sig=$(echo "$sigs" | tail -n1) + mount_opts="$opts,ecryptfs_sig=$mount_sig,ecryptfs_fnek_sig=$fnek_sig,ecryptfs_cipher=aes,ecryptfs_key_bytes=16" + ;; + *) + continue + ;; + esac + (keyctl list @u | grep -qs "$mount_sig") || error "The key required to access this private data is not available." + (keyctl list @u | grep -qs "$fnek_sig") || error "The key required to access this private data is not available." + tmpdir=$(mktemp -d /tmp/ecryptfs.XXXXXXXX) + if mount -i -t ecryptfs -o "$mount_opts" "$d" "$tmpdir"; then + info "Success! Private data mounted at [$tmpdir]." + else + error "Failed to mount private data at [$tmpdir]." + fi +done diff --git a/src/utils/ecryptfs-rewrite-file b/src/utils/ecryptfs-rewrite-file new file mode 100755 index 0000000..c4f67f5 --- /dev/null +++ b/src/utils/ecryptfs-rewrite-file @@ -0,0 +1,75 @@ +#!/bin/sh -e +# +# ecryptfs-rewrite-file +# Copyright (C) 2008 Canonical Ltd. +# +# Authors: Dustin Kirkland <kirkland@ubuntu.com> +# +# 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, version 2 of the License. +# +# 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, see <http://www.gnu.org/licenses/>. + +TEXTDOMAIN="ecryptfs-utils" + +error() { + echo `gettext "[FAILED]"` + echo `gettext "ERROR:"` "$1" 1>&2 +} +j=0 +OKs=0 +for i in "$@"; do + j=`expr $j + 1` + echo -n `gettext "INFO:"` `gettext "Rewriting"` "[$j/$#] [$i] ... " + if [ ! -e "$i" ] ; then + error `gettext "File does not exist"` + continue + fi + if [ "$i" = "." ]; then + echo `gettext "[EXCLUDED]"` >&2 + continue + fi + opt= + if [ -d "$i" -a ! -h "$i" ]; then + # A directory, re-encrypt the filename + temp1=`mktemp -d "$i".XXXXXXXXXX` || { + error `gettext "Could not create tempdir"` + continue + } + mv -f -T "$i" "$temp1" 2>/dev/null || { + error `gettext "Could not rename"` "[$i] -> [$temp1]" + rmdir "$temp1" + continue + } + mv -f "$temp1" "$i" 2>/dev/null || { + error `gettext "Could not rename"` "[$temp1] -> [$i]" + } + else + # A file or symlink, re-encrypt the contents + temp1=`mktemp "$i".XXXXXXXXXX` || { + error `gettext "Could not create tempfile"` + continue + } + cp -a "$i" "$temp1" 2>/dev/null || { + error `gettext "Could not copy"` "[$i] -> [$temp1]" + rm -f "$temp1" + continue + } + mv -f "$temp1" "$i" 2>/dev/null || { + error `gettext "Could not rename"` "[$temp1] -> [$i]" + continue + } + fi + echo `gettext "[OK]"` + OKs=$((OKs+1)) +done +echo "$OKs/$j" `gettext "rewrites succeeded"` +[ $OKs -ne $j ] && exit 1 +exit 0 diff --git a/src/utils/ecryptfs-setup-private b/src/utils/ecryptfs-setup-private new file mode 100755 index 0000000..5969ed2 --- /dev/null +++ b/src/utils/ecryptfs-setup-private @@ -0,0 +1,464 @@ +#!/bin/sh +# This script sets up an ecryptfs mount in a user's ~/Private +# +# Originally ecryptfs-setup-pam-wrapped.sh by Michael Halcrow, IBM +# +# Ported for use on Ubuntu by Dustin Kirkland <kirkland@ubuntu.com> +# Copyright (C) 2008 Canonical Ltd. +# Copyright (C) 2007-2008 International Business Machines +PRIVATE_DIR="Private" +WRAPPING_PASS="LOGIN" +ECRYPTFS_DIR="/home/.ecryptfs" +PW_ATTEMPTS=3 +TEXTDOMAIN="ecryptfs-utils" +MESSAGE="$(gettext 'Enter your login passphrase')" +CIPHER="aes" +KEYBYTES="16" +FNEK= + +# Zero out user-defined GREP_OPTIONS, such as --line-number +GREP_OPTIONS= + +usage() { + echo " +Usage: + +$0 [-f|--force] [-w|--wrapping] [--nopwcheck] [-n|--no-fnek] + [-u|--username USER] [-l|--loginpass LOGINPASS] + [-m|--mountpass MOUNTPASS] + + -f, --force Force overwriting of an existing setup + -w, --wrapping Use an independent wrapping passphrase, + different from the login passphrase + -n, --no-fnek Do not encrypt filenames; If this flag is + omitted, and the kernel supports filename + encryption, then filenames will be encrypted + -u, --username Username for encrypted private mountpoint, + defaults to yourself + -l, --loginpass Login/Wrapping passphrase for USER, + used to wrap MOUNTPASS + --nopwcheck Do not check the validity of the specified + login password (useful for LDAP user accounts) + --noautomount Setup this user such that the encrypted private + directory is not automatically mounted on login + --noautoumount Setup this user such that the encrypted private + directory is not automatically unmounted at + logout + -m, --mountpass Passphrase for mounting the ecryptfs directory, + defaults to randomly generated $KEYBYTES bytes + -b, --bootstrap Bootstrap a new user's entire home directory + Generates a random mount passphrase, which + will be wrapped when the new login passphrase + is set. SHOULD ONLY BE CALLED FROM 'adduser'. + --undo Provide instructions on how to undo an + encrypted private setup + + Be sure to properly escape your parameters according to your + shell's special character nuances, and also surround the + parameters by double quotes, if necessary. +" + exit 1 +} + +undo_msg() { + echo " +In the event that you want to remove your eCryptfs Private Directory setup, +you will need to very carefully perform the following actions manually: + + 1. Obtain your Private directory mountpoint + $ PRIVATE=\`cat ~/.ecryptfs/Private.mnt 2>/dev/null || echo \$HOME/$PRIVATE_DIR\` + 2. Ensure that you have moved all relevant data out of your \$PRIVATE directory + 3. Unmount your encrypted private directory + $ ecryptfs-umount-private + 4. Make your Private directory writable again + $ chmod 700 \$PRIVATE + 5. Remove \$PRIVATE, ~/.Private, ~/.ecryptfs + Note: THIS IS VERY PERMANENT, BE VERY CAREFUL + $ rm -rf \$PRIVATE ~/.Private ~/.ecryptfs + 6. Uninstall the utilities (this is specific to your Linux distribution) + $ sudo apt-get remove ecryptfs-utils libecryptfs0 +" +} + +error() { + echo "$(gettext 'ERROR: ')" "$@" 1>&2 + exit 1 +} + +error_testing() { + rm -f "$1" >/dev/null + shift + /sbin/umount.ecryptfs_private >/dev/null + error "$@" + exit 1 +} + +random_passphrase () { + bytes=$1 + # Pull $1 of random data from /dev/urandom, + # and convert to a string of hex digits + od -x -N $bytes --width=$bytes /dev/urandom | head -n 1 | sed "s/^0000000//" | sed "s/\s*//g" +} + +filename_encryption_available() { + version=$(cat /sys/fs/ecryptfs/version 2>/dev/null) + [ -z "$version" ] && error "$(gettext 'Cannot get ecryptfs version, ecryptfs kernel module not loaded?')" + [ $(($version & 0x100)) -eq 0 ] && return 1 + return 0 +} + +filename_encryption_available && FNEK="--fnek" + +if [ ! -z "$SUDO_USER" ]; then + USER="$SUDO_USER" +fi + +while [ ! -z "$1" ]; do + case "$1" in + -u|--username) + USER="$2" + shift 2 + ;; + -l|--loginpass) + LOGINPASS="$2" + shift 2 + ;; + -m|--mountpass) + MOUNTPASS="$2" + shift 2 + ;; + -w|--wrapping) + WRAPPING_PASS="INDEPENDENT" + MESSAGE="$(gettext 'Enter your wrapping passphrase')" + shift 1 + ;; + -f|--force) + FORCE=1 + shift 1 + ;; + --nopwcheck) + NOPWCHECK=1 + shift 1 + ;; + --noautomount) + NOAUTOMOUNT=1 + shift 1 + ;; + --noautoumount) + NOAUTOUMOUNT=1 + shift 1 + ;; + --undo) + undo_msg + exit 0 + ;; + -b|--bootstrap) + [ `whoami` = "root" ] || error "$(gettext 'You must be root to bootstrap encrypt a home directory')" + BOOTSTRAP=1 + MOUNTPASS=`random_passphrase $KEYBYTES` + RANDOM_MOUNTPASS=1 + shift 1 + ;; + -n|--no-fnek) + FNEK= + shift 1 + ;; + *) + usage + ;; + esac +done + +# Prompt for the USER name, if not on the command line and not in the env +if [ -z "$USER" ]; then + while [ true ]; do + echo -n "$(gettext 'Enter the username: ')" + USER=`head -n1` + echo + if [ -z "$USER" ]; then + echo "$(gettext 'ERROR: ')" "$(gettext 'You must provide a username')" + continue + else + # Verify that the user exists + if ! id "$USER" >/dev/null; then + echo "$(gettext 'ERROR: ')" "$(gettext 'User does not exist')" " [$USER]" + continue + fi + break + fi + done +else + # Verify that the user exists + id "$USER" >/dev/null || error "$(gettext 'User does not exist')" "[$USER]" +fi + +# Obtain USER's primary group +GROUP=$(id -g $USER) + +# Check if the ecryptfs group exists, and user is member of ecryptfs group +if grep -qs "^ecryptfs:" /etc/group; then + if ! id "$USER" | grep -qs "\(ecryptfs\)"; then + error "$(gettext 'User needs to be a member of ecryptfs group')" + fi +fi + +# Obtain the user's home directory +HOME=`getent passwd "$USER" | awk -F: '{print $6}'` +if [ ! -d "$HOME" ]; then + error "$(gettext 'User home directory does not exist')" "[$HOME]" +fi + +if [ "$BOOTSTRAP" = "1" ]; then + # If we want to encrypt the entire homedir, we need the .ecryptfs + # config dir elsewhere, but linked into the homedir + mkdir -p -m 700 $ECRYPTFS_DIR/$USER/.ecryptfs + ln -sf $ECRYPTFS_DIR/$USER/.ecryptfs $HOME/.ecryptfs + ln -sf $ECRYPTFS_DIR/$USER/.$PRIVATE_DIR $HOME/.$PRIVATE_DIR + MOUNTPOINT="$HOME" + CRYPTDIR="$ECRYPTFS_DIR/$USER/.$PRIVATE_DIR" +else + mkdir -p -m 700 $HOME/.ecryptfs + MOUNTPOINT="$HOME/$PRIVATE_DIR" + CRYPTDIR="$HOME/.$PRIVATE_DIR" +fi + +# Check for previously setup private directory +if [ -s "$HOME/.ecryptfs/wrapped-passphrase" -a "$FORCE" != "1" ]; then + error "$(gettext 'wrapped-passphrase file already exists, use --force to overwrite.')" +fi +if [ -s "$HOME/.ecryptfs/$PRIVATE_DIR.sig" -a "$FORCE" != "1" ]; then + error "$PRIVATE_DIR.sig" "$(gettext 'file already exists, use --force to overwrite.')" +fi + +# Check for active mounts +grep -qs "$MOUNTPOINT " /proc/mounts && error "[$MOUNTPOINT]" "$(gettext 'is already mounted')" +grep -qs "$CRYPTDIR " /proc/mounts && error "[$CRYPTDIR]" "$(gettext 'is already mounted')" + +# Check that the mount point and encrypted directory are empty (skip symlinks). +# Perhaps one day we could provide a migration mode (using rsync or something), +# but this would be VERY hard to do safely. +count=`ls -Al "$MOUNTPOINT" 2>/dev/null | egrep -c "^[drwx-]{10}"` +if [ "$count" != "0" ]; then + error "$MOUNTPOINT" "$(gettext 'must be empty before proceeding')" +fi +count=`ls -Al "$CRYPTDIR" 2>/dev/null | egrep -c "^[dlrwx-]{10}"` +if [ "$count" != "0" ]; then + error "$CRYPTDIR" "$(gettext 'must be empty before proceeding')" +fi + +stty_orig=`stty -g` +# Prompt for the LOGINPASS, if not on the command line and not in the env +if [ -z "$LOGINPASS" ] && ( [ "$BOOTSTRAP" != "1" ] || [ "$ECRYPTFS_MIGRATE" = "1" ] ); then + tries=0 + while [ $tries -lt $PW_ATTEMPTS ]; do + stty -echo + echo -n "$MESSAGE [$USER]: " + LOGINPASS=`head -n1` + stty $stty_orig + echo + if [ $WRAPPING_PASS != "LOGIN" -o ! -x /sbin/unix_chkpwd ]; then + # If we can't check the accuracy of the user's entered + # passphrase, force them to type it twice (matching) + stty -echo + echo -n "$MESSAGE [$USER] (again): " + LOGINPASS2=`head -n1` + stty $stty_orig + echo + if [ "$LOGINPASS" != "$LOGINPASS2" ]; then + echo "$(gettext 'ERROR: ')" "$(gettext 'Wrapping passphrases must match')" + else + break + fi + tries=$(($tries + 1)) + continue + fi + if [ -z "$LOGINPASS" ]; then + echo "$(gettext 'ERROR: ')" "$(gettext 'You must provide a login passphrase')" + tries=$(($tries + 1)) + else + if [ "$NOPWCHECK" = "1" ]; then + echo "$(gettext 'INFO:')" "$(gettext 'Skipping password verification')" + break + else + if printf "%s\0" "$LOGINPASS" | /sbin/unix_chkpwd "$USER" nullok; then + break + else + echo "$(gettext 'ERROR: ')" "$(gettext 'Your login passphrase is incorrect')" + tries=$(($tries + 1)) + fi + fi + fi + done + if [ $tries -ge $PW_ATTEMPTS ]; then + error "$(gettext 'Too many incorrect password attempts, exiting')" + fi +fi + +# Prompt for the MOUNTPASS, if not on the command line and not in the env +if [ -z "$MOUNTPASS" ]; then + tries=0 + while [ $tries -lt $PW_ATTEMPTS ]; do + stty -echo + echo -n "$(gettext 'Enter your mount passphrase [leave blank to generate one]: ')" + MOUNTPASS=`head -n1` + stty $stty_orig + echo + if [ -z "$MOUNTPASS" ]; then + MOUNTPASS=`random_passphrase $KEYBYTES` + RANDOM_MOUNTPASS=1 + break + else + stty -echo + echo -n "$(gettext 'Enter your mount passphrase (again): ')" + MOUNTPASS2=`head -n1` + stty $stty_orig + echo + if [ "$MOUNTPASS" != "$MOUNTPASS2" ]; then + echo "$(gettext 'ERROR: ')" "$(gettext 'Mount passphrases do not match')" + tries=$(($tries + 1)) + else + break + fi + fi + done + if [ $tries -ge $PW_ATTEMPTS ]; then + error "$(gettext 'Too many incorrect passphrase attempts, exiting')" + fi +fi + +echo +echo "************************************************************************" +echo "$(gettext 'YOU SHOULD RECORD YOUR MOUNT PASSPHRASE AND STORE IT IN A SAFE LOCATION.')" +echo " ecryptfs-unwrap-passphrase ~/.ecryptfs/wrapped-passphrase" +echo "$(gettext 'THIS WILL BE REQUIRED IF YOU NEED TO RECOVER YOUR DATA AT A LATER TIME.')" +echo "************************************************************************" +echo + +############################################################################### + +# Setup private directory in home +mkdir -m 700 -p "$CRYPTDIR" || error "$(gettext 'Could not create crypt directory')" "[$CRYPTDIR]" +mkdir -m 700 -p "$MOUNTPOINT" || error "$(gettext 'Could not create mount directory')" "[$MOUNTPOINT]" +ln -sf /usr/share/ecryptfs-utils/ecryptfs-mount-private.txt "$MOUNTPOINT"/README.txt +ln -sf /usr/share/ecryptfs-utils/ecryptfs-mount-private.desktop "$MOUNTPOINT"/Access-Your-Private-Data.desktop +chmod 500 "$MOUNTPOINT" + +# Setup ~/.ecryptfs directory +if [ "$NOAUTOMOUNT" = "1" ]; then + echo "$(gettext 'INFO:')" "$HOME/$PRIVATE_DIR" "$(gettext 'will not be mounted on login')" +else + touch $HOME/.ecryptfs/auto-mount || error "$(gettext 'Could not setup ecryptfs auto-mount')" +fi +if [ "$NOAUTOUMOUNT" = "1" ]; then + echo "$(gettext 'INFO:')" "$HOME/$PRIVATE_DIR" "$(gettext 'will not be unmounted on logout')" +else + touch $HOME/.ecryptfs/auto-umount || error "$(gettext 'Could not setup ecryptfs auto-umount')" +fi + +if [ "$WRAPPING_PASS" = "LOGIN" ]; then + rm -f $HOME/.ecryptfs/wrapping-independent || error "$(gettext 'Could not remove ecryptfs wrapping-independent')" +else + touch $HOME/.ecryptfs/wrapping-independent || error "$(gettext 'Could not setup ecryptfs wrapping-independent')" +fi + + +# Backup any existing wrapped-passphrase or sig files; we DO NOT destroy this +timestamp=`date +%Y%m%d%H%M%S` +for i in "$HOME/.ecryptfs/wrapped-passphrase" "$HOME/.ecryptfs/$PRIVATE_DIR.sig"; do + if [ -s "$i" ]; then + mv -f "$i" "$i.$timestamp" || error "(gettext 'Could not backup existing data')" "[$i]" + fi +done + +# Setup wrapped-passphrase file +u=`umask` +umask 377 +if [ -z "$LOGINPASS" ] && [ "$BOOTSTRAP" = "1" ]; then + # This will be wrapped by pam_ecryptfs's chauthtok as soon as the user + # chooses a password. Until that happens (hopefully soon), standard + # file permissions (600) are all that's protecting it. Write it to + # ramdisk, to keep it from leaking to the hard-drive. + temp=`mktemp /dev/shm/.ecryptfs-XXXXXX` + printf "%s" "$MOUNTPASS" > "$temp" + mv -f -T "$temp" "/dev/shm/.ecryptfs-$USER" || error "Could not create passphrase file" +else + printf "%s\n%s" "$MOUNTPASS" "$LOGINPASS" | ecryptfs-wrap-passphrase "$HOME/.ecryptfs/wrapped-passphrase" - || error "$(gettext 'Could not wrap passphrase')" +fi +umask $u + +# Add the passphrase to current keyring +# On subsequent logins, this should be handled by "pam_ecryptfs.so unwrap" +response=`printf "%s" "$MOUNTPASS" | ecryptfs-add-passphrase $FNEK -` +if [ $? -ne 0 ]; then + error "$(gettext 'Could not add passphrase to the current keyring')" +fi +sig=`echo "$response" | grep "Inserted auth tok" | sed "s/^.*\[//" | sed "s/\].*$//"` +if ! echo "$sig" | egrep -qs "^[0-9a-fA-F]{$KEYBYTES,$KEYBYTES}$"; then + error "$(gettext 'Could not obtain the key signature')" +fi +temp=`mktemp` +echo "$sig" > "$temp" || error "$(gettext 'Could not create signature file')" "[$HOME/.ecryptfs/$PRIVATE_DIR.sig]" +mv "$temp" "$HOME/.ecryptfs/$PRIVATE_DIR.sig" +which restorecon 2>/dev/null && restorecon "$HOME/.ecryptfs/$PRIVATE_DIR.sig" > /dev/null 2>&1 +temp=`mktemp` +echo "$MOUNTPOINT" > "$temp" || error "$(gettext 'Could not create mountpoint file')" "[$HOME/.ecryptfs/$PRIVATE_DIR.mnt]" +mv "$temp" "$HOME/.ecryptfs/$PRIVATE_DIR.mnt" +which restorecon 2>/dev/null && restorecon "$HOME/.ecryptfs/$PRIVATE_DIR.mnt" > /dev/null 2>&1 + +echo +echo "$(gettext 'Done configuring.')" +echo + +# Skip the tests if we're in bootstrap mode, but exit with the encrypted +# homedir mounted +if [ "$BOOTSTRAP" = "1" ]; then + # Force the mount here, since the root user has the key loaded, + # and the calling 'adduser' is about to copy over /etc/skel + # NOTE: it is the responsibility of 'adduser' to unmount! + # And ensure that $USER owns the files/dirs we've created as root + chown $USER:$GROUP "$CRYPTDIR" /dev/shm/.ecryptfs-$USER + chown -R $USER:$GROUP $ECRYPTFS_DIR/$USER + chown -R $USER:$GROUP $MOUNTPOINT + if [ "$FNEK" = "--fnek" ]; then + fnek_sig=`tail -n 1 "$HOME/.ecryptfs/$PRIVATE_DIR.sig"` + sig=`head -n 1 "$HOME/.ecryptfs/$PRIVATE_DIR.sig"` + sig_opt="ecryptfs_sig=$sig,ecryptfs_fnek_sig=$fnek_sig" + else + sig_opt="ecryptfs_sig=$sig" + fi + # Do the mount, and provide some helpful symlinks + mount -i -t ecryptfs -o "rw,$sig_opt,ecryptfs_cipher=$CIPHER,ecryptfs_key_bytes=$KEYBYTES" "$CRYPTDIR" "$MOUNTPOINT" || error "Could not mount" + ln -sf $ECRYPTFS_DIR/$USER/.ecryptfs $MOUNTPOINT/.ecryptfs + ln -sf $ECRYPTFS_DIR/$USER/.$PRIVATE_DIR $MOUNTPOINT/.$PRIVATE_DIR + chown -R $USER:$GROUP $ECRYPTFS_DIR/$USER + chown -R $USER:$GROUP $MOUNTPOINT + exit 0 +fi + +# Now let's perform some basic mount/write/umount/read sanity testing... +echo "$(gettext 'Testing mount/write/umount/read...')" +printf "%s" "$MOUNTPASS" | ecryptfs-add-passphrase $FNEK - +/sbin/mount.ecryptfs_private || error "$(gettext 'Could not mount private ecryptfs directory')" +temp=`mktemp "$MOUNTPOINT/ecryptfs.test.XXXXXX"` || error_testing "$temp" "$(gettext 'Could not create empty file')" +random_data=`head -c 16000 /dev/urandom | od -x` || error_testing "$temp" "$(gettext 'Could not generate random data')" +echo "$random_data" > "$temp" || error_testing "$temp" "$(gettext 'Could not write encrypted file')" +md5sum1=`md5sum "$temp"` || error_testing "$temp" "$(gettext 'Could not read encrypted file')" +/sbin/umount.ecryptfs_private || error_testing "$temp" "$(gettext 'Could not unmount private ecryptfs directory')" +printf "%s" "$MOUNTPASS" | ecryptfs-add-passphrase $FNEK - +/sbin/mount.ecryptfs_private || error_testing "$temp" "$(gettext 'Could not mount private ecryptfs directory (2)')" +md5sum2=`md5sum "$temp"` || error_testing "$temp" "$(gettext 'Could not read encrypted file (2)')" +rm -f "$temp" +# Use ecryptfs-umount-private on the final run, to clear the used keys +# out of the keyring +ecryptfs-umount-private || error_testing "$temp" "$(gettext 'Could not unmount private ecryptfs directory (2)')" +if [ "$md5sum1" != "$md5sum2" ]; then + error "$(gettext 'Testing failed.')" +else + echo "$(gettext 'Testing succeeded.')" +fi + +echo +echo "$(gettext 'Logout, and log back in to begin using your encrypted directory.')" +echo + +exit 0 diff --git a/src/utils/ecryptfs-setup-swap b/src/utils/ecryptfs-setup-swap new file mode 100755 index 0000000..042c743 --- /dev/null +++ b/src/utils/ecryptfs-setup-swap @@ -0,0 +1,181 @@ +#!/bin/sh -e +# ecryptfs-setup-swap +# Copyright (C) 2008 Canonical Ltd. +# +# Authors: Dustin Kirkland <kirkland@ubuntu.com> +# +# 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; version 2 of the License. +# +# 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, see <http://www.gnu.org/licenses/>. + +# The cryptswap setup used here follows a guide published at: +# * http://ubuntumagnet.com/2007/11/creating-encrypted-swap-file-ubuntu-using-cryptsetup + +TEXTDOMAIN="ecryptfs-utils" + +error() { + echo `gettext "ERROR:"` "$@" 1>&2 + exit 1 +} + +info() { + echo `gettext "INFO:"` "$@" +} + +warn() { + echo `gettext "WARNING:"` "$@" 1>&2 +} + +usage() { + echo + echo `gettext "Usage:"` + echo " $0 [-f|--force] [-n|--no-reload]" + echo + exit 1 +} + +# Handle command line options +FORCE=0 +while [ ! -z "$1" ]; do + case "$1" in + -f|--force) + FORCE=1 + shift 1 + ;; + -n|--no-reload) + NO_RELOAD=1 + shift 1 + ;; + *) + usage + ;; + esac +done + +# Ensure that cryptsetup is available +[ -x /sbin/cryptsetup ] || error `gettext "Please install"` "'cryptsetup'" + +# Ensure that we're running with root privileges +[ -w /etc/passwd ] || error `gettext "This program must be run with 'sudo', or as root"` + +# Count swap spaces available +if [ $(grep -c "^/" /proc/swaps) -eq 0 ]; then + mem=$(grep "^MemTotal:" /proc/meminfo | awk '{print $2}') + swapsize=$((4*$mem)) + info "You do not currently have any swap space defined." + echo + echo `gettext "You can create a swap file by doing:"` + echo " $ sudo dd if=/dev/zero of=/swapfile count=$swapsize" + echo " $ sudo mkswap /swapfile" + echo " $ sudo swapon /swapfile" + echo + echo `gettext "And then re-run"` "$0" + echo + exit 0 +fi + +swaps=$(grep "^/" /proc/swaps | awk '{print $1}') + +filtered_swaps=$( +for swap in $swaps; do + # Make sure this is swap space + if [ "$(blkid -o value -s TYPE $swap)" != "swap" ]; then + warn "[$swap]" `gettext "does not appear to be swap space, skipping."` + continue + fi + + if [ "${swap#/dev/ram}" != "$swap" ] || [ "${swap#/dev/zram}" != "$swap" ]; then + warn "[$swap]" `gettext "is a RAM device, skipping."` + continue + fi + + # Check if this swap space is already setup for encryption + if /sbin/dmsetup table "$swap" 2>/dev/null | grep -qs " crypt "; then + warn "[$swap]" `gettext "already appears to be encrypted, skipping."` + continue + fi + + base=$(basename "$swap") + if grep -qs "^$base.*swap.*cipher" /etc/crypttab 2>/dev/null; then + warn "[$swap]" `gettext "already has an entry in /etc/crypttab, skipping."` + continue + fi + if grep -qs "$swap" /etc/initramfs-tools/conf.d/cryptroot 2>/dev/null; then + warn "[$swap]" `gettext "already has an entry in /etc/crypttab, skipping."` + continue + fi + + echo $swap +done +) +swaps="$filtered_swaps" +if [ -z "$swaps" ]; then + warn "There were no usable swap devices to be encrypted. Exiting." + exit 0 +fi +########################################################################## +# Warn the user about breaking hibernate mode +if [ "$FORCE" != 1 ]; then + echo + echo `gettext "WARNING:"` + echo `gettext "An encrypted swap is required to help ensure that encrypted files are not leaked to disk in an unencrypted format."` + echo + echo `gettext "HOWEVER, THE SWAP ENCRYPTION CONFIGURATION PRODUCED BY THIS PROGRAM WILL BREAK HIBERNATE/RESUME ON THIS SYSTEM!"` + echo + echo `gettext "NOTE: Your suspend/resume capabilities will not be affected."` + echo + echo -n `gettext "Do you want to proceed with encrypting your swap?"` "[y/N]: " + CONFIRM=`head -n1` + echo + if [ "$CONFIRM" != "y" -a "$CONFIRM" != "Y" ]; then + echo + info `gettext "Aborting."` + echo + exit 0 + fi +fi +########################################################################## + + +i=0 +for swap in $swaps; do + info `gettext "Setting up swap:"` "[$swap]" + uuid=$(blkid -o value -s UUID $swap) + for target in "UUID=$uuid" $swap; do + if [ -n "$target" ] && grep -qs "^$target " /etc/fstab; then + sed -i "s:^$target :\#$target :" /etc/fstab + warn "Commented out your unencrypted swap from /etc/fstab" + fi + done + + while :; do + i=$((i+1)) + [ -e "/dev/mapper/cryptswap$i" ] || break + done + # Add crypttab entry + echo "cryptswap$i UUID=$uuid /dev/urandom swap,cipher=aes-cbc-essiv:sha256" >> /etc/crypttab + + # Add fstab entry + echo "/dev/mapper/cryptswap$i none swap sw 0 0" >> /etc/fstab +done + +if [ "$NO_RELOAD" != 1 ]; then + # Turn swap off + swapoff -a + + # Restart cryptdisks + /etc/init.d/cryptdisks restart + + # Turn the swap on + swapon -a +fi + +info `gettext "Successfully setup encrypted swap!"` diff --git a/src/utils/ecryptfs-stat.c b/src/utils/ecryptfs-stat.c new file mode 100644 index 0000000..dda3310 --- /dev/null +++ b/src/utils/ecryptfs-stat.c @@ -0,0 +1,75 @@ +/** + * Present statistics on encrypted eCryptfs file attributes + */ + +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "../include/ecryptfs.h" + +static void usage(const char *filename) +{ + printf("Usage:\n\n" + "%s <filename>\n", filename); +} + +int main(int argc, const char *argv[]) +{ + const char *filename; + int fd = -1; + ssize_t quant_read; + struct ecryptfs_crypt_stat_user crypt_stat; + char buf[4096]; + int rc = 0; + + if (argc == 1) { + usage(argv[0]); + goto out; + } + filename = argv[1]; + fd = open(filename, O_RDONLY); + if (fd == -1) { + printf("Error opening file [%s] for RD_ONLY access; errno msg " + "= [%m]\n", filename); + rc = -EIO; + goto out; + } + quant_read = read(fd, buf, 4096); + if (quant_read == -1) { + printf("Error attempting to read from file [%s]; errno msg " + "= [%m]\n", filename); + rc = -EIO; + goto out; + } + rc = ecryptfs_parse_stat(&crypt_stat, buf, quant_read); + if (rc) { + printf("Valid eCryptfs metadata information not found in [%s]" + "\n", filename); + rc = 0; + goto out; + } + printf("File version: [%d]\n", crypt_stat.file_version); + printf("Decrypted file size: [%llu]\n", + (unsigned long long)crypt_stat.file_size); + printf("Number of header bytes at front of file: [%zu]\n", + crypt_stat.num_header_bytes_at_front); + if (crypt_stat.flags & ECRYPTFS_METADATA_IN_XATTR) + printf("Metadata in the extended attribute region\n"); + else + printf("Metadata in the header region\n"); + if (crypt_stat.flags & ECRYPTFS_ENCRYPTED) + printf("Encrypted\n"); + else + printf("Plaintext\n"); + if (crypt_stat.flags & ECRYPTFS_ENABLE_HMAC) + printf("HMAC enabled\n"); + else + printf("HMAC disabled\n"); +out: + if (fd != -1) + close(fd); + return rc; +} diff --git a/src/utils/ecryptfs-umount-private b/src/utils/ecryptfs-umount-private new file mode 100755 index 0000000..28e0b08 --- /dev/null +++ b/src/utils/ecryptfs-umount-private @@ -0,0 +1,26 @@ +#!/bin/sh -e +# This script unmounts a user's private ecryptfs folder +# and clears the kernel keyring of the relevant keys +# +# Original by Michael Halcrow, IBM +# Extracted to a stand-alone script by Dustin Kirkland <kirkland@ubuntu.com> + +TEXTDOMAIN="ecryptfs-utils" + +if grep -qs "$HOME/.Private $PWD ecryptfs " /proc/mounts 2>/dev/null; then + pwd_mounted=1 +fi +if /sbin/umount.ecryptfs_private; then + for sig in `cat "$HOME/.ecryptfs/Private.sig"`; do + for key_id in `keyctl list @u | grep "$sig$" | awk -F: '{print $1}'`; do + keyctl unlink "$key_id" @u + done + done + if [ "$pwd_mounted" = "1" ]; then + echo + echo `gettext "INFO:"` `gettext "Your private directory has been unmounted."` + echo `gettext "INFO:"` `gettext "To see this change in your current shell:"` + echo " cd $PWD" + echo + fi +fi diff --git a/src/utils/ecryptfs-verify b/src/utils/ecryptfs-verify new file mode 100755 index 0000000..b55641d --- /dev/null +++ b/src/utils/ecryptfs-verify @@ -0,0 +1,245 @@ +#!/bin/sh -e +# ecryptfs-verify +# Copyright (C) 2011 Dustin Kirkland <kirkland@ubuntu.com> +# +# Authors: Dustin Kirkland <kirkland@ubuntu.com> +# +# 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; version 2 of the License. +# +# 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, see <http://www.gnu.org/licenses/>. + +error() { + echo `gettext "ERROR:"` "$@" 1>&2 + echo `gettext "ERROR:"` "Configuration invalid" 1>&2 + exit 1 +} + +info() { + echo `gettext "INFO:"` "$@" +} + +usage() { + echo " +Usage: +ecryptfs-verify [-h|--home] [-p|--private] [-e|--filenames-encrypted] [-n|--filenames-not-encrypted] [-u|--user USER] [--help] + + -h|--home True if HOME is correctly configured for + encryption, False otherwise + + -p|--private True if a non-HOME directory is correctly + configured for encryption, False otherwise + + -e|--filenames-encrypted True if filenames are set for encryption, + False otherwise + + -n|--filenames-not-encrypted True if filenames are not encrypted, + False otherwise + + -u|--user USER By default, the current user's configuration + is checked, override with this option + + --help This usage information + + Note that options are additive. ALL checks must pass in order for this + program to exit 0. Any failing check will cause this program to exit + non-zero. + +" + return 1 +} + +ecryptfs_exists() { + local dotecryptfs="$1/.ecryptfs" + if [ -d "$dotecryptfs" ]; then + info "[$dotecryptfs] exists" + else + error "[$dotecryptfs] does not exist" + fi + return 0 +} + +sigfile_valid() { + local sigfile="$1/.ecryptfs/Private.sig" + if [ -f "$sigfile" ]; then + info "[$sigfile] exists" + else + error "[$sigfile] does not exist" + fi + local c=$(wc -l "$sigfile" | awk '{print $1}') + if [ "$c" = "1" ] || [ "$c" = "2" ]; then + info "[$sigfile] contains [$c] signatures" + else + error "[$sigfile] does not contain exactly 1 or 2 lines" + fi + return 0 +} + +mountfile_valid() { + local mountfile="$1/.ecryptfs/Private.mnt" + if [ -f "$mountfile" ]; then + info "[$mountfile] exists" + else + error "[$mountfile] does not exist" + fi + local m=$(cat "$mountfile") + if [ -d "$m" ]; then + info "[$m] is a directory" + else + error "[$m] is not a directory" + fi + return 0 +} + +automount_true() { + local home="$1" + local automount="$1/.ecryptfs/auto-mount" + if [ -f "$automount" ]; then + info "[$automount] Automount is set" + else + error "[$home/.ecryptfs/auto-mount] does not exist" + fi + return 0 +} + +owns_mountpoint() { + local owner=$(stat -c "%U" "$2") + if [ "$owner" = "$1" ]; then + info "Ownership [$owner] of mount point [$2] is correct" + else + error "Invalid owner [$owner] of mount point [$2]" + fi +} + +mount_is_home() { + local home="$1" + local mountfile="$home/.ecryptfs/Private.mnt" + local m=$(cat "$mountfile") + if [ "$m" = "$home" ]; then + info "Mount point [$m] is the user's home" + else + error "Mount point [$m] is not the user's home [$home]" + fi + owns_mountpoint "$user" "$m" + return 0 +} + +mount_is_private() { + local home="$1" + local mountfile="$home/.ecryptfs/Private.mnt" + local m=$(cat "$mountfile") + if [ "$m" != "$home" ]; then + info "Mount point [$m] is not the user's home [$home]" + else + error "Mount point [$m] is the user's home" + fi + if [ -d "$m" ]; then + info "Mount point [$m] is a valid directory" + else + error "[$m] is not a valid mount point" + fi + owns_mountpoint "$user" "$m" + return 0 +} + +filenames_encrypted() { + local sigfile="$1/.ecryptfs/Private.sig" + local c=$(wc -l "$sigfile" | awk '{print $1}') + if [ "$c" = "2" ]; then + info "Filenames are encrypted" + else + error "Filenames are not encrypted" + fi + return 0 +} + +filenames_not_encrypted() { + local sigfile="$1/.ecryptfs/Private.sig" + local c=$(wc -l "$sigfile" | awk '{print $1}') + if [ "$c" = "1" ]; then + info "Filenames are not encrypted" + else + error "Filenames are encrypted" + fi + return 0 +} + +home="$HOME" +user="$USER" +checks= +while [ ! -z "$1" ]; do + case "$1" in + -h|--home) + checks="$checks check_home" + shift + ;; + -p|--private) + checks="$checks check_private" + shift + ;; + -e|--filenames-encrypted) + checks="$checks check_filenames_encrypted" + shift + ;; + -n|--filenames-not-encrypted) + checks="$checks check_filenames_not_encrypted" + shift + ;; + --help) + usage + ;; + -u|--user) + user="$2" + home=$(getent passwd "$user" | awk -F: '{print $6}') + if [ ! -d "$home" ]; then + error "Invalid home directory [$home] of [$user]" + fi + shift 2 + ;; + esac +done + +if [ -z "$checks" ]; then + error "No checks given" +fi + +for i in $checks; do + case "$i" in + check_home) + ecryptfs_exists "$home" + sigfile_valid "$home" + mountfile_valid "$home" + automount_true "$home" + mount_is_home "$home" + ;; + check_private) + ecryptfs_exists "$home" + sigfile_valid "$home" + mountfile_valid "$home" + mount_is_private "$home" + ;; + check_filenames_encrypted) + ecryptfs_exists "$home" + sigfile_valid "$home" + filenames_encrypted "$home" + ;; + check_filenames_not_encrypted) + ecryptfs_exists "$home" + sigfile_valid "$home" + filenames_not_encrypted "$home" + ;; + *) + error "Invalid check [$i]" + ;; + esac +done + +info "Configuration valid" +exit 0 diff --git a/src/utils/ecryptfs_add_passphrase.c b/src/utils/ecryptfs_add_passphrase.c new file mode 100644 index 0000000..a2b3345 --- /dev/null +++ b/src/utils/ecryptfs_add_passphrase.c @@ -0,0 +1,123 @@ +/** + * Copyright (C) 2007 International Business Machines + * Author(s): Michael Halcrow <mhalcrow@us.ibm.com> + * Dustin Kirkland <kirkland@ubuntu.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <ecryptfs.h> + +void usage(void) +{ + printf("Usage:\n" + "ecryptfs-add-passphrase [--fnek]\n" + "or\n" + "printf \"%%s\" \"passphrase\" | ecryptfs-add-passphrase" + " [--fnek] -\n" + "\n"); +} + +int main(int argc, char *argv[]) +{ + char *passphrase; + char auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; + char salt[ECRYPTFS_SALT_SIZE]; + char salt_hex[ECRYPTFS_SALT_SIZE_HEX]; + int rc = 0; + int fnek = 0; + uint32_t version; + + if (argc == 1) { + /* interactive mode */ + passphrase = ecryptfs_get_passphrase("Passphrase"); + } else if (argc == 2 && + strlen(argv[1]) == 6 && strncmp(argv[1], "--fnek", 6) == 0) { + /* interactive mode, plus fnek */ + passphrase = ecryptfs_get_passphrase("Passphrase"); + fnek = 1; + } else if (argc == 2 && + strlen(argv[1]) == 1 && strncmp(argv[1], "-", 1) == 0) { + /* stdin mode */ + passphrase = ecryptfs_get_passphrase(NULL); + } else if (argc == 3 && + /* stdin mode, plus fnek */ + (strlen(argv[1])==6 && strncmp(argv[1], "--fnek", 6)==0) && + (strlen(argv[2])==1 && strncmp(argv[2], "-", 1)==0)) { + passphrase = ecryptfs_get_passphrase(NULL); + fnek = 1; + } else { + usage(); + goto out; + } + if (passphrase == NULL || + strlen(passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH) { + usage(); + rc = 1; + goto out; + } + if (fnek == 1) { + rc = ecryptfs_get_version(&version); + if (rc!=0 || !ecryptfs_supports_filename_encryption(version)) { + fprintf(stderr, "%s\n", ECRYPTFS_ERROR_FNEK_SUPPORT); + rc = 1; + goto out; + } + } + + rc = ecryptfs_read_salt_hex_from_rc(salt_hex); + if (rc) { + from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE); + } else + from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE); + if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig_hex, + passphrase, + salt)) < 0) { + fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_INSERT_KEY, rc); + fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG); + rc = 1; + goto out; + } else + rc = 0; + auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; + printf("Inserted auth tok with sig [%s] into the user session " + "keyring\n", auth_tok_sig_hex); + + if (fnek == 0) { + goto out; + } + + /* If we make it here, filename encryption is enabled, and it has + * been requested that we add the fnek to the keyring too + */ + if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig_hex, + passphrase, + ECRYPTFS_DEFAULT_SALT_FNEK_HEX)) < 0) { + fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_INSERT_KEY, rc); + fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG); + rc = 1; + goto out; + } else + rc = 0; + auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; + printf("Inserted auth tok with sig [%s] into the user session " + "keyring\n", auth_tok_sig_hex); + +out: + return rc; +} diff --git a/src/utils/ecryptfs_generate_tpm_key.c b/src/utils/ecryptfs_generate_tpm_key.c new file mode 100644 index 0000000..002ae70 --- /dev/null +++ b/src/utils/ecryptfs_generate_tpm_key.c @@ -0,0 +1,264 @@ +/* + * + * Copyright (C) International Business Machines Corp., 2007 + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NAME + * ecryptfs_generate_tpm_key + * + * DESCRIPTION + * + * Generate a sealing (storage) key bound to a specified set of + * PCRs values in the current TPM's PCR's. The SRk password is + * assumed to be the SHA1 hash of 0 bytes. + * + * USAGE + * ecryptfs_generate_tpm_key -p 1 -p 2 -p 3 + * + * HISTORY + * v1: Initial revision + * v2: Fixed bug in which PCR values were read from the TPM + * + * Author: Kent Yoder <kyoder@users.sf.net> + * + */ + +#include <stdio.h> +#include <getopt.h> +#include <errno.h> +#include <trousers/tss.h> +#include <trousers/trousers.h> + +#define PRINT_ERR(x, ...) fprintf(stderr, "%s:%d Error: " x "\n", __FILE__, __LINE__, ##__VA_ARGS__) +#define PRINT_TSS_ERR(s,r) fprintf(stderr, "%s:%d: Error: %s failed: %s\n", __FILE__, __LINE__, s, \ + Trspi_Error_String(r)) + +const TSS_UUID SRK_UUID = TSS_UUID_SRK; + +void usage(char *name) +{ + fprintf(stderr, "usage: %s <options>\n\n" + "options: -p <num>\n" + " \tBind the key to PCR <num>'s current value\n" + " \trepeat this option to bind to more than 1 PCR\n", + name); +} + +char *util_bytes_to_string(char *bytes, int chars) +{ + char *ret = (char *)malloc((chars*2) + 1); + int i, len = chars*2; + + if (ret == NULL) + return ret; + for (i = 0; i < chars; i+=4) { + sprintf(&ret[i*2], "%02x%02x%02x%02x", bytes[i] & 0xff, + bytes[i+1] & 0xff, bytes[i+2] & 0xff, + bytes[i+3] & 0xff); + } + ret[len] = '\0'; + return ret; +} + +int main(int argc, char **argv) +{ + TSS_HKEY hKey, hSRK; + TSS_HCONTEXT hContext; + TSS_HTPM hTPM; + TSS_RESULT result; + TSS_HPOLICY hPolicy; + TSS_HPCRS hPcrs; + UINT32 ulPcrValueLength, subCap, subCapLength; + UINT32 pulRespDataLength, numPcrs; + BYTE *pNumPcrs, *rgbPcrValue, *uuidString, *pcrsSelectedValues[24]; + int i, c, *pcrsSelected = NULL, numPcrsSelected = 0; + TSS_UUID *uuid; + BYTE wellknown[] = TSS_WELL_KNOWN_SECRET; + char *tmp_pcrs; + + while (1) { + c = getopt(argc, argv, "p:"); + if (c == -1) + break; + switch (c) { + case 'p': + numPcrsSelected++; + tmp_pcrs = realloc(pcrsSelected, + (sizeof(int) + * numPcrsSelected)); + if (tmp_pcrs == NULL) { + PRINT_ERR("Malloc of %zd bytes failed.", + (sizeof(int) + * numPcrsSelected)); + free(pcrsSelected); + return -1; + } + pcrsSelected = tmp_pcrs; + pcrsSelected[numPcrsSelected - 1] = + atoi(optarg); + break; + default: + usage(argv[0]); + break; + } + } + if (numPcrsSelected == 0) + printf("Warning: Key will not be bound to any PCR's!\n"); + if (numPcrsSelected > 24) { + PRINT_ERR("Too many PCRs selected! Exiting."); + return -EINVAL; + } + result = Tspi_Context_Create(&hContext); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Context_Create", result); + return result; + } + result = Tspi_Context_Connect(hContext, NULL); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Context_Connect", result); + Tspi_Context_Close(hContext); + return result; + } + result = Tspi_Context_GetTpmObject(hContext, &hTPM); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Context_GetTpmObject", result); + Tspi_Context_Close(hContext); + return result; + } + subCap = TSS_TPMCAP_PROP_PCR; + subCapLength = sizeof(UINT32); + result = Tspi_TPM_GetCapability(hTPM, TSS_TPMCAP_PROPERTY, + subCapLength, (BYTE *)&subCap, + &pulRespDataLength, &pNumPcrs ); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_TPM_GetCapability", result); + Tspi_Context_Close(hContext); + return result; + } + numPcrs = *(UINT32 *)pNumPcrs; + for (i = 0; i < (int)numPcrsSelected; i++) { + if (pcrsSelected[i] > (int)numPcrs) { + fprintf(stderr, "%d: invalid PCR register. PCRs range " + "from 0 - %u\n", pcrsSelected[i], numPcrs); + return -1; + } + } + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS, 0, + &hPcrs); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Context_CreateObject", result); + return result; + } + for (i = 0; i < numPcrsSelected; i++) { + result = Tspi_TPM_PcrRead(hTPM, pcrsSelected[i], + &ulPcrValueLength, &rgbPcrValue); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_TPM_PcrRead", result); + Tspi_Context_Close(hContext); + return result; + } + result = Tspi_PcrComposite_SetPcrValue(hPcrs, pcrsSelected[i], + ulPcrValueLength, + rgbPcrValue); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_PcrComposite_SetPcrValue", result ); + Tspi_Context_Close( hContext ); + return result; + } + + pcrsSelectedValues[i] = rgbPcrValue; + } + result = Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, + SRK_UUID, &hSRK); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Context_LoadKeyByUUID", result); + Tspi_Context_Close(hContext); + return result; + } + result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hPolicy); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_GetPolicyObject", result); + Tspi_Context_Close(hContext); + return result; + } + + result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, + sizeof(wellknown), wellknown); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_GetPolicyObject", result); + Tspi_Context_Close(hContext); + return result; + } + result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, + (TSS_KEY_TYPE_STORAGE + | TSS_KEY_SIZE_2048 + | TSS_KEY_VOLATILE + | TSS_KEY_NO_AUTHORIZATION + | TSS_KEY_NOT_MIGRATABLE), &hKey); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Context_CreateObject", result); + Tspi_Context_Close(hContext); + return result; + } + result = Tspi_Key_CreateKey(hKey, hSRK, hPcrs); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Key_CreateKey", result); + Tspi_Context_Close(hContext); + return result; + } + result = Tspi_TPM_GetRandom(hTPM, (UINT32)16, (BYTE **)&uuid); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_TPM_GetRandom", result); + Tspi_Context_Close(hContext); + return result; + } + result = Tspi_Context_RegisterKey(hContext, hKey, TSS_PS_TYPE_USER, + *uuid, TSS_PS_TYPE_SYSTEM, SRK_UUID); + if (result != TSS_SUCCESS) { + PRINT_TSS_ERR("Tspi_Context_RegisterKey", result); + Tspi_Context_Close(hContext); + return result; + } + printf("Success: Key created bound to:\n"); + for (i = 0; i < numPcrsSelected; i++) { + uuidString = (unsigned char *) + util_bytes_to_string((char *) + pcrsSelectedValues[i], 20); + if (uuidString == NULL) { + PRINT_ERR("malloc of 41 bytes failed"); + Tspi_Context_Close(hContext); + return result; + } + + printf("PCR %d: %s\n", pcrsSelected[i], uuidString); + free(uuidString); + Tspi_Context_FreeMemory(hContext, pcrsSelectedValues[i]); + } + uuidString = (BYTE *)util_bytes_to_string((char *)uuid, 16); + if (uuidString == NULL) { + PRINT_ERR("malloc of 33 bytes failed"); + Tspi_Context_Close(hContext); + return result; + } + printf("And registered in persistent storage with UUID " + "(tspi_uuid parameter): %s\n", uuidString); + Tspi_Context_FreeMemory(hContext, (BYTE *)uuid); + free(uuidString); + Tspi_Context_Close(hContext); + return 0; +} diff --git a/src/utils/ecryptfs_insert_wrapped_passphrase_into_keyring.c b/src/utils/ecryptfs_insert_wrapped_passphrase_into_keyring.c new file mode 100644 index 0000000..98b0167 --- /dev/null +++ b/src/utils/ecryptfs_insert_wrapped_passphrase_into_keyring.c @@ -0,0 +1,97 @@ +/** + * Copyright (C) 2007 International Business Machines + * Author(s): Michael Halcrow <mhalcrow@us.ibm.com> + * Dustin Kirkland <kirkland@ubuntu.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <ecryptfs.h> +#include <string.h> + +void usage(void) +{ + printf("Usage:\n" + "\n" + "ecryptfs-insert-wrapped-passphrase-into-keyring [file]\n" + "or\n" + "printf \"%%s\" \"wrapping passphrase\" | " + "ecryptfs-insert-wrapped-passphrase-into-keyring [file] -\n" + "\n"); +} + +int main(int argc, char *argv[]) +{ + char *file; + char *wrapping_passphrase; + char auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; + char salt[ECRYPTFS_SALT_SIZE]; + char salt_hex[ECRYPTFS_SALT_SIZE_HEX]; + int rc = 0; + + if (argc == 1) { + /* interactive, and try default wrapped-passphrase file */ + file = ecryptfs_get_wrapped_passphrase_filename(); + if (file == NULL) { + usage(); + goto out; + } + wrapping_passphrase = ecryptfs_get_passphrase("Passphrase"); + } else if (argc == 2) { + /* interactive mode */ + file = argv[1]; + wrapping_passphrase = ecryptfs_get_passphrase("Passphrase"); + } else if (argc == 3 && + strlen(argv[2]) == 1 && strncmp(argv[2], "-", 1) == 0) { + /* stdin mode */ + file = argv[1]; + wrapping_passphrase = ecryptfs_get_passphrase(NULL); + } else if (argc == 3 && + (strlen(argv[2]) != 1 || strncmp(argv[2], "-", 1) != 0)) { + /* argument mode */ + file = argv[1]; + wrapping_passphrase = argv[2]; + } else { + usage(); + goto out; + } + if (wrapping_passphrase == NULL || + strlen(wrapping_passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH) { + usage(); + goto out; + } + + rc = ecryptfs_read_salt_hex_from_rc(salt_hex); + if (rc) { + from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE); + } else + from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE); + if ((rc = ecryptfs_insert_wrapped_passphrase_into_keyring( + auth_tok_sig_hex, file, wrapping_passphrase, salt)) < 0) { + fprintf(stderr, "%s [%d]\n", + ECRYPTFS_ERROR_UNWRAP_AND_INSERT, rc); + fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG); + rc = 1; + goto out; + } else + rc = 0; + auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; + printf("Inserted auth tok with sig [%s] into the user session " + "keyring\n", auth_tok_sig_hex); +out: + return rc; +} diff --git a/src/utils/ecryptfs_rewrap_passphrase.c b/src/utils/ecryptfs_rewrap_passphrase.c new file mode 100644 index 0000000..03ab821 --- /dev/null +++ b/src/utils/ecryptfs_rewrap_passphrase.c @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2007 International Business Machines + * Author(s): Michael Halcrow <mhalcrow@us.ibm.com> + * Dustin Kirkland <kirkland@ubuntu.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <ecryptfs.h> +#include <string.h> + +void usage(void) +{ + printf("Usage:\n" + "\n" + "ecryptfs-rewrap-passphrase [file]\n" + "or\n" + "printf \"%%s\\n%%s\" \"old wrapping passphrase\" " + "\"new wrapping passphrase\" " + "| ecryptfs-rewrap-passphrase [file] -\n" + "\n"); +} + +int main(int argc, char *argv[]) +{ + char *file; + char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH + 1]; + char *old_wrapping_passphrase; + char *new_wrapping_passphrase; + char salt[ECRYPTFS_SALT_SIZE]; + char salt_hex[ECRYPTFS_SALT_SIZE_HEX]; + int rc = 0; + + if (argc == 2) { + char *new_wrapping_passphrase2; + + /* interactive mode */ + old_wrapping_passphrase = + ecryptfs_get_passphrase("Old wrapping passphrase"); + new_wrapping_passphrase = + ecryptfs_get_passphrase("New wrapping passphrase"); + new_wrapping_passphrase2 = + ecryptfs_get_passphrase("New wrapping passphrase (again)"); + + if (!new_wrapping_passphrase) { + fprintf(stderr, "Failed to read new wrapping passphrase\n"); + rc = 1; + goto out; + } else if (!new_wrapping_passphrase2) { + fprintf(stderr, "Failed to read new wrapping passphrase confirmation\n"); + rc = 1; + goto out; + } else if (strcmp(new_wrapping_passphrase, + new_wrapping_passphrase2)) { + fprintf(stderr, "New wrapping passphrases do not match\n"); + rc = 1; + goto out; + } + } else if (argc == 3 + && strlen(argv[2]) == 1 && strncmp(argv[2], "-", 1) == 0) { + /* stdin mode */ + old_wrapping_passphrase = ecryptfs_get_passphrase(NULL); + new_wrapping_passphrase = ecryptfs_get_passphrase(NULL); + } else if (argc == 4) { + /* argument mode */ + old_wrapping_passphrase = argv[2]; + new_wrapping_passphrase = argv[3]; + } else { + usage(); + goto out; + } + if (!old_wrapping_passphrase || !new_wrapping_passphrase || + strlen(old_wrapping_passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH || + strlen(new_wrapping_passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH) { + usage(); + goto out; + } + + file = argv[1]; + rc = ecryptfs_read_salt_hex_from_rc(salt_hex); + if (rc) { + from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE); + } else + from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE); + if ((rc = ecryptfs_unwrap_passphrase(passphrase, file, + old_wrapping_passphrase, salt))) { + fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_UNWRAP, rc); + fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG); + rc = 1; + goto out; + } + if ((rc = ecryptfs_wrap_passphrase(file, new_wrapping_passphrase, salt, + passphrase))) { + fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_WRAP, rc); + fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG); + rc = 1; + goto out; + } +out: + return rc; +} diff --git a/src/utils/ecryptfs_unwrap_passphrase.c b/src/utils/ecryptfs_unwrap_passphrase.c new file mode 100644 index 0000000..a61d59e --- /dev/null +++ b/src/utils/ecryptfs_unwrap_passphrase.c @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2007 International Business Machines + * Author(s): Michael Halcrow <mhalcrow@us.ibm.com> + * Dustin Kirkland <kirkland@ubuntu.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <ecryptfs.h> +#include <string.h> + +void usage(void) +{ + printf("Usage:\n" + "\n" + "ecryptfs-unwrap-passphrase [file]\n" + "or\n" + "printf \"%%s\" \"wrapping passphrase\" | " + "ecryptfs-unwrap-passphrase [file] -\n" + "\n"); +} + +int main(int argc, char *argv[]) +{ + char *file; + char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH + 1]; + char *wrapping_passphrase; + char salt[ECRYPTFS_SALT_SIZE]; + char salt_hex[ECRYPTFS_SALT_SIZE_HEX]; + int rc = 0; + + if (argc == 1) { + /* interactive, and try default wrapped-passphrase file */ + file = ecryptfs_get_wrapped_passphrase_filename(); + if (file == NULL) { + usage(); + goto out; + } + wrapping_passphrase = ecryptfs_get_passphrase("Passphrase"); + } else if (argc == 2) { + /* interactive mode */ + file = argv[1]; + wrapping_passphrase = ecryptfs_get_passphrase("Passphrase"); + } else if (argc == 3 && + strlen(argv[2]) == 1 && strncmp(argv[2], "-", 1) == 0) { + /* stdin mode */ + file = argv[1]; + wrapping_passphrase = ecryptfs_get_passphrase(NULL); + } else if (argc == 3 && + (strlen(argv[2]) != 1 || strncmp(argv[2], "-", 1) == 0)) { + /* argument mode */ + file = argv[1]; + wrapping_passphrase = argv[2]; + } else { + usage(); + goto out; + } + if (wrapping_passphrase == NULL || + strlen(wrapping_passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH) { + usage(); + goto out; + } + + rc = ecryptfs_read_salt_hex_from_rc(salt_hex); + if (rc) { + from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE); + } else + from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE); + if ((rc = ecryptfs_unwrap_passphrase(passphrase, file, + wrapping_passphrase, salt))) { + fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_UNWRAP, rc); + fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG); + rc = 1; + goto out; + } + printf("%s\n", passphrase); +out: + return rc; +} diff --git a/src/utils/ecryptfs_wrap_passphrase.c b/src/utils/ecryptfs_wrap_passphrase.c new file mode 100644 index 0000000..f915cd3 --- /dev/null +++ b/src/utils/ecryptfs_wrap_passphrase.c @@ -0,0 +1,96 @@ +/** + * Copyright (C) 2007 International Business Machines + * Author(s): Michael Halcrow <mhalcrow@us.ibm.com> + * Dustin Kirkland <kirkland@ubuntu.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <ecryptfs.h> +#include <string.h> + +void usage(void) +{ + printf("Usage:\n" + "\n" + "ecryptfs-wrap-passphrase [file]\n" + "or\n" + "printf \"%%s\\n%%s\" \"passphrase to wrap\" " + "\"wrapping passphrase\" " + "| ecryptfs-wrap-passphrase [file] -\n" + "\n" + "note: passphrase can be at most %d bytes long\n", + ECRYPTFS_MAX_PASSWORD_LENGTH); +} + +int main(int argc, char *argv[]) +{ + char *file; + char *passphrase = NULL; + char *wrapping_passphrase = NULL; + char salt[ECRYPTFS_SALT_SIZE]; + char salt_hex[ECRYPTFS_SALT_SIZE_HEX]; + int rc = 0; + + if (argc == 2) { + /* interactive mode */ + passphrase = ecryptfs_get_passphrase("Passphrase to wrap"); + if (passphrase) + wrapping_passphrase = + ecryptfs_get_passphrase("Wrapping passphrase"); + } else if (argc == 3 && strlen(argv[2]) == 1 && + strncmp(argv[2], "-", 1) == 0) { + /* stdin mode */ + passphrase = ecryptfs_get_passphrase(NULL); + if (passphrase) + wrapping_passphrase = ecryptfs_get_passphrase(NULL); + } else if (argc == 4) { + /* argument mode */ + passphrase = argv[2]; + wrapping_passphrase = argv[3]; + } else { + usage(); + goto out; + } + if (passphrase == NULL || wrapping_passphrase == NULL || + strlen(passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH || + strlen(wrapping_passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH) { + usage(); + rc = 1; + goto out; + } + file = argv[1]; + rc = ecryptfs_read_salt_hex_from_rc(salt_hex); + if (rc) { + from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE); + } else + from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE); + if ((rc = ecryptfs_wrap_passphrase(file, wrapping_passphrase, salt, + passphrase))) { + fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_WRAP, rc); + fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG); + rc = 1; + goto out; + } +out: + if (argc != 4) { + free(passphrase); + free(wrapping_passphrase); + } + return rc; +} diff --git a/src/utils/ecryptfsrc b/src/utils/ecryptfsrc new file mode 100644 index 0000000..1c856af --- /dev/null +++ b/src/utils/ecryptfsrc @@ -0,0 +1,2 @@ +key=passphrase +cipher=aes diff --git a/src/utils/gen_key.c b/src/utils/gen_key.c new file mode 100644 index 0000000..217b648 --- /dev/null +++ b/src/utils/gen_key.c @@ -0,0 +1,180 @@ +/** + * Copyright (C) 2007 International Business Machines + * Author(s): Michael Halcrow <mhalcrow@us.ibm.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <string.h> +#include <errno.h> +#include "ecryptfs.h" +#include "io.h" + +/** + * TODO: Use decision graph here + */ +int ecryptfs_generate_key(void) +{ + return -EINVAL; +/* struct ecryptfs_ctx ctx; + struct ecryptfs_key_mod *key_mod = NULL; + char *home; + char *directory; + char *file; + uid_t id; + struct passwd *pw; + int rc = 0; + + id = getuid(); + pw = getpwuid(id); + home = pw->pw_dir; + printf("\n"); + printf("This is the eCryptfs key generation utility. At any time \n" + "you may hit enter to selected a default option appearing in \n" + "brackets.\n"); + printf("\n"); + if ((rc = ecryptfs_get_key_mod_list(&ctx))) { + fprintf(stderr, "Error: eCryptfs was unable to initialize the " + "PKI modules.\n"); + return 0; + } + if (ecryptfs_select_key_mod(&key_mod, &ctx)) { + fprintf(stderr, "Error: Problem loading the selected PKI.\n"); + return 0; + } + file = malloc(MAX_PATH_SIZE); + if (!file) { + fprintf(stderr, "Out of memory\n"); + return 0; + } + printf("\nEnter the filename where the key should be written.\n" + "[%s%s%s/key.pem]:", home, "/.ecryptfs/pki/", + key_mod->alias); + get_string(file, MAX_PATH_SIZE, ECHO); + if (*file == '\0') + memcpy(file, "key.pem", 8); + if (*file == '/') { + rc = key_mod->ops->generate_key(file); + if (rc) { + fprintf(stderr, "Error: unable to write key to file\n"); + return 0; + } + } else { + rc = create_default_dir(home, selected_pki); + if (rc) { + fprintf(stderr, "Error: unable to create default pki directory\n"); + goto out; + } + rc = create_subdirectory(file, home, selected_pki); + if (rc) { + fprintf(stderr, "Error: unable to create the desired subdirectories\n"); + goto out; + } + rc = asprintf(&directory, "%s/.ecryptfs/pki/%s/%s", home, + selected_pki->pki_name, file); + if (rc == -1) { + fprintf(stderr, "Out of memory\n"); + rc = 0; + goto out; + } + rc = selected_pki->ops.generate_key(directory); + if (rc) + fprintf(stderr, "Error: unable to write key to file\n"); + } +out: +return rc; */ +} + +int +create_subdirectory(char *file, char *home, struct ecryptfs_key_mod *key_mod) +{ + char *substring; + char *directory; + int rc = 0; + + substring = file; + while((substring = strstr(substring, "/")) != NULL) { + char temp = *(substring + 1); + *(substring + 1) = '\0'; + if (asprintf(&directory, "%s/.ecryptfs/pki/%s/%s", + home, key_mod->alias, file) < 0) { + rc = errno; + fprintf(stderr, "Error: %m\n"); + goto out; + } + printf("%s\n",directory); + if (mkdir(directory,0700) != 0 && errno != EEXIST) { + rc = errno; + fprintf(stderr, "Error: %m\n"); + goto out; + } + free(directory); + *(substring + 1) = temp; + substring = substring + 1; + } +out: + return rc; +} + +int create_default_dir(char *home, struct ecryptfs_key_mod *key_mod) +{ + char *directory; + int rc = 0; + + if (asprintf(&directory, "%s/.ecryptfs/", home) < 0) { + rc = errno; + fprintf(stderr, "Error: %m\n"); + goto out; + } + if (mkdir(directory,0700) != 0 && errno != EEXIST) { + rc = errno; + fprintf(stderr, "Error: %m\n"); + goto out; + } + free(directory); + if (asprintf(&directory, "%s/.ecryptfs/pki/", home) < 0) { + rc = errno; + fprintf(stderr, "Error: %m\n"); + goto out; + } + if (mkdir(directory,0700) != 0 && errno != EEXIST) { + rc = errno; + fprintf(stderr, "Error: %m"); + goto out; + } + free(directory); + if (asprintf(&directory, "%s/.ecryptfs/pki/%s/", home, + key_mod->alias) < 0) { + rc = errno; + fprintf(stderr, "Error: %m\n"); + goto out; + } + if (mkdir(directory,0700) != 0 && errno != EEXIST) { + rc = errno; + fprintf(stderr, "Error: %m\n"); + goto out; + } + free(directory); +out: + return rc; +} diff --git a/src/utils/io.c b/src/utils/io.c new file mode 100644 index 0000000..3e372c2 --- /dev/null +++ b/src/utils/io.c @@ -0,0 +1,293 @@ +/** + * Copyright (C) 2006 International Business Machines + * Author(s): Trevor Highland <tshighla@us.ibm.com> + * Theresa Nelson <tmnelson@us.ibm.com> + * Tyler Hicks <tyhicks@ou.edu> + * + * I/O functions for mount helper + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <termios.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/mman.h> +#include "ecryptfs.h" +#include "io.h" + +static int disable_echo(struct termios *saved_settings) +{ + struct termios current_settings; + int rc = 0; + + rc = tcgetattr(0, ¤t_settings); + if (rc) + return rc; + *saved_settings = current_settings; + current_settings.c_lflag &= ~ECHO; + rc = tcsetattr(0, TCSANOW, ¤t_settings); + return rc; +} + +static int enable_echo(struct termios *saved_settings) +{ + return tcsetattr(0, TCSANOW, saved_settings); +} + +int mygetchar(void) +{ + int c = getchar(); + + if (c == '\r') + c = '\n'; + return c; +} + +int get_string_stdin(char **val, char *prompt, int echo) +{ +#define DEFAULT_STRING_LENGTH 16 + int count = 0; + struct termios saved_settings; + int length = DEFAULT_STRING_LENGTH; + char *temp; + int rc = 0; + int c; + + printf("%s: ", prompt); + temp = malloc(length); + if (!temp) { + rc = -ENOMEM; + goto out; + } + temp[0] = '\0'; + *val = temp; + if (!echo) { + rc = disable_echo(&saved_settings); + if (rc) + goto out; + } + do { + if (count == length) { + temp = malloc(length * 2); + if (!temp) { + rc = -ENOMEM; + goto out; + } + memcpy(temp, *val, length); + memset(*val, 0, length); + length *= 2; + free(*val); + *val = temp; + } + if ((c = mygetchar()) != EOF) + (*val)[count] = c; + else + (*val)[count] = '\n'; + count++; + } while(c != EOF && (*val)[count-1] != '\n'); + (*val)[count - 1] = '\0'; + if (!echo) { + printf("\n"); + rc = enable_echo(&saved_settings); + } + if (count == 1 && c == EOF) { + free(*val); + *val = NULL; + rc = -EIO; + } +out: + return rc; +} + +int get_string(char *val, int len, int echo) +{ + int count = 0; + struct termios saved_settings; + int rc = 0; + int c; + + if (echo == ECRYPTFS_ECHO_OFF) { + rc = disable_echo(&saved_settings); + if (rc) + goto out; + } + do { + if ((c = mygetchar()) != EOF) + val[count] = c; + else + val[count] = '\n'; + count++; + } while(c != EOF && val[count-1] != '\n' && (count < len)); + if (echo == ECRYPTFS_ECHO_OFF) { + printf("\n"); + rc = enable_echo(&saved_settings); + } + if (count == 1 && c == EOF) { + *val = '\0'; + rc = -EIO; + } else if (count > len) + val[len - 1] = '\0'; + else + val[count - 1] = '\0'; +out: + return rc; +} + +static inline int munch_newline(void) +{ + int c; + if ((c=mygetchar()) == '\n' || c == EOF) + return 0; + while ((c=mygetchar()) != '\n' && c != EOF); + return -1; +} + +int manager_menu(void) +{ + char str[8]; + int selection; + + printf("\neCryptfs key management menu\n"); + printf("-------------------------------\n"); + printf("\t%d. Add passphrase key to keyring\n", MME_MOUNT_PASSPHRASE); + printf("\t%d. Add public key to keyring\n", MME_MOUNT_PUBKEY); + printf("\t%d. Generate new public/private keypair\n", MME_GEN_PUBKEY); + printf("\t%d. Exit\n", MME_ABORT); +try_again: + printf("\nMake selection: "); + str[0] = mygetchar(); + if (munch_newline()) { + printf("Invalid selection\n"); + goto try_again; + } + str[strlen(str)] = '\0'; + selection = atoi(str); + switch (selection) { + case MME_MOUNT_PASSPHRASE: + case MME_MOUNT_PUBKEY: + case MME_GEN_PUBKEY: + case MME_ABORT: + break; + default: + printf("Invalid selection\n"); + goto try_again; + } + return selection; +} + +int read_passphrase_salt(char *pass, char *salt) +{ + char *confirmed_pass; + int rc = 0; + + confirmed_pass = malloc(ECRYPTFS_MAX_PASSWORD_LENGTH); + if (!confirmed_pass) { + rc = -ENOMEM; + ecryptfs_syslog(LOG_ERR, "Failed to allocate memory\n"); + goto ret; + } + mlock(confirmed_pass, ECRYPTFS_MAX_PASSWORD_LENGTH); + printf("\n\tMount-wide passphrase: "); + rc = get_string(pass, ECRYPTFS_MAX_PASSWORD_LENGTH, ECRYPTFS_ECHO_OFF); + if (rc) + goto out; + if (pass[0] == '\0') { + printf("Invalid passphrase. Aborting mount.\n"); + rc = -EINVAL; + goto out; + } + printf("\tConfirm passphrase: "); + rc = get_string(confirmed_pass, ECRYPTFS_MAX_PASSWORD_LENGTH, + ECRYPTFS_ECHO_OFF); + if (rc) { + ecryptfs_syslog(LOG_ERR, "Failed to read passphrase\n"); + goto out; + } + if (strcmp(pass, confirmed_pass) != 0) { + printf("Passphrase mismatch. Aborting mount\n"); + rc = -EINVAL; + goto out; + } + printf("\tUsing the default salt value\n"); +out: + memset(confirmed_pass, 0, ECRYPTFS_MAX_PASSWORD_LENGTH); + free(confirmed_pass); +ret: + return rc; +} + +int ecryptfs_select_key_mod(struct ecryptfs_key_mod **key_mod, + struct ecryptfs_ctx *ctx) +{ + int rc; + int key_mod_type; + int count; + struct ecryptfs_key_mod *curr; + char str[8]; + int default_key_mod = 1; + +prompt_user: + count = 1; + curr = ctx->key_mod_list_head.next; + if (!curr) { + rc = 1; + goto out; + } + if (!(curr->next)) + goto success; + printf("\nThe following PKI modules are available:\n"); + while (curr) { + printf("\t%i. %s\n", count, curr->alias); + count++; + curr = curr->next; + } + printf("\nSelect desired key module [%d]: ", default_key_mod); + if (fgets(str, 4, stdin) == NULL) { + printf("\nError reading input\n"); + rc = -EIO; + goto out; + } + printf("\n"); + str[strlen(str)] = '\0'; + if (str[0] == '\n') + key_mod_type = default_key_mod; + else + key_mod_type = atoi(str); + if (key_mod_type < 1 || key_mod_type >= count) { + char *pch = strstr(str, "\n"); + + printf("Invalid selection\n"); + if (!pch) { + int ch; + + while ((ch = mygetchar()) != '\n' && ch != EOF); + } + goto prompt_user; + } + curr = ctx->key_mod_list_head.next; + while(key_mod_type > 1) { + curr = curr->next; + key_mod_type--; + } +success: + (*key_mod) = curr; + rc = 0; +out: + return rc; +} diff --git a/src/utils/io.h b/src/utils/io.h new file mode 100644 index 0000000..1edd4ec --- /dev/null +++ b/src/utils/io.h @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2006 International Business Machines + * Author(s): Michael C Thompson <mcthomps@us.ibm.com> + * + * I/O functions for mount helper header file + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "ecryptfs.h" + +int main_menu(uint32_t version); +int manager_menu(void); +int read_passphrase_salt(char *pass, char *salt); +int get_string_stdin(char **val, char *prompt, int echo); +int ecryptfs_select_key_mod(struct ecryptfs_key_mod **key_mod, + struct ecryptfs_ctx *ctx); + +int mygetchar(); diff --git a/src/utils/manager.c b/src/utils/manager.c new file mode 100644 index 0000000..a7ede51 --- /dev/null +++ b/src/utils/manager.c @@ -0,0 +1,146 @@ +/** + * Copyright (C) 2006 International Business Machines + * Author(s): Trevor S. Highland <trevor.highland@gmail.com> + * Michael C. Thompson <mcthomps@us.ibm.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <errno.h> +#include <getopt.h> +#include <sys/types.h> +#include <keyutils.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include "../include/ecryptfs.h" +#include "../include/decision_graph.h" +#include "io.h" + +int main(int argc, char **argv) +{ + int quit, rc, selection; + uint32_t version; + char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH]; + char salt[ECRYPTFS_SALT_SIZE]; + struct ecryptfs_ctx ecryptfs_ctx; + struct val_node *dummy_mnt_params; + char auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX+1]; + + if ((rc = ecryptfs_validate_keyring())) { + printf("Error attempting to validate keyring integrity; " + "rc = [%d]\n", rc); + return 1; + } + memset(passphrase, 0, ECRYPTFS_MAX_PASSWORD_LENGTH); + memset(salt, 0, ECRYPTFS_SALT_SIZE); +selection: + quit = 0; + selection = manager_menu(); + switch (selection) { + case MME_MOUNT_PASSPHRASE: + if ((rc = read_passphrase_salt(passphrase, salt))) + goto out_wipe; + if (!(*salt)) + memcpy(salt, common_salt, ECRYPTFS_SALT_SIZE); + rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig, + passphrase, salt); + if (rc == 1) { + rc = 0; + printf("\nThat key was already in the keyring.\n\n"); + } else if (!rc) + printf("\nAdded key to keyring with signature [%s]." + "\n\n", auth_tok_sig); + memset(passphrase, 0, ECRYPTFS_MAX_PASSWORD_LENGTH); + memset(salt, 0, ECRYPTFS_SALT_SIZE); + break; + case MME_MOUNT_PUBKEY: + if ((rc = ecryptfs_get_version(&version))) { + printf("\nUnable to get the version number of the kernel\n"); + printf("module. Please make sure that you have the eCryptfs\n"); + printf("kernel module loaded, you have sysfs mounted, and\n"); + printf("the sysfs mount point is in /etc/mtab. This is\n"); + printf("necessary so that the mount helper knows which \n"); + printf("kernel options are supported.\n\n"); + printf("Make sure that your system is set up to auto-load\n" + "your filesystem kernel module on mount.\n\n"); + printf("Enabling passphrase-mode only for now.\n\n"); + version = ECRYPTFS_VERSIONING_PASSPHRASE; + } + ecryptfs_ctx.get_string = &get_string_stdin; + if ((dummy_mnt_params = malloc(sizeof(struct val_node))) + == NULL) { + rc = -ENOMEM; + goto out; + } + if ((rc = ecryptfs_process_decision_graph( + &ecryptfs_ctx, &dummy_mnt_params, version, "", + ECRYPTFS_KEY_MODULE_ONLY))) { + printf("Error processing key generation decision graph;" + " rc = [%d]\n", rc); + goto out; + } + if ((rc = ecryptfs_free_key_mod_list(&ecryptfs_ctx))) { + printf("\nUnable to free key modules\n"); + } + printf("Returning to main menu\n"); + break; + case MME_GEN_PUBKEY: + memset(&ecryptfs_ctx, 0, sizeof(struct ecryptfs_ctx)); + if ((rc = ecryptfs_get_version(&version))) { + printf("\nUnable to get the version number of the kernel\n"); + printf("module. Please make sure that you have the eCryptfs\n"); + printf("kernel module loaded, you have sysfs mounted, and\n"); + printf("the sysfs mount point is in /etc/mtab. This is\n"); + printf("necessary so that the mount helper knows which \n"); + printf("kernel options are supported.\n\n"); + printf("Make sure that your system is set up to auto-load\n" + "your filesystem kernel module on mount.\n\n"); + printf("Enabling passphrase-mode only for now.\n\n"); + version = ECRYPTFS_VERSIONING_PASSPHRASE; + } + ecryptfs_ctx.get_string = &get_string_stdin; + if ((rc = ecryptfs_process_key_gen_decision_graph(&ecryptfs_ctx, + version))) { + printf("Error processing key generation decision graph;" + " rc = [%d]\n", rc); + goto out; + } + if ((rc = ecryptfs_free_key_mod_list(&ecryptfs_ctx))) { + printf("\nUnable to free key modules\n"); + } + printf("Returning to main menu\n"); + goto selection; + case MME_ABORT: + quit = 1; + goto out_wipe; + default: + fprintf(stderr, "Unknown option, aborting\n"); + quit = 1; + rc = -1; + goto out_wipe; + } +out_wipe: + memset(passphrase, 0, ECRYPTFS_MAX_PASSWORD_LENGTH); + memset(salt, 0, ECRYPTFS_SALT_SIZE); + if (!quit) + goto selection; +out: + if (selection == MME_MOUNT_PUBKEY || selection == MME_GEN_PUBKEY) + rc = ecryptfs_free_key_mod_list(&ecryptfs_ctx); + return rc; +} diff --git a/src/utils/mount.ecryptfs.c b/src/utils/mount.ecryptfs.c new file mode 100644 index 0000000..4b83979 --- /dev/null +++ b/src/utils/mount.ecryptfs.c @@ -0,0 +1,646 @@ +/** + * Copyright (C) 2006 International Business Machines + * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> + * Stephan Mueller <smueller@chronox.de> + * Tyler Hicks <tyhicks@ou.edu> + * Michael C. Thompson <mcthomps@us.ibm.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <keyutils.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <sys/mman.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include "ecryptfs.h" +#include "decision_graph.h" +#include "io.h" + +#define NUM_REQUIRED_ARGS 3 + +static void usage() +{ + fprintf(stderr, "\teCryptfs mount helper\n\tusage: " + "mount -t ecryptfs [lower directory] [ecryptfs mount point]\n" + "\n" + "See the README file in the ecryptfs-utils package for " + "complete usage guidelines.\n" + ); + exit(-EINVAL); +} + +/** + * This function will malloc any argument that is passed in as non-NULL. + * In the event of a failure, all returned pointers are invalid and no + * memory is left allocated. + * + * returns 0 on success + */ +static int parse_arguments(int argc, char **argv, char **src, char **target, + char **options) +{ + int rc = 0; + char *ptr; + size_t len; + + if (src) + *src = NULL; + if (target) + *target = NULL; + if (options) + *options = NULL; + + if (src) { + ptr = argv[1]; + len = strlen(ptr) + 1; /* + NULL terminator */ + *src = malloc(len); + if (!*src) { + fprintf(stderr, "Unable to allocate source buffer\n"); + rc = -ENOMEM; + goto out; + } + memcpy(*src, ptr, len); + if ((*src)[len - 1] == '/') + (*src)[len - 1] = '\0'; + } + if (target) { + ptr = argv[2]; + len = strlen(ptr) + 1; /* + NULL-terminator */ + *target = malloc(len); + if (!*target) { + fprintf(stderr, "Unable to allocate target buffer\n"); + rc = -ENOMEM; + goto out; + } + memcpy(*target, ptr, len); + if ((*target)[len - 1] == '/') + (*target)[len - 1] = '\0'; + } + if ((options) && (argc >= NUM_REQUIRED_ARGS)) { + int i; + + ptr = NULL; + for (i = 3; i < (argc-1); i++) + if (!strcmp("-o", argv[i])) { + ptr = argv[i+1]; + break; + } + if (!ptr) { + fprintf(stderr, "Unable to find a list of options to " + "parse, defaulting to interactive " + "mount\n"); + return 0; + } + len = strlen(ptr) + 1; /* + NULL-terminator */ + *options = malloc(len); + if (!*options){ + fprintf(stderr, "Unable to allocate memory for options " + "buffer\n"); + rc = -ENOMEM; + goto out; + } + memcpy(*options, ptr, len); + } + return 0; +out: + if (src && *src) + free(*src); + if (target && *target) + free(*target); + if (options && *options) + free(*options); + return rc; +} + +char *parameters_to_scrub[] = { + "key=", + "cipher=", + "passthrough", + "ecryptfs_passthrough", + "hmac", + "ecryptfs_hmac", + "xattr", + "ecryptfs_xattr", + "encrypted_view", + "ecryptfs_encrypted_view", + "user", + "sig", + "no_sig_cache", + "verbose", + "verbosity", + "ecryptfs_enable_filename_crypto", + NULL +}; + +char *parameters_to_not_scrub[] = { + "xattr_user", + NULL +}; + +static int parameter_should_not_be_scrubbed(char *str) { + int i; + + for (i = 0; parameters_to_not_scrub[i]; i++) + if (strstr(str, parameters_to_not_scrub[i]) == str) + return 1; + return 0; +} + +static int parameter_should_be_scrubbed(char *str) +{ + int i; + + for (i = 0; parameters_to_scrub[i]; i++) + if (strstr(str, parameters_to_scrub[i]) == str + && !parameter_should_not_be_scrubbed(str)) + return 1; + return 0; +} + +/** + * Remove from the options string known options which should not be passed + * into the kernel. Any options that are unknown will be passed in. + * This is to account for options like "rw". + * + * Returns zero on success, non-zero otherwise + */ +static int strip_userland_opts(char *options) +{ + char *cur = NULL, *next = NULL; + char *temp, *temp_end; + size_t len; + int used = 0, first = 1; + + if (!options) + return 0; + + len = (strlen(options) + 1); + if ((temp = (char*)malloc(len)) == NULL) { + fprintf(stderr, "Out of memory\n"); + return -1; + } + temp_end = temp; + memset(temp, 0, len); + cur = options; + while (cur) { + int opt_len; + + next = strstr(cur, ","); + if (next) { + *next='\0'; + next++; + } + if (!parameter_should_be_scrubbed(cur)) { + if (!first) { + memcpy(temp_end, ",", 1); + temp_end++; + } + opt_len = strlen(cur); + memcpy(temp_end, cur, opt_len); + temp_end = temp_end + opt_len; + used += opt_len; + first = 0; + } + cur = next; + } + memcpy(options,temp,len); + free(temp); + return 0; +} + +static int process_sig(char *auth_tok_sig, struct passwd *pw) +{ + char *home; + char *sig_cache_filename = NULL; + char *dot_ecryptfs_dir; + int flags; + char *yesno = NULL; + int rc; + int tries; + + home = pw->pw_dir; + rc = asprintf(&dot_ecryptfs_dir, "%s/.ecryptfs", home); + if (rc == -1) { + rc = -ENOMEM; + goto out; + } + (void)mkdir(dot_ecryptfs_dir, S_IRWXU); + if (chown(dot_ecryptfs_dir, getuid(), getgid()) == -1) + printf("Can't change ownership of sig file; " + "errno = [%d]; [%m]\n", errno); + free(dot_ecryptfs_dir); + rc = asprintf(&sig_cache_filename, "%s/.ecryptfs/sig-cache.txt", + home); + if (rc == -1) { + rc = -ENOMEM; + goto out; + } + flags = 0; + if ((rc = ecryptfs_check_sig(auth_tok_sig, sig_cache_filename, + &flags))) + goto out; + if (flags & ECRYPTFS_SIG_FLAG_NOENT) { + printf("WARNING: Based on the contents of [%s],\n" + "it looks like you have never mounted with this key \n" + "before. This could mean that you have typed your \n" + "passphrase wrong.\n\n", sig_cache_filename); + tries = 0; + yesno = NULL; + do { + free(yesno); + if ((rc = get_string_stdin(&yesno, + "Would you like to proceed with " + "the mount (yes/no)? ",ECRYPTFS_ECHO_ON))) + goto out; + } while ((rc = strcmp(yesno, "yes")) && strcmp(yesno, "no") + && (++tries < 5)); + if (rc == 0) { + tries = 0; + do { + free(yesno); + printf("Would you like to append sig [%s] to\n" + "[%s] \nin order to avoid this warning " + "in the future", auth_tok_sig, + sig_cache_filename); + if ((rc = get_string_stdin(&yesno," (yes/no)? ", + ECRYPTFS_ECHO_ON))) + goto out; + } while ((rc = strcmp(yesno, "yes")) + && strcmp(yesno, "no") && (++tries < 5)); + if (rc == 0) { + if ((rc = ecryptfs_append_sig( + auth_tok_sig, + sig_cache_filename))) { + printf("Error appending to [%s]; rc = " + "[%d]. Aborting mount.\n", + sig_cache_filename, rc); + goto out; + } + printf("Successfully appended new sig to user " + "sig cache file\n"); + } else { + if (strcmp(yesno,"no")) + rc = -EINVAL; + else { + printf("Not adding sig to user sig " + "cache file; continuing with " + "mount.\n"); + rc = 0; + } + } + } else { + if (strcmp(yesno,"no")) + rc = -EINVAL; + printf("Aborting mount.\n"); + rc = ECANCELED; + goto out; + } + } +out: + free(yesno); + free(sig_cache_filename); + return rc; +} + +static int opts_str_contains_option(char *options, char *option) +{ + char *opt; + char *next_opt; + + if (!options || !option) + return 0; + + int option_len = strlen(option); + + opt = options; + while (opt) { + if ((next_opt = strchr(opt, ','))) + next_opt++; + if (!strncmp(opt, option, option_len)) + return 1; + else + opt = next_opt; + } + return 0; +} + +char *required_mount_opts[] = { + "ecryptfs_key_bytes=", + NULL +}; + +static int ecryptfs_validate_mount_opts(char *opts) +{ + int i = 0; + int rc = 0; + + while (required_mount_opts[i]) { + if (!opts_str_contains_option(opts, required_mount_opts[i])) { + printf("Required mount option not provided: [%s]\n", + required_mount_opts[i]); + rc = -EINVAL; + goto out; + } + i++; + } +out: + return rc; +} + +int ecryptfs_mount(char *source, char *target, char *opts) +{ + pid_t pid, pid_child; + char *fullpath_source = NULL; + char *fullpath_target = NULL; + int rc, status; + + if (!source) { + rc = -EINVAL; + syslog(LOG_ERR, "Invalid source directory\n"); + goto out; + } + + if (!target) { + rc = -EINVAL; + syslog(LOG_ERR, "Invalid target directory\n"); + goto out; + } + + /* source & target are canonicalized here, so the correct error + * is sent to syslog. + * /bin/mount tells you the error on normal output only, not to syslog. + */ + fullpath_source = realpath(source, NULL); + if (!fullpath_source) { + rc = -errno; + syslog(LOG_ERR, "could not resolve full path for source %s [%d]", + source, -errno); + goto out; + } + + fullpath_target = realpath(target, NULL); + if (!fullpath_target) { + rc = -errno; + syslog(LOG_ERR, "could not resolve full path for target %s [%d]", + target, -errno); + goto out; + } + + pid = fork(); + if (pid == -1) { + syslog(LOG_ERR, "Could not fork process to mount eCryptfs: [%d]\n", -errno); + rc = -errno; + } else if (pid == 0) { + execl("/bin/mount", "mount", "-i", "--no-canonicalize", "-t", "ecryptfs", fullpath_source, fullpath_target, "-o", opts, NULL); + + /* error message shown in console to let users know what was wrong */ + /* i.e. /bin/mount does not exist */ + perror("Failed to execute /bin/mount command"); + exit(errno); + } else { + pid_child = waitpid(pid, &status, 0); + if (pid_child == -1) { + syslog(LOG_ERR, "Failed waiting for /bin/mount process: [%d]\n", -errno); + rc = -errno; + goto out; + } + + rc = -EPERM; + if (WIFEXITED(status)) + rc = -WEXITSTATUS(status); + + if (rc) { + syslog(LOG_ERR, "Failed to perform eCryptfs mount: [%d]\n", rc); + if (-EPIPE == rc) { + rc = -EPERM; + } + } + } + +out: + free(fullpath_source); + free(fullpath_target); + + return rc; +} + +/** + * ecryptfs_do_mount + * @params: + * + * The mount options actually sent to the kernel are in the @params + * linked list of struct val_node objects. params <- + * ecryptfs_process_decision_graph(head) -> decision_graph_mount(head) + * -> eval_param_tree(val_stack_head) -> do_transition(val_stack_head) + * -> trans_func(head). + */ +static int ecryptfs_do_mount(int argc, char **argv, struct val_node *mnt_params, + int sig_cache, struct passwd *pw) +{ + int rc; + char *src = NULL, *targ = NULL, *opts = NULL, *new_opts = NULL, *temp; + char *val; + + if ((rc = parse_arguments(argc, argv, &src, &targ, &opts))) { + fprintf(stderr, "Unable to understand the mount options\n"); + goto out; + } + rc = strip_userland_opts(opts); + if (rc) + goto out; + if (!(temp = strdup("ecryptfs_unlink_sigs"))) { + rc = -ENOMEM; + goto out; + } + if ((rc = stack_push(&mnt_params, (void *)temp))) + goto out; + printf("Attempting to mount with the following options:\n"); + new_opts = opts; + opts = NULL; + while (!stack_pop_val(&mnt_params, (void *)&val)) { + if(!val) + break; + temp = new_opts; + printf(" %s\n", val); + if (sig_cache && memcmp(val, "ecryptfs_sig=", 13) == 0) { + if ((rc = process_sig(&val[13], pw))) { + if (rc != ECANCELED) + printf("Error processing sig; " + "rc = [%d]\n", rc); + goto out; + } + } + if (!temp || !strstr(temp, val)) { + rc = asprintf(&new_opts, "%s%c%s", val, + ((temp && *temp) ? ',' : '\0'), temp); + if (rc == -1) { + new_opts = NULL; + rc = -ENOMEM; + goto out; + } + free(temp); + } + rc = 0; + } + if ((rc = ecryptfs_validate_mount_opts(new_opts)) != 0) { + printf("Invalid mount options; aborting. rc = [%d]\n", + rc); + goto out; + } + rc = ecryptfs_mount(src, targ, new_opts); +out: + free(src); + free(targ); + free(opts); + free(new_opts); + return rc; +} + +static int dump_args = 0; + +int main(int argc, char **argv) +{ + uint32_t version; + char *opts_str; + struct val_node *mnt_params; + struct ecryptfs_ctx ctx; + int sig_cache = 1; + int rc; + struct passwd *pw; + + rc = mlockall(MCL_FUTURE); + if (rc) { + fprintf(stderr, "Exiting. Unable to mlockall address space: %m\n"); + return -1; + } + + pw = getpwuid(getuid()); + if (!pw) { + fprintf(stderr, "Exiting. Unable to obtain passwd info\n"); + rc = -EIO; + goto out; + } + + if (dump_args) { + int i; + + for (i = 0; i < argc; i++) + printf("argv[%d] = [%s]\n", i, argv[i]); + } + if (argc < NUM_REQUIRED_ARGS) { + fprintf(stderr, "Insufficient number of arguments\n"); + usage(); + rc = -EINVAL; + goto out; + } + rc = ecryptfs_get_version(&version); + if (rc) { + printf("\nUnable to get the version number of the kernel\n"); + printf("module. Please make sure that you have the eCryptfs\n"); + printf("kernel module loaded, you have sysfs mounted, and\n"); + printf("the sysfs mount point is in /etc/mtab. This is\n"); + printf("necessary so that the mount helper knows which \n"); + printf("kernel options are supported.\n\n"); + printf("Make sure that your system is set up to auto-load\n" + "your filesystem kernel module on mount.\n\n"); + printf("Enabling passphrase-mode only for now.\n\n"); + version = ECRYPTFS_VERSIONING_PASSPHRASE; + } + if ((rc = ecryptfs_validate_keyring())) { + printf("Unable to link the KEY_SPEC_USER_KEYRING into the " + "KEY_SPEC_SESSION_KEYRING; there is something wrong " + "with your kernel keyring. Did you build key retention " + "support into your kernel?\n"); + goto out; + } + mnt_params = malloc(sizeof(struct val_node)); + memset(mnt_params, 0, sizeof(struct val_node)); + memset(&ctx, 0, sizeof(struct ecryptfs_ctx)); + ctx.get_string = &get_string_stdin; + if ((rc = parse_arguments(argc, argv, NULL, NULL, &opts_str))) + goto out; + if (opts_str_contains_option(opts_str, "verbose")) + ecryptfs_verbosity = 1; + if (!opts_str_contains_option(opts_str, "remount")) { + if (opts_str_contains_option(opts_str, "no_sig_cache")) + sig_cache = 0; + if (opts_str_contains_option(opts_str, "no_prompt") + || opts_str_contains_option(opts_str, "wild_ass_guess")) { + if (!opts_str_contains_option(opts_str, + "verbosity=0")) { + char *tmp; + + rc = asprintf(&tmp, "%s,verbosity=0", opts_str); + if (rc == -1) { + rc = -ENOMEM; + goto out; + } + rc = 0; + opts_str = tmp; + } + } + if (opts_str_contains_option(opts_str, "verbosity=0")) + sig_cache = 0; + rc = ecryptfs_process_decision_graph( + &ctx, &mnt_params, version, opts_str, + ECRYPTFS_ASK_FOR_ALL_MOUNT_OPTIONS); + if (rc) { + if (rc > 0) + rc = -EINVAL; + printf("Error attempting to evaluate mount options: " + "[%d] %s\nCheck your system logs for details " + "on why this happened.\nTry updating your " + "ecryptfs-utils package, and/or\nsubmit a bug " + "report on https://bugs.launchpad.net/ecryptfs\n", + rc, strerror(-rc)); + goto out; + } + rc = ecryptfs_do_mount(argc, argv, mnt_params, sig_cache, pw); + if (rc == ECANCELED) { + rc = 0; + goto out; + } + if (rc) { + if (rc > 0) + rc = -rc; + printf("Error mounting eCryptfs: [%d] %s\n" + "Check your system logs; visit " + "<http://ecryptfs.org/support.html>\n", + rc, strerror(-rc)); + if (rc == -ENODEV) + printf("Try ``modprobe ecryptfs''\n"); + } else + printf("Mounted eCryptfs\n"); + } else { + fprintf(stderr, "When remounting eCryptfs, you need " + "to pass the mount utility the -i parameter to avoid " + "calling the mount helper\n"); + rc = -EINVAL; + } + +out: + munlockall(); + return rc; +} diff --git a/src/utils/mount.ecryptfs_private.c b/src/utils/mount.ecryptfs_private.c new file mode 100644 index 0000000..959c93b --- /dev/null +++ b/src/utils/mount.ecryptfs_private.c @@ -0,0 +1,724 @@ +/* + * This is an ecryptfs private directory mount/unmount helper program + * for non-root users. + * + * Copyright (C) 2008 Canonical Ltd. + * + * This code was originally written by Dustin Kirkland <kirkland@ubuntu.com>. + * Enhanced by Serge Hallyn <hallyn@ubuntu.com>. + * + * 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, see <http://www.gnu.org/licenses/>. + * + * On Debian-based systems, the complete text of the GNU General Public + * License can be found in /usr/share/common-licenses/GPL-2 + * + */ + +#include <sys/file.h> +#include <sys/mount.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <ctype.h> +#include <errno.h> +#include <keyutils.h> +#include <mntent.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <syslog.h> +#include <values.h> +#include "../include/ecryptfs.h" + +/* Perhaps a future version of this program will allow these to be configurable + * by the system administrator (or user?) at run time. For now, these are set + * to reasonable values to reduce the burden of input validation. + */ +#define KEY_BYTES 16 +#define KEY_CIPHER "aes" +#define FSTYPE "ecryptfs" +#define TMP "/dev/shm" + +int read_config(char *pw_dir, uid_t uid, char *alias, char **s, char **d, char **o) { +/* Read an fstab(5) style config file */ + char *fnam; + struct stat mstat; + struct mntent *e; + FILE *fin; + if (asprintf(&fnam, "%s/.ecryptfs/%s.conf", pw_dir, alias) < 0) { + perror("asprintf"); + return -1; + } + if (stat(fnam, &mstat)!=0 || (!S_ISREG(mstat.st_mode) || mstat.st_uid!=uid)) { + fputs("Bad file\n", stderr); + free(fnam); + return -1; + } + fin = fopen(fnam, "r"); + free(fnam); + if (!fin) { + perror("fopen"); + return -1; + } + e = getmntent(fin); + fclose(fin); + if (!e) { + perror("getmntent"); + return -1; + } + if (strcmp(e->mnt_type, "ecryptfs") != 0) { + fputs("Bad fs type\n", stderr); + return -1; + } + *o = strdup(e->mnt_opts); + if (!*o) + return -2; + *d = strdup(e->mnt_dir); + if (!*d) + return -2; + *s = strdup(e->mnt_fsname); + if (!*s) + return -2; + + return 0; +} + +int check_username(char *u) { +/* We follow the username guidelines used by the adduser program. Quoting its + * error message: + * adduser: To avoid problems, the username should consist only of + * letters, digits, underscores, periods, at signs and dashes, and not start + * with a dash (as defined by IEEE Std 1003.1-2001). For compatibility with + * Samba machine accounts $ is also supported at the end of the username + */ + int i; + char c; + int len; + + if (u == NULL) + goto empty; + len = strlen(u); + if (len == 0) + goto empty; + + for (i=0; i<len; i++) { + c = u[i]; + if ( !(c>='a' && c<='z') && !(c>='A' && c<='Z') && + !(c>='0' && c<='9') && + !(c=='_') && !(c=='.') && !(c=='@') && + !(c=='-' && i!=0) && + !(c=='$' && i==(len-1)) + ) { + fputs("Username has unsupported characters\n", stderr); + return 1; + } + } + return 0; +empty: + fputs("Username is empty\n", stderr); + return 1; +} + +char **fetch_sig(char *pw_dir, char *alias, int mounting) { +/* Read ecryptfs signature from file and validate + * Return signature as a string, or NULL on failure + */ + char *sig_file; + FILE *fh = NULL; + char **sig = NULL; + unsigned int i, j; + /* Construct sig file name */ + if (asprintf(&sig_file, "%s/.ecryptfs/%s.sig", pw_dir, alias) < 0) { + perror("asprintf"); + goto err; + } + fh = fopen(sig_file, "r"); + if (fh == NULL) { + perror("fopen"); + goto err; + } + /* Read up to 2 lines from the file */ + if ((sig = malloc(sizeof(char*) * 2)) == NULL) { + perror("malloc"); + goto err; + } + + sig[0] = NULL; + sig[1] = NULL; + for (i=0; i<2; i++) { + if ((sig[i] = (char *)malloc(KEY_BYTES*sizeof(char)+2)) == NULL) { + perror("malloc"); + goto err; + } + memset(sig[i], '\0', KEY_BYTES+2); + /* Read KEY_BYTES characters from line */ + if (fgets(sig[i], KEY_BYTES+2, fh) == NULL) { + if (i == 0) { + fputs("Missing file encryption signature", stderr); + goto err; + } else { + /* Filename encryption isn't in use */ + free(sig[i]); + sig[i] = NULL; + goto out; + } + } + /* Validate hex signature */ + for (j=0; j<strlen(sig[i]); j++) { + if (isxdigit(sig[i][j]) == 0 && isspace(sig[i][j]) == 0) { + fputs("Invalid hex signature\n", stderr); + goto err; + } + if (isspace(sig[i][j]) != 0) { + /* truncate at first whitespace */ + sig[i][j] = '\0'; + } + } + if (strlen(sig[i]) > 0 && strlen(sig[i]) != KEY_BYTES) { + fputs("Invalid hex signature length\n", stderr); + goto err; + } + /* Validate that signature is in the current keyring, + * compile with -lkeyutils + */ + if (keyctl_search(KEY_SPEC_USER_KEYRING, "user", sig[i], 0) < 0) { + if (mounting) + fputs("Signature not found in user keyring\n" + "Perhaps try the interactive " + "'ecryptfs-mount-private'\n", stderr); + goto err; + } + } +out: + if (fh != NULL) { + fclose(fh); + } + return sig; +err: + if (fh) { + fclose(fh); + } + /* Clean up malloc'd memory if failure */ + if (sig) { + free(sig[0]); + free(sig[1]); + free(sig); + } + return NULL; +} + +int check_ownership_mnt(uid_t uid, char **mnt) { +/* Check ownership of mount point, chdir into it, and + * canonicalize the path for use in mtab updating. + * Return 0 if everything is in order, 1 on error. + */ + struct stat s; + char *cwd; + + /* From here on, we'll refer to "." as our mountpoint, to avoid + * races. + */ + if (chdir(*mnt) != 0) { + fputs("Cannot chdir into mountpoint.\n", stderr); + return 1; + } + if (stat(".", &s) != 0) { + fputs("Cannot examine mountpoint.\n", stderr); + return 1; + } + if (!S_ISDIR(s.st_mode)) { + fputs("Mountpoint is not a directory.\n", stderr); + return 1; + } + if (s.st_uid != uid) { + fputs("You do not own that mountpoint.\n", stderr); + return 1; + } + + /* Canonicalize our pathname based on the current directory to + * avoid races. + */ + cwd = getcwd(NULL, 0); + if (!cwd) { + fputs("Failed to get current directory\n", stderr); + return 1; + } + *mnt = cwd; + return 0; +} + + +int check_ownerships(uid_t uid, char *path) { +/* Check ownership of device and mount point. + * Return 0 if everything is in order, 1 on error. + */ + struct stat s; + if (stat(path, &s) != 0) { + fputs("Cannot examine encrypted directory\n", stderr); + return 1; + } + if (!S_ISDIR(s.st_mode)) { + fputs("Device or mountpoint is not a directory\n", stderr); + return 1; + } + if (s.st_uid != uid) { + fputs("You do not own that encrypted directory\n", stderr); + return 1; + } + return 0; +} + + +int update_mtab(char *dev, char *mnt, char *opt) { +/* Update /etc/mtab with new mount entry unless it is a symbolic link + * Return 0 on success, 1 on failure. + */ + char dummy; + int useMtab; + /* Check if mtab is a symlink */ + useMtab = (readlink("/etc/mtab", &dummy, 1) < 0); + if (!useMtab) { + /* No need updating mtab */ + return 0; + } + + int fd; + FILE *old_mtab, *new_mtab; + struct mntent *old_ent, new_ent; + mode_t old_umask; + + /* Make an attempt to play nice with other mount helpers + * by creating an /etc/mtab~ lock file. Of course this + * only works if those other helpers actually check for + * this. + */ + old_umask = umask(033); + fd = open("/etc/mtab~", O_RDONLY | O_CREAT | O_EXCL, 0644); + if (fd < 0) { + perror("open"); + return 1; + } + close(fd); + + old_mtab = setmntent("/etc/mtab", "r"); + if (old_mtab == NULL) { + perror("setmntent"); + return 1; + } + + new_mtab = setmntent("/etc/mtab.tmp", "w"); + if (new_mtab == NULL) { + perror("setmntent"); + goto fail_early; + } + + while ((old_ent = getmntent(old_mtab))) { + if (addmntent(new_mtab, old_ent) != 0) { + perror("addmntent"); + goto fail; + } + } + endmntent(old_mtab); + + new_ent.mnt_fsname = dev; + new_ent.mnt_dir = mnt; + new_ent.mnt_type = FSTYPE; + new_ent.mnt_opts = opt; + new_ent.mnt_freq = 0; + new_ent.mnt_passno = 0; + + if (addmntent(new_mtab, &new_ent) != 0) { + perror("addmntent"); + goto fail; + } + + if (fchmod(fileno(new_mtab), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) { + perror("fchmod"); + goto fail; + } + endmntent(new_mtab); + + if (rename("/etc/mtab.tmp", "/etc/mtab") < 0) { + perror("rename"); + goto fail_late; + } + + unlink("/etc/mtab~"); + + umask(old_umask); + + return 0; + +fail: + endmntent(new_mtab); +fail_late: + unlink("/etc/mtab.tmp"); +fail_early: + endmntent(old_mtab); + unlink("/etc/mtab~"); + umask(old_umask); + return 1; +} + +FILE *lock_counter(char *u, uid_t uid, char *alias) { + char *f; + int fd; + FILE *fh; + struct stat s; + int i = 1; + /* We expect TMP to exist, be writeable by the user, + * and to be cleared on boot */ + if (asprintf(&f, "%s/%s-%s-%s", TMP, FSTYPE, u, alias) < 0) { + perror("asprintf"); + return NULL; + } + /* If the counter path exists, and it's either not a regular + * file, or it's not owned by the current user, append iterator + * until we find a filename we can use. + */ + while (i < 50) { + if (((fd = open(f, O_RDWR | O_CREAT | O_NOFOLLOW, 0600)) >= 0) && + (fstat(fd, &s)==0 && (S_ISREG(s.st_mode) && s.st_uid==uid))) { + break; + } else { + if (fd >= 0) { + close(fd); + fd = -1; + } + free(f); + if (asprintf(&f, "%s/%s-%s-%s-%d", TMP, FSTYPE, u, + alias, i++) < 0) { + perror("asprintf"); + return NULL; + } + } + } + + if (fd < 0) { + perror("open"); + return NULL; + } + + flock(fd, LOCK_EX); + fh = fdopen(fd, "r+"); + if (fh == NULL) { + perror("fopen"); + close(fd); + return NULL; + } + return fh; +} + +void unlock_counter(FILE *fh) { + if (fh != NULL) { + /* This should remove the lock too */ + fclose(fh); + } +} + +int bump_counter(FILE *fh, int delta) { +/* Maintain a mount counter + * increment on delta = 1 + * decrement on delta = -1 + * remove the counter file on delta = 0 + * return the updated count, negative on error + */ + int count; + /* Read the count from file, default to 0 */ + rewind(fh); + if (fscanf(fh, "%d\n", &count) != 1) { + count = 0; + } + /* Increment/decrement the counter */ + count += delta; + if (count < 0) { + /* Never set a count less than 0 */ + count = 0; + } + /* Write the count to file */ + rewind(fh); + fprintf(fh, "%d\n", count); + fflush(fh); + return count; +} + + +int increment(FILE *fh) { +/* Bump counter up */ + return bump_counter(fh, 1); +} + + +int decrement(FILE *fh) { +/* Bump counter down */ + return bump_counter(fh, -1); +} + +int zero(FILE *fh) { +/* Zero the counter file */ + return bump_counter(fh, -MAXINT+1); +} + + +/* This program is a setuid-executable allowing a non-privileged user to mount + * and unmount an ecryptfs private directory. This program is necessary to + * keep from adding such entries to /etc/fstab. + * + * A single executable is created and hardlinked to two different names. + * The mode of operation (mounting|unmounting) is determined by examining + * the name of the executable. "Mounting" mode is assumed, unless the + * executable contains the string "umount". + * Example: + * /sbin/mount.ecryptfs_private + * /sbin/umount.ecryptfs_private + * + * At the moment, this program: + * - mounts ~/.Private onto ~/Private + * - as an ecryptfs filesystem + * - using the AES cipher + * - with a key length of 16 bytes + * - and using the signature defined in ~/.ecryptfs/Private.sig + * - ONLY IF the user + * - has the signature's key in his keyring + * - owns both ~/.Private and ~/Private + * - is not already mounted + * - unmounts ~/.Private from ~/Private + * - using the signature defined in ~/.ecryptfs/Private.sig + * - ONLY IF the user + * - owns both ~/.Private and ~/Private + * - is currently ecryptfs mounted + * + * The only setuid operations in this program are: + * a) mounting + * b) unmounting + * c) updating /etc/mtab + */ +int main(int argc, char *argv[]) { + uid_t uid; + gid_t gid; + int mounting; + int force = 0; + struct passwd *pwd; + char *alias, *src, *dest, *opt, *opts2; + char *sig_fekek = NULL, *sig_fnek = NULL; + char **sigs; + FILE *fh_counter = NULL; + + uid = getuid(); + gid = getgid(); + /* Non-privileged effective uid is sufficient for all but the code + * that mounts, unmounts, and updates /etc/mtab. + * Run at a lower privilege until we need it. + */ + if (seteuid(uid)<0 || geteuid()!=uid) { + perror("setuid"); + goto fail; + } + if ((pwd = getpwuid(uid)) == NULL) { + perror("getpwuid"); + goto fail; + } + + /* If no arguments, default to private dir; but accept at most one + argument, an alias for the configuration to read and use. + */ + if (argc == 1) { + /* Use default source and destination dirs */ + alias = ECRYPTFS_PRIVATE_DIR; + if ((asprintf(&src, "%s/.%s", pwd->pw_dir, alias) < 0) || src == NULL) { + perror("asprintf (src)"); + goto fail; + } + dest = ecryptfs_fetch_private_mnt(pwd->pw_dir); + if (dest == NULL) { + perror("asprintf (dest)"); + goto fail; + } + } else if (argc == 2) { + alias = argv[1]; + /* Read the source and destination dirs from .conf file */ + if (read_config(pwd->pw_dir, uid, alias, &src, &dest, &opts2) < 0) { + fputs("Error reading configuration file\n", stderr); + exit(1); + } + if (opts2 != NULL && strlen(opts2) != 0 && strcmp(opts2, "none") != 0) { + fputs("Mount options are not supported here\n", stderr); + exit(1); + } + } else { + fputs("Too many arguments\n", stderr); + exit(1); + } + + if (strstr(alias, "..")) { + fputs("Invalid alias", stderr); + exit(1); + } + + /* Lock the counter through the rest of the program */ + fh_counter = lock_counter(pwd->pw_name, uid, alias); + if (fh_counter == NULL) { + fputs("Error locking counter\n", stderr); + goto fail; + } + + if (check_username(pwd->pw_name) != 0) { + /* Must protect against a crafted user=john,suid from entering + * filesystem options + */ + goto fail; + } + + /* Determine if mounting or unmounting by looking at the invocation */ + if (strstr(argv[0], "umount") == NULL) { + mounting = 1; + } else { + mounting = 0; + /* Determine if unmounting is forced */ + if (argv[1] != NULL && strncmp(argv[1], "-f", 2) == 0) { + force = 1; + } else { + force = 0; + } + } + + /* Fetch signatures from file */ + /* First line is the file content encryption key signature */ + /* Second line, if present, is the filename encryption key signature */ + sigs = fetch_sig(pwd->pw_dir, alias, mounting); + if (!sigs && mounting) { + /* if umounting, no sig is ok */ + goto fail; + } else if (sigs) { + sig_fekek = sigs[0]; + sig_fnek = sigs[1]; + } + + /* Build mount options */ + if ( + (asprintf(&opt, "ecryptfs_check_dev_ruid,ecryptfs_cipher=%s,ecryptfs_key_bytes=%d,ecryptfs_unlink_sigs%s%s%s%s", + KEY_CIPHER, + KEY_BYTES, + sig_fekek ? ",ecryptfs_sig=" : "", + sig_fekek ? sig_fekek : "", + sig_fnek ? ",ecryptfs_fnek_sig=" : "", + sig_fnek ? sig_fnek : "" + ) < 0 + ) || opt == NULL + ) { + perror("asprintf (opt)"); + goto fail; + } + + /* Check ownership of the mountpoint. From here on, dest refers + * to a canonicalized path, and the mountpoint is the cwd. */ + if (check_ownership_mnt(uid, &dest) != 0) { + goto fail; + } + + if (mounting == 1) { + /* Increment mount counter, errors non-fatal */ + if (increment(fh_counter) < 0) { + fputs("Error incrementing mount counter\n", stderr); + } + /* Mounting, so exit if already mounted */ + if (ecryptfs_private_is_mounted(src, dest, sig_fekek, mounting) == 1) { + goto success; + } + /* We must maintain our real uid as the user who called this + * program in order to have access to their kernel keyring. + * Even though root has the power to mount, only a user with + * the correct key in their keyring can mount an ecryptfs + * directory correctly. + * Root does not necessarily have the user's key, so we need + * the real uid to be that of the user. + * And we need the effective uid to be root in order to mount. + */ + if (setreuid(-1, 0) < 0) { + perror("setreuid"); + goto fail; + } + if (setregid(-1, 0) < 0) { + perror("setregid"); + goto fail; + } + /* Perform mount */ + if (mount(src, ".", FSTYPE, MS_NOSUID | MS_NODEV, opt) == 0) { + if (update_mtab(src, dest, opt) != 0) { + goto fail; + } + } else { + perror("mount"); + /* Drop privileges since the mount did not succeed */ + if (setreuid(uid, uid) < 0) { + perror("setreuid"); + } + if (setregid(gid, gid) < 0) { + perror("setregid"); + } + goto fail; + } + } else { + int rc = 0; + /* Decrement counter, exiting if >0, and non-forced unmount */ + if (force == 1) { + zero(fh_counter); + } else if (decrement(fh_counter) > 0) { + fputs("Sessions still open, not unmounting\n", stderr); + goto fail; + } + /* Attempt to clear the user's keys from the keyring, + to prevent root from mounting without the user's key. + This is a best-effort basis, so we'll just print messages + on error. */ + if (sig_fekek != NULL) { + rc = ecryptfs_remove_auth_tok_from_keyring(sig_fekek); + if (rc != 0 && rc != ENOKEY) + fputs("Could not remove key from keyring, try 'ecryptfs-umount-private'\n", stderr); + } + if (sig_fnek != NULL) { + rc = ecryptfs_remove_auth_tok_from_keyring(sig_fnek); + if (rc != 0 && rc != ENOKEY) + fputs("Could not remove key from keyring, try 'ecryptfs-umount-private'\n", stderr); + } + /* Unmounting, so exit if not mounted */ + if (ecryptfs_private_is_mounted(src, dest, sig_fekek, mounting) == 0) { + goto fail; + } + /* The key is not needed for unmounting, so we set res=0. + * Perform umount by calling umount utility. This execl will + * update mtab for us, and replace the current process. + * Do not use the umount.ecryptfs helper (-i). + */ + setresuid(0,0,0); + setresgid(0,0,0); + clearenv(); + + /* Since we're doing a lazy unmount anyway, just unmount the current + * directory. This avoids a lot of complexity in dealing with race + * conditions, and guarantees that we're only unmounting a filesystem + * that we own. */ + execl("/bin/umount", "umount", "-i", "-l", ".", NULL); + perror("execl unmount failed"); + goto fail; + } +success: + unlock_counter(fh_counter); + return 0; +fail: + unlock_counter(fh_counter); + return 1; +} diff --git a/src/utils/plaintext_decision_graph.c b/src/utils/plaintext_decision_graph.c new file mode 100644 index 0000000..0bb84d0 --- /dev/null +++ b/src/utils/plaintext_decision_graph.c @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2006 International Business Machines + * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "../include/ecryptfs.h" +#include "../include/decision_graph.h" + +struct param_node plaintext_arr[] = { + {.num_mnt_opt_names = 1, + .mnt_opt_names = {"passthrough"}, + .prompt = "Enable Plaintext Passthrough", + .val_type = VAL_STR, + .val = NULL, + .display_opts = NULL, + .default_val = "0", + .flags = 0, + .num_transitions = 2, + .tl = {{.val = "1", + .pretty_val = "Yes", + .next_token = NULL, + .trans_func = NULL}, + {.val = "0", + .pretty_val = "No", + .next_token = NULL, + .trans_func = NULL}}} +}; diff --git a/src/utils/test.c b/src/utils/test.c new file mode 100644 index 0000000..d844283 --- /dev/null +++ b/src/utils/test.c @@ -0,0 +1,480 @@ +/** + * Copyright (C) 2006 International Business Machines + * Written by Michael A. Halcrow <mhalcrow@us.ibm.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "ecryptfs.h" + +#define ASSERT(EX) \ +do { \ + if (!(EX)) { \ + printf("ASSERTION FAILED: %s at %s:%d (%s)\n", #EX, \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ +} while (0) + +struct ecryptfs_crypt_stat { + int header_extent_size; + int num_header_extents_at_front; + int extent_size; +}; + +void +ecryptfs_extent_to_lwr_pg_idx_and_offset(unsigned long *lower_page_idx, + int *byte_offset, + struct ecryptfs_crypt_stat *crypt_stat, + unsigned long extent_num, + int page_size) +{ + unsigned long lower_extent_num; + int extents_occupied_by_headers_at_front; + int bytes_occupied_by_headers_at_front; + int extent_offset; + int extents_per_page; + + bytes_occupied_by_headers_at_front = + ( crypt_stat->header_extent_size + * crypt_stat->num_header_extents_at_front ); + extents_occupied_by_headers_at_front = + ( bytes_occupied_by_headers_at_front + / crypt_stat->extent_size ); + lower_extent_num = extents_occupied_by_headers_at_front + extent_num; + extents_per_page = page_size / crypt_stat->extent_size; + (*lower_page_idx) = lower_extent_num / extents_per_page; + extent_offset = lower_extent_num % extents_per_page; + (*byte_offset) = extent_offset * crypt_stat->extent_size; +} + +struct translation_test_vector_element { + int page_size; + unsigned long header_extent_size; + int num_header_extents_at_front; + unsigned long extent_num; + unsigned long lower_page_idx; + int byte_offset; +}; + +#define ECRYPTFS_EXTENT_SIZE 4096 /* Test vector only valid for 4096 */ + +struct translation_test_vector_element translation_test_vector[] = { + {4096, 8192, 1, 0, 2, 0}, + {4096, 8192, 1, 1, 3, 0}, + {4096, 8192, 1, 2, 4, 0}, + {4096, 8192, 1, 3, 5, 0}, + {8192, 8192, 1, 0, 1, 0}, + {8192, 8192, 1, 1, 1, 4096}, + {8192, 8192, 1, 2, 2, 0}, + {8192, 8192, 1, 3, 2, 4096}, + {8192, 8192, 1, 4, 3, 0}, + {16384, 8192, 1, 0, 0, 8192}, + {16384, 8192, 1, 1, 0, 12288}, + {16384, 8192, 1, 2, 1, 0}, + {16384, 8192, 1, 3, 1, 4096}, + {16384, 8192, 1, 4, 1, 8192}, + {16384, 8192, 1, 5, 1, 12288}, + {16384, 8192, 1, 6, 2, 0}, +}; + +int test_extent_translation(void) +{ + struct ecryptfs_crypt_stat crypt_stat; + unsigned long lower_page_idx; + int byte_offset; + int rc = 0; + size_t i; + + printf("Testing ecryptfs_extent_to_lwr_pg_idx_and_offset()... "); + crypt_stat.extent_size = ECRYPTFS_EXTENT_SIZE; + for (i = 0; + i < (sizeof(translation_test_vector) + / sizeof(struct translation_test_vector_element)); + i++) { + crypt_stat.header_extent_size = + translation_test_vector[i].header_extent_size; + crypt_stat.num_header_extents_at_front = + translation_test_vector[i].num_header_extents_at_front; + ecryptfs_extent_to_lwr_pg_idx_and_offset( + &lower_page_idx, &byte_offset, &crypt_stat, + translation_test_vector[i].extent_num, + translation_test_vector[i].page_size); + if (lower_page_idx + != translation_test_vector[i].lower_page_idx) { + rc = -1; + printf("\nError on test vector entry [%zu]; " + "lower_page_idx = [%lu]\n", i, lower_page_idx); + goto out; + } + if (byte_offset + != translation_test_vector[i].byte_offset) { + rc = -1; + printf("\nError on test vector entry [%zd]; " + "byte offset = [%d]\n", i, byte_offset); + goto out; + } + } +out: + if (!rc) { + printf("Pass\n"); + } + return rc; +} + +struct page { + unsigned long index; +}; + +struct inode { +}; + +struct file { +}; + +struct writeback_control { +}; + +struct ecryptfs_page_crypt_context { + struct page *page; +#define ECRYPTFS_PREPARE_COMMIT_MODE 0 +#define ECRYPTFS_WRITEPAGE_MODE 1 + int mode; + union { + struct file *lower_file; + struct writeback_control *wbc; + } param; +}; + +void ecryptfs_unmap_and_release_lower_page(struct page *lower_page) +{ + printf("%s: Called w/ lower_page = [%p]\n", __FUNCTION__, lower_page); + free(lower_page); +} + +int +ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode, + struct file *lower_file, int byte_offset, + int region_size) +{ + int rc = 0; + + printf("%s: Called w/ lower_page = [%p], lower_inode = [%p], " + "lower_file = [%p], byte_offset = [%d], region_size = [%d]\n", + __FUNCTION__, + lower_page, lower_inode, lower_file, byte_offset, region_size); + ecryptfs_unmap_and_release_lower_page(lower_page); + return rc; +} + +int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, + struct inode *lower_inode, + struct writeback_control *wbc) +{ + printf("%s: Called w/ lower_page = [%p], lower_inode = [%p], wbc = " + "[%p]\n", __FUNCTION__, lower_page, lower_inode, wbc); + return 0; +} + +int ecryptfs_write_out_page(struct ecryptfs_page_crypt_context *ctx, + struct page *lower_page, struct inode *lower_inode, + int byte_offset_in_page, int bytes_to_write) +{ + int rc = 0; + + rc = ecryptfs_commit_lower_page(lower_page, lower_inode, + NULL, + byte_offset_in_page, + bytes_to_write); + return rc; +} + +int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, + struct file *lower_file, + unsigned long lower_page_index, int byte_offset, + int region_bytes) +{ + printf("%s: Called w/ **lower_page = [%p], lower_inode = [%p], " + "lower_file = [%p], lower_page_index = [%lu], byte_offset = " + "[%d], region_bytes = [%d]\n", __FUNCTION__, lower_page, + lower_inode, lower_file, lower_page_index, byte_offset, + region_bytes); + printf("[Call to prepare_write]\n"); + (*lower_page) = (struct page *)malloc(sizeof(struct page)); + (*lower_page)->index = lower_page_index; + return 0; +} + +int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx, + struct page **lower_page, struct inode *lower_inode, + unsigned long lower_page_idx, int byte_offset_in_page, + int page_cache_size) +{ + int rc = 0; + + printf("%s: Called w/ **lower_page = [%p], lower_inode = [%p]; " + "lower_page_idx " + "= [%lu], byte_offset_in_page = [%d]\n", __FUNCTION__, + lower_page, lower_inode, + lower_page_idx, byte_offset_in_page); + rc = ecryptfs_get_lower_page(lower_page, lower_inode, + NULL, + lower_page_idx, + byte_offset_in_page, + (page_cache_size + - byte_offset_in_page)); + return rc; +} + +int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, + unsigned long offset) +{ + printf("%s: Called w/ offset = [%lu]\n", __FUNCTION__, offset); + return 0; +} + +int +ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, + struct page *dst_page, int dst_offset, + struct page *src_page, int src_offset, int size, + unsigned char *iv) +{ + printf("%s: Called:\n * dst_page->index = [%lu]\n * dst_offset = [%d]\n" + " * src_page->index = [%lu]\n * src_offset = [%d]\n", + __FUNCTION__, dst_page->index, dst_offset, src_page->index, + src_offset); + return 0; +} + +#define ECRYPTFS_MAX_IV_BYTES 16 + +int ecryptfs_encrypt_page(int page_cache_size, int extent_size, + struct page *page, int header_extent_size, + int num_header_extents_at_front) +{ + char extent_iv[ECRYPTFS_MAX_IV_BYTES]; + unsigned long base_extent; + unsigned long extent_offset = 0; + unsigned long lower_page_idx = 0; + unsigned long prior_lower_page_idx = 0; + unsigned int num_extents_per_page; + struct page *lower_page; + struct inode *lower_inode; + struct ecryptfs_crypt_stat *crypt_stat; + int rc = 0; + int lower_byte_offset = 0; + int orig_byte_offset = 0; +#define ECRYPTFS_PAGE_STATE_UNREAD 0 +#define ECRYPTFS_PAGE_STATE_READ 1 +#define ECRYPTFS_PAGE_STATE_MODIFIED 2 +#define ECRYPTFS_PAGE_STATE_WRITTEN 3 + int page_state; + + crypt_stat = (struct ecryptfs_crypt_stat *)malloc( + sizeof(struct ecryptfs_crypt_stat)); + if (!crypt_stat) { + rc = 1; + goto out; + } + crypt_stat->extent_size = extent_size; + crypt_stat->header_extent_size = header_extent_size; + crypt_stat->num_header_extents_at_front = num_header_extents_at_front; + + lower_inode = NULL; + num_extents_per_page = page_cache_size / crypt_stat->extent_size; + base_extent = (page->index * num_extents_per_page); + page_state = ECRYPTFS_PAGE_STATE_UNREAD; + while (extent_offset < num_extents_per_page) { + ecryptfs_extent_to_lwr_pg_idx_and_offset( + &lower_page_idx, &lower_byte_offset, crypt_stat, + (base_extent + extent_offset), page_cache_size); + if (prior_lower_page_idx != lower_page_idx + && page_state == ECRYPTFS_PAGE_STATE_MODIFIED) { + rc = ecryptfs_write_out_page(NULL, lower_page, + lower_inode, + orig_byte_offset, + (page_cache_size + - orig_byte_offset)); + page_state = ECRYPTFS_PAGE_STATE_WRITTEN; + } + if (page_state == ECRYPTFS_PAGE_STATE_UNREAD + || page_state == ECRYPTFS_PAGE_STATE_WRITTEN) { + rc = ecryptfs_read_in_page(NULL, &lower_page, + lower_inode, lower_page_idx, + lower_byte_offset, + page_cache_size); + orig_byte_offset = lower_byte_offset; + prior_lower_page_idx = lower_page_idx; + page_state = ECRYPTFS_PAGE_STATE_READ; + } + ASSERT(page_state == ECRYPTFS_PAGE_STATE_MODIFIED + || page_state == ECRYPTFS_PAGE_STATE_READ); + rc = ecryptfs_derive_iv(extent_iv, crypt_stat, + (base_extent + extent_offset)); + rc = ecryptfs_encrypt_page_offset( + crypt_stat, lower_page, lower_byte_offset, page, + (extent_offset * crypt_stat->extent_size), + crypt_stat->extent_size, (unsigned char *)extent_iv); + page_state = ECRYPTFS_PAGE_STATE_MODIFIED; + extent_offset++; + } + ASSERT(orig_byte_offset == 0); + rc = ecryptfs_write_out_page(NULL, lower_page, lower_inode, 0, + (lower_byte_offset + + crypt_stat->extent_size)); +out: + if (crypt_stat) + free(crypt_stat); + return rc; +} + +int test_encrypt(void) +{ + int rc = 0; + struct page page; + + page.index = 0; + /* int ecryptfs_encrypt_page(int page_cache_size, int extent_size, + struct page *page, int header_extent_size, + int num_header_extents_at_front) */ + rc = ecryptfs_encrypt_page(16384, /* page_cache_size */ + 4096, /* extent_size */ + &page, + 8192, /* header size */ + 1); /* num_headers */ + return rc; +} + +unsigned long +upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, + unsigned long upper_size) +{ + unsigned long lower_size; + + lower_size = ( crypt_stat->header_extent_size + * crypt_stat->num_header_extents_at_front ); + if (upper_size != 0) { + unsigned long num_extents; + + num_extents = upper_size / crypt_stat->extent_size; + if (upper_size % crypt_stat->extent_size) + num_extents++; + lower_size += (num_extents * crypt_stat->extent_size); + } + return lower_size; +} + +struct upper_lower_test_vector_element { + unsigned long header_extent_size; + int num_header_extents_at_front; + int extent_size; + unsigned long upper_size; + unsigned long lower_size; +}; + +struct upper_lower_test_vector_element upper_lower_test_vector[] = { + {8192, 1, 4096, 0, 8192}, + {8192, 1, 4096, 1, 12288}, + {8192, 1, 4096, 2, 12288}, + {8192, 1, 4096, 4094, 12288}, + {8192, 1, 4096, 4095, 12288}, + {8192, 1, 4096, 4096, 12288}, + {8192, 1, 4096, 4097, 16384}, + {8192, 1, 4096, 4098, 16384}, + {8192, 1, 4096, 8191, 16384}, + {8192, 1, 4096, 8192, 16384}, + {8192, 1, 4096, 8193, 20480} +}; + +int test_upper_size_to_lower_size(void) +{ + int rc = 0; + unsigned long lower_size; + struct ecryptfs_crypt_stat crypt_stat; + size_t i; + + for (i = 0; + i < (sizeof(upper_lower_test_vector) + / sizeof(struct upper_lower_test_vector_element)); + i++) { + crypt_stat.header_extent_size = + upper_lower_test_vector[i].header_extent_size; + crypt_stat.num_header_extents_at_front = + upper_lower_test_vector[i].num_header_extents_at_front; + crypt_stat.extent_size = upper_lower_test_vector[i].extent_size; + lower_size = upper_size_to_lower_size( + &crypt_stat, upper_lower_test_vector[i].upper_size); + if (lower_size != upper_lower_test_vector[i].lower_size) { + printf("Unexpected lower size [%lu] for upper size " + "[%lu]\n", lower_size, + upper_lower_test_vector[i].upper_size); + rc = -1; + goto out; + } + } +out: + return rc; +} + +int test_nv_list_from_file(void) +{ + int rc = 0; + struct ecryptfs_name_val_pair nv_pair_head; + struct ecryptfs_name_val_pair *cursor; + int fd; + + nv_pair_head.next = NULL; + fd = open("ecryptfsrc", O_RDONLY); + if (fd == -1) { + rc = -EIO; + goto out; + } + rc = parse_options_file(fd, &nv_pair_head); + close(fd); + cursor = nv_pair_head.next; + while (cursor) { + printf("cursor->name = [%s]\n", cursor->name); + printf("cursor->value = [%s]\n\n", cursor->value); + cursor = cursor->next; + } +out: + return rc; +} + +int main() +{ + int rc = 0; + + rc = test_nv_list_from_file(); + goto out; + rc = test_extent_translation(); + if (rc) + goto out; + rc = test_encrypt(); + if (rc) + goto out; + rc = test_upper_size_to_lower_size(); + if (rc) + goto out; +out: + return rc; +} diff --git a/src/utils/umount.ecryptfs.c b/src/utils/umount.ecryptfs.c new file mode 100644 index 0000000..46eaeea --- /dev/null +++ b/src/utils/umount.ecryptfs.c @@ -0,0 +1,190 @@ +/** + * Copyright (C) 2009 International Business Machines + * Author(s): Tyler Hicks <tyhicks@linux.vnet.ibm.com> + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <errno.h> +#include <mntent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "ecryptfs.h" + +static void usage() +{ + fprintf(stderr, "\teCryptfs umount helper\n\tusage: " + "umount [ecryptfs mount point]\n" + ); + exit(-EINVAL); +} + + /** + * Parses a string of mount options, searching for an option name, and returns + * a pointer to the option value. For example, if name was "ecryptfs_sig=", + * it would set value to a string containing the sig, up to the first + * comma or NULL character in the mount options. Name must end with an = sign. + * value must be freed by the caller. + */ +static int get_mount_opt_value(char *mnt_opts, char *name, char **value) +{ + char *name_start, *val_start, *val_stop; + size_t name_len, val_len; + int rc = 0; + + name_len = strlen(name); + if (name[name_len - 1] != '=') { + rc = EINVAL; + goto out; + } + + name_start = strstr(mnt_opts, name); + if (!name_start) { + rc = EINVAL; + goto out; + } + + val_start = name_start + name_len; + val_stop = strstr(val_start, ","); + if (!val_stop) + val_stop = mnt_opts + strlen(mnt_opts); + + val_len = val_stop - val_start; + *value = malloc(val_len + 1); + if (!(*value)) { + rc = ENOMEM; + goto out; + } + memcpy(*value, val_start, val_len); + (*value)[val_len] = '\0'; +out: + return rc; +} + +static int unlink_keys_from_keyring(const char *mnt_point) +{ + struct mntent *mntent; + FILE *file; + char *fekek_sig = NULL, *fnek_sig = NULL; + int fekek_fail = 0, fnek_fail = 0; + int rc; + + file = setmntent("/etc/mtab", "r"); + if (!file) { + rc = EINVAL; + goto out; + } + while ((mntent = getmntent(file))) { + if (strcmp("ecryptfs", mntent->mnt_type)) + continue; + if (strcmp(mnt_point, mntent->mnt_dir)) + continue; + break; + } + if (!mntent) { + rc = EINVAL; + goto end_out; + } + if (!hasmntopt(mntent, "ecryptfs_unlink_sigs")) { + rc = 0; + goto end_out; + } + rc = get_mount_opt_value(mntent->mnt_opts, "ecryptfs_sig=", &fekek_sig); + if (!rc) { + fekek_fail = ecryptfs_remove_auth_tok_from_keyring(fekek_sig); + if (fekek_fail == ENOKEY) + fekek_fail = 0; + if (fekek_fail) + fprintf(stderr, "Failed to remove fekek with sig [%s] " + "from keyring: %s\n", fekek_sig, + strerror(fekek_fail)); + } else { + fekek_fail = rc; + } + if (!get_mount_opt_value(mntent->mnt_opts, + "ecryptfs_fnek_sig=", &fnek_sig) + && strcmp(fekek_sig, fnek_sig)) { + fnek_fail = ecryptfs_remove_auth_tok_from_keyring(fnek_sig); + if (fnek_fail == ENOKEY) + fnek_fail = 0; + if (fnek_fail) { + fprintf(stderr, "Failed to remove fnek with sig [%s] " + "from keyring: %s\n", fnek_sig, + strerror(fnek_fail)); + } + } + free(fekek_sig); + free(fnek_sig); +end_out: + endmntent(file); +out: + return (fekek_fail ? fekek_fail : (fnek_fail ? fnek_fail : rc)); +} + +static int construct_umount_args(int argc, char **argv, char ***new_argv) +{ + int new_argc = argc + 1; + int i, rc; + + *new_argv = malloc(sizeof(char *) * (new_argc + 1)); + if (!*new_argv) { + rc = errno; + goto out; + } + (*new_argv)[0] = "umount"; + (*new_argv)[1] = "-i"; + for (i = 2; i < new_argc; i++) + (*new_argv)[i] = argv[i - 1]; + (*new_argv)[i] = NULL; + rc = 0; +out: + return rc; +} + +#define UMOUNT_PATH "/bin/umount" +int main(int argc, char **argv) +{ + char **new_argv; + int rc; + + if (argc<2) + usage(); + + if (unlink_keys_from_keyring(argv[1])) + fprintf(stderr, "Could not unlink the key(s) from your keying. " + "Please use `keyctl unlink` if you wish to remove the " + "key(s). Proceeding with umount.\n"); + rc = construct_umount_args(argc, argv, &new_argv); + if (rc) { + fprintf(stderr, "Failed to construct umount arguments: %s\n", + strerror(rc)); + goto out; + } + rc = execv(UMOUNT_PATH, new_argv); + if (rc < 0) { + rc = errno; + fprintf(stderr, "Failed to execute %s: %m\n", UMOUNT_PATH); + goto free_out; + } + rc = 0; +free_out: + free(new_argv); +out: + return rc; +} + |